WmProtocol.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /*
  24. * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC.
  25. * ALL RIGHTS RESERVED
  26. */
  27. /*
  28. * Motif Release 1.2.3
  29. */
  30. /*
  31. * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
  32. /*
  33. * Included Files:
  34. */
  35. #include "WmGlobal.h"
  36. #include "WmICCC.h"
  37. /*
  38. * include extern functions
  39. */
  40. #include "WmError.h"
  41. #include "WmFunction.h"
  42. #include "WmKeyFocus.h"
  43. #include "WmMenu.h"
  44. #include "WmWinInfo.h"
  45. #include "WmEvent.h"
  46. #include "WmPanelP.h"
  47. /*
  48. * Function Declarations:
  49. */
  50. #include "WmProtocol.h"
  51. static Boolean wmq_convert (Widget w, Atom *pSelection, Atom *pTarget,
  52. Atom *pType_return, XtPointer *pValue_return, unsigned long *pLength_return,
  53. int *pFormat_return);
  54. static Boolean wmq_convert_all_clients (Widget w, int screen,
  55. Atom *pType_return, XtPointer *pValue_return, unsigned long *pLength_return,
  56. int *pFormat_return);
  57. static void wmq_list_subtree (ClientData *pCD);
  58. static void wmq_add_xid (XID win);
  59. static void wmq_done (Widget w, Atom *pSelection, Atom *pTarget);
  60. static void wmq_lose (Widget w, Atom *pSelection);
  61. static void wmq_bump_xids(void);
  62. /*
  63. * Global Variables:
  64. */
  65. Atom *xa_WM_QUERY = NULL;
  66. Atom xa_WM_POINTER_WINDOW;
  67. Atom xa_WM_CLIENT_WINDOW;
  68. Atom xa_WM_ALL_CLIENTS;
  69. XID *pXids = NULL;
  70. int numXids = -1;
  71. int curXids = 0;
  72. /*************************************<->*************************************
  73. *
  74. * SetupWmICCC ()
  75. *
  76. *
  77. * Description:
  78. * -----------
  79. * This function sets up the window manager handling of the inter-client
  80. * communications conventions.
  81. *
  82. *
  83. * Outputs:
  84. * -------
  85. * (wmGD) = Atoms id's are setup.
  86. *
  87. *************************************<->***********************************/
  88. void SetupWmICCC (void)
  89. {
  90. enum {
  91. XA_WM_STATE, XA_WM_PROTOCOLS, XA_WM_CHANGE_STATE,
  92. XA_WM_SAVE_YOURSELF, XA_WM_DELETE_WINDOW,
  93. XA_WM_COLORMAP_WINDOWS, XA_WM_TAKE_FOCUS, XA_MWM_HINTS,
  94. XA_MWM_MENU, XA_MWM_MESSAGES, XA_MOTIF_WM_OFFSET,
  95. XA_MOTIF_WM_CLIENT_WINDOW, XA_MOTIF_WM_POINTER_WINDOW,
  96. XA_MOTIF_WM_ALL_CLIENTS,
  97. XA_COMPOUND_TEXT, NUM_ATOMS };
  98. static char *atom_names[] = {
  99. _XA_WM_STATE, _XA_WM_PROTOCOLS, _XA_WM_CHANGE_STATE,
  100. _XA_WM_SAVE_YOURSELF, _XA_WM_DELETE_WINDOW,
  101. _XA_WM_COLORMAP_WINDOWS, _XA_WM_TAKE_FOCUS, _XA_MWM_HINTS,
  102. _XA_MWM_MENU, _XA_MWM_MESSAGES, _XA_MOTIF_WM_OFFSET,
  103. # ifdef _XA_MOTIF_WM_CLIENT_WINDOW
  104. _XA_MOTIF_WM_CLIENT_WINDOW, _XA_MOTIF_WM_POINTER_WINDOW,
  105. _XA_MOTIF_WM_ALL_CLIENTS,
  106. # else
  107. "_MOTIF_WM_CLIENT_WINDOW", "_MOTIF_WM_POINTER_WINDOW",
  108. "_MOTIF_WM_ALL_CLIENTS",
  109. # endif
  110. "COMPOUND_TEXT"
  111. };
  112. XIconSize sizeList;
  113. int scr;
  114. Atom atoms[XtNumber(atom_names) + 1];
  115. /*
  116. * Make atoms that are required by the ICCC and mwm. The atom for
  117. * _MOTIF_WM_INFO is intern'ed in ProcessMotifWmInfo.
  118. */
  119. XInternAtoms(DISPLAY, atom_names, XtNumber(atom_names), False, atoms);
  120. wmGD.xa_WM_STATE = atoms[XA_WM_STATE];
  121. wmGD.xa_WM_PROTOCOLS = atoms[XA_WM_PROTOCOLS];
  122. wmGD.xa_WM_CHANGE_STATE = atoms[XA_WM_CHANGE_STATE];
  123. wmGD.xa_WM_SAVE_YOURSELF = atoms[XA_WM_SAVE_YOURSELF];
  124. wmGD.xa_WM_DELETE_WINDOW = atoms[XA_WM_DELETE_WINDOW];
  125. wmGD.xa_WM_COLORMAP_WINDOWS = atoms[XA_WM_COLORMAP_WINDOWS];
  126. wmGD.xa_WM_TAKE_FOCUS = atoms[XA_WM_TAKE_FOCUS];
  127. wmGD.xa_MWM_HINTS = atoms[XA_MWM_HINTS];
  128. wmGD.xa_MWM_MENU = atoms[XA_MWM_MENU];
  129. wmGD.xa_MWM_MESSAGES = atoms[XA_MWM_MESSAGES];
  130. wmGD.xa_MWM_OFFSET = atoms[XA_MOTIF_WM_OFFSET];
  131. wmGD.xa_COMPOUND_TEXT = atoms[XA_COMPOUND_TEXT];
  132. if (!(xa_WM_QUERY = (Atom *) XtMalloc (wmGD.numScreens * (sizeof (Atom)))))
  133. {
  134. Warning (((char *)GETMESSAGE(56, 2, "Insufficient memory to XInternAtom _MOTIF_WM_QUERY_nn")));
  135. }
  136. for (scr = 0; scr < wmGD.numScreens; scr++)
  137. {
  138. if (wmGD.Screens[scr].managed)
  139. {
  140. char wm_query_scr[32];
  141. sprintf(wm_query_scr, "_MOTIF_WM_QUERY_%d",
  142. wmGD.Screens[scr].screen);
  143. xa_WM_QUERY[scr] = XInternAtom(DISPLAY, wm_query_scr, False);
  144. }
  145. else
  146. {
  147. xa_WM_QUERY[scr] = 0;
  148. }
  149. }
  150. xa_WM_CLIENT_WINDOW = atoms[XA_MOTIF_WM_CLIENT_WINDOW];
  151. xa_WM_POINTER_WINDOW = atoms[XA_MOTIF_WM_POINTER_WINDOW];
  152. xa_WM_ALL_CLIENTS = atoms[XA_MOTIF_WM_ALL_CLIENTS];
  153. /*
  154. * Setup the icon size property on the root window.
  155. */
  156. sizeList.width_inc = 1;
  157. sizeList.height_inc = 1;
  158. for (scr = 0; scr < wmGD.numScreens; scr++)
  159. {
  160. if (wmGD.Screens[scr].managed)
  161. {
  162. sizeList.min_width = wmGD.Screens[scr].iconImageMinimum.width;
  163. sizeList.min_height = wmGD.Screens[scr].iconImageMinimum.height;
  164. sizeList.max_width = wmGD.Screens[scr].iconImageMaximum.width;
  165. sizeList.max_height = wmGD.Screens[scr].iconImageMaximum.height;
  166. XSetIconSizes (DISPLAY, wmGD.Screens[scr].rootWindow,
  167. &sizeList, 1);
  168. }
  169. }
  170. /*
  171. * Assert ownership of the WM_QUERY selection
  172. */
  173. for (scr = 0; scr < wmGD.numScreens; scr++)
  174. {
  175. if (wmGD.Screens[scr].managed)
  176. {
  177. if (!XtOwnSelection(wmGD.topLevelW,
  178. xa_WM_QUERY[scr],
  179. GetTimestamp(),
  180. wmq_convert,
  181. wmq_lose,
  182. wmq_done))
  183. {
  184. Warning (((char *)GETMESSAGE(56, 3, "Failed to own _MOTIF_WM_QUERY_nn selection")));
  185. }
  186. }
  187. }
  188. } /* END OF FUNCTION SetupWmICCC */
  189. /*************************************<->*************************************
  190. *
  191. * SendConfigureNotify (pCD)
  192. *
  193. *
  194. * Description:
  195. * -----------
  196. * This function is used to send a synthetic ConfigureNotify event when
  197. * a client window is reconfigured in certain ways (e.g., the window is
  198. * moved without being resized).
  199. *
  200. *
  201. * Inputs:
  202. * ------
  203. * pCD = pointer to client data (window id and client size data)
  204. *
  205. *************************************<->***********************************/
  206. void SendConfigureNotify (ClientData *pCD)
  207. {
  208. XConfigureEvent notifyEvent;
  209. /*
  210. * Send a synthetic ConfigureNotify message:
  211. */
  212. notifyEvent.type = ConfigureNotify;
  213. notifyEvent.display = DISPLAY;
  214. notifyEvent.event = pCD->client;
  215. notifyEvent.window = pCD->client;
  216. if (pCD->pECD)
  217. {
  218. int rootX, rootY;
  219. Window wChild;
  220. WmFpEmbeddedClientData *pECD = (WmFpEmbeddedClientData *)pCD->pECD;
  221. /*
  222. * The front panel uses clientX, clientY for position in
  223. * front panel. Translate to root coords for client's
  224. * information.
  225. */
  226. XTranslateCoordinates (DISPLAY, pECD->winParent,
  227. ROOT_FOR_CLIENT(pCD), pCD->clientX, pCD->clientY,
  228. &rootX, &rootY, &wChild);
  229. notifyEvent.x = rootX;
  230. notifyEvent.y = rootY;
  231. notifyEvent.width = pCD->clientWidth;
  232. notifyEvent.height = pCD->clientHeight;
  233. }
  234. else
  235. if (pCD->maxConfig)
  236. {
  237. notifyEvent.x = pCD->maxX;
  238. notifyEvent.y = pCD->maxY;
  239. notifyEvent.width = pCD->maxWidth;
  240. notifyEvent.height = pCD->maxHeight;
  241. }
  242. else
  243. {
  244. notifyEvent.x = pCD->clientX;
  245. notifyEvent.y = pCD->clientY;
  246. notifyEvent.width = pCD->clientWidth;
  247. notifyEvent.height = pCD->clientHeight;
  248. }
  249. notifyEvent.border_width = 0;
  250. notifyEvent.above = None;
  251. notifyEvent.override_redirect = False;
  252. XSendEvent (DISPLAY, pCD->client, False, StructureNotifyMask,
  253. (XEvent *)&notifyEvent);
  254. } /* END OF FUNCTION SendConfigureNotify */
  255. /*************************************<->*************************************
  256. *
  257. * SendClientOffsetMessage (pCD)
  258. *
  259. *
  260. * Description:
  261. * -----------
  262. * This function is used to send a client message containing the offset
  263. * between the window position reported to the user and the actual
  264. * window position of the client over the root.
  265. *
  266. * This can be used by clients that map and unmap windows to help them
  267. * work with the window manager to place the window in the same location
  268. * when remapped.
  269. *
  270. * Inputs:
  271. * ------
  272. * pCD = pointer to client data (frame geometry info)
  273. *
  274. *************************************<->***********************************/
  275. void SendClientOffsetMessage (ClientData *pCD)
  276. {
  277. long borderWidth = (long)pCD->xBorderWidth;
  278. long offsetX = pCD->clientOffset.x;
  279. long offsetY = pCD->clientOffset.y;
  280. XClientMessageEvent clientMsgEvent;
  281. clientMsgEvent.type = ClientMessage;
  282. clientMsgEvent.window = pCD->client;
  283. clientMsgEvent.message_type = wmGD.xa_MWM_MESSAGES;
  284. clientMsgEvent.format = 32;
  285. clientMsgEvent.data.l[0] = wmGD.xa_MWM_OFFSET;
  286. /*
  287. * Use window gravity to allow the user to specify the window
  288. * position on the screen without having to know the dimensions
  289. * of the decoration that mwm is adding.
  290. */
  291. switch (pCD->windowGravity)
  292. {
  293. case NorthWestGravity:
  294. default:
  295. {
  296. clientMsgEvent.data.l[1] = offsetX;
  297. clientMsgEvent.data.l[2] = offsetY;
  298. break;
  299. }
  300. case NorthGravity:
  301. {
  302. clientMsgEvent.data.l[1] = borderWidth;
  303. clientMsgEvent.data.l[2] = offsetY;
  304. break;
  305. }
  306. case NorthEastGravity:
  307. {
  308. clientMsgEvent.data.l[1] = -(offsetX - (2 * borderWidth));
  309. clientMsgEvent.data.l[2] = offsetY;
  310. break;
  311. }
  312. case EastGravity:
  313. {
  314. clientMsgEvent.data.l[1] = -(offsetX - (2 * borderWidth));
  315. clientMsgEvent.data.l[2] = borderWidth + (offsetY - offsetX)/2;
  316. break;
  317. }
  318. case SouthEastGravity:
  319. {
  320. clientMsgEvent.data.l[1] = -(offsetX - (2 * borderWidth));
  321. clientMsgEvent.data.l[2] = -(offsetX - (2 * borderWidth));
  322. break;
  323. }
  324. case SouthGravity:
  325. {
  326. clientMsgEvent.data.l[1] = borderWidth;
  327. clientMsgEvent.data.l[2] = -(offsetX - (2 * borderWidth));
  328. break;
  329. }
  330. case SouthWestGravity:
  331. {
  332. clientMsgEvent.data.l[1] = offsetX;
  333. clientMsgEvent.data.l[2] = -(offsetX - (2 * borderWidth));
  334. break;
  335. }
  336. case WestGravity:
  337. {
  338. clientMsgEvent.data.l[1] = offsetX;
  339. clientMsgEvent.data.l[2] = borderWidth + (offsetY - offsetX)/2;
  340. break;
  341. }
  342. case CenterGravity:
  343. {
  344. clientMsgEvent.data.l[2] = (offsetY - offsetX)/2;
  345. break;
  346. }
  347. }
  348. XSendEvent (DISPLAY, pCD->client, False, NoEventMask,
  349. (XEvent *)&clientMsgEvent);
  350. } /* END OF FUNCTION SendClientOffsetMessage */
  351. /*************************************<->*************************************
  352. *
  353. * SendClientMsg (window, type, data0, time, pData, dataLen)
  354. *
  355. *
  356. * Description:
  357. * -----------
  358. * This function is used to send a client message event that to a client
  359. * window. The message may be sent as part of a protocol arranged for by
  360. * the client with the WM_PROTOCOLS property.
  361. *
  362. *
  363. * Inputs:
  364. * ------
  365. * window = destination window for the client message event
  366. *
  367. * type = client message type
  368. *
  369. * data0 = data0 value in the client message
  370. *
  371. * time = timestamp to be used in the event
  372. *
  373. * pData = pointer to data to be used in the event
  374. *
  375. * dataLen = len of data (in 32 bit units)
  376. *
  377. *************************************<->***********************************/
  378. void SendClientMsg (Window window, long type, long data0, Time time, long *pData, int dataLen)
  379. {
  380. XClientMessageEvent clientMsgEvent;
  381. int i;
  382. clientMsgEvent.type = ClientMessage;
  383. clientMsgEvent.window = window;
  384. clientMsgEvent.message_type = type;
  385. clientMsgEvent.format = 32;
  386. clientMsgEvent.data.l[0] = data0;
  387. clientMsgEvent.data.l[1] = (long)time;
  388. if (pData)
  389. {
  390. /*
  391. * Fill in the rest of the ClientMessage event (that holds up to
  392. * 5 words of data).
  393. */
  394. if (dataLen > 3)
  395. {
  396. dataLen = 3;
  397. }
  398. for (i = 2; i < (2 + dataLen); i++)
  399. {
  400. clientMsgEvent.data.l[i] = pData[i];
  401. }
  402. }
  403. XSendEvent (DISPLAY, window, False, NoEventMask,
  404. (XEvent *)&clientMsgEvent);
  405. XFlush(DISPLAY);
  406. } /* END OF FUNCTION SendClientMsg */
  407. /*************************************<->*************************************
  408. *
  409. * AddWmTimer (timerType, timerInterval, pCD)
  410. *
  411. *
  412. * Description:
  413. * -----------
  414. * This function sets a window manager timer of the specified type.
  415. *
  416. *
  417. * Inputs:
  418. * ------
  419. * timerType = type of timer to be set
  420. *
  421. * timerInterval = length of timeout in ms
  422. *
  423. * pCD = pointer to client data associated with the timer
  424. *
  425. * return = True if timer could be set
  426. *
  427. *************************************<->***********************************/
  428. Boolean AddWmTimer (unsigned int timerType, unsigned long timerInterval, ClientData *pCD)
  429. {
  430. WmTimer *pWmTimer;
  431. if (!(pWmTimer = (WmTimer *)XtMalloc (sizeof (WmTimer))))
  432. {
  433. Warning (((char *)GETMESSAGE(56, 1, "Insufficient memory for window manager data")));
  434. return (False);
  435. }
  436. /* !!! handle for XtAppAddTimeOut error !!! */
  437. pWmTimer->timerId = XtAppAddTimeOut (wmGD.mwmAppContext,
  438. timerInterval, (XtTimerCallbackProc)TimeoutProc, (caddr_t)pCD);
  439. pWmTimer->timerCD = pCD;
  440. pWmTimer->timerType = timerType;
  441. pWmTimer->nextWmTimer = wmGD.wmTimers;
  442. wmGD.wmTimers = pWmTimer;
  443. return(True);
  444. } /* END OF FUNCTION AddWmTimer */
  445. /*************************************<->*************************************
  446. *
  447. * DeleteClientWmTimers (pCD)
  448. *
  449. *
  450. * Description:
  451. * -----------
  452. * This function deletes all window manager timers that are associated with
  453. * the specified client window.
  454. *
  455. *
  456. * Inputs:
  457. * ------
  458. * pCD = pointer to client data for client whose timers are to be deleted
  459. *
  460. * wmGD = (wmTimers)
  461. *
  462. *************************************<->***********************************/
  463. void DeleteClientWmTimers (ClientData *pCD)
  464. {
  465. WmTimer *pPrevTimer;
  466. WmTimer *pWmTimer;
  467. WmTimer *pRemoveTimer;
  468. pPrevTimer = NULL;
  469. pWmTimer = wmGD.wmTimers;
  470. while (pWmTimer)
  471. {
  472. if (pWmTimer->timerCD == pCD)
  473. {
  474. if (pPrevTimer)
  475. {
  476. pPrevTimer->nextWmTimer = pWmTimer->nextWmTimer;
  477. }
  478. else
  479. {
  480. wmGD.wmTimers = pWmTimer->nextWmTimer;
  481. }
  482. pRemoveTimer = pWmTimer;
  483. pWmTimer = pWmTimer->nextWmTimer;
  484. XtRemoveTimeOut (pRemoveTimer->timerId);
  485. XtFree ((char *)pRemoveTimer);
  486. }
  487. else
  488. {
  489. pPrevTimer = pWmTimer;
  490. pWmTimer = pWmTimer->nextWmTimer;
  491. }
  492. }
  493. } /* END OF FUNCTION DeleteClientWmTimers */
  494. /*************************************<->*************************************
  495. *
  496. * TimeoutProc (client_data, id)
  497. *
  498. *
  499. * Description:
  500. * -----------
  501. * This function is an Xtk timeout handler. It is used to handle various
  502. * window manager timers (i.e. WM_SAVE_YOURSELF quit timeout).
  503. *
  504. *
  505. * Inputs:
  506. * ------
  507. * client_data = pointer to window manager client data
  508. *
  509. * id = Xtk timer id
  510. *
  511. *************************************<->***********************************/
  512. void TimeoutProc (caddr_t client_data, XtIntervalId *id)
  513. {
  514. WmTimer *pPrevTimer;
  515. WmTimer *pWmTimer;
  516. /*
  517. * Find out if the timer still needs to be serviced.
  518. */
  519. pPrevTimer = NULL;
  520. pWmTimer = wmGD.wmTimers;
  521. while (pWmTimer)
  522. {
  523. if (pWmTimer->timerId == *id)
  524. {
  525. break;
  526. }
  527. pPrevTimer = pWmTimer;
  528. pWmTimer = pWmTimer->nextWmTimer;
  529. }
  530. if (pWmTimer)
  531. {
  532. /*
  533. * Do the timer related action.
  534. */
  535. switch (pWmTimer->timerType)
  536. {
  537. case TIMER_QUIT:
  538. {
  539. XKillClient (DISPLAY, pWmTimer->timerCD->client);
  540. break;
  541. }
  542. case TIMER_RAISE:
  543. {
  544. Boolean sameScreen;
  545. if ((wmGD.keyboardFocus == pWmTimer->timerCD) &&
  546. (pWmTimer->timerCD->focusPriority ==
  547. (PSD_FOR_CLIENT(pWmTimer->timerCD))->focusPriority) &&
  548. (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER) &&
  549. (pWmTimer->timerCD == GetClientUnderPointer(&sameScreen)))
  550. {
  551. Do_Raise (pWmTimer->timerCD, (ClientListEntry *)NULL, STACK_NORMAL);
  552. }
  553. break;
  554. }
  555. }
  556. /*
  557. * Remove the timer from the wm timer list.
  558. */
  559. if (pPrevTimer)
  560. {
  561. pPrevTimer->nextWmTimer = pWmTimer->nextWmTimer;
  562. }
  563. else
  564. {
  565. wmGD.wmTimers = pWmTimer->nextWmTimer;
  566. }
  567. XtFree ((char *)pWmTimer);
  568. }
  569. /*
  570. * Free up the timer.
  571. */
  572. XtRemoveTimeOut (*id);
  573. } /* END OF FUNCTION TimeoutProc */
  574. /*************************************<->*************************************
  575. *
  576. * Boolean wmq_convert (w, pSelection, pTarget, pType_return,
  577. * pValue_return, pLength_return, pFormat_return)
  578. *
  579. *
  580. * Description:
  581. * -----------
  582. * This function converts WM_QUERY selections
  583. *
  584. * Inputs:
  585. * ------
  586. * w - widget
  587. * pSelection - pointer to selection type (atom)
  588. * pTarget - pointer to requested target type (atom)
  589. *
  590. * Outputs:
  591. * ------
  592. * pType_return - pointer to type of data returned (atom)
  593. * pValue_return - pointer to pointer to data returned
  594. * pLength_return - ptr to length of data returned
  595. * pFormat_return - ptr to format of data returned
  596. *
  597. * Comments:
  598. * --------
  599. *
  600. *************************************<->***********************************/
  601. static Boolean
  602. wmq_convert (
  603. Widget w,
  604. Atom *pSelection,
  605. Atom *pTarget,
  606. Atom *pType_return,
  607. XtPointer *pValue_return,
  608. unsigned long *pLength_return,
  609. int *pFormat_return
  610. )
  611. {
  612. Boolean wm_query_found = False;
  613. int scr;
  614. for (scr = 0; scr < wmGD.numScreens; scr++)
  615. {
  616. if (wmGD.Screens[scr].managed)
  617. {
  618. if (*pSelection == xa_WM_QUERY[scr])
  619. {
  620. wm_query_found = True;
  621. break;
  622. }
  623. }
  624. }
  625. if (wm_query_found)
  626. {
  627. if (*pTarget == xa_WM_POINTER_WINDOW)
  628. {
  629. return (False);
  630. }
  631. else if (*pTarget == xa_WM_CLIENT_WINDOW)
  632. {
  633. return (False);
  634. }
  635. else if (*pTarget == xa_WM_ALL_CLIENTS)
  636. {
  637. return (wmq_convert_all_clients (w, scr, pType_return,
  638. pValue_return, pLength_return,
  639. pFormat_return));
  640. }
  641. }
  642. return (wm_query_found);
  643. } /* END OF FUNCTION wmq_convert */
  644. /*************************************<->*************************************
  645. *
  646. * Boolean wmq_convert_all_clients (w, screen, pType_return,
  647. * pValue_return, pLength_return, pFormat_return)
  648. *
  649. *
  650. * Description:
  651. * -----------
  652. * This function converts the WM_QUERY selection target WM_ALL_CLIENTS
  653. *
  654. * Inputs:
  655. * ------
  656. * w - widget
  657. * screen - screen number
  658. *
  659. * Outputs:
  660. * ------
  661. * pType_return - pointer to type of data returned (atom)
  662. * pValue_return - pointer to pointer to data returned
  663. * pLength_return - ptr to length of data returned
  664. * pFormat_return - ptr to format of data returned
  665. *
  666. * Comments:
  667. * --------
  668. *
  669. *************************************<->***********************************/
  670. static Boolean
  671. wmq_convert_all_clients (
  672. Widget w,
  673. int screen,
  674. Atom *pType_return,
  675. XtPointer *pValue_return,
  676. unsigned long *pLength_return,
  677. int *pFormat_return
  678. )
  679. {
  680. WmScreenData *pSD = NULL;
  681. ClientListEntry *pEntry;
  682. ClientData *pCD;
  683. /*
  684. * Start with empty client list
  685. */
  686. curXids = 0;
  687. /*
  688. * Get all clients on the specified screen
  689. */
  690. if (wmGD.Screens[screen].managed)
  691. {
  692. pSD = &wmGD.Screens[screen];
  693. /*
  694. * Traverse the client list for this screen and
  695. * add to the list of window IDs
  696. */
  697. pEntry = pSD->clientList;
  698. while (pEntry)
  699. {
  700. /*
  701. * Filter out entries for icons
  702. */
  703. if (pEntry->type != MINIMIZED_STATE)
  704. {
  705. pCD = pEntry->pCD;
  706. if (pCD->transientChildren)
  707. {
  708. wmq_list_subtree(pCD->transientChildren);
  709. }
  710. wmq_add_xid ((XID) pCD->client);
  711. }
  712. pEntry = pEntry->nextSibling;
  713. }
  714. }
  715. *pType_return = XA_WINDOW;
  716. *pValue_return = (XtPointer) pXids;
  717. *pLength_return = curXids;
  718. *pFormat_return = 32;
  719. return (True);
  720. } /* END OF FUNCTION wmq_convert_all_clients */
  721. /*************************************<->*************************************
  722. *
  723. * void wmq_list_subtree (pCD)
  724. *
  725. *
  726. * Description:
  727. * -----------
  728. * This function adds the windows in a transient subtree to the
  729. * global window list
  730. *
  731. * Inputs:
  732. * ------
  733. * pCD - client data for "leftmost" child of a subtree
  734. *
  735. * Outputs:
  736. * ------
  737. *
  738. * Comments:
  739. * --------
  740. *
  741. *************************************<->***********************************/
  742. static void
  743. wmq_list_subtree (
  744. ClientData *pCD
  745. )
  746. {
  747. /*
  748. * Do children first
  749. */
  750. if (pCD->transientChildren)
  751. {
  752. wmq_list_subtree(pCD->transientChildren);
  753. }
  754. /*
  755. * Do me
  756. */
  757. wmq_add_xid ((XID) pCD->client);
  758. /*
  759. * Do siblings
  760. */
  761. if (pCD->transientSiblings)
  762. {
  763. wmq_list_subtree(pCD->transientSiblings);
  764. }
  765. } /* END OF FUNCTION wmq_list_subtree */
  766. /*************************************<->*************************************
  767. *
  768. * void wmq_add_xid (win)
  769. *
  770. *
  771. * Description:
  772. * -----------
  773. * This function adds an xid to the list
  774. *
  775. * Inputs:
  776. * ------
  777. * win - xid to add
  778. *
  779. * Outputs:
  780. * ------
  781. *
  782. * Comments:
  783. * --------
  784. *
  785. *************************************<->***********************************/
  786. static void
  787. wmq_add_xid (
  788. XID win
  789. )
  790. {
  791. if (curXids >= numXids)
  792. {
  793. wmq_bump_xids();
  794. }
  795. if (curXids < numXids)
  796. {
  797. pXids[curXids++] = win;
  798. }
  799. } /* END OF FUNCTION wmq_add_xid */
  800. /*************************************<->*************************************
  801. *
  802. * void wmq_lose (w, pSelection)
  803. *
  804. *
  805. * Description:
  806. * -----------
  807. * This function is called when we lose the WM_QUERY selection
  808. *
  809. * Inputs:
  810. * ------
  811. * w - widget
  812. * pSelection - pointer to selection type (atom)
  813. *
  814. * Outputs:
  815. * ------
  816. *
  817. * Comments:
  818. * --------
  819. * This shouldn't happen!
  820. *
  821. *************************************<->***********************************/
  822. static void
  823. wmq_lose (
  824. Widget w,
  825. Atom *pSelection
  826. )
  827. {
  828. Warning (((char *)GETMESSAGE(56, 4, "Lost _MOTIF_WM_QUERY_nn selection")));
  829. } /* END OF FUNCTION wmq_lose */
  830. /*************************************<->*************************************
  831. *
  832. * void wmq_done (w, pSelection, pTarget)
  833. *
  834. *
  835. * Description:
  836. * -----------
  837. * This function is called when selection conversion is done.
  838. *
  839. * Inputs:
  840. * ------
  841. * w - widget
  842. * pSelection - pointer to selection type (atom)
  843. * pTarget - pointer to requested target type (atom)
  844. *
  845. * Outputs:
  846. * ------
  847. *
  848. * Comments:
  849. * --------
  850. * This is here to prevent Xt from freeing our buffers.
  851. *
  852. *************************************<->***********************************/
  853. static void
  854. wmq_done (
  855. Widget w,
  856. Atom *pSelection,
  857. Atom *pTarget
  858. )
  859. {
  860. } /* END OF FUNCTION wmq_done */
  861. /*************************************<->*************************************
  862. *
  863. * static void wmq_bump_xids ()
  864. *
  865. *
  866. * Description:
  867. * -----------
  868. * This function allocates more xids in our local buffer
  869. *
  870. * Inputs:
  871. * ------
  872. * w - widget
  873. * pSelection - pointer to selection type (atom)
  874. * pTarget - pointer to requested target type (atom)
  875. *
  876. * Outputs:
  877. * ------
  878. *
  879. * Comments:
  880. * --------
  881. * This is here to prevent Xt from freeing our buffers.
  882. *
  883. *************************************<->***********************************/
  884. static void
  885. wmq_bump_xids ( void )
  886. {
  887. XID *px;
  888. if (pXids)
  889. {
  890. if (!(px = (XID *)
  891. XtRealloc ((char *) pXids, (numXids + 32) * (sizeof (XID)))))
  892. {
  893. Warning (((char *)GETMESSAGE(56, 5, "Insufficient memory to convert _MOTIF_WM_QUERY_nn selection")));
  894. }
  895. else
  896. {
  897. pXids = px;
  898. numXids += 32;
  899. }
  900. }
  901. else
  902. {
  903. if (!(pXids = (XID *)
  904. XtMalloc (32 * (sizeof (XID)))))
  905. {
  906. Warning (((char *)GETMESSAGE(56, 5, "Insufficient memory to convert _MOTIF_WM_QUERY_nn selection")));
  907. }
  908. else
  909. {
  910. numXids = 32;
  911. }
  912. }
  913. }