4 * Communicating with the Motif window manager.
7 * Copyright (c) 1996, Expert Interface Technologies
9 * See the file "license.terms" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
18 #include <X11/Xatom.h>
19 #include <X11/Xproto.h>
20 #include <X11/Xutil.h>
24 #include <Xm/MwmUtil.h>
28 * This section is provided for the machines that don't have the Motif
29 * header files installed.
32 #define MWM_DECOR_ALL (1L << 0)
33 #define MWM_DECOR_BORDER (1L << 1)
34 #define MWM_DECOR_RESIZEH (1L << 2)
35 #define MWM_DECOR_TITLE (1L << 3)
36 #define MWM_DECOR_MENU (1L << 4)
37 #define MWM_DECOR_MINIMIZE (1L << 5)
38 #define MWM_DECOR_MAXIMIZE (1L << 6)
40 #define MWM_HINTS_DECORATIONS (1L << 1)
42 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
43 #define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS
45 /* atom name for _MWM_HINTS property */
46 #define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS"
47 #define _XA_MWM_HINTS _XA_MOTIF_WM_HINTS
49 #define _XA_MOTIF_WM_MENU "_MOTIF_WM_MENU"
50 #define _XA_MWM_MENU _XA_MOTIF_WM_MENU
52 #define _XA_MOTIF_WM_INFO "_MOTIF_WM_INFO"
53 #define _XA_MWM_INFO _XA_MOTIF_WM_INFO
55 #define PROP_MOTIF_WM_INFO_ELEMENTS 2
56 #define PROP_MWM_INFO_ELEMENTS PROP_MOTIF_WM_INFO_ELEMENTS
67 typedef PropMotifWmHints PropMwmHints;
75 typedef PropMotifWmInfo PropMwmInfo;
77 #endif /* HAS_MOTIF_INC */
79 #define MWM_DECOR_UNKNOWN (-1)
80 #define MWM_DECOR_EVERYTHING (MWM_DECOR_BORDER |\
87 typedef struct _Tix_MwmInfo {
90 PropMwmHints prop; /* not used */
92 Tcl_HashTable protocols;
93 unsigned int isremapping : 1;
94 unsigned int resetProtocol : 1;
95 unsigned int addedMwmMsg : 1;
98 typedef struct Tix_MwmProtocol {
103 unsigned int active : 1;
107 /* Function declaration */
109 static void AddMwmProtocol _ANSI_ARGS_((Tcl_Interp *interp,
110 Tix_MwmInfo *wmPtr, char * name, char * message));
111 static void ActivateMwmProtocol _ANSI_ARGS_((Tcl_Interp *interp,
112 Tix_MwmInfo *wmPtr, char * name));
113 static void DeactivateMwmProtocol _ANSI_ARGS_((Tcl_Interp *interp,
114 Tix_MwmInfo *wmPtr, char * name));
115 static void DeleteMwmProtocol _ANSI_ARGS_((Tcl_Interp *interp,
116 Tix_MwmInfo *wmPtr, char * name));
117 static Tix_MwmInfo * GetMwmInfo _ANSI_ARGS_((Tcl_Interp *interp,
119 static Tix_MwmProtocol* GetMwmProtocol _ANSI_ARGS_((Tcl_Interp * interp,
120 Tix_MwmInfo * wmPtr, Atom protocol));
121 static int IsMwmRunning _ANSI_ARGS_((Tcl_Interp * interp,
123 static int MwmDecor _ANSI_ARGS_((Tcl_Interp * interp,
125 static int MwmProtocol _ANSI_ARGS_((Tcl_Interp * interp,
126 Tix_MwmInfo * wmPtr, int argc, char ** argv));
127 static void QueryMwmHints _ANSI_ARGS_((Tix_MwmInfo * wmPtr));
128 static void RemapWindow _ANSI_ARGS_((ClientData clientData));
129 static void RemapWindowWhenIdle _ANSI_ARGS_((
130 Tix_MwmInfo * wmPtr));
131 static void ResetProtocols _ANSI_ARGS_((ClientData clientData));
132 static void ResetProtocolsWhenIdle _ANSI_ARGS_((
133 Tix_MwmInfo * wmPtr));
134 static int SetMwmDecorations _ANSI_ARGS_((Tcl_Interp *interp,
135 Tix_MwmInfo*wmPtr, int argc, char ** argv));
136 static int SetMwmTransientFor _ANSI_ARGS_((Tcl_Interp *interp,
137 Tix_MwmInfo*wmPtr, TkWindow *mainWindow, int argc,
139 static void StructureProc _ANSI_ARGS_((ClientData clientData,
142 /* Local variables */
144 static Tcl_HashTable mwmTable;
148 *----------------------------------------------------------------------
152 * This procedure is invoked to process the "mwm" Tcl command.
153 * See the user documentation for details on what it does.
156 * A standard Tcl result.
159 * See the user documentation.
161 *----------------------------------------------------------------------
166 Tix_MwmCmd(clientData, interp, argc, argv)
167 ClientData clientData; /* Main window associated with
169 Tcl_Interp *interp; /* Current interpreter. */
170 int argc; /* Number of arguments. */
171 char **argv; /* Argument strings. */
173 Tk_Window tkwin = (Tk_Window) clientData;
180 Tcl_AppendResult(interp, "wrong # args: should be \"",
181 argv[0], " option pathname ?arg ...?\"", (char *) NULL);
185 length = strlen(argv[1]);
187 if (!(winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin))) {
190 if (!Tk_IsTopLevel(winPtr)) {
191 Tcl_AppendResult(interp, argv[2], " is not a toplevel window.", NULL);
194 if (!(wmPtr=GetMwmInfo(interp, (Tk_Window) winPtr))) {
198 if ((c == 'd') && (strncmp(argv[1], "decorations", length) == 0)) {
199 return SetMwmDecorations(interp, wmPtr, argc-3, argv+3);
201 else if ((c == 'i') && (strncmp(argv[1], "ismwmrunning", length) == 0)) {
202 if (IsMwmRunning(interp, wmPtr)) {
203 Tcl_AppendResult(interp, "1", NULL);
205 Tcl_AppendResult(interp, "0", NULL);
209 else if ((c == 'p') && (strncmp(argv[1], "protocol", length) == 0)) {
210 return MwmProtocol(interp, wmPtr, argc-3, argv+3);
212 else if ((c == 't') && (strncmp(argv[1], "transientfor", length) == 0)) {
213 return SetMwmTransientFor(interp, wmPtr, winPtr, argc-3, argv+3);
216 Tcl_AppendResult(interp, "unknown or ambiguous option \"",
217 argv[1], "\": must be decorations, ismwmrunning, protocol ",
225 *----------------------------------------------------------------------
226 * TixMwmProtocolHandler --
228 * A generic X event handler that handles the events from the Mwm
232 * True iff the event has been handled.
236 *----------------------------------------------------------------------
240 TixMwmProtocolHandler(clientData, eventPtr)
241 ClientData clientData;
245 Window handlerWindow;
247 if (eventPtr->type != ClientMessage) {
251 handlerWindow = eventPtr->xany.window;
252 winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, handlerWindow);
253 if (winPtr != NULL) {
254 if (eventPtr->xclient.message_type ==
255 Tk_InternAtom((Tk_Window) winPtr,"_MOTIF_WM_MESSAGES")) {
256 TkWmProtocolEventProc(winPtr, eventPtr);
264 MwmDecor(interp, string)
268 size_t len = strlen(string);
270 if (strncmp(string, "-all", len) == 0) {
271 return MWM_DECOR_ALL;
272 } else if (strncmp(string, "-border", len) == 0) {
273 return MWM_DECOR_BORDER;
274 } else if (strncmp(string, "-resizeh", len) == 0) {
275 return MWM_DECOR_RESIZEH;
276 } else if (strncmp(string, "-title", len) == 0) {
277 return MWM_DECOR_TITLE;
278 } else if (strncmp(string, "-menu", len) == 0) {
279 return MWM_DECOR_MENU;
280 } else if (strncmp(string, "-minimize", len) == 0) {
281 return MWM_DECOR_MINIMIZE;
282 } else if (strncmp(string, "-maximize", len) == 0) {
283 return MWM_DECOR_MAXIMIZE;
285 Tcl_AppendResult(interp, "unknown decoration \"", string, "\"", NULL);
297 unsigned long numItems, bytesAfter;
299 wmPtr->prop.flags = MWM_HINTS_DECORATIONS;
301 if (XGetWindowProperty(Tk_Display(wmPtr->tkwin),Tk_WindowId(wmPtr->tkwin),
302 wmPtr->mwm_hints_atom, 0, PROP_MWM_HINTS_ELEMENTS,
303 False, wmPtr->mwm_hints_atom, &actualType, &actualFormat, &numItems,
304 &bytesAfter, (unsigned char **) & wmPtr->prop) == Success) {
306 if ((actualType != wmPtr->mwm_hints_atom) || (actualFormat != 32) ||
308 /* It looks like this window doesn't have a _XA_MWM_HINTS
309 * property. Let's give the default value
311 wmPtr->prop.decorations = MWM_DECOR_EVERYTHING;
314 /* We get an error somehow. Pretend that the decorations are all
316 wmPtr->prop.decorations = MWM_DECOR_EVERYTHING;
321 RemapWindow(clientData)
322 ClientData clientData;
324 Tix_MwmInfo * wmPtr = (Tix_MwmInfo *)clientData;
326 Tk_UnmapWindow(wmPtr->tkwin);
327 Tk_MapWindow(wmPtr->tkwin);
328 wmPtr->isremapping = 0;
332 RemapWindowWhenIdle(wmPtr)
335 if (!wmPtr->isremapping) {
336 wmPtr->isremapping = 1;
337 Tk_DoWhenIdle(RemapWindow, (ClientData)wmPtr);
342 * SetMwmDecorations --
347 int SetMwmDecorations(interp, wmPtr, argc, argv)
357 if (argc == 0 || argc == 1) {
359 * Query the existing settings
361 QueryMwmHints(wmPtr);
367 sprintf(buff, "-border %d",
368 ((wmPtr->prop.decorations & MWM_DECOR_BORDER)!=0));
369 Tcl_AppendElement(interp, buff);
371 sprintf(buff, "-resizeh %d",
372 ((wmPtr->prop.decorations &MWM_DECOR_RESIZEH)!=0));
373 Tcl_AppendElement(interp, buff);
375 sprintf(buff, "-title %d",
376 ((wmPtr->prop.decorations & MWM_DECOR_TITLE)!=0));
377 Tcl_AppendElement(interp, buff);
379 sprintf(buff, "-menu %d",
380 ((wmPtr->prop.decorations & MWM_DECOR_MENU)!=0));
381 Tcl_AppendElement(interp, buff);
383 sprintf(buff, "-minimize %d",
384 ((wmPtr->prop.decorations&MWM_DECOR_MINIMIZE)!=0));
385 Tcl_AppendElement(interp, buff);
387 sprintf(buff, "-maximize %d",
388 ((wmPtr->prop.decorations&MWM_DECOR_MAXIMIZE)!=0));
389 Tcl_AppendElement(interp, buff);
394 * Query only one hint
396 if ((decor = MwmDecor(interp, argv[0])) == MWM_DECOR_UNKNOWN) {
400 if (wmPtr->prop.decorations & decor) {
401 Tcl_AppendResult(interp, "1", NULL);
403 Tcl_AppendResult(interp, "0", NULL);
409 Tcl_AppendResult(interp, "value missing for option \"",
410 argv[argc-1], "\"", NULL);
414 for (i=0; i<argc; i+=2) {
417 if ((decor = MwmDecor(interp, argv[i])) == MWM_DECOR_UNKNOWN) {
421 if (Tcl_GetBoolean(interp, argv[i+1], &value) != TCL_OK) {
426 wmPtr->prop.decorations |= decor;
429 wmPtr->prop.decorations &= ~decor;
432 if (decor == MWM_DECOR_ALL) {
434 wmPtr->prop.decorations |= MWM_DECOR_EVERYTHING;
436 wmPtr->prop.decorations &= ~MWM_DECOR_EVERYTHING;
441 wmPtr->prop.flags = MWM_HINTS_DECORATIONS;
442 XChangeProperty(Tk_Display(wmPtr->tkwin), Tk_WindowId(wmPtr->tkwin),
443 wmPtr->mwm_hints_atom, wmPtr->mwm_hints_atom, 32, PropModeReplace,
444 (unsigned char *) &wmPtr->prop, PROP_MWM_HINTS_ELEMENTS);
446 if (Tk_IsMapped(wmPtr->tkwin)) {
447 /* Needs unmap/map to refresh */
448 RemapWindowWhenIdle(wmPtr);
454 static int MwmProtocol(interp, wmPtr, argc, argv)
463 Tcl_HashSearch hSearch;
464 Tcl_HashEntry * hashPtr;
465 Tix_MwmProtocol * ptPtr;
467 /* Iterate over all the entries in the hash table */
468 for (hashPtr = Tcl_FirstHashEntry(&wmPtr->protocols, &hSearch);
470 hashPtr = Tcl_NextHashEntry(&hSearch)) {
472 ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr);
473 Tcl_AppendElement(interp, ptPtr->name);
478 len = strlen(argv[0]);
479 if (strncmp(argv[0], "add", len) == 0 && argc == 3) {
480 AddMwmProtocol(interp, wmPtr, argv[1], argv[2]);
482 else if (strncmp(argv[0], "activate", len) == 0 && argc == 2) {
483 ActivateMwmProtocol(interp, wmPtr, argv[1]);
485 else if (strncmp(argv[0], "deactivate", len) == 0 && argc == 2) {
486 DeactivateMwmProtocol(interp, wmPtr, argv[1]);
488 else if (strncmp(argv[0], "delete", len) == 0 && argc == 2) {
489 DeleteMwmProtocol(interp, wmPtr, argv[1]);
492 Tcl_AppendResult(interp, "unknown option \"", argv[0],
493 "\" should be add, activate, deactivate or delete", NULL);
501 static void AddMwmProtocol(interp, wmPtr, name, message)
508 Tix_MwmProtocol *ptPtr;
510 protocol = Tk_InternAtom(wmPtr->tkwin, name);
511 ptPtr = GetMwmProtocol(interp, wmPtr, protocol);
513 if (ptPtr->menuMessage != NULL) {
514 /* This may happen if "protocol add" called twice for the same name */
515 ckfree(ptPtr->menuMessage);
518 if (ptPtr->name == NULL) {
519 ptPtr->name = (char*)tixStrDup(name);
521 ptPtr->menuMessage = (char*)tixStrDup(message);
522 ptPtr->messageLen = strlen(message);
525 ResetProtocolsWhenIdle(wmPtr);
528 static void ActivateMwmProtocol(interp, wmPtr, name)
534 Tix_MwmProtocol *ptPtr;
536 protocol = Tk_InternAtom(wmPtr->tkwin, name);
537 ptPtr = GetMwmProtocol(interp, wmPtr, protocol);
540 ResetProtocolsWhenIdle(wmPtr);
543 static void DeactivateMwmProtocol(interp, wmPtr, name)
549 Tix_MwmProtocol *ptPtr;
551 protocol = Tk_InternAtom(wmPtr->tkwin, name);
552 ptPtr = GetMwmProtocol(interp, wmPtr, protocol);
555 ResetProtocolsWhenIdle(wmPtr);
559 * Any "wm protocol" event handlers for the deleted protocol are
560 * *not* automatically deleted. It is the application programmer's
561 * responsibility to delete them using
563 * wm protocol SOME_JUNK_PROTOCOL {}
565 static void DeleteMwmProtocol(interp, wmPtr, name)
571 Tix_MwmProtocol *ptPtr;
572 Tcl_HashEntry * hashPtr;
574 protocol = Tk_InternAtom(wmPtr->tkwin, name);
575 hashPtr = Tcl_FindHashEntry(&wmPtr->protocols, (char*)protocol);
578 ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr);
580 ckfree(ptPtr->menuMessage);
581 ckfree((char*)ptPtr);
582 Tcl_DeleteHashEntry(hashPtr);
585 ResetProtocolsWhenIdle(wmPtr);
590 ResetProtocolsWhenIdle(wmPtr)
593 if (!wmPtr->resetProtocol) {
594 wmPtr->resetProtocol = 1;
595 Tk_DoWhenIdle(ResetProtocols, (ClientData)wmPtr);
599 static void ResetProtocols(clientData)
600 ClientData clientData;
602 Tix_MwmInfo * wmPtr = (Tix_MwmInfo *) clientData;
603 int numProtocols = wmPtr->protocols.numEntries;
604 Atom * atoms, mwm_menu_atom, motif_msgs;
605 Tcl_HashSearch hSearch;
606 Tcl_HashEntry * hashPtr;
607 Tix_MwmProtocol * ptPtr;
611 atoms = (Atom*)ckalloc(numProtocols * sizeof(Atom));
612 Tcl_DStringInit(&dString);
614 /* Iterate over all the entries in the hash table */
615 for (hashPtr = Tcl_FirstHashEntry(&wmPtr->protocols, &hSearch), n=0;
617 hashPtr = Tcl_NextHashEntry(&hSearch)) {
620 ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr);
622 atoms[n++] = ptPtr->protocol;
625 Tcl_DStringAppend(&dString, ptPtr->menuMessage, ptPtr->messageLen);
626 sprintf(tmp, " f.send_msg %d\n", (int)(ptPtr->protocol));
627 Tcl_DStringAppend(&dString, tmp, (int)strlen(tmp));
630 /* Atoms for managing the MWM messages */
631 mwm_menu_atom = Tk_InternAtom(wmPtr->tkwin, _XA_MWM_MENU);
632 motif_msgs = Tk_InternAtom(wmPtr->tkwin, "_MOTIF_WM_MESSAGES");
634 /* The _MOTIF_WM_MESSAGES atom must be in the wm_protocols. Otherwise
635 * Mwm refuese to enable our menu items
637 if (!wmPtr->addedMwmMsg) {
638 Tix_GlobalVarEval(wmPtr->interp, "wm protocol ",
639 Tk_PathName(wmPtr->tkwin), " _MOTIF_WM_MESSAGES {;}", NULL);
640 wmPtr->addedMwmMsg = 1;
644 * These are the extra MWM protocols defined by this application.
646 XChangeProperty(Tk_Display(wmPtr->tkwin), Tk_WindowId(wmPtr->tkwin),
647 motif_msgs, XA_ATOM, 32, PropModeReplace,
648 (unsigned char *)atoms, n);
651 * Update the MWM menu items
653 XChangeProperty(Tk_Display(wmPtr->tkwin), Tk_WindowId(wmPtr->tkwin),
654 mwm_menu_atom, mwm_menu_atom, 8, PropModeReplace,
655 (unsigned char *)dString.string, dString.length+1);
657 Tcl_DStringFree(&dString);
658 ckfree((char*)atoms);
661 wmPtr->resetProtocol = 0;
662 if (Tk_IsMapped(wmPtr->tkwin)) {
663 /* Needs unmap/map to refresh */
664 RemapWindowWhenIdle(wmPtr);
670 int SetMwmTransientFor(interp, wmPtr, mainWindow, argc, argv)
673 TkWindow *mainWindow;
680 transfor_atom = Tk_InternAtom(wmPtr->tkwin, "WM_TRANSIENT_FOR");
683 } else if (argc == 1) {
684 master = (TkWindow *) Tk_NameToWindow(interp, argv[0],
685 (Tk_Window)mainWindow);
686 if (master == NULL) {
689 XChangeProperty(Tk_Display(wmPtr->tkwin), Tk_WindowId(wmPtr->tkwin),
690 transfor_atom, XA_WINDOW, 32, PropModeReplace,
691 (unsigned char *)&master->window, 1);
699 *----------------------------------------------------------------------
703 * Gets called in response to StructureNotify events in toplevels
704 * operated by the tixMwm command.
710 * The Tix_MwmInfo for the toplevel is deleted when the toplevel
713 *----------------------------------------------------------------------
716 StructureProc(clientData, eventPtr)
717 ClientData clientData; /* Our information about window
718 * referred to by eventPtr. */
719 XEvent *eventPtr; /* Describes what just happened. */
721 register Tix_MwmInfo * wmPtr = (Tix_MwmInfo *) clientData;
722 Tcl_HashEntry *hashPtr;
724 if (eventPtr->type == DestroyNotify) {
725 Tcl_HashSearch hSearch;
726 Tix_MwmProtocol * ptPtr;
728 /* Delete all protocols in the hash table associated with
731 for (hashPtr = Tcl_FirstHashEntry(&wmPtr->protocols, &hSearch);
733 hashPtr = Tcl_NextHashEntry(&hSearch)) {
735 ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr);
737 ckfree(ptPtr->menuMessage);
738 ckfree((char*)ptPtr);
739 Tcl_DeleteHashEntry(hashPtr);
742 Tcl_DeleteHashTable(&wmPtr->protocols);
745 * Delete info about this toplevel in the table of all toplevels
746 * controlled by tixMwm
748 hashPtr = Tcl_FindHashEntry(&mwmTable, (char*)wmPtr->tkwin);
749 if (hashPtr != NULL) {
750 Tcl_DeleteHashEntry(hashPtr);
753 if (wmPtr->resetProtocol) {
754 Tk_CancelIdleCall(ResetProtocols, (ClientData)wmPtr);
755 wmPtr->resetProtocol = 0;
758 ckfree((char*)wmPtr);
763 GetMwmInfo(interp, tkwin)
768 Tcl_HashEntry *hashPtr;
772 Tcl_InitHashTable(&mwmTable, TCL_ONE_WORD_KEYS);
776 hashPtr = Tcl_CreateHashEntry(&mwmTable, (char*)tkwin, &isNew);
779 return (Tix_MwmInfo *)Tcl_GetHashValue(hashPtr);
784 wmPtr = (Tix_MwmInfo*) ckalloc(sizeof(Tix_MwmInfo));
785 wmPtr->interp = interp;
786 wmPtr->tkwin = tkwin;
787 wmPtr->isremapping = 0;
788 wmPtr->resetProtocol = 0;
789 wmPtr->addedMwmMsg = 0;
790 if (Tk_WindowId(wmPtr->tkwin) == 0) {
791 Tk_MakeWindowExist(wmPtr->tkwin);
793 wmPtr->mwm_hints_atom = Tk_InternAtom(wmPtr->tkwin, _XA_MWM_HINTS);
795 Tcl_InitHashTable(&wmPtr->protocols, TCL_ONE_WORD_KEYS);
797 QueryMwmHints(wmPtr);
799 Tcl_SetHashValue(hashPtr, (char*)wmPtr);
801 Tk_CreateEventHandler(tkwin, StructureNotifyMask,
802 StructureProc, (ClientData)wmPtr);
808 static Tix_MwmProtocol *
809 GetMwmProtocol(interp, wmPtr, protocol)
814 Tcl_HashEntry * hashPtr;
816 Tix_MwmProtocol * ptPtr;
818 hashPtr = Tcl_CreateHashEntry(&wmPtr->protocols, (char*)protocol, &isNew);
820 ptPtr = (Tix_MwmProtocol *)Tcl_GetHashValue(hashPtr);
822 ptPtr = (Tix_MwmProtocol *)ckalloc(sizeof(Tix_MwmProtocol));
824 ptPtr->protocol = protocol;
826 ptPtr->menuMessage = NULL;
828 Tcl_SetHashValue(hashPtr, (char*)ptPtr);
836 IsMwmRunning(interp, wmPtr)
840 Atom motif_wm_info_atom;
843 unsigned long num_items, bytes_after;
844 PropMotifWmInfo *prop = 0;
847 root = XRootWindow(Tk_Display(wmPtr->tkwin),Tk_ScreenNumber(wmPtr->tkwin));
848 motif_wm_info_atom = Tk_InternAtom(wmPtr->tkwin, _XA_MOTIF_WM_INFO);
851 * If mwm is running, it will store info in the _XA_MOTIF_WM_INFO
852 * atom in the root window
854 XGetWindowProperty (Tk_Display(wmPtr->tkwin),
855 root, motif_wm_info_atom, 0, (long)PROP_MOTIF_WM_INFO_ELEMENTS,
856 0, motif_wm_info_atom, &actual_type, &actual_format,
857 &num_items, &bytes_after, (unsigned char **) &prop);
859 if ((actual_type != motif_wm_info_atom) || (actual_format != 32) ||
860 (num_items < PROP_MOTIF_WM_INFO_ELEMENTS)) {
863 * The _XA_MOTIF_WM_INFO doesn't exist for the root window.
864 * Persumably Mwm is not running.
873 * We still need to verify that the wm_window is indeed a child of
876 Window wm_window = (Window) prop->wmWindow;
877 Window top, parent, *children;
878 unsigned int num_children;
882 if (XQueryTree(Tk_Display(wmPtr->tkwin), root, &top, &parent,
883 &children, &num_children)) {
885 for (returnVal = 0, i = 0; i < num_children; i++) {
886 if (children[i] == wm_window) {
888 * is indeed a window of this root: mwm is rinning
900 XFree((char *)children);