URL
https://opencores.org/ocsvn/or1k_old/or1k_old/trunk
Subversion Repositories or1k_old
[/] [or1k_old/] [trunk/] [insight/] [tix/] [generic/] [tixMwm.c] - Rev 578
Go to most recent revision | Compare with Previous | Blame | View Log
/* * tixMwm.c -- * * Communicating with the Motif window manager. * * * Copyright (c) 1996, Expert Interface Technologies * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include <tkInt.h> #include <tixPort.h> #include <tixInt.h> #include <X11/Xlib.h> #include <X11/Xatom.h> #include <X11/Xproto.h> #include <X11/Xutil.h> #ifdef HAS_MOTIF_INC #include <Xm/MwmUtil.h> #else /* * This section is provided for the machines that don't have the Motif * header files installed. */ #define MWM_DECOR_ALL (1L << 0) #define MWM_DECOR_BORDER (1L << 1) #define MWM_DECOR_RESIZEH (1L << 2) #define MWM_DECOR_TITLE (1L << 3) #define MWM_DECOR_MENU (1L << 4) #define MWM_DECOR_MINIMIZE (1L << 5) #define MWM_DECOR_MAXIMIZE (1L << 6) #define MWM_HINTS_DECORATIONS (1L << 1) #define PROP_MOTIF_WM_HINTS_ELEMENTS 5 #define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS /* atom name for _MWM_HINTS property */ #define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" #define _XA_MWM_HINTS _XA_MOTIF_WM_HINTS #define _XA_MOTIF_WM_MENU "_MOTIF_WM_MENU" #define _XA_MWM_MENU _XA_MOTIF_WM_MENU #define _XA_MOTIF_WM_INFO "_MOTIF_WM_INFO" #define _XA_MWM_INFO _XA_MOTIF_WM_INFO #define PROP_MOTIF_WM_INFO_ELEMENTS 2 #define PROP_MWM_INFO_ELEMENTS PROP_MOTIF_WM_INFO_ELEMENTS typedef struct { CARD32 flags; CARD32 functions; CARD32 decorations; INT32 inputMode; CARD32 status; } PropMotifWmHints; typedef PropMotifWmHints PropMwmHints; typedef struct { CARD32 flags; CARD32 wmWindow; } PropMotifWmInfo; typedef PropMotifWmInfo PropMwmInfo; #endif /* HAS_MOTIF_INC */ #define MWM_DECOR_UNKNOWN (-1) #define MWM_DECOR_EVERYTHING (MWM_DECOR_BORDER |\ MWM_DECOR_RESIZEH |\ MWM_DECOR_TITLE |\ MWM_DECOR_MENU |\ MWM_DECOR_MINIMIZE |\ MWM_DECOR_MAXIMIZE) typedef struct _Tix_MwmInfo { Tcl_Interp * interp; Tk_Window tkwin; PropMwmHints prop; /* not used */ Atom mwm_hints_atom; Tcl_HashTable protocols; unsigned int isremapping : 1; unsigned int resetProtocol : 1; unsigned int addedMwmMsg : 1; } Tix_MwmInfo; typedef struct Tix_MwmProtocol { Atom protocol; char * name; char * menuMessage; size_t messageLen; unsigned int active : 1; } Tix_MwmProtocol; /* Function declaration */ static void AddMwmProtocol _ANSI_ARGS_((Tcl_Interp *interp, Tix_MwmInfo *wmPtr, char * name, char * message)); static void ActivateMwmProtocol _ANSI_ARGS_((Tcl_Interp *interp, Tix_MwmInfo *wmPtr, char * name)); static void DeactivateMwmProtocol _ANSI_ARGS_((Tcl_Interp *interp, Tix_MwmInfo *wmPtr, char * name)); static void DeleteMwmProtocol _ANSI_ARGS_((Tcl_Interp *interp, Tix_MwmInfo *wmPtr, char * name)); static Tix_MwmInfo * GetMwmInfo _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin)); static Tix_MwmProtocol* GetMwmProtocol _ANSI_ARGS_((Tcl_Interp * interp, Tix_MwmInfo * wmPtr, Atom protocol)); static int IsMwmRunning _ANSI_ARGS_((Tcl_Interp * interp, Tix_MwmInfo*wmPtr)); static int MwmDecor _ANSI_ARGS_((Tcl_Interp * interp, char * string)); static int MwmProtocol _ANSI_ARGS_((Tcl_Interp * interp, Tix_MwmInfo * wmPtr, int argc, char ** argv)); static void QueryMwmHints _ANSI_ARGS_((Tix_MwmInfo * wmPtr)); static void RemapWindow _ANSI_ARGS_((ClientData clientData)); static void RemapWindowWhenIdle _ANSI_ARGS_(( Tix_MwmInfo * wmPtr)); static void ResetProtocols _ANSI_ARGS_((ClientData clientData)); static void ResetProtocolsWhenIdle _ANSI_ARGS_(( Tix_MwmInfo * wmPtr)); static int SetMwmDecorations _ANSI_ARGS_((Tcl_Interp *interp, Tix_MwmInfo*wmPtr, int argc, char ** argv)); static int SetMwmTransientFor _ANSI_ARGS_((Tcl_Interp *interp, Tix_MwmInfo*wmPtr, TkWindow *mainWindow, int argc, char ** argv)); static void StructureProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); /* Local variables */ static Tcl_HashTable mwmTable; /* *---------------------------------------------------------------------- * * Tix_MwmCmd -- * * This procedure is invoked to process the "mwm" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tix_MwmCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { Tk_Window tkwin = (Tk_Window) clientData; TkWindow *winPtr; char c; size_t length; Tix_MwmInfo * wmPtr; if (argc < 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option pathname ?arg ...?\"", (char *) NULL); return TCL_ERROR; } c = argv[1][0]; length = strlen(argv[1]); if (!(winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin))) { return TCL_ERROR; } if (!Tk_IsTopLevel(winPtr)) { Tcl_AppendResult(interp, argv[2], " is not a toplevel window.", NULL); return TCL_ERROR; } if (!(wmPtr=GetMwmInfo(interp, (Tk_Window) winPtr))) { return TCL_ERROR; } if ((c == 'd') && (strncmp(argv[1], "decorations", length) == 0)) { return SetMwmDecorations(interp, wmPtr, argc-3, argv+3); } else if ((c == 'i') && (strncmp(argv[1], "ismwmrunning", length) == 0)) { if (IsMwmRunning(interp, wmPtr)) { Tcl_AppendResult(interp, "1", NULL); } else { Tcl_AppendResult(interp, "0", NULL); } return TCL_OK; } else if ((c == 'p') && (strncmp(argv[1], "protocol", length) == 0)) { return MwmProtocol(interp, wmPtr, argc-3, argv+3); } else if ((c == 't') && (strncmp(argv[1], "transientfor", length) == 0)) { return SetMwmTransientFor(interp, wmPtr, winPtr, argc-3, argv+3); } else { Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1], "\": must be decorations, ismwmrunning, protocol ", "or transientfor", NULL); return TCL_ERROR; } } /* *---------------------------------------------------------------------- * TixMwmProtocolHandler -- * * A generic X event handler that handles the events from the Mwm * Window manager. * * Results: * True iff the event has been handled. * * Side effects: * None. *---------------------------------------------------------------------- */ int TixMwmProtocolHandler(clientData, eventPtr) ClientData clientData; XEvent *eventPtr; { TkWindow *winPtr; Window handlerWindow; if (eventPtr->type != ClientMessage) { return 0; } handlerWindow = eventPtr->xany.window; winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, handlerWindow); if (winPtr != NULL) { if (eventPtr->xclient.message_type == Tk_InternAtom((Tk_Window) winPtr,"_MOTIF_WM_MESSAGES")) { TkWmProtocolEventProc(winPtr, eventPtr); return 1; } } return 0; } static int MwmDecor(interp, string) Tcl_Interp * interp; char * string; { size_t len = strlen(string); if (strncmp(string, "-all", len) == 0) { return MWM_DECOR_ALL; } else if (strncmp(string, "-border", len) == 0) { return MWM_DECOR_BORDER; } else if (strncmp(string, "-resizeh", len) == 0) { return MWM_DECOR_RESIZEH; } else if (strncmp(string, "-title", len) == 0) { return MWM_DECOR_TITLE; } else if (strncmp(string, "-menu", len) == 0) { return MWM_DECOR_MENU; } else if (strncmp(string, "-minimize", len) == 0) { return MWM_DECOR_MINIMIZE; } else if (strncmp(string, "-maximize", len) == 0) { return MWM_DECOR_MAXIMIZE; } else { Tcl_AppendResult(interp, "unknown decoration \"", string, "\"", NULL); return -1; } } static void QueryMwmHints(wmPtr) Tix_MwmInfo * wmPtr; { Atom actualType; int actualFormat; unsigned long numItems, bytesAfter; wmPtr->prop.flags = MWM_HINTS_DECORATIONS; if (XGetWindowProperty(Tk_Display(wmPtr->tkwin),Tk_WindowId(wmPtr->tkwin), wmPtr->mwm_hints_atom, 0, PROP_MWM_HINTS_ELEMENTS, False, wmPtr->mwm_hints_atom, &actualType, &actualFormat, &numItems, &bytesAfter, (unsigned char **) & wmPtr->prop) == Success) { if ((actualType != wmPtr->mwm_hints_atom) || (actualFormat != 32) || (numItems <= 0)) { /* It looks like this window doesn't have a _XA_MWM_HINTS * property. Let's give the default value */ wmPtr->prop.decorations = MWM_DECOR_EVERYTHING; } } else { /* We get an error somehow. Pretend that the decorations are all */ wmPtr->prop.decorations = MWM_DECOR_EVERYTHING; } } static void RemapWindow(clientData) ClientData clientData; { Tix_MwmInfo * wmPtr = (Tix_MwmInfo *)clientData; Tk_UnmapWindow(wmPtr->tkwin); Tk_MapWindow(wmPtr->tkwin); wmPtr->isremapping = 0; } static void RemapWindowWhenIdle(wmPtr) Tix_MwmInfo * wmPtr; { if (!wmPtr->isremapping) { wmPtr->isremapping = 1; Tk_DoWhenIdle(RemapWindow, (ClientData)wmPtr); } } /* * SetMwmDecorations -- * * */ static int SetMwmDecorations(interp, wmPtr, argc, argv) Tcl_Interp *interp; Tix_MwmInfo*wmPtr; int argc; char ** argv; { int i; int decor; char buff[40]; if (argc == 0 || argc == 1) { /* * Query the existing settings */ QueryMwmHints(wmPtr); if (argc == 0) { /* * Query all hints */ sprintf(buff, "-border %d", ((wmPtr->prop.decorations & MWM_DECOR_BORDER)!=0)); Tcl_AppendElement(interp, buff); sprintf(buff, "-resizeh %d", ((wmPtr->prop.decorations &MWM_DECOR_RESIZEH)!=0)); Tcl_AppendElement(interp, buff); sprintf(buff, "-title %d", ((wmPtr->prop.decorations & MWM_DECOR_TITLE)!=0)); Tcl_AppendElement(interp, buff); sprintf(buff, "-menu %d", ((wmPtr->prop.decorations & MWM_DECOR_MENU)!=0)); Tcl_AppendElement(interp, buff); sprintf(buff, "-minimize %d", ((wmPtr->prop.decorations&MWM_DECOR_MINIMIZE)!=0)); Tcl_AppendElement(interp, buff); sprintf(buff, "-maximize %d", ((wmPtr->prop.decorations&MWM_DECOR_MAXIMIZE)!=0)); Tcl_AppendElement(interp, buff); return TCL_OK; } else { /* * Query only one hint */ if ((decor = MwmDecor(interp, argv[0])) == MWM_DECOR_UNKNOWN) { return TCL_ERROR; } if (wmPtr->prop.decorations & decor) { Tcl_AppendResult(interp, "1", NULL); } else { Tcl_AppendResult(interp, "0", NULL); } return TCL_OK; } } else { if (argc %2) { Tcl_AppendResult(interp, "value missing for option \"", argv[argc-1], "\"", NULL); return TCL_ERROR; } for (i=0; i<argc; i+=2) { int value; if ((decor = MwmDecor(interp, argv[i])) == MWM_DECOR_UNKNOWN) { return TCL_ERROR; } if (Tcl_GetBoolean(interp, argv[i+1], &value) != TCL_OK) { return TCL_ERROR; } if (value) { wmPtr->prop.decorations |= decor; } else { wmPtr->prop.decorations &= ~decor; } if (decor == MWM_DECOR_ALL) { if (value) { wmPtr->prop.decorations |= MWM_DECOR_EVERYTHING; } else { wmPtr->prop.decorations &= ~MWM_DECOR_EVERYTHING; } } } wmPtr->prop.flags = MWM_HINTS_DECORATIONS; XChangeProperty(Tk_Display(wmPtr->tkwin), Tk_WindowId(wmPtr->tkwin), wmPtr->mwm_hints_atom, wmPtr->mwm_hints_atom, 32, PropModeReplace, (unsigned char *) &wmPtr->prop, PROP_MWM_HINTS_ELEMENTS); if (Tk_IsMapped(wmPtr->tkwin)) { /* Needs unmap/map to refresh */ RemapWindowWhenIdle(wmPtr); } return TCL_OK; } } static int MwmProtocol(interp, wmPtr, argc, argv) Tcl_Interp * interp; Tix_MwmInfo * wmPtr; int argc; char ** argv; { size_t len; if (argc == 0) { Tcl_HashSearch hSearch; Tcl_HashEntry * hashPtr; Tix_MwmProtocol * ptPtr; /* Iterate over all the entries in the hash table */ for (hashPtr = Tcl_FirstHashEntry(&wmPtr->protocols, &hSearch); hashPtr; hashPtr = Tcl_NextHashEntry(&hSearch)) { ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr); Tcl_AppendElement(interp, ptPtr->name); } return TCL_OK; } len = strlen(argv[0]); if (strncmp(argv[0], "add", len) == 0 && argc == 3) { AddMwmProtocol(interp, wmPtr, argv[1], argv[2]); } else if (strncmp(argv[0], "activate", len) == 0 && argc == 2) { ActivateMwmProtocol(interp, wmPtr, argv[1]); } else if (strncmp(argv[0], "deactivate", len) == 0 && argc == 2) { DeactivateMwmProtocol(interp, wmPtr, argv[1]); } else if (strncmp(argv[0], "delete", len) == 0 && argc == 2) { DeleteMwmProtocol(interp, wmPtr, argv[1]); } else { Tcl_AppendResult(interp, "unknown option \"", argv[0], "\" should be add, activate, deactivate or delete", NULL); return TCL_ERROR; } return TCL_OK; } static void AddMwmProtocol(interp, wmPtr, name, message) Tcl_Interp *interp; Tix_MwmInfo *wmPtr; char * name; char * message; { Atom protocol; Tix_MwmProtocol *ptPtr; protocol = Tk_InternAtom(wmPtr->tkwin, name); ptPtr = GetMwmProtocol(interp, wmPtr, protocol); if (ptPtr->menuMessage != NULL) { /* This may happen if "protocol add" called twice for the same name */ ckfree(ptPtr->menuMessage); } if (ptPtr->name == NULL) { ptPtr->name = (char*)tixStrDup(name); } ptPtr->menuMessage = (char*)tixStrDup(message); ptPtr->messageLen = strlen(message); ptPtr->active = 1; ResetProtocolsWhenIdle(wmPtr); } static void ActivateMwmProtocol(interp, wmPtr, name) Tcl_Interp *interp; Tix_MwmInfo *wmPtr; char * name; { Atom protocol; Tix_MwmProtocol *ptPtr; protocol = Tk_InternAtom(wmPtr->tkwin, name); ptPtr = GetMwmProtocol(interp, wmPtr, protocol); ptPtr->active = 1; ResetProtocolsWhenIdle(wmPtr); } static void DeactivateMwmProtocol(interp, wmPtr, name) Tcl_Interp *interp; Tix_MwmInfo *wmPtr; char * name; { Atom protocol; Tix_MwmProtocol *ptPtr; protocol = Tk_InternAtom(wmPtr->tkwin, name); ptPtr = GetMwmProtocol(interp, wmPtr, protocol); ptPtr->active = 0; ResetProtocolsWhenIdle(wmPtr); } /* * Any "wm protocol" event handlers for the deleted protocol are * *not* automatically deleted. It is the application programmer's * responsibility to delete them using * * wm protocol SOME_JUNK_PROTOCOL {} */ static void DeleteMwmProtocol(interp, wmPtr, name) Tcl_Interp *interp; Tix_MwmInfo *wmPtr; char * name; { Atom protocol; Tix_MwmProtocol *ptPtr; Tcl_HashEntry * hashPtr; protocol = Tk_InternAtom(wmPtr->tkwin, name); hashPtr = Tcl_FindHashEntry(&wmPtr->protocols, (char*)protocol); if (hashPtr) { ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr); ckfree(ptPtr->name); ckfree(ptPtr->menuMessage); ckfree((char*)ptPtr); Tcl_DeleteHashEntry(hashPtr); } ResetProtocolsWhenIdle(wmPtr); } static void ResetProtocolsWhenIdle(wmPtr) Tix_MwmInfo * wmPtr; { if (!wmPtr->resetProtocol) { wmPtr->resetProtocol = 1; Tk_DoWhenIdle(ResetProtocols, (ClientData)wmPtr); } } static void ResetProtocols(clientData) ClientData clientData; { Tix_MwmInfo * wmPtr = (Tix_MwmInfo *) clientData; int numProtocols = wmPtr->protocols.numEntries; Atom * atoms, mwm_menu_atom, motif_msgs; Tcl_HashSearch hSearch; Tcl_HashEntry * hashPtr; Tix_MwmProtocol * ptPtr; int n; Tcl_DString dString; atoms = (Atom*)ckalloc(numProtocols * sizeof(Atom)); Tcl_DStringInit(&dString); /* Iterate over all the entries in the hash table */ for (hashPtr = Tcl_FirstHashEntry(&wmPtr->protocols, &hSearch), n=0; hashPtr; hashPtr = Tcl_NextHashEntry(&hSearch)) { char tmp[100]; ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr); if (ptPtr->active) { atoms[n++] = ptPtr->protocol; } Tcl_DStringAppend(&dString, ptPtr->menuMessage, ptPtr->messageLen); sprintf(tmp, " f.send_msg %d\n", (int)(ptPtr->protocol)); Tcl_DStringAppend(&dString, tmp, (int)strlen(tmp)); } /* Atoms for managing the MWM messages */ mwm_menu_atom = Tk_InternAtom(wmPtr->tkwin, _XA_MWM_MENU); motif_msgs = Tk_InternAtom(wmPtr->tkwin, "_MOTIF_WM_MESSAGES"); /* The _MOTIF_WM_MESSAGES atom must be in the wm_protocols. Otherwise * Mwm refuese to enable our menu items */ if (!wmPtr->addedMwmMsg) { Tix_GlobalVarEval(wmPtr->interp, "wm protocol ", Tk_PathName(wmPtr->tkwin), " _MOTIF_WM_MESSAGES {;}", NULL); wmPtr->addedMwmMsg = 1; } /* * These are the extra MWM protocols defined by this application. */ XChangeProperty(Tk_Display(wmPtr->tkwin), Tk_WindowId(wmPtr->tkwin), motif_msgs, XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, n); /* * Update the MWM menu items */ XChangeProperty(Tk_Display(wmPtr->tkwin), Tk_WindowId(wmPtr->tkwin), mwm_menu_atom, mwm_menu_atom, 8, PropModeReplace, (unsigned char *)dString.string, dString.length+1); Tcl_DStringFree(&dString); ckfree((char*)atoms); /* Done ! */ wmPtr->resetProtocol = 0; if (Tk_IsMapped(wmPtr->tkwin)) { /* Needs unmap/map to refresh */ RemapWindowWhenIdle(wmPtr); } } static int SetMwmTransientFor(interp, wmPtr, mainWindow, argc, argv) Tcl_Interp *interp; Tix_MwmInfo*wmPtr; TkWindow *mainWindow; int argc; char ** argv; { Atom transfor_atom; TkWindow * master; transfor_atom = Tk_InternAtom(wmPtr->tkwin, "WM_TRANSIENT_FOR"); if (argc == 0) { return TCL_OK; } else if (argc == 1) { master = (TkWindow *) Tk_NameToWindow(interp, argv[0], (Tk_Window)mainWindow); if (master == NULL) { return TCL_ERROR; } XChangeProperty(Tk_Display(wmPtr->tkwin), Tk_WindowId(wmPtr->tkwin), transfor_atom, XA_WINDOW, 32, PropModeReplace, (unsigned char *)&master->window, 1); return TCL_OK; } else { return TCL_ERROR; } } /* *---------------------------------------------------------------------- * * StructureProc -- * * Gets called in response to StructureNotify events in toplevels * operated by the tixMwm command. * * Results: * none * * Side effects: * The Tix_MwmInfo for the toplevel is deleted when the toplevel * is destroyed. * *---------------------------------------------------------------------- */ static void StructureProc(clientData, eventPtr) ClientData clientData; /* Our information about window * referred to by eventPtr. */ XEvent *eventPtr; /* Describes what just happened. */ { register Tix_MwmInfo * wmPtr = (Tix_MwmInfo *) clientData; Tcl_HashEntry *hashPtr; if (eventPtr->type == DestroyNotify) { Tcl_HashSearch hSearch; Tix_MwmProtocol * ptPtr; /* Delete all protocols in the hash table associated with * this toplevel */ for (hashPtr = Tcl_FirstHashEntry(&wmPtr->protocols, &hSearch); hashPtr; hashPtr = Tcl_NextHashEntry(&hSearch)) { ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr); ckfree(ptPtr->name); ckfree(ptPtr->menuMessage); ckfree((char*)ptPtr); Tcl_DeleteHashEntry(hashPtr); } Tcl_DeleteHashTable(&wmPtr->protocols); /* * Delete info about this toplevel in the table of all toplevels * controlled by tixMwm */ hashPtr = Tcl_FindHashEntry(&mwmTable, (char*)wmPtr->tkwin); if (hashPtr != NULL) { Tcl_DeleteHashEntry(hashPtr); } if (wmPtr->resetProtocol) { Tk_CancelIdleCall(ResetProtocols, (ClientData)wmPtr); wmPtr->resetProtocol = 0; } ckfree((char*)wmPtr); } } static Tix_MwmInfo * GetMwmInfo(interp, tkwin) Tcl_Interp * interp; Tk_Window tkwin; { static inited = 0; Tcl_HashEntry *hashPtr; int isNew; if (!inited) { Tcl_InitHashTable(&mwmTable, TCL_ONE_WORD_KEYS); inited = 1; } hashPtr = Tcl_CreateHashEntry(&mwmTable, (char*)tkwin, &isNew); if (!isNew) { return (Tix_MwmInfo *)Tcl_GetHashValue(hashPtr); } else { Tix_MwmInfo * wmPtr; wmPtr = (Tix_MwmInfo*) ckalloc(sizeof(Tix_MwmInfo)); wmPtr->interp = interp; wmPtr->tkwin = tkwin; wmPtr->isremapping = 0; wmPtr->resetProtocol = 0; wmPtr->addedMwmMsg = 0; if (Tk_WindowId(wmPtr->tkwin) == 0) { Tk_MakeWindowExist(wmPtr->tkwin); } wmPtr->mwm_hints_atom = Tk_InternAtom(wmPtr->tkwin, _XA_MWM_HINTS); Tcl_InitHashTable(&wmPtr->protocols, TCL_ONE_WORD_KEYS); QueryMwmHints(wmPtr); Tcl_SetHashValue(hashPtr, (char*)wmPtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, StructureProc, (ClientData)wmPtr); return wmPtr; } } static Tix_MwmProtocol * GetMwmProtocol(interp, wmPtr, protocol) Tcl_Interp * interp; Tix_MwmInfo * wmPtr; Atom protocol; { Tcl_HashEntry * hashPtr; int isNew; Tix_MwmProtocol * ptPtr; hashPtr = Tcl_CreateHashEntry(&wmPtr->protocols, (char*)protocol, &isNew); if (!isNew) { ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr); } else { ptPtr = (Tix_MwmProtocol *)ckalloc(sizeof(Tix_MwmProtocol)); ptPtr->protocol = protocol; ptPtr->name = NULL; ptPtr->menuMessage = NULL; Tcl_SetHashValue(hashPtr, (char*)ptPtr); } return ptPtr; } static int IsMwmRunning(interp, wmPtr) Tcl_Interp *interp; Tix_MwmInfo*wmPtr; { Atom motif_wm_info_atom; Atom actual_type; int actual_format; unsigned long num_items, bytes_after; PropMotifWmInfo *prop = 0; Window root; root = XRootWindow(Tk_Display(wmPtr->tkwin),Tk_ScreenNumber(wmPtr->tkwin)); motif_wm_info_atom = Tk_InternAtom(wmPtr->tkwin, _XA_MOTIF_WM_INFO); /* * If mwm is running, it will store info in the _XA_MOTIF_WM_INFO * atom in the root window */ XGetWindowProperty (Tk_Display(wmPtr->tkwin), root, motif_wm_info_atom, 0, (long)PROP_MOTIF_WM_INFO_ELEMENTS, 0, motif_wm_info_atom, &actual_type, &actual_format, &num_items, &bytes_after, (unsigned char **) &prop); if ((actual_type != motif_wm_info_atom) || (actual_format != 32) || (num_items < PROP_MOTIF_WM_INFO_ELEMENTS)) { /* * The _XA_MOTIF_WM_INFO doesn't exist for the root window. * Persumably Mwm is not running. */ if (prop) { XFree((char *)prop); } return(0); } else { /* * We still need to verify that the wm_window is indeed a child of * the root window. */ Window wm_window = (Window) prop->wmWindow; Window top, parent, *children; unsigned int num_children; int returnVal = 0; int i; if (XQueryTree(Tk_Display(wmPtr->tkwin), root, &top, &parent, &children, &num_children)) { for (returnVal = 0, i = 0; i < num_children; i++) { if (children[i] == wm_window) { /* * is indeed a window of this root: mwm is rinning */ returnVal = 1; break; } } } if (prop) { XFree((char *)prop); } if (children) { XFree((char *)children); } return (returnVal); } }
Go to most recent revision | Compare with Previous | Blame | View Log