home *** CD-ROM | disk | FTP | other *** search
- /*
- * tmUtils.c --
- * This module contains general purpose routines
- * used by the Tm toolkit.
- *
- * Copyright 1993 Jan Newmarch, University of Canberra.
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The author
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #include <sys/time.h>
- #include <ctype.h>
- #include <X11/keysym.h>
- #include "tm.h"
- #include "tmFuncs.h"
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_StoreWidgetInfo --
- *
- * create a hash table entry for a new widget, with useful
- * info in it.
- *
- * Results:
- *
- * modifies hash table in "interp"
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
- void
- Tm_StoreWidgetInfo(path, w, interp)
- char *path;
- Tm_Widget *w;
- Tcl_Interp *interp;
- {
- int new;
- Tcl_HashEntry *hPtr;
-
- /*
- hPtr = Tcl_CreateHashEntry(&WidgetTable, path, &new);
- Tcl_SetHashValue(hPtr, (ClientData) w);
- */
- }
-
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_NameFromPath --
- *
- * find the part of the path after the last '.'
- *
- * Results:
- *
- * returns a pointer to the name
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
- char *
- Tm_NameFromPath(pathName)
- char *pathName;
- {
- char *p;
-
- if ((p = strrchr(pathName, '.')) == NULL) {
- return pathName;
- } else {
- return (p + 1);
- }
- }
-
-
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_HiddenParentPath --
- *
- * Create a path based on current path that cannot be duplicated
- * actually, makes "first.last" into "first..last"
- *
- * Results:
- *
- * returns a pointer to the name
- *
- * Side effects:
- *
- * allocates memory
- *--------------------------------------------------------------
- */
-
- char *
- Tm_HiddenParentPath(path)
- char *path;
- {
- char *p;
- char *parent;
- int len;
-
- p = strrchr(path, '.');
- if (p == NULL) {
- return NULL;
- }
- len = p - path + 1;
-
- parent = XtMalloc(strlen(path) + 2);
- strncpy(parent, path, len);
- parent[len] = '.';
- strcpy(parent + len + 1, p + 1);
-
- return parent;
- }
-
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_HiddenParentPath --
- *
- * Create a path based on current path that cannot be duplicated
- * actually, makes "first.last" into "first..last"
- *
- * Results:
- *
- * returns a pointer to the name
- *
- * Side effects:
- *
- * allocates memory
- *--------------------------------------------------------------
- */
-
- char *
- Tm_ParentPath(path)
- char *path;
- {
- char *p;
- char *parent;
- int len;
-
- p = strrchr(path, '.');
- if (p == NULL) {
- return NULL;
- }
- if (p == path)
- len = 1; /* parent is `.' */
- else
- len = p - path;
-
- parent = XtMalloc(len + 1);
- strncpy(parent, path, len);
- parent[len] = '\0';
-
- return parent;
- }
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_ExtractArg --
- * find a name and its value in a list
- *
- * Results:
- * returns a pointer to the value
- *
- * Side effects:
- * none
- *--------------------------------------------------------------
- */
-
- static char *
- Tm_ExtractArg(name, argc, argv)
- char *name;
- int argc;
- char *argv[];
- {
- int n;
-
- for (n = 0; n < argc; n++) {
- if (strcmp(name, argv[n]) == 0) {
- if (++n < argc) {
- return argv[n];
- } else {
- return NULL;
- }
- }
- }
- return NULL;
- }
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_MakeXEvent --
- *
- * Create an X event that can be used to send to another window
- *
- * Results:
- * a Tcl result value
- *
- * Side effects:
- * returns a filled in event in xev
- *
- * Restrictions:
- * only handles a small number of X types
- *--------------------------------------------------------------
- */
- int
- Tm_MakeXEvent(w, interp, xev, argc, argv)
- Widget w;
- Tcl_Interp *interp;
- XEvent *xev;
- int argc;
- char **argv;
- {
- char *type;
- char *value;
- struct timeval tp;
- Display *display;
-
-
- /* let them know we made this thing up */
- xev->xany.send_event = True;
-
- /* fill in the rest of the xany values.
- */
- xev->xany.display = display = XtDisplay(w);
- xev->xany.window = XtWindow(w);
-
- if ((type = Tm_ExtractArg("-type", argc, argv)) == NULL) {
- type = "ClientMessage";
- }
-
- if (type[0] == 'B') {
- if (strcmp(type, "ButtonRelease") == 0) {
- xev->type = ButtonRelease;
- } else
- if (strcmp(type, "ButtonPress") == 0) {
- xev->type = ButtonPress;
- } else {
- sprintf(interp->result, "illegal type %s\n", type);
- return TCL_ERROR;
- }
-
- xev->xbutton.time = XtLastTimestampProcessed(display);
-
- if ((value = Tm_ExtractArg("-x", argc, argv)) != NULL) {
- xev->xbutton.x = atoi(value);
- } else {
- xev->xbutton.x = 0;
- }
-
- if ((value = Tm_ExtractArg("-y", argc, argv)) != NULL) {
- xev->xbutton.y = atoi(value);
- } else {
- xev->xbutton.y = 0;
- }
-
- return TCL_OK;
- }
-
- if (type[0] == 'K') {
- unsigned int mask;
- KeySym keysym;
- KeyCode keycode;
-
- if (strcmp(type, "KeyRelease") == 0) {
- xev->type = KeyRelease;
- } else
- if (strcmp(type, "KeyPress") == 0) {
- xev->type = KeyPress;
- } else {
- sprintf(interp->result, "illegal type %s\n", type);
- return TCL_ERROR;;
- }
-
- xev->xkey.time = XtLastTimestampProcessed(display);
-
- if ((value = Tm_ExtractArg("-x", argc, argv)) != NULL) {
- xev->xkey.x = atoi(value);
- } else {
- xev->xkey.x = 0;
- }
-
- if ((value = Tm_ExtractArg("-y", argc, argv)) != NULL) {
- xev->xkey.y = atoi(value);
- } else {
- xev->xkey.y = 0;
- }
-
- if ((value = Tm_ExtractArg("-keysym", argc, argv)) != NULL) {
- if ((keysym = XStringToKeysym(value)) == NoSymbol) {
- sprintf(interp->result, "illegal keysym\"%s\"", value);
- return TCL_ERROR;
- }
- if ((keycode = XKeysymToKeycode(display, keysym)) == 0) {
- sprintf(interp->result, "no keycode for keysym \"%s\"", value);
- return TCL_ERROR;
- }
-
- mask = 0;
- /* is this what we should do? */
- if (keysym >= XK_A && keysym <= XK_Z)
- mask |= ShiftMask;
-
- xev->xkey.keycode = keycode;
- xev->xkey.state = mask;
- } else {
- sprintf(interp->result, "Key event must have a keysym");
- return TCL_ERROR;
- }
-
- return TCL_OK;
- }
-
- if (strcmp(type, "ClientMessage") == 0) {
- return TCL_OK;
- }
-
- sprintf(interp->result, "illegal type %s\n", type);
- return TCL_ERROR;;
- }
-
- /*
- *--------------------------------------------------------------
- *
- * Tm_EndToken --
- *
- * return the next char past a string or quoted string
- * using the actions parameter syntax (Asente & Swick appendix B)
- *
- * Results:
- * return pointer to next char after string
- *
- *--------------------------------------------------------------
- */
-
- char *
- Tm_EndToken(s)
- char *s;
- {
- if (s == NULL || *s == '\0')
- return s;
-
- /* quoted string */
- if (*s == '"') {
- s++;
- while (*s != '"' && *s != '\0')
- s++;
- if (*s == '"')
- return (s+1);
- else
- return s;
- }
-
- /* unquoted string */
- while (*s != ' ' && *s != '\t' && *s != ',' &&
- *s != '\n' && *s != ')' && *s != '\0')
- s++;
- return s;
- }
- /*
- *--------------------------------------------------------------
- *
- * Tm_ParseAction --
- *
- * Parse an action into action name + args
- *
- * Results:
- * sets the action, options and num_options
- *
- * Side-effects:
- * none
- *
- * Caveats:
- * Somehow, this is an ugly piece of code. Tidy it up!
- *--------------------------------------------------------------
- */
-
- int
- Tm_ParseAction(orig, action, params, num_params)
- char *orig;
- char **action;
- char *params[];
- Cardinal *num_params;
- {
- int n = 0;
- char *start, *end;
- # define skipblanks(p) while (isspace(*p)) p++;
-
- skipblanks(orig);
- /* make a new string, and put nulls in it at the end of tokens */
- start = XtNewString(orig);
- *action = end = start;
-
- /* delimit action name */
- while (isalnum(*end) || *end == '_' || *end == '-')
- end++;
- if (*end != '(') {
- fprintf(stderr, "no \"(\" after name\n");
- return TCL_ERROR;
- }
- *end = '\0';
-
- start = end + 1;
- for (n = 0; n < TM_NUM_PARAMS; True) {
- skipblanks(start);
- if (*start == ')')
- break;
-
- /* new token */
- end = Tm_EndToken(start);
-
- /* lose quotes if it was a quoted string */
- if (*start == '"') {
- start++;
- *(end - 1) = '\0';
- }
- params[n++] = start;
-
- if (isspace(*end)) {
- *end++ = '\0';
- }
- skipblanks(end);
- if (*end == '\0') {
- fprintf(stderr, "unterminated action\n");
- return TCL_ERROR;
- }
- if (*end == ')') {
- *end = '\0';
- break;
- }
- if (*end != ',') {
- fprintf(stderr, "no \",\" delimiter\n");
- return TCL_ERROR;
- }
- *end = '\0';
- start = end + 1;
- }
-
- *num_params = n;
- return TCL_OK;
- }
-