WmOL.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  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 Sun Microsystems, Inc.
  25. * (c) Copyright 1993 HEWLETT-PACKARD COMPANY
  26. * ALL RIGHTS RESERVED
  27. */
  28. /*
  29. * Included Files:
  30. */
  31. #include <stdlib.h>
  32. #include "WmGlobal.h"
  33. #include "WmOL.h"
  34. #include "WmProperty.h"
  35. #include <Xm/AtomMgr.h>
  36. #define ValidPropertyList(pcd) ((pcd)->paInitialProperties != NULL)
  37. /*************************************<->*************************************
  38. *
  39. * InitOLCompat ()
  40. *
  41. * Description:
  42. * -----------
  43. * Interns the atoms necessary for OL protocols.
  44. *
  45. * Inputs:
  46. * ------
  47. *
  48. * Outputs:
  49. * --------
  50. *
  51. *************************************<->***********************************/
  52. void
  53. InitOLCompat(void)
  54. {
  55. wmGD.xa_OL_WIN_ATTR =
  56. XmInternAtom (DISPLAY, OL_WIN_ATTR, False);
  57. wmGD.xa_OL_DECOR_RESIZE =
  58. XmInternAtom (DISPLAY, OL_DECOR_RESIZE, False);
  59. wmGD.xa_OL_DECOR_HEADER =
  60. XmInternAtom (DISPLAY, OL_DECOR_HEADER, False);
  61. wmGD.xa_OL_DECOR_CLOSE =
  62. XmInternAtom (DISPLAY, OL_DECOR_CLOSE, False);
  63. wmGD.xa_OL_DECOR_PIN =
  64. XmInternAtom (DISPLAY, OL_DECOR_PIN, False);
  65. wmGD.xa_OL_DECOR_ADD =
  66. XmInternAtom (DISPLAY, OL_DECOR_ADD, False);
  67. wmGD.xa_OL_DECOR_DEL =
  68. XmInternAtom (DISPLAY, OL_DECOR_DEL, False);
  69. wmGD.xa_OL_WT_BASE =
  70. XmInternAtom (DISPLAY, OL_WT_BASE, False);
  71. wmGD.xa_OL_WT_COMMAND =
  72. XmInternAtom (DISPLAY, OL_WT_CMD, False);
  73. wmGD.xa_OL_WT_HELP =
  74. XmInternAtom (DISPLAY, OL_WT_HELP, False);
  75. wmGD.xa_OL_WT_NOTICE =
  76. XmInternAtom (DISPLAY, OL_WT_NOTICE, False);
  77. wmGD.xa_OL_WT_OTHER =
  78. XmInternAtom (DISPLAY, OL_WT_OTHER, False);
  79. wmGD.xa_OL_PIN_IN =
  80. XmInternAtom (DISPLAY, OL_PIN_IN, False);
  81. wmGD.xa_OL_PIN_OUT =
  82. XmInternAtom (DISPLAY, OL_PIN_OUT, False);
  83. wmGD.xa_OL_MENU_LIMITED =
  84. XmInternAtom (DISPLAY, OL_MENU_LIMITED, False);
  85. wmGD.xa_OL_MENU_FULL =
  86. XmInternAtom (DISPLAY, OL_MENU_FULL, False);
  87. } /* END OF FUNCTION InitOLCompat */
  88. /*************************************<->*************************************
  89. *
  90. * HasOpenLookHints (pCD)
  91. *
  92. * Description:
  93. * -----------
  94. * Returns True if this client has OpenLook hints on it.
  95. *
  96. * Inputs:
  97. * ------
  98. * pCD = pointer to client data
  99. *
  100. * Outputs:
  101. * --------
  102. * Returns True if client has the _OL_WIN_ATTR property on it.
  103. *
  104. *************************************<->***********************************/
  105. Boolean
  106. HasOpenLookHints(
  107. ClientData *pCD )
  108. {
  109. Boolean rval = False;
  110. OLWinAttr *property = NULL;
  111. if (ValidPropertyList (pCD) &&
  112. HasProperty(pCD, wmGD.xa_OL_WIN_ATTR))
  113. {
  114. rval = True;
  115. }
  116. else if ((property=GetOLWinAttr (pCD)) != NULL)
  117. {
  118. XFree ((char *) property);
  119. rval = True;
  120. }
  121. return (rval);
  122. } /* END OF FUNCTION HasOpenLookHints */
  123. /*************************************<->*************************************
  124. *
  125. * GetOLWinAttr (pCD)
  126. *
  127. * Description:
  128. * -----------
  129. * Fetches the OLWinAttr property off of the client
  130. *
  131. * Inputs:
  132. * ------
  133. * pCD = pointer to client data
  134. *
  135. * Outputs:
  136. * --------
  137. * Returns a pointer to the OLWinAttr property if found and valid.
  138. * (Returned data should be freed with XFree())
  139. * Returns NULL pointer otherwise.
  140. *
  141. *************************************<->***********************************/
  142. OLWinAttr *
  143. GetOLWinAttr(
  144. ClientData *pCD )
  145. {
  146. Boolean rval = False;
  147. OLWinAttr *property = NULL;
  148. OLWinAttr *prop_new;
  149. Atom actual_type;
  150. int actual_format;
  151. unsigned long nitems;
  152. unsigned long leftover;
  153. int ret_val;
  154. ret_val = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_OL_WIN_ATTR,
  155. 0L, ENTIRE_CONTENTS,
  156. False, wmGD.xa_OL_WIN_ATTR,
  157. &actual_type, &actual_format,
  158. &nitems, &leftover, (unsigned char **)&property);
  159. if (ret_val != Success)
  160. {
  161. property = NULL;
  162. }
  163. else if ((actual_format != 32) ||
  164. (actual_type != wmGD.xa_OL_WIN_ATTR))
  165. {
  166. if (property)
  167. XFree((char *)property);
  168. property = NULL;
  169. }
  170. if (property && (nitems == OLDOLWINATTRLENGTH))
  171. {
  172. /* Old size, convert to new size */
  173. /*
  174. * !!! Should use XAlloc() here, but Xlib doesn't
  175. * define an inverse function of XFree(). !!!
  176. */
  177. prop_new = (OLWinAttr *) malloc (sizeof(OLWinAttr));
  178. prop_new->flags = WA_WINTYPE | WA_MENUTYPE | WA_PINSTATE;
  179. prop_new->win_type = ((old_OLWinAttr *)property)->win_type;
  180. prop_new->menu_type = ((old_OLWinAttr *)property)->menu_type;
  181. prop_new->pin_initial_state =
  182. ((old_OLWinAttr *)property)->pin_initial_state;
  183. XFree ((char *) property);
  184. property = prop_new;
  185. }
  186. /* convert pin state for old clients */
  187. if (property && (property->flags & WA_PINSTATE))
  188. {
  189. if (property->pin_initial_state == wmGD.xa_OL_PIN_IN)
  190. {
  191. property->pin_initial_state = PIN_IN;
  192. }
  193. else if (property->pin_initial_state == wmGD.xa_OL_PIN_OUT)
  194. {
  195. property->pin_initial_state = PIN_OUT;
  196. }
  197. }
  198. return (property);
  199. } /* END OF FUNCTION GetOLWinAttr */
  200. /*************************************<->*************************************
  201. *
  202. * GetOLDecorFlags (pCD, property, pDecor)
  203. *
  204. * Description:
  205. * -----------
  206. * Fetches the _OL_DECOR_ADD or _OL_DECOR_DEL property off of the
  207. * client and returns OL flavored decor flags.
  208. *
  209. * Inputs:
  210. * ------
  211. * pCD = pointer to client data
  212. * property = property to fetch
  213. * pDecor = pointer to OL decor flags word
  214. *
  215. * Outputs:
  216. * --------
  217. * Return = True if property found, False otherwise
  218. * *pDecor = OL decor flags if valid property found,
  219. * undefined if property not found.
  220. *
  221. *************************************<->***********************************/
  222. Boolean
  223. GetOLDecorFlags(
  224. ClientData *pCD,
  225. Atom property,
  226. unsigned long *pDecor)
  227. {
  228. int status, i;
  229. Boolean rval;
  230. Atom actual_type;
  231. int actual_format;
  232. unsigned long nitems;
  233. unsigned long leftover;
  234. Atom *pAtoms = NULL;
  235. status = XGetWindowProperty (DISPLAY, pCD->client, property,
  236. 0L, ENTIRE_CONTENTS,
  237. False, XA_ATOM,
  238. &actual_type, &actual_format,
  239. &nitems, &leftover, (unsigned char **)&pAtoms);
  240. if ((status != Success) ||
  241. !pAtoms ||
  242. (nitems == 0) ||
  243. (actual_type != XA_ATOM) ||
  244. (actual_format != 32))
  245. {
  246. if (pAtoms)
  247. XFree((char *)pAtoms);
  248. rval = False;
  249. }
  250. else
  251. {
  252. *pDecor = 0;
  253. /*
  254. * We only look for the ones we might be interested in.
  255. * Several OL decoration types are ignored.
  256. */
  257. for (i = 0; i < nitems; i++) {
  258. if (pAtoms[i] == wmGD.xa_OL_DECOR_RESIZE)
  259. *pDecor |= OLDecorResizable;
  260. else if (pAtoms[i] == wmGD.xa_OL_DECOR_HEADER)
  261. *pDecor |= OLDecorHeader;
  262. else if (pAtoms[i] == wmGD.xa_OL_DECOR_CLOSE)
  263. *pDecor |= OLDecorCloseButton;
  264. else if (pAtoms[i] == wmGD.xa_OL_DECOR_PIN)
  265. *pDecor |= OLDecorPushPin;
  266. }
  267. XFree((char *)pAtoms);
  268. rval = True;
  269. }
  270. return (rval);
  271. } /* END OF FUNCTION GetOLDecorFlags */
  272. /*************************************<->*************************************
  273. *
  274. * ProcessOLDecoration (pCD)
  275. *
  276. * Description:
  277. * -----------
  278. *
  279. * Inputs:
  280. * ------
  281. * pCD = pointer to client data
  282. *
  283. * Outputs:
  284. * --------
  285. * pCD = possibly modified with new decoration info
  286. *
  287. *************************************<->***********************************/
  288. void
  289. ProcessOLDecoration(
  290. ClientData *pCD)
  291. {
  292. OLWinAttr * pOLWinAttr;
  293. unsigned long OLdecor;
  294. long decorMask;
  295. if (HasOpenLookHints (pCD) &&
  296. ((pOLWinAttr = GetOLWinAttr (pCD)) != NULL))
  297. {
  298. /*
  299. * This window already has some decoration applied to
  300. * it based on its ICCCM type (transient or not).
  301. * Use the OL hints to construct a mask to further
  302. * modify these decorations.
  303. */
  304. if ((pOLWinAttr->flags & WA_WINTYPE) == 0)
  305. {
  306. /*
  307. * Window type not specified, assume all decorations
  308. */
  309. decorMask = WM_DECOR_ALL;
  310. }
  311. else if (pOLWinAttr->win_type == wmGD.xa_OL_WT_BASE)
  312. {
  313. /*
  314. * Base windows can have all decorations
  315. */
  316. decorMask = WM_DECOR_ALL;
  317. }
  318. else if (pOLWinAttr->win_type == wmGD.xa_OL_WT_COMMAND)
  319. {
  320. /*
  321. * Command windows have titles, pins (close button), and
  322. * resize handles.
  323. */
  324. decorMask = WM_DECOR_TITLE | WM_DECOR_SYSTEM | WM_DECOR_RESIZEH;
  325. }
  326. else if (pOLWinAttr->win_type == wmGD.xa_OL_WT_HELP)
  327. {
  328. /*
  329. * Help windows have titles and pins (close button).
  330. * No resize, but give it a border to look nicer.
  331. */
  332. decorMask = (WM_DECOR_TITLE | WM_DECOR_SYSTEM | WM_DECOR_BORDER);
  333. }
  334. else if ((pOLWinAttr->win_type == wmGD.xa_OL_WT_NOTICE) &&
  335. (pOLWinAttr->win_type == wmGD.xa_OL_WT_OTHER))
  336. {
  337. decorMask = WM_DECOR_NONE;
  338. }
  339. else
  340. {
  341. decorMask = WM_DECOR_ALL;
  342. }
  343. if (GetOLDecorAdd(pCD,&OLdecor))
  344. {
  345. if (OLdecor & OLDecorResizable)
  346. {
  347. decorMask |= WM_DECOR_RESIZEH;
  348. }
  349. if (OLdecor & OLDecorHeader)
  350. {
  351. decorMask |= WM_DECOR_TITLE;
  352. }
  353. if (OLdecor & OLDecorCloseButton)
  354. {
  355. /* OL "close" is same as "Motif" minimize */
  356. decorMask |= MWM_DECOR_MINIMIZE;
  357. }
  358. if (OLdecor & OLDecorPushPin)
  359. {
  360. /*
  361. * windows with pins can't be minimized
  362. */
  363. decorMask &= ~MWM_DECOR_MINIMIZE;
  364. decorMask |= MWM_DECOR_TITLE | MWM_DECOR_MENU;
  365. }
  366. }
  367. if (GetOLDecorDel(pCD,&OLdecor))
  368. {
  369. if (OLdecor & OLDecorResizable)
  370. {
  371. decorMask &= ~MWM_DECOR_RESIZEH;
  372. }
  373. if (OLdecor & OLDecorHeader)
  374. {
  375. decorMask &= ~WM_DECOR_TITLEBAR;
  376. }
  377. if (OLdecor & OLDecorCloseButton)
  378. {
  379. /* OL "close" is same as "Motif" minimize */
  380. decorMask &= ~MWM_DECOR_MINIMIZE;
  381. }
  382. /* push pin is ignored here */
  383. }
  384. /*
  385. * If the window has a push pin or a limited menu,
  386. * then consider it very similar to a secondary window.
  387. */
  388. if (((pOLWinAttr->flags & WA_PINSTATE) &&
  389. (pOLWinAttr->pin_initial_state == PIN_IN)) ||
  390. ((pOLWinAttr->flags & WA_MENUTYPE) &&
  391. (pOLWinAttr->menu_type == wmGD.xa_OL_MENU_LIMITED)))
  392. {
  393. decorMask &= ~(MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE);
  394. pCD->bPseudoTransient = True;
  395. pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
  396. }
  397. /*
  398. * Reduce decoration on this window according to OL hints
  399. */
  400. pCD->clientDecoration &= decorMask;
  401. /*
  402. * Reduce client functions if necessary.
  403. */
  404. if (!(decorMask & MWM_DECOR_MINIMIZE))
  405. {
  406. pCD->clientFunctions &= ~MWM_FUNC_MINIMIZE;
  407. }
  408. if (!(decorMask & MWM_DECOR_MAXIMIZE))
  409. {
  410. pCD->clientFunctions &= ~MWM_FUNC_MAXIMIZE;
  411. }
  412. if (!(decorMask & MWM_DECOR_RESIZEH))
  413. {
  414. pCD->clientFunctions &= ~MWM_FUNC_RESIZE;
  415. }
  416. /*
  417. * Set the clients secondariesOnTop value to false to allow
  418. * open look transient behaviour (transients below primary).
  419. */
  420. pCD->secondariesOnTop = False;
  421. if (pOLWinAttr)
  422. XFree((char *)pOLWinAttr);
  423. }
  424. } /* END OF FUNCTION ProcessOLDecoration */