WmProperty.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999
  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, 1993 HEWLETT-PACKARD COMPANY */
  32. /*
  33. * Included Files:
  34. */
  35. #include "WmGlobal.h"
  36. #include "WmICCC.h"
  37. #include <limits.h>
  38. #include <stdio.h>
  39. #include <Dt/WsmP.h>
  40. #include <X11/Xatom.h>
  41. #include <Xm/AtomMgr.h>
  42. /*
  43. * include extern functions
  44. */
  45. #include "WmColormap.h"
  46. #include "WmError.h"
  47. #include "WmResParse.h"
  48. #include "WmIconBox.h"
  49. /*
  50. * Function Declarations:
  51. */
  52. #include "WmProperty.h"
  53. /*
  54. * Global Variables:
  55. */
  56. static SizeHints sizeHints;
  57. /*************************************<->*************************************
  58. *
  59. * SizeHints *
  60. * GetNormalHints (pCD)
  61. *
  62. *
  63. * Description:
  64. * -----------
  65. * This function replaces the XGetNormalHints Xlib function. This function
  66. * gets the information in the WM_NORMAL_HINTS property on the client window.
  67. * The property encoding can be any of the supported versions (R2, R3+).
  68. *
  69. *
  70. * Inputs:
  71. * ------
  72. * pCD = (client)
  73. *
  74. *
  75. * Outputs:
  76. * -------
  77. * Return = A pointer to a filled out SizeHints structure is returned.
  78. * Default values are set if the WM_NORMAL_HINTS property could
  79. * not be retrieved.
  80. *
  81. *************************************<->***********************************/
  82. SizeHints *
  83. GetNormalHints(
  84. ClientData *pCD )
  85. {
  86. PropSizeHints *property = NULL;
  87. Atom actualType;
  88. int actualFormat;
  89. unsigned long leftover;
  90. unsigned long nitems;
  91. /*
  92. * Retrieve the property data.
  93. *
  94. * ICCC_R2 version: nitems = PROP_SIZE_HINTS_ELEMENTS - 3
  95. * ICCC_CURRENT version: nitems = PROP_SIZE_HINTS_ELEMENTS
  96. */
  97. if ((!HasProperty (pCD, XA_WM_NORMAL_HINTS)) ||
  98. ((Success != XGetWindowProperty (DISPLAY, pCD->client,
  99. XA_WM_NORMAL_HINTS, 0L, (long)PROP_SIZE_HINTS_ELEMENTS,
  100. False, XA_WM_SIZE_HINTS, &actualType, &actualFormat,
  101. &nitems, &leftover, (unsigned char **)&property)) ||
  102. (actualType != XA_WM_SIZE_HINTS) ||
  103. (nitems < (PROP_SIZE_HINTS_ELEMENTS - 3)) ||
  104. (actualFormat != 32)))
  105. {
  106. /*
  107. * Indicate no property values were retrieved:
  108. */
  109. sizeHints.icccVersion = ICCC_UNKNOWN;
  110. sizeHints.flags = 0;
  111. }
  112. else
  113. {
  114. /*
  115. * Parse the hint values out of the property data:
  116. */
  117. sizeHints.flags = property->flags;
  118. sizeHints.x = property->x;
  119. sizeHints.y = property->y;
  120. sizeHints.width = property->width;
  121. sizeHints.height = property->height;
  122. sizeHints.min_width = property->minWidth;
  123. sizeHints.min_height = property->minHeight;
  124. sizeHints.max_width = property->maxWidth;
  125. sizeHints.max_height = property->maxHeight;
  126. sizeHints.width_inc = property->widthInc;
  127. sizeHints.height_inc = property->heightInc;
  128. sizeHints.min_aspect.x = (int)property->minAspectX;
  129. sizeHints.min_aspect.y = (int)property->minAspectY;
  130. sizeHints.max_aspect.x = (int)property->maxAspectX;
  131. sizeHints.max_aspect.y = (int)property->maxAspectY;
  132. if (nitems == (PROP_SIZE_HINTS_ELEMENTS - 3))
  133. {
  134. /*
  135. * This is ICCC_R2.
  136. */
  137. sizeHints.icccVersion = ICCC_R2;
  138. }
  139. else
  140. {
  141. /*
  142. * This is ICCC_CURRENT.
  143. */
  144. sizeHints.icccVersion = ICCC_CURRENT;
  145. sizeHints.base_width = property->baseWidth;
  146. sizeHints.base_height = property->baseHeight;
  147. sizeHints.win_gravity = property->winGravity;
  148. }
  149. }
  150. /*
  151. * Free the property data buffer:
  152. */
  153. if (property)
  154. {
  155. XFree ((char *)property);
  156. }
  157. /*
  158. * Return the hints values:
  159. */
  160. return (&sizeHints);
  161. } /* END OF FUNCTION GetNormalHints */
  162. /*************************************<->*************************************
  163. *
  164. * ProcessWmProtocols (pCD)
  165. *
  166. *
  167. * Description:
  168. * -----------
  169. * This function reads and processes the WM_PROTOCOLS property that is
  170. * associated with a client window.
  171. *
  172. * ICCC_COMPLIANT check added to allow older clients to work, for now...
  173. * eventually, this code should be removed.
  174. *
  175. * Inputs:
  176. * ------
  177. * pCD = pointer to client data
  178. *
  179. *
  180. * Outputs:
  181. * -------
  182. * pCD = (clientProtocols, clientProtocolCount, protocolFlags)
  183. *
  184. *************************************<->***********************************/
  185. void ProcessWmProtocols (ClientData *pCD)
  186. {
  187. int rValue;
  188. Atom *property = NULL;
  189. #ifndef ICCC_COMPLIANT
  190. Atom actualType;
  191. int actualFormat;
  192. unsigned long leftover;
  193. unsigned long nitems;
  194. #else
  195. int nitems;
  196. #endif /* ICCC_COMPLIANT */
  197. int i;
  198. if (pCD->clientProtocols)
  199. {
  200. XtFree ((char *)pCD->clientProtocols);
  201. pCD->clientProtocols = NULL;
  202. }
  203. pCD->clientProtocolCount = 0;
  204. pCD->protocolFlags = 0;
  205. /*
  206. * Read the WM_PROTOCOLS property.
  207. */
  208. #ifndef ICCC_COMPLIANT
  209. if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
  210. rValue = -1;
  211. else
  212. rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_WM_PROTOCOLS, 0L,
  213. (long)MAX_CLIENT_PROTOCOL_COUNT, False, AnyPropertyType,
  214. &actualType, &actualFormat, &nitems, &leftover,
  215. (unsigned char **)&property);
  216. if ((rValue != Success) || (actualType == None) || (actualFormat != 32))
  217. #else
  218. if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
  219. rValue = -1;
  220. else
  221. rValue = XGetWMProtocols (DISPLAY, pCD->client,
  222. (Atom **)&property, &nitems);
  223. if (0 == rValue)
  224. #endif /* ICCC_COMPLIANT */
  225. {
  226. /*
  227. * WM_PROTOCOLS does not exist or it is an invalid type or size.
  228. */
  229. pCD->clientProtocols = NULL;
  230. }
  231. else
  232. {
  233. if (!(pCD->clientProtocols = (Atom *)XtMalloc (nitems * sizeof (Atom))))
  234. {
  235. /* unable to allocate space */
  236. Warning (((char *)GETMESSAGE(54, 1, "Insufficient memory for window management data")));
  237. }
  238. else
  239. {
  240. /*
  241. * Save the protocols in the client data and look for predefined
  242. * protocols.
  243. */
  244. pCD->clientProtocolCount = nitems;
  245. for (i = 0; i < nitems; i++)
  246. {
  247. pCD->clientProtocols[i] = property[i];
  248. if (property[i] == wmGD.xa_WM_SAVE_YOURSELF)
  249. {
  250. pCD->protocolFlags |= PROTOCOL_WM_SAVE_YOURSELF;
  251. }
  252. else if (property[i] == wmGD.xa_WM_TAKE_FOCUS)
  253. {
  254. pCD->protocolFlags |= PROTOCOL_WM_TAKE_FOCUS;
  255. }
  256. else if (property[i] == wmGD.xa_WM_DELETE_WINDOW)
  257. {
  258. pCD->protocolFlags |= PROTOCOL_WM_DELETE_WINDOW;
  259. }
  260. else if (property[i] == wmGD.xa_MWM_MESSAGES)
  261. {
  262. pCD->protocolFlags |= PROTOCOL_MWM_MESSAGES;
  263. }
  264. }
  265. }
  266. }
  267. if (property)
  268. {
  269. XFree ((char *)property);
  270. }
  271. } /* END OF FUNCTION ProcessWmProtocols */
  272. /*************************************<->*************************************
  273. *
  274. * ProcessMwmMessages (pCD)
  275. *
  276. *
  277. * Description:
  278. * -----------
  279. * This function reads and processes the _MWM_MESSAGES property that is
  280. * associated with a client window.
  281. *
  282. *
  283. * Inputs:
  284. * ------
  285. * pCD = pointer to client data
  286. *
  287. *
  288. * Outputs:
  289. * -------
  290. * pCD = (mwmMessagesCount, mwmMessages)
  291. *
  292. *************************************<->***********************************/
  293. void ProcessMwmMessages (ClientData *pCD)
  294. {
  295. int rValue;
  296. long *property = NULL;
  297. Atom actualType;
  298. int actualFormat;
  299. unsigned long leftover;
  300. unsigned long nitems;
  301. int i;
  302. if (pCD->mwmMessages)
  303. {
  304. XtFree ((char *)pCD->mwmMessages);
  305. pCD->mwmMessages = NULL;
  306. }
  307. pCD->mwmMessagesCount = 0;
  308. /*
  309. * Read the _MWM_MESSAGES property.
  310. */
  311. if (!HasProperty (pCD, wmGD.xa_MWM_MESSAGES))
  312. rValue = ~Success;
  313. else
  314. rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_MESSAGES, 0L,
  315. (long)MAX_MWM_MESSAGES_COUNT, False, AnyPropertyType,
  316. &actualType, &actualFormat, &nitems, &leftover,
  317. (unsigned char **)&property);
  318. if ((rValue != Success) || (actualType == None) || (actualFormat != 32)
  319. || (nitems == 0))
  320. {
  321. /*
  322. * _MWM_MESSAGES does not exist or it is an invalid type.
  323. */
  324. pCD->mwmMessages = NULL;
  325. }
  326. else
  327. {
  328. if (!(pCD->mwmMessages = (long *)XtMalloc (nitems * sizeof (long))))
  329. {
  330. /* unable to allocate space */
  331. Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
  332. }
  333. else
  334. {
  335. /*
  336. * Save the protocols in the client data and look for predefined
  337. * protocols.
  338. */
  339. pCD->mwmMessagesCount = nitems;
  340. for (i = 0; i < nitems; i++)
  341. {
  342. if ((pCD->mwmMessages[i] = property[i]) == wmGD.xa_MWM_OFFSET)
  343. {
  344. pCD->protocolFlags |= PROTOCOL_MWM_OFFSET;
  345. }
  346. }
  347. }
  348. }
  349. if (property)
  350. {
  351. XFree ((char *)property);
  352. }
  353. } /* END OF FUNCTION ProcessMwmMessages */
  354. /*************************************<->*************************************
  355. *
  356. * SetMwmInfo (propWindow, flags, wmWindow)
  357. *
  358. *
  359. * Description:
  360. * -----------
  361. * This function sets up the _MOTIF_WM_INFO property on the specified (usually
  362. * the root) window.
  363. *
  364. *
  365. * Inputs:
  366. * ------
  367. * propWindow = window on which the _MOTIF_WM_INFO property is to be set
  368. *
  369. * flags = motifWmInfo.flags value
  370. *
  371. * wmWindow = motifWmInfo.wmWindow value
  372. *
  373. *
  374. * Outputs:
  375. * -------
  376. * _MWM_INFO = this property is set on the specified window
  377. *
  378. *************************************<->***********************************/
  379. void SetMwmInfo (Window propWindow, long flags, Window wmWindow)
  380. {
  381. PropMwmInfo property;
  382. property.flags = flags;
  383. property.wmWindow = wmWindow;
  384. XChangeProperty (DISPLAY, propWindow, wmGD.xa_MWM_INFO, wmGD.xa_MWM_INFO,
  385. 32, PropModeReplace, (unsigned char *)&property,
  386. PROP_MWM_INFO_ELEMENTS);
  387. } /* END OF FUNCTION SetMwmInfo */
  388. /*************************************<->*************************************
  389. *
  390. * SetMwmSaveSessionInfo (wmWindow)
  391. *
  392. *
  393. * Description:
  394. * -----------
  395. * This function sets up the WM_SAVE_YOURSELF property on the wm window
  396. *
  397. *
  398. * Inputs:
  399. * ------
  400. * wmWindow = motifWmInfo.wmWindow
  401. *
  402. *
  403. * Outputs:
  404. * -------
  405. * WM_SAVE_YOURSELF = this property is set on the wm window
  406. *
  407. *************************************<->***********************************/
  408. void SetMwmSaveSessionInfo (Window wmWindow)
  409. {
  410. Atom property;
  411. property = wmGD.xa_WM_SAVE_YOURSELF;
  412. XChangeProperty (DISPLAY, wmWindow,
  413. wmGD.xa_WM_PROTOCOLS, XA_ATOM,
  414. 32, PropModeReplace,
  415. (unsigned char *) &property, 1);
  416. SetWMState(wmWindow, NORMAL_STATE, 0);
  417. } /* END OF FUNCTION SetMwmSaveSessionInfo */
  418. /*************************************<->*************************************
  419. *
  420. * GetWMState (window)
  421. *
  422. *
  423. * Description:
  424. * -----------
  425. * This function gets the WM_STATE property on a client top-level
  426. * window.
  427. *
  428. *
  429. * Inputs:
  430. * ------
  431. * window = client window from which the WM_STATE property is to be retrieved
  432. *
  433. *
  434. * Outputs:
  435. * -------
  436. * RETURN = a pointer to the WM_STATE property value (NULL if not defined)
  437. *
  438. *
  439. * Comments:
  440. * --------
  441. * This function will eventually be superseded when WM_STATE support is
  442. * added to the official X release.
  443. *
  444. *************************************<->***********************************/
  445. PropWMState *
  446. GetWMState(
  447. Window window )
  448. {
  449. int ret_val;
  450. PropWMState *property = NULL;
  451. Atom actual_type;
  452. int actual_format;
  453. unsigned long nitems;
  454. unsigned long leftover;
  455. ret_val = XGetWindowProperty (DISPLAY, window, wmGD.xa_WM_STATE,
  456. 0L, PROP_WM_STATE_ELEMENTS,
  457. False, wmGD.xa_WM_STATE,
  458. &actual_type, &actual_format,
  459. &nitems, &leftover, (unsigned char **)&property);
  460. if (!((ret_val == Success) && (actual_type == wmGD.xa_WM_STATE) &&
  461. (nitems == PROP_WM_STATE_ELEMENTS)))
  462. {
  463. /*
  464. * The property could not be retrieved or is not correctly set up.
  465. */
  466. if (property)
  467. {
  468. XFree ((char *)property);
  469. property = NULL;
  470. }
  471. }
  472. return (property);
  473. } /* END OF FUNCTION GetWMState */
  474. /*************************************<->*************************************
  475. *
  476. * SetWMState (window, state, icon)
  477. *
  478. *
  479. * Description:
  480. * -----------
  481. * This function sets up the WM_STATE property on a client top-level
  482. * window.
  483. *
  484. *
  485. * Inputs:
  486. * ------
  487. * window = client window on which the WM_STATE property is to be set
  488. *
  489. * state = state of the client application
  490. *
  491. * icon = window manager's icon window
  492. *
  493. *
  494. * Outputs:
  495. * -------
  496. * WM_STATE = this property is set on the client window
  497. *
  498. *
  499. * Comments:
  500. * --------
  501. * This function will eventually be superseded when WM_STATE support is
  502. * added to the official X release.
  503. *
  504. *************************************<->***********************************/
  505. void SetWMState (Window window, int state, Window icon)
  506. {
  507. PropWMState property;
  508. property.state = state;
  509. property.icon = icon;
  510. XChangeProperty (DISPLAY, window, wmGD.xa_WM_STATE, wmGD.xa_WM_STATE, 32,
  511. PropModeReplace, (unsigned char *)&property, PROP_WM_STATE_ELEMENTS);
  512. } /* END OF FUNCTION SetWMState */
  513. /*************************************<->*************************************
  514. *
  515. * PropMwmHints *
  516. * GetMwmHints (pCD)
  517. *
  518. *
  519. * Description:
  520. * -----------
  521. * This function reads any _MWM_HINTS property that is associated with a
  522. * client window.
  523. *
  524. * Inputs:
  525. * ------
  526. * pCD = pointer to client data
  527. *
  528. * Outputs:
  529. * -------
  530. * RETURN = ptr to mwm hints property, or NULL ptr if failure
  531. *
  532. *************************************<->***********************************/
  533. PropMwmHints *
  534. GetMwmHints(
  535. ClientData *pCD )
  536. {
  537. int ret_val;
  538. PropMwmHints *property = NULL;
  539. Atom actual_type;
  540. int actual_format;
  541. unsigned long nitems;
  542. unsigned long leftover;
  543. if (!HasProperty(pCD, wmGD.xa_MWM_HINTS))
  544. ret_val = ~Success;
  545. else
  546. ret_val = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_HINTS,
  547. 0L, PROP_MWM_HINTS_ELEMENTS,
  548. False, wmGD.xa_MWM_HINTS,
  549. &actual_type, &actual_format,
  550. &nitems, &leftover, (unsigned char **)&property);
  551. /*
  552. * Retrieve the property data.
  553. *
  554. * Motif 1.1.n clients: nitems = PROP_MWM_HINTS_ELEMENTS
  555. * Motif 1.2 clients: nitems = PROP_MWM_HINTS_ELEMENTS + 2
  556. *
  557. * NOTES: We don't need to check (nitems == PROP_MWM_HINTS_ELEMENTS)
  558. * since...
  559. *
  560. * If running Motif 1.1.n client with Mwm 1.2, then ignore extra elements
  561. * since property.flags won't have extra elements set.
  562. *
  563. * If running Motif 1.2 client with Mwm 1.1.n, then ignore extra elements
  564. * since Mwm 1.1.n won't try to access the extra elements.
  565. */
  566. if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_HINTS))
  567. {
  568. return (property); /* indicate success */
  569. }
  570. /*
  571. * The property could not be retrieved or is not correctly set up.
  572. */
  573. if (property)
  574. {
  575. XFree ((char *)property);
  576. }
  577. return (NULL); /* indicate failure */
  578. } /* END OF FUNCTION GetMwmHints */
  579. /*************************************<->*************************************
  580. *
  581. * PropMwmInfo *
  582. * GetMwmInfo (rootWindowOfScreen)
  583. *
  584. *
  585. * Description:
  586. * -----------
  587. * This function reads the _MOTIF_WM_INFO property from the root window if
  588. * it is setup.
  589. *
  590. * Inputs:
  591. * ------
  592. * pSD = pointer to screen data
  593. *
  594. * Outputs:
  595. * -------
  596. * RETURN = ptr to motif wm info property, or NULL ptr if no property
  597. *
  598. *************************************<->***********************************/
  599. PropMwmInfo *GetMwmInfo (Window rootWindowOfScreen)
  600. {
  601. int ret_val;
  602. PropMwmInfo *property = NULL;
  603. Atom actual_type;
  604. int actual_format;
  605. unsigned long nitems;
  606. unsigned long leftover;
  607. ret_val = XGetWindowProperty (DISPLAY, rootWindowOfScreen,
  608. wmGD.xa_MWM_INFO,
  609. 0L, PROP_MWM_INFO_ELEMENTS,
  610. False, wmGD.xa_MWM_INFO,
  611. &actual_type, &actual_format,
  612. &nitems, &leftover,
  613. (unsigned char **)&property);
  614. if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_INFO) &&
  615. (nitems == PROP_MWM_INFO_ELEMENTS))
  616. {
  617. return (property); /* indicate success */
  618. }
  619. /*
  620. * The property could not be retrieved or is not correctly set up.
  621. */
  622. if (property)
  623. {
  624. XFree ((char *)property);
  625. }
  626. return (NULL); /* indicate failure */
  627. } /* END OF FUNCTION GetMwmInfo */
  628. /*************************************<->*************************************
  629. *
  630. * ProcessWmColormapWindows (pCD)
  631. *
  632. *
  633. * Description:
  634. * -----------
  635. * This function retrieves and processes the WM_COLORMAP_WINDOWS client
  636. * window property.
  637. *
  638. *
  639. * Inputs:
  640. * ------
  641. * pCD = pointer to client data
  642. *
  643. *
  644. * Outputs:
  645. * -------
  646. * pCD = (cmapWindows, clientCmapList, clientCmapCount, clientCmapIndex)
  647. *
  648. *************************************<->***********************************/
  649. void ProcessWmColormapWindows (ClientData *pCD)
  650. {
  651. int rValue;
  652. Window *property = NULL;
  653. Atom actualType;
  654. int actualFormat;
  655. unsigned long leftover;
  656. unsigned long nitems;
  657. int i;
  658. Window *pWindows;
  659. Colormap *pColormaps;
  660. int colormapCount;
  661. XWindowAttributes wAttributes;
  662. ClientData *pcd;
  663. XSetWindowAttributes sAttributes;
  664. int *pCmapFlags;
  665. /*
  666. * pCD->clientCmapCount and pCD->clientCmapIndex are initialized in
  667. * WmWinInfo.c.
  668. */
  669. /*
  670. * Read the WM_COLORMAP_WINDOWS property.
  671. */
  672. rValue = XGetWindowProperty (DISPLAY, pCD->client,
  673. wmGD.xa_WM_COLORMAP_WINDOWS, 0L,
  674. (long)MAX_COLORMAP_WINDOWS_COUNT, False, AnyPropertyType,
  675. &actualType, &actualFormat, &nitems, &leftover,
  676. (unsigned char **)&property);
  677. if ((rValue == Success) && (actualType != None) && (actualFormat == 32) &&
  678. (nitems > 0))
  679. {
  680. /*
  681. * WM_COLORMAP_WINDOWS exists and is a valid type.
  682. */
  683. if (!(pWindows = (Window *)XtMalloc ((nitems * sizeof (Window)) + 1)) ||
  684. !(pColormaps = (Colormap *)XtMalloc ((nitems*sizeof(Colormap)) + 1)))
  685. {
  686. /* unable to allocate space */
  687. Warning (((char *)GETMESSAGE(54, 3, "Insufficient memory for window management data")));
  688. if (pWindows)
  689. {
  690. XtFree ((char *)pWindows);
  691. }
  692. }
  693. /* Is the above OSF code a bug -- allocates one extra byte, rather */
  694. /* than one extra element, for the top window if needed? */
  695. else if ( ! (pCmapFlags = (int *)XtCalloc(nitems+1,sizeof(int)))) {
  696. /* unable to allocate space */
  697. Warning (((char *)GETMESSAGE(54, 4, "Insufficient memory for window manager flags")));
  698. XtFree ((char *)pWindows); XtFree ((char *)pColormaps);
  699. }
  700. else
  701. {
  702. /*
  703. * Check to see if the top-level client window is in the list.
  704. * If it is not then add it to the head of the list.
  705. */
  706. for (i = 0; i < nitems; i++)
  707. {
  708. if (property[i] == pCD->client)
  709. {
  710. break;
  711. }
  712. }
  713. colormapCount = 0;
  714. if (i == nitems)
  715. {
  716. /* add the client window to the colormap window list */
  717. pWindows[0] = pCD->client;
  718. pColormaps[0] = FindColormap (pCD, pCD->client);
  719. colormapCount++;
  720. }
  721. sAttributes.event_mask = (ColormapChangeMask);
  722. for (i = 0; i < nitems; i++)
  723. {
  724. if ((pColormaps[colormapCount] =
  725. FindColormap (pCD, property[i])) != None)
  726. {
  727. pWindows[colormapCount] = property[i];
  728. colormapCount++;
  729. }
  730. else if (XFindContext (DISPLAY, property[i],
  731. wmGD.windowContextType, (caddr_t *)&pcd))
  732. {
  733. /*
  734. * The window is not a top level window or a window that
  735. * is already being tracked for colormap changes.
  736. * Track colormap attribute changes.
  737. */
  738. XChangeWindowAttributes (DISPLAY, property[i], CWEventMask,
  739. &sAttributes);
  740. if (XGetWindowAttributes (DISPLAY, property[i],
  741. &wAttributes))
  742. {
  743. pWindows[colormapCount] = property[i];
  744. pColormaps[colormapCount] = wAttributes.colormap;
  745. colormapCount++;
  746. }
  747. }
  748. }
  749. /*
  750. * Free up the old colormap window data if it has been set. Set
  751. * new window contexts.
  752. */
  753. ResetColormapData (pCD, pWindows, colormapCount);
  754. /*
  755. * Set the colormap window data.
  756. */
  757. pCD->clientColormap = pColormaps[0];
  758. if (colormapCount > 1)
  759. {
  760. /*
  761. * The top level window and at least one other window is in
  762. * the colormap windows list.
  763. */
  764. pCD->clientCmapCount = colormapCount;
  765. pCD->cmapWindows = pWindows;
  766. pCD->clientCmapList = pColormaps;
  767. pCD->clientCmapIndex = 0;
  768. pCD->clientCmapFlags = pCmapFlags;
  769. }
  770. else
  771. {
  772. /*
  773. * Only the top level window is being tracked for colormap
  774. * data.
  775. */
  776. pCD->clientCmapCount = 0;
  777. XtFree ((char *)pWindows);
  778. XtFree ((char *)pColormaps);
  779. XtFree((char *)pCmapFlags);
  780. }
  781. }
  782. }
  783. if (property)
  784. {
  785. XFree ((char *)property);
  786. }
  787. } /* END OF FUNCTION ProcessWmColormapWindows */
  788. /*************************************<->*************************************
  789. *
  790. * FindColormap (pCD, window)
  791. *
  792. *
  793. * Description:
  794. * -----------
  795. * This function checks colormap information that is currently saved in
  796. * the client data for the colormap of the specified window.
  797. *
  798. *
  799. * Inputs:
  800. * ------
  801. * pCD = pointer to client data
  802. *
  803. * window = get the colormap id for this window
  804. *
  805. *
  806. * Outputs:
  807. * -------
  808. * RETURN = colormap id for window (NULL if no colormap information)
  809. *
  810. *************************************<->***********************************/
  811. Colormap FindColormap (ClientData *pCD, Window window)
  812. {
  813. Colormap colormap = (Colormap)0;
  814. int i;
  815. if (pCD->clientCmapCount == 0)
  816. {
  817. /*
  818. * If the colormap count is 0 there is no list of colormaps and
  819. * clientColormap is the colormap of the top-level window.
  820. */
  821. if (window == pCD->client)
  822. {
  823. colormap = pCD->clientColormap;
  824. }
  825. }
  826. else
  827. {
  828. for (i = 0; i < pCD->clientCmapCount; i++)
  829. {
  830. if (pCD->cmapWindows[i] == window)
  831. {
  832. colormap = pCD->clientCmapList[i];
  833. break;
  834. }
  835. }
  836. }
  837. return (colormap);
  838. } /* END OF FUNCTION FindColormap */
  839. /*************************************<->*************************************
  840. *
  841. * GetMwmMenuItems (pCD)
  842. *
  843. *
  844. * Description:
  845. * -----------
  846. * This function reads and processes any _MWM_MENU property that is
  847. * associated with a client window and returns a list of MenuItem structures
  848. * specified by the property, or NULL.
  849. *
  850. *
  851. * Inputs:
  852. * ------
  853. * pCD = pointer to client data
  854. *
  855. *
  856. * Outputs:
  857. * -------
  858. * Return = MenuItem list or NULL.
  859. *
  860. *************************************<->***********************************/
  861. MenuItem *
  862. GetMwmMenuItems(
  863. ClientData *pCD )
  864. {
  865. int rValue;
  866. XTextProperty textProperty;
  867. MenuItem *menuItems;
  868. /*
  869. * Read the _MWM_MENU property.
  870. */
  871. textProperty.value = (unsigned char *)NULL;
  872. rValue = XGetTextProperty(DISPLAY, pCD->client, &textProperty,
  873. wmGD.xa_MWM_MENU);
  874. if ((rValue == 0) || (textProperty.value == (unsigned char *)NULL))
  875. /* _MWM_MENU does not exist or it is an invalid type. */
  876. {
  877. menuItems = NULL;
  878. }
  879. else
  880. /* parse the property string */
  881. {
  882. char **textList;
  883. int nItems;
  884. if (XmbTextPropertyToTextList(DISPLAY, &textProperty,
  885. &textList, &nItems) != Success)
  886. {
  887. menuItems = NULL;
  888. }
  889. else
  890. {
  891. menuItems = ParseMwmMenuStr (PSD_FOR_CLIENT(pCD),
  892. (unsigned char *)textList[0]);
  893. XFreeStringList(textList);
  894. }
  895. XFree((void *)textProperty.value);
  896. }
  897. return (menuItems);
  898. } /* END OF FUNCTION GetMwmMenuItems */
  899. /*************************************<->*************************************
  900. *
  901. * GetWorkspaceHints (display, window, ppWsAtoms, pCount, pbAll)
  902. *
  903. *
  904. * Description:
  905. * -----------
  906. * Get the contents of the WM_COMMAND property on a window
  907. *
  908. *
  909. * Inputs:
  910. * ------
  911. * display - X display
  912. * window - window to get hints from
  913. * ppWsAtoms - pointer to a list of workspace atoms (to be returned)
  914. * pCount - ptr to a number of atoms (to be returned)
  915. * pbAll - ptr to a boolean (to be returned)
  916. *
  917. *
  918. * Returns:
  919. * --------
  920. * Success if suceeded, otherwise failure code.
  921. *
  922. *
  923. * Outputs:
  924. * -------
  925. * *ppWsAtoms - list of workspace atoms
  926. * *pCount - number of atoms in *ppWsAtoms
  927. * *pbAll - True if should put in all workspaces
  928. *
  929. *
  930. * Comments:
  931. * --------
  932. * The caller must XtFree *ppWsAtoms when done!!!
  933. *
  934. *************************************<->***********************************/
  935. Status GetWorkspaceHints (Display *display, Window window,
  936. Atom **ppWsAtoms, unsigned int *pCount,
  937. Boolean *pbAll)
  938. {
  939. int rcode;
  940. DtWorkspaceHints *pWsHints;
  941. Atom *paWs;
  942. rcode = _DtWsmGetWorkspaceHints(display, window, &pWsHints);
  943. if (rcode == Success)
  944. {
  945. if (pWsHints->flags & DT_WORKSPACE_HINTS_WORKSPACES)
  946. {
  947. paWs = (Atom *)
  948. XtMalloc (pWsHints->numWorkspaces * sizeof(Atom));
  949. memcpy (paWs,
  950. pWsHints->pWorkspaces,
  951. (pWsHints->numWorkspaces * sizeof(Atom)));
  952. *pCount = pWsHints->numWorkspaces;
  953. *ppWsAtoms = paWs;
  954. }
  955. else
  956. {
  957. *pCount = 0;
  958. *ppWsAtoms = NULL;
  959. }
  960. if ((pWsHints->flags & DT_WORKSPACE_HINTS_WSFLAGS) &&
  961. (pWsHints->wsflags & DT_WORKSPACE_FLAGS_OCCUPY_ALL))
  962. {
  963. *pbAll = True;
  964. }
  965. else
  966. {
  967. *pbAll = False;
  968. }
  969. _DtWsmFreeWorkspaceHints (pWsHints);
  970. }
  971. return(rcode);
  972. } /* END OF FUNCTION GetWorkspaceHints */
  973. /*************************************<->*************************************
  974. *
  975. * SetEmbeddedClientsProperty (propWindow, pEmbeddedClients,
  976. * cEmbeddedCLients)
  977. *
  978. *
  979. * Description:
  980. * -----------
  981. * This function writes the _DT_WORKSPACE_EMBEDDED_CLIENTS property
  982. *
  983. *
  984. * Inputs:
  985. * ------
  986. * propWindow = window on which the property is to be written
  987. * pEmbeddedClients = pointer to data (array of window IDs)
  988. * cEmbeddedClients = number of window IDs in the array
  989. *
  990. *************************************<->***********************************/
  991. void SetEmbeddedClientsProperty (Window propWindow,
  992. Window *pEmbeddedClients, unsigned long cEmbeddedClients)
  993. {
  994. XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_EMBEDDED_CLIENTS,
  995. wmGD.xa_DT_EMBEDDED_CLIENTS,
  996. 32, PropModeReplace, (unsigned char *)pEmbeddedClients,
  997. cEmbeddedClients);
  998. } /* END OF FUNCTION SetEmbeddedClientsProperty */
  999. /*************************************<->*************************************
  1000. *
  1001. * SetWorkspaceListProperty (pSD)
  1002. *
  1003. *
  1004. * Description:
  1005. * -----------
  1006. * This function sets up the _DT_WORKSPACE_LIST property
  1007. *
  1008. *
  1009. * Inputs:
  1010. * ------
  1011. * pSD = ptr to screen data
  1012. *
  1013. *
  1014. *************************************<->***********************************/
  1015. void
  1016. SetWorkspaceListProperty (WmScreenData *pSD)
  1017. {
  1018. WmWorkspaceData *pws;
  1019. Atom *pWsList;
  1020. int count;
  1021. pWsList = (Atom *)
  1022. XtMalloc (pSD->numWorkspaces * sizeof(Atom));
  1023. pws = pSD->pWS;
  1024. for (count = 0; count < pSD->numWorkspaces; count++)
  1025. {
  1026. pWsList[count] = pws->id;
  1027. pws++;
  1028. }
  1029. XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
  1030. wmGD.xa_DT_WORKSPACE_LIST,
  1031. XA_ATOM,
  1032. 32, PropModeReplace, (unsigned char *)pWsList,
  1033. (pSD->numWorkspaces * sizeof(Atom))/sizeof(long));
  1034. XtFree ((char *) pWsList);
  1035. } /* END OF FUNCTION SetWorkspaceListProperty */
  1036. /*************************************<->*************************************
  1037. *
  1038. * SetCurrentWorkspaceProperty (pSD)
  1039. *
  1040. *
  1041. * Description:
  1042. * -----------
  1043. * This function sets up the _DT_WORKSPACE_CURRENT property
  1044. *
  1045. *
  1046. * Inputs:
  1047. * ------
  1048. * pSD = ptr to screen data
  1049. *
  1050. *
  1051. *************************************<->***********************************/
  1052. void
  1053. SetCurrentWorkspaceProperty (WmScreenData *pSD)
  1054. {
  1055. Atom aCurrent;
  1056. aCurrent = pSD->pActiveWS->id;
  1057. XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
  1058. wmGD.xa_DT_WORKSPACE_CURRENT,
  1059. XA_ATOM,
  1060. 32, PropModeReplace, (unsigned char *)&aCurrent,
  1061. (sizeof(Atom))/sizeof(long));
  1062. XSync (DISPLAY, False); /* XFlush didn't work here, why? */
  1063. } /* END OF FUNCTION SetCurrentWorkspaceProperty */
  1064. /*************************************<->*************************************
  1065. *
  1066. * SetWorkspaceInfoProperty (pWS)
  1067. *
  1068. *
  1069. * Description:
  1070. * -----------
  1071. * This function sets up the _DT_WORKSPACE_INFO_<name> property
  1072. * for a particular workspace
  1073. *
  1074. *
  1075. * Inputs:
  1076. * ------
  1077. * pWS = ptr to workspace data
  1078. *
  1079. *
  1080. *************************************<->***********************************/
  1081. void
  1082. SetWorkspaceInfoProperty (WmWorkspaceData *pWS)
  1083. {
  1084. char *pch;
  1085. Atom aProperty;
  1086. String sTitle;
  1087. char **ppchList;
  1088. int iNumStrings;
  1089. int count;
  1090. int i, ix;
  1091. Status status;
  1092. XTextProperty tp;
  1093. #define WIP_NUMBER_SIZE 16
  1094. /*
  1095. * Construct our property name
  1096. */
  1097. pch = WorkspacePropertyName (pWS);
  1098. aProperty = XmInternAtom (DISPLAY, pch, FALSE);
  1099. XtFree ((char *) pch);
  1100. /*
  1101. * Determine the number of strings in our vector. One for each of
  1102. *
  1103. * workspace title
  1104. * pixel set id
  1105. * backdrop background
  1106. * backdrop foreground
  1107. * backdrop name
  1108. * number of backdrop windows
  1109. * list of backdrop windows
  1110. */
  1111. iNumStrings = 7; /* number of fields minus backdrop window(s) */
  1112. count = 1; /* number of backdrop windows */
  1113. iNumStrings += count;
  1114. /* allocate string vector */
  1115. ppchList = (char **) XtMalloc (iNumStrings * sizeof (char *));
  1116. pch = (char *) XtMalloc (iNumStrings * WIP_NUMBER_SIZE * sizeof(char));
  1117. i = 0;
  1118. /* Convert workspace title to ascii */
  1119. sTitle = (String) WmXmStringToString (pWS->title);
  1120. ppchList[i++] = (char *) sTitle;
  1121. /* Pixel set id */
  1122. ix = (i * WIP_NUMBER_SIZE);
  1123. sprintf (&pch[ix], "%d", pWS->backdrop.colorSet);
  1124. ppchList[i++] = &pch[ix];
  1125. /* backdrop background */
  1126. ix = (i * WIP_NUMBER_SIZE);
  1127. sprintf (&pch[ix], "0x%lx", pWS->backdrop.background);
  1128. ppchList[i++] = &pch[ix];
  1129. /* backdrop foreground */
  1130. ix = (i * WIP_NUMBER_SIZE);
  1131. sprintf (&pch[ix], "0x%lx", pWS->backdrop.foreground);
  1132. ppchList[i++] = &pch[ix];
  1133. /* backdrop name */
  1134. ix = (i * WIP_NUMBER_SIZE);
  1135. sprintf (&pch[ix], "0x%lx", pWS->backdrop.nameAtom);
  1136. ppchList[i++] = &pch[ix];
  1137. /* backdrop type */
  1138. ix = (i * WIP_NUMBER_SIZE);
  1139. sprintf (&pch[ix], "%d", pWS->backdrop.imageType);
  1140. ppchList[i++] = &pch[ix];
  1141. /* number of backdrop windows */
  1142. ix = (i * WIP_NUMBER_SIZE);
  1143. if (pWS->backdrop.window == None)
  1144. {
  1145. strcpy (&pch[ix], "0");
  1146. }
  1147. else
  1148. {
  1149. sprintf (&pch[ix], "%d", count);
  1150. }
  1151. ppchList[i++] = &pch[ix];
  1152. /* backdrop windows */
  1153. /*
  1154. * One or zero backdrop windows
  1155. * (NULL written if zero)
  1156. */
  1157. ix = (i * WIP_NUMBER_SIZE);
  1158. sprintf (&pch[ix], "0x%lx", pWS->backdrop.window);
  1159. ppchList[i++] = &pch[ix];
  1160. /*
  1161. * Write out the property
  1162. */
  1163. status = XmbTextListToTextProperty (DISPLAY, ppchList, iNumStrings,
  1164. XStdICCTextStyle, &tp);
  1165. if ((status == Success) || (status > 0))
  1166. {
  1167. /*
  1168. * Complete or partial conversion
  1169. */
  1170. XSetTextProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, &tp, aProperty);
  1171. XFree (tp.value);
  1172. }
  1173. XtFree ((char *) ppchList);
  1174. XtFree (pch);
  1175. if (sTitle) XtFree ((char *)sTitle);
  1176. } /* END OF FUNCTION SetWorkspaceInfoProperty */
  1177. /*************************************<->*************************************
  1178. *
  1179. * DeleteWorkspaceInfoProperty (pWS)
  1180. *
  1181. *
  1182. * Description:
  1183. * -----------
  1184. * This function deletes a _DT_WORKSPACE_INFO_<name> property
  1185. * for a particular workspace
  1186. *
  1187. *
  1188. * Inputs:
  1189. * ------
  1190. * pWS = ptr to workspace data
  1191. *
  1192. *
  1193. *************************************<->***********************************/
  1194. void
  1195. DeleteWorkspaceInfoProperty (WmWorkspaceData *pWS)
  1196. {
  1197. char *pch;
  1198. Atom aProperty;
  1199. /*
  1200. * Get the atom for the workspace property.
  1201. */
  1202. pch = WorkspacePropertyName (pWS);
  1203. aProperty = XmInternAtom (DISPLAY, pch, FALSE);
  1204. XtFree ((char *) pch);
  1205. /*
  1206. * Do the property deletion
  1207. */
  1208. XDeleteProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, aProperty);
  1209. XFlush (DISPLAY);
  1210. } /* END OF FUNCTION DeleteWorkspaceInfoProperty */
  1211. /*************************************<->*************************************
  1212. *
  1213. * WorkspacePropertyName (pWS)
  1214. *
  1215. *
  1216. * Description:
  1217. * -----------
  1218. * This function returns a string containing the property name for a
  1219. * workspace.
  1220. *
  1221. *
  1222. * Inputs:
  1223. * ------
  1224. * pWS = ptr to workspace data
  1225. *
  1226. * Returns
  1227. * -------
  1228. * string containing the workspace property name (Free with XtFree)
  1229. *
  1230. *
  1231. *************************************<->***********************************/
  1232. char *
  1233. WorkspacePropertyName (WmWorkspaceData *pWS)
  1234. {
  1235. char *pch;
  1236. char *pchName;
  1237. int len;
  1238. /*
  1239. * Construct our property name
  1240. */
  1241. pchName = pWS->name;
  1242. len = strlen(pchName) + strlen (_XA_DT_WORKSPACE_INFO) + 4;
  1243. pch = (char *) XtMalloc (len);
  1244. strcpy (pch, _XA_DT_WORKSPACE_INFO);
  1245. strcat (pch, "_");
  1246. strcat (pch, pchName);
  1247. return (pch);
  1248. } /* END OF FUNCTION WorkspacePropertyName */
  1249. /*************************************<->*************************************
  1250. *
  1251. * SetWorkspacePresence (propWindow, pWsPresence, cPresence)
  1252. *
  1253. *
  1254. * Description:
  1255. * -----------
  1256. * This function sets up the _DT_WORKSPACE_PRESENCE property
  1257. *
  1258. *
  1259. * Inputs:
  1260. * ------
  1261. * propWindow = window on which the _DT_WORKSPACE_PRESENCE property
  1262. * is to be set
  1263. * pWsPresence = pointer to workspace presence data
  1264. * cPresence = size of workspace presence data
  1265. *
  1266. *
  1267. *************************************<->***********************************/
  1268. void SetWorkspacePresence (Window propWindow, Atom *pWsPresence, unsigned long cPresence)
  1269. {
  1270. XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_PRESENCE,
  1271. wmGD.xa_DT_WORKSPACE_PRESENCE, 32, PropModeReplace,
  1272. (unsigned char *)pWsPresence, cPresence);
  1273. XFlush (DISPLAY);
  1274. } /* END OF FUNCTION SetWorkspacePresence */
  1275. /*************************************<->*************************************
  1276. *
  1277. * GetDtSessionHints (pSD, sNum)
  1278. *
  1279. *
  1280. * Description:
  1281. * -----------
  1282. * This function reads and processes _DT_SESSION_HINTS property that is
  1283. * associated with the root window of each screen managed by dtwm
  1284. *
  1285. *
  1286. * Inputs:
  1287. * ------
  1288. *
  1289. *
  1290. * Outputs:
  1291. * -------
  1292. *
  1293. *************************************<->***********************************/
  1294. void GetDtSessionHints (WmScreenData *pSD, int sNum)
  1295. {
  1296. int rValue;
  1297. char *property = NULL;
  1298. Atom actualType;
  1299. int actualFormat;
  1300. unsigned long leftover;
  1301. unsigned long nitems;
  1302. /*
  1303. * Read the property.
  1304. */
  1305. rValue = XGetWindowProperty (DISPLAY, pSD->rootWindow,
  1306. wmGD.xa_DT_SESSION_HINTS, 0L,
  1307. (long)1000000, False, AnyPropertyType,
  1308. &actualType, &actualFormat, &nitems,
  1309. &leftover, (unsigned char **)&property);
  1310. if ((rValue != Success) || (actualType == None) || (actualFormat != 8))
  1311. /* _DT_SESSION_HINTS does not exist or it is an invalid type. */
  1312. {
  1313. pSD->pDtSessionItems = NULL;
  1314. }
  1315. else
  1316. /* parse the property string */
  1317. {
  1318. ParseDtSessionHints (pSD, (unsigned char *)property);
  1319. }
  1320. if (property)
  1321. {
  1322. XFree ((char *)property);
  1323. }
  1324. /*
  1325. * Delete the property so we don't see it if the user
  1326. * restarts dtwm.
  1327. */
  1328. #ifndef DEBUG_SESSION_HINTS
  1329. XDeleteProperty (DISPLAY, pSD->rootWindow, wmGD.xa_DT_SESSION_HINTS);
  1330. #endif /* DEBUG_SESSION_HINTS */
  1331. } /* END OF FUNCTION GetDtSessionHints */
  1332. /*************************************<->*************************************
  1333. *
  1334. * GetDtWmRequest (pSD, pszReq, pmore)
  1335. *
  1336. *
  1337. * Description:
  1338. * -----------
  1339. * This function returns the next request
  1340. *
  1341. *
  1342. * Inputs:
  1343. * ------
  1344. * pSD - pointer to screen data
  1345. * psdReq - pointer to a char pointer
  1346. *
  1347. *
  1348. * Outputs:
  1349. * -------
  1350. * *pszReq - pointer to null terminated string containing next
  1351. * request
  1352. * *pmore - set to true if more data is left in the property
  1353. *
  1354. * Comments:
  1355. * ---------
  1356. * The data for pszReq is allocated in here. The caller must free up
  1357. * this space using XtFree.
  1358. *
  1359. *
  1360. *************************************<->***********************************/
  1361. void
  1362. GetDtWmRequest (
  1363. WmScreenData *pSD,
  1364. char **pszReq,
  1365. Boolean *pmore)
  1366. {
  1367. int rValue;
  1368. char *chRequest = NULL;
  1369. static char *property = NULL;
  1370. static int iNext = -1;
  1371. int i;
  1372. Atom actualType;
  1373. int actualFormat;
  1374. unsigned long leftover;
  1375. static unsigned long nitems = 0;
  1376. /*
  1377. * We need to read the property again if we have no data left
  1378. * over from last time;
  1379. */
  1380. if (property == NULL)
  1381. {
  1382. /*
  1383. * Read the property and delete it.
  1384. */
  1385. rValue = XGetWindowProperty (DISPLAY, pSD->wmWorkspaceWin,
  1386. wmGD.xa_DT_WM_REQUEST, 0L,
  1387. (long)1000000, True, AnyPropertyType,
  1388. &actualType, &actualFormat, &nitems,
  1389. &leftover, (unsigned char **)&property);
  1390. /*
  1391. * Validate the property that we've read
  1392. */
  1393. if ((rValue != Success) ||
  1394. (actualType == None) ||
  1395. (actualFormat != 8))
  1396. {
  1397. /* The property does not exist or it is an invalid type. */
  1398. property = NULL;
  1399. iNext = -1;
  1400. nitems = 0;
  1401. }
  1402. else
  1403. {
  1404. /* the property is fine, set the index of the next char. */
  1405. iNext = 0;
  1406. }
  1407. }
  1408. /*
  1409. * If we've got something, then extract and return the next
  1410. * request.
  1411. */
  1412. if (property && iNext >= 0)
  1413. {
  1414. int len = 0;
  1415. for (i=iNext; i<nitems; i++)
  1416. {
  1417. if (property [i] == '\0')
  1418. {
  1419. break;
  1420. }
  1421. }
  1422. if (i>=nitems) i=nitems;
  1423. len = i - iNext + 1 + ((property[i] == '\0') ? 0 : 1);
  1424. chRequest = (char *) XtMalloc (len);
  1425. if (chRequest == NULL)
  1426. {
  1427. Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
  1428. }
  1429. else
  1430. {
  1431. /* dequeue the request */
  1432. strncpy (chRequest, &property[iNext], len);
  1433. if (property[i] != '\0')
  1434. {
  1435. chRequest[len-1]='\0';
  1436. }
  1437. iNext = i+1;
  1438. }
  1439. if (iNext >= nitems)
  1440. {
  1441. /*
  1442. * Extracted the last request, free up the storage
  1443. * and reset for next time.
  1444. */
  1445. XFree ((char *)property);
  1446. iNext = -1;
  1447. property = NULL;
  1448. }
  1449. }
  1450. *pmore = (property != NULL);
  1451. *pszReq = chRequest;
  1452. } /* END OF FUNCTION GetDtWmRequest */
  1453. /*************************************<->*************************************
  1454. *
  1455. * GetIntialPropertyList (ClientData *)
  1456. *
  1457. *
  1458. * Description:
  1459. * -----------
  1460. * Get the list of initial properties on the window
  1461. *
  1462. *
  1463. * Inputs:
  1464. * ------
  1465. * pCD - pointer to client data
  1466. *
  1467. *
  1468. * Outputs:
  1469. * -------
  1470. * pCD - paInitialProperties member is updated
  1471. *
  1472. *
  1473. * Comments:
  1474. * --------
  1475. * The caller must XFree the paIntialialProperties member!
  1476. *
  1477. *************************************<->***********************************/
  1478. void
  1479. GetInitialPropertyList (ClientData *pCD)
  1480. {
  1481. Atom *paList;
  1482. int iProps;
  1483. paList = XListProperties (DISPLAY, pCD->client, &iProps);
  1484. if (paList)
  1485. {
  1486. pCD->paInitialProperties = paList;
  1487. pCD->numInitialProperties = iProps;
  1488. }
  1489. else
  1490. {
  1491. pCD->paInitialProperties = NULL;
  1492. pCD->numInitialProperties = 0;
  1493. }
  1494. } /* END OF FUNCTION GetInitialPropertyList */
  1495. /*************************************<->*************************************
  1496. *
  1497. * DiscardIntialPropertyList (ClientData *)
  1498. *
  1499. *
  1500. * Description:
  1501. * -----------
  1502. * Tosses out the intial property list for a client, frees data
  1503. *
  1504. *
  1505. * Inputs:
  1506. * ------
  1507. * pCD - pointer to client data
  1508. *
  1509. *
  1510. * Outputs:
  1511. * -------
  1512. * pCD - paInitialProperties member is updated
  1513. *
  1514. *
  1515. * Comments:
  1516. * --------
  1517. *
  1518. *
  1519. *************************************<->***********************************/
  1520. void
  1521. DiscardInitialPropertyList (ClientData *pCD)
  1522. {
  1523. if (pCD->paInitialProperties)
  1524. {
  1525. /*
  1526. * Free the initial property list.
  1527. * (see HasProperty() function)
  1528. */
  1529. XFree ((char *) pCD->paInitialProperties);
  1530. pCD->paInitialProperties = NULL;
  1531. pCD->numInitialProperties = 0;
  1532. }
  1533. } /* END OF FUNCTION DiscardInitialPropertyList */
  1534. /*************************************<->*************************************
  1535. *
  1536. * HasProperty (pCD, aProperty)
  1537. *
  1538. *
  1539. * Description:
  1540. * -----------
  1541. * Returns True if this client had this property when it was mapped
  1542. *
  1543. *
  1544. * Inputs:
  1545. * ------
  1546. * pCD - pointer to client data
  1547. * aProperty - atom of property to test for
  1548. *
  1549. *
  1550. * Outputs:
  1551. * -------
  1552. * Return - True if this property was on the initial list for this
  1553. * client; False otherwise.
  1554. *
  1555. *
  1556. * Comments:
  1557. * --------
  1558. *
  1559. *************************************<->***********************************/
  1560. Boolean
  1561. HasProperty (
  1562. ClientData * pCD,
  1563. Atom aProperty)
  1564. {
  1565. Boolean bFound = False;
  1566. Atom * paList;
  1567. int count;
  1568. paList = pCD->paInitialProperties;
  1569. if (paList)
  1570. {
  1571. count = pCD->numInitialProperties;
  1572. while ((!bFound) && (count > 0))
  1573. {
  1574. bFound = (*paList == aProperty);
  1575. count--;
  1576. paList++;
  1577. }
  1578. }
  1579. else
  1580. {
  1581. /*
  1582. * The property list doesn't exist. Return
  1583. * True to force a read of this property. The most likely
  1584. * case is that this property was updated after the
  1585. * window was managed and needs to be read.
  1586. */
  1587. bFound = True;
  1588. }
  1589. return (bFound);
  1590. } /* END OF FUNCTION HasProperty */
  1591. /**
  1592. * @brief This function calls XGetWindowProperty to get the UTF8_STRING
  1593. * property.
  1594. *
  1595. * @param display
  1596. * @param w
  1597. * @param property
  1598. *
  1599. * @return A string or NULL.
  1600. */
  1601. char *GetUtf8String (Display *display, Window w, Atom property)
  1602. {
  1603. int actualFormat;
  1604. char *propReturn;
  1605. unsigned long nitems, leftover;
  1606. Atom actualType;
  1607. Atom reqType = wmGD.xa_UTF8_STRING;
  1608. if (XGetWindowProperty (display, w, property, 0L, USHRT_MAX, False, reqType,
  1609. &actualType, &actualFormat, &nitems, &leftover,
  1610. (unsigned char **) &propReturn) != Success)
  1611. goto err;
  1612. if (!nitems) goto err;
  1613. if (actualType != reqType) goto err;
  1614. return propReturn;
  1615. err:
  1616. if (propReturn) XFree (propReturn);
  1617. return NULL;
  1618. }
  1619. /**
  1620. * @brief This function calls XChangeProperty to set the UTF8_STRING property.
  1621. *
  1622. * @param display
  1623. * @param w
  1624. * @param property
  1625. * @param s
  1626. */
  1627. void SetUtf8String (Display *display, Window w, Atom property, const char *s)
  1628. {
  1629. size_t len;
  1630. if (!(s && s[0])) return;
  1631. len = strnlen (s, USHRT_MAX);
  1632. XChangeProperty (display, w, property, wmGD.xa_UTF8_STRING, 8,
  1633. PropModeReplace, (unsigned char *)s, len);
  1634. }
  1635. /**
  1636. * @brief This function updates _NET_WM_STATE property.
  1637. *
  1638. * @param window
  1639. * @param states
  1640. * @param nstates
  1641. * @param action
  1642. */
  1643. void UpdateNetWmState (Window window, Atom *states, unsigned long nstates,
  1644. long action)
  1645. {
  1646. int i, j, actualFormat;
  1647. unsigned long nold, leftover;
  1648. Atom actualType, *oldStates, *newStates;
  1649. unsigned long nnew = 0;
  1650. Atom type = wmGD.xa__NET_WM_STATE;
  1651. if (!(XGetWindowProperty (DISPLAY, window, type, 0L, 1000000L, False,
  1652. XA_ATOM, &actualType, &actualFormat, &nold,
  1653. &leftover, (unsigned char **) &oldStates)
  1654. == Success && actualType == XA_ATOM)) nold = 0;
  1655. if (!(states && nstates) && nold) goto done;
  1656. newStates = malloc ((nstates + nold) * sizeof (Atom));
  1657. if (!newStates) goto done;
  1658. for (i = 0; i < nold; ++i)
  1659. {
  1660. Atom oldState = oldStates[i];
  1661. for (j = 0; j < nstates; ++j) if (oldState == states[j]) break;
  1662. if (j >= nstates) newStates[nnew++] = oldState;
  1663. }
  1664. if (action == _NET_WM_STATE_ADD)
  1665. {
  1666. for (i = 0; i < nstates; ++i) newStates[nnew++] = states[i];
  1667. }
  1668. else if (action == _NET_WM_STATE_TOGGLE)
  1669. {
  1670. for (i = 0; i < nstates; ++i)
  1671. {
  1672. Atom state = states[i];
  1673. for (j = 0; j < nold; ++j) if (state == oldStates[j]) break;
  1674. if (j >= nold) newStates[nnew++] = state;
  1675. }
  1676. }
  1677. XChangeProperty (DISPLAY, window, type, XA_ATOM, 32, PropModeReplace,
  1678. (unsigned char *) newStates, nnew);
  1679. done:
  1680. if (oldStates) XFree (oldStates);
  1681. if (newStates) free (newStates);
  1682. }