WmBackdrop.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  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 1987,1988,1989,1990,1992,1993,1994 HEWLETT-PACKARD COMPANY
  25. * (c) Copyright 1993, 1994 International Business Machines Corp.
  26. * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  27. * (c) Copyright 1993, 1994 Novell, Inc.
  28. */
  29. #define BANDWIDTH 16
  30. #define BOTTOM 0
  31. #define CHANGE_BACKDROP (1L << 0)
  32. #if defined(USE_XRENDER)
  33. #include <X11/extensions/Xrender.h>
  34. #endif /* USE_XRENDER */
  35. #include <Dt/UserMsg.h>
  36. #include "WmGlobal.h"
  37. #include "WmResource.h"
  38. #include "WmResNames.h"
  39. #include "WmWrkspace.h"
  40. #define DTWM_NEED_BACKBITS
  41. #include "WmIBitmap.h"
  42. #include "WmBackdrop.h"
  43. #include "WmError.h"
  44. #include "WmProperty.h"
  45. #include <X11/Core.h>
  46. #include <X11/StringDefs.h>
  47. #include <X11/Intrinsic.h>
  48. #include <X11/Xatom.h>
  49. #include <X11/Shell.h>
  50. #include <Dt/Message.h>
  51. #include <Dt/DtP.h>
  52. #include <Dt/WsmM.h>
  53. #include <Xm/Xm.h>
  54. #include <Xm/AtomMgr.h>
  55. #include <errno.h>
  56. #include <signal.h>
  57. #include <stdio.h>
  58. #include <sys/types.h>
  59. #include <sys/stat.h>
  60. #include <stdlib.h>
  61. #include "WmIPC.h" /* must be after DtP.h */
  62. /**************************************
  63. Functions
  64. **/
  65. /******** Static Function Declarations ********/
  66. static Pixmap WmXmGetPixmap2(
  67. Screen *screen,
  68. char *pchName,
  69. Pixel fg,
  70. Pixel bg
  71. ) ;
  72. /******** End Static Function Declarations ********/
  73. /*
  74. * externals
  75. */
  76. #include "WmImage.h"
  77. #include "WmResParse.h"
  78. /********************************************
  79. Globals
  80. **/
  81. /* maximum band width in tile units */
  82. #define MAX_BAND_WIDTH 3
  83. #define TOP_BAND_WIDTH 2
  84. static int bottom = BOTTOM;
  85. static int xa_NO_BACKDROP;
  86. /******************************<->*************************************
  87. *
  88. * ChangeBackdrop ( pWS )
  89. *
  90. *
  91. * Description:
  92. * -----------
  93. *
  94. * Inputs:
  95. * ------
  96. *
  97. * Outputs:
  98. * -------
  99. *
  100. *************************************<->***********************************/
  101. void
  102. ChangeBackdrop(
  103. WmWorkspaceData *pWS )
  104. {
  105. int iwin;
  106. if (pWS->backdrop.window)
  107. {
  108. if (pWS->backdrop.window == pWS->pSD->lastBackdropWin)
  109. {
  110. /* re-expose the window */
  111. XClearWindow (DISPLAY, pWS->backdrop.window);
  112. }
  113. else
  114. {
  115. /*
  116. * The old and new backdrops are different.
  117. * Map the new backdrop and unmap the old.
  118. */
  119. XLowerWindow(DISPLAY, pWS->backdrop.window);
  120. XMapWindow(DISPLAY, pWS->backdrop.window);
  121. }
  122. }
  123. if (pWS->pSD->lastBackdropWin &&
  124. (pWS->backdrop.window != pWS->pSD->lastBackdropWin))
  125. {
  126. XUnmapWindow(DISPLAY, pWS->pSD->lastBackdropWin);
  127. }
  128. pWS->pSD->lastBackdropWin = pWS->backdrop.window;
  129. }
  130. /******************************<->*************************************
  131. *
  132. * ProcessBackdropResources (pWS, callFlags)
  133. *
  134. * Description:
  135. * -----------
  136. * Processes a backdrop for a particular workspace
  137. *
  138. * Inputs:
  139. * ------
  140. * pWS = pointer to screen data (backdrop data in particular)
  141. * callFlags = processing flags
  142. * CHANGE_BACKDROP - the pixmap has already been created.
  143. *
  144. * Outputs:
  145. * -------
  146. * pWS = modifies the backdrop data that's part of this structure
  147. *
  148. * Comments:
  149. * ---------
  150. * This routine interprets the backdrop.image field and converts
  151. * it from a string to the appropriate bitmap/pixmap images.
  152. * It also creates windows necessary for the backdrop.
  153. *
  154. *************************************<->***********************************/
  155. void
  156. ProcessBackdropResources(
  157. WmWorkspaceData *pWS,
  158. unsigned long callFlags )
  159. {
  160. XSetWindowAttributes xswa;
  161. unsigned int xswamask;
  162. unsigned char *pchImageName = NULL;
  163. unsigned char *pchL = NULL;
  164. unsigned char *pch, *pLine;
  165. Pixmap tmpPix;
  166. int x, y;
  167. unsigned int w, h, bw, depth;
  168. Window root;
  169. unsigned long oldFlags;
  170. static String none_string = NULL;
  171. static String no_backdrop_string = NULL;
  172. Boolean bNone = False;
  173. unsigned int chlen;
  174. if (callFlags & CHANGE_BACKDROP)
  175. {
  176. oldFlags = pWS->backdrop.flags;
  177. }
  178. if (!no_backdrop_string &&
  179. (no_backdrop_string = XtNewString (DTWM_REQP_BACKDROP_NONE)))
  180. {
  181. ToLower(no_backdrop_string);
  182. xa_NO_BACKDROP = XmInternAtom (DISPLAY, no_backdrop_string, False);
  183. /* for compatiblity with DT 2.01 */
  184. none_string = XtNewString ("none");
  185. }
  186. if (!no_backdrop_string)
  187. {
  188. Warning(((char *)GETMESSAGE(6, 4, "Insufficient memory for backdrop window.")));
  189. return;
  190. }
  191. pWS->backdrop.flags = BACKDROP_NONE; /* by default */
  192. /*
  193. * see if we're using a bitmap
  194. */
  195. if (pWS->backdrop.image)
  196. {
  197. /*
  198. * Strip off leading '@', if any
  199. */
  200. pch = (unsigned char *) pWS->backdrop.image;
  201. chlen = mblen ((char *)pch, MB_CUR_MAX);
  202. if (chlen == 1 && *pch++ == '@')
  203. {
  204. chlen = mblen ((char *)pch, MB_CUR_MAX);
  205. if (chlen >= 1)
  206. {
  207. int j;
  208. int il = 1+strlen ((char *)pch);
  209. unsigned char *pchD = (unsigned char *)pWS->backdrop.image;
  210. while (il)
  211. {
  212. *pchD++ = *pch++;
  213. il--;
  214. }
  215. }
  216. }
  217. /*
  218. * Use a copy of the string because our parsing routines
  219. * destroy the thing being parsed.
  220. */
  221. if ((pLine = pchImageName = (unsigned char *)
  222. strdup (pWS->backdrop.image)) &&
  223. (pch = GetString(&pLine)))
  224. {
  225. pchL = (unsigned char *) strdup ((char *)pch);
  226. if (*pchL)
  227. ToLower((char *)pchL);
  228. if (!(strcmp ((char *)pchL, (char *)no_backdrop_string)) ||
  229. !(strcmp ((char *)pchL, (char *)none_string)))
  230. {
  231. /*
  232. * No backdrop (root window shows through)
  233. */
  234. pWS->backdrop.window = None;
  235. pWS->backdrop.nameAtom = xa_NO_BACKDROP;
  236. bNone = True;
  237. }
  238. if (pch && !bNone)
  239. {
  240. /*
  241. * Bitmap backdrop
  242. * Load in the bitmap, create a pixmap of
  243. * the right depth, and make the backdrop
  244. * window if necessary.
  245. */
  246. if ((callFlags & CHANGE_BACKDROP))
  247. {
  248. GC gc;
  249. Display *display;
  250. Window win;
  251. int status, x, y;
  252. unsigned int bw, depth, h, w, junk;
  253. /*
  254. * We're changing the backdrop, so the
  255. * imagePixmap actually contains a depth 1
  256. * pixmap. Convert it into a pixmap of the
  257. * proper depth.
  258. */
  259. tmpPix = pWS->backdrop.imagePixmap;
  260. if (XmUNSPECIFIED_PIXMAP != tmpPix)
  261. {
  262. display = XtDisplay(pWS->workspaceTopLevelW);
  263. XGetGeometry(
  264. display, tmpPix,
  265. &win, &x, &y, &w, &h, &bw, &depth);
  266. gc = XCreateGC(display, tmpPix, 0, NULL);
  267. if(pWS->backdrop.imageType == DtWSM_BACKDROP_IMAGETYPE_CENTER)
  268. {
  269. /* Centered */
  270. if(pWS->backdrop.window) {
  271. unsigned int wbw, wdepth, wh, ww;
  272. Window wwin;
  273. int wx, wy;
  274. /* Find the size of the containing background, to centre the pixmap
  275. * within */
  276. XGetGeometry(
  277. display, pWS->backdrop.window,
  278. &wwin, &wx, &wy, &ww, &wh, &wbw, &wdepth);
  279. /* Create a pixmap the size of the whole desktop */
  280. pWS->backdrop.imagePixmap =
  281. XCreatePixmap(display, tmpPix, ww, wh, depth);
  282. /* Clear the background to a theme specific bg colour */
  283. XSetForeground(display, gc, pWS->backdrop.background);
  284. XFillRectangle(display, pWS->backdrop.imagePixmap, gc, 0, 0, ww, wh);
  285. /* Copy in the pixmap to the middle, also handles the pixmap being
  286. * larger or smaller than the desktop */
  287. status = XCopyArea(
  288. XtDisplay(pWS->workspaceTopLevelW),
  289. tmpPix, pWS->backdrop.imagePixmap, gc,
  290. 0, 0, w, h, (ww - w) / 2, (wh - h) / 2);
  291. }
  292. }
  293. #if defined(USE_XRENDER)
  294. else if(pWS->backdrop.imageType == DtWSM_BACKDROP_IMAGETYPE_FIT
  295. || pWS->backdrop.imageType == DtWSM_BACKDROP_IMAGETYPE_FILL)
  296. {
  297. int minor_version, major_version;
  298. /* USE_XRENDER just checks if the compile time enviroment
  299. * had the Xrender library, this runtime check makes sure
  300. * the current server has the X render extension installed
  301. * and available */
  302. if(XRenderQueryVersion(display, &minor_version, &major_version)) {
  303. /* Fill the screen */
  304. if(pWS->backdrop.window) {
  305. unsigned int wbw, wdepth, wh, ww;
  306. Window wwin;
  307. int wx, wy;
  308. double xscale;
  309. double yscale;
  310. XRenderPictureAttributes pic_attributes;
  311. Picture src_pict;
  312. Picture dst_pict;
  313. int resizedW;
  314. int resizedH;
  315. /* Find the size of the containing background, to centre the pixmap
  316. * within */
  317. XGetGeometry(
  318. display, pWS->backdrop.window,
  319. &wwin, &wx, &wy, &ww, &wh, &wbw, &wdepth);
  320. /* Create a pixmap the size of the whole desktop */
  321. pWS->backdrop.imagePixmap =
  322. XCreatePixmap(display, tmpPix, ww, wh, depth);
  323. /* Clear the background to a theme specific bg colour */
  324. XSetForeground(display, gc, pWS->backdrop.background);
  325. XFillRectangle(display, pWS->backdrop.imagePixmap, gc, 0, 0, ww, wh);
  326. /* Fill scales to the whole area */
  327. xscale = (double) w / (double) ww;
  328. yscale = (double) h / (double) wh;
  329. /* Whereas Fit, scales to one axis and applies that scale to both */
  330. /* preserving aspect ratio */
  331. if(pWS->backdrop.imageType == DtWSM_BACKDROP_IMAGETYPE_FIT) {
  332. if(xscale > yscale) {
  333. yscale = xscale;
  334. } else {
  335. xscale = yscale;
  336. }
  337. }
  338. XTransform xform = {{
  339. { XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(0) },
  340. { XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0) },
  341. { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1.0) }
  342. }};
  343. /* Convert pixmaps to Pictures for Xrender */
  344. src_pict = XRenderCreatePicture(display,
  345. tmpPix,
  346. XRenderFindStandardFormat(display, PictStandardRGB24),
  347. 0,
  348. &pic_attributes);
  349. dst_pict = XRenderCreatePicture(display,
  350. pWS->backdrop.imagePixmap,
  351. XRenderFindStandardFormat(display, PictStandardRGB24),
  352. 0,
  353. &pic_attributes);
  354. if(src_pict && dst_pict) {
  355. XRenderSetPictureTransform(display, src_pict, &xform);
  356. resizedW = (double) w / xscale;
  357. resizedH = (double) h / yscale;
  358. XRenderComposite(display, PictOpOver,
  359. src_pict, 0, dst_pict, /* src, mask, dest */
  360. 0, 0, /* src xy (in destination space!) */
  361. 0, 0, /* mask xy */
  362. (ww - resizedW) / 2, (wh - resizedH) / 2, ww, wh);
  363. }
  364. if(src_pict) { XRenderFreePicture(display, src_pict); }
  365. if(dst_pict) { XRenderFreePicture(display, dst_pict); }
  366. }
  367. }
  368. }
  369. #endif /* USE_XRENDER */
  370. else
  371. {
  372. /* Tiled */
  373. pWS->backdrop.imagePixmap =
  374. XCreatePixmap(display, tmpPix, w, h, depth);
  375. status = XCopyArea(
  376. XtDisplay(pWS->workspaceTopLevelW),
  377. tmpPix, pWS->backdrop.imagePixmap, gc,
  378. 0, 0, w, h, 0, 0);
  379. }
  380. XFreeGC(display, gc);
  381. }
  382. if (XmUNSPECIFIED_PIXMAP == tmpPix || BadDrawable == status)
  383. pWS->backdrop.imagePixmap =
  384. WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
  385. (char *)pch,
  386. pWS->backdrop.foreground,
  387. pWS->backdrop.background);
  388. }
  389. else
  390. {
  391. pWS->backdrop.imagePixmap =
  392. WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
  393. (char *)pch,
  394. pWS->backdrop.foreground,
  395. pWS->backdrop.background);
  396. }
  397. if ((callFlags & CHANGE_BACKDROP) &&
  398. (pWS->backdrop.window))
  399. {
  400. if (pWS->backdrop.imagePixmap !=
  401. XmUNSPECIFIED_PIXMAP)
  402. {
  403. XSetWindowBackgroundPixmap (DISPLAY,
  404. pWS->backdrop.window,
  405. pWS->backdrop.imagePixmap);
  406. }
  407. else
  408. {
  409. /*
  410. * Failed to find bitmap
  411. * set background to "background"
  412. */
  413. XSetWindowBackground (DISPLAY,
  414. pWS->backdrop.window,
  415. pWS->backdrop.background);
  416. }
  417. }
  418. else
  419. {
  420. if (pWS->backdrop.imagePixmap !=
  421. XmUNSPECIFIED_PIXMAP)
  422. {
  423. xswa.override_redirect = True;
  424. xswa.background_pixmap =
  425. pWS->backdrop.imagePixmap;
  426. xswamask = CWOverrideRedirect | CWBackPixmap;
  427. }
  428. else
  429. {
  430. xswa.override_redirect = True;
  431. xswa.background_pixel =
  432. pWS->backdrop.background;
  433. xswamask = CWOverrideRedirect | CWBackPixel;
  434. }
  435. if ((wmGD.keyboardFocusPolicy ==
  436. KEYBOARD_FOCUS_POINTER) ||
  437. (wmGD.colormapFocusPolicy ==
  438. CMAP_FOCUS_POINTER))
  439. {
  440. /*
  441. * Listen for enter/levae events if we
  442. * have a pointer tracking focus policy
  443. */
  444. xswamask |= CWEventMask;
  445. xswa.event_mask = EnterWindowMask |
  446. LeaveWindowMask;
  447. }
  448. xswa.backing_store = NotUseful;
  449. xswa.save_under = False;
  450. xswamask |= (CWBackingStore | CWSaveUnder);
  451. pWS->backdrop.window = XCreateWindow(DISPLAY,
  452. pWS->pSD->rootWindow,
  453. 0, 0,
  454. DisplayWidth(DISPLAY, pWS->pSD->screen),
  455. DisplayHeight(DISPLAY, pWS->pSD->screen),
  456. 0,
  457. XDefaultDepth(DISPLAY,pWS->pSD->screen),
  458. CopyFromParent,
  459. CopyFromParent,
  460. xswamask,
  461. &xswa);
  462. }
  463. if (pch &&
  464. (pWS->backdrop.imagePixmap != XmUNSPECIFIED_PIXMAP) &&
  465. (pWS->backdrop.window))
  466. {
  467. /*
  468. * Succeeded in setting up a bitmap backdrop.
  469. */
  470. pWS->backdrop.flags |= BACKDROP_BITMAP;
  471. pWS->backdrop.nameAtom = XmInternAtom (DISPLAY,
  472. pWS->backdrop.image, False);
  473. }
  474. else
  475. {
  476. char msg[MAXWMPATH+1];
  477. sprintf ((char *)msg,
  478. ((char *)GETMESSAGE(6, 3, "Unable to get image %s for workspace %s.")),
  479. pWS->backdrop.image, pWS->name);
  480. Warning(msg);
  481. }
  482. pch = NULL;
  483. }
  484. free (pchImageName); /* temporary string */
  485. pchImageName = NULL;
  486. free (pchL); /* temporary string */
  487. }
  488. }
  489. free (pchImageName);
  490. }
  491. /******************************<->*************************************
  492. *
  493. * static Pixmap WmXmGetPixmap2
  494. *
  495. * Description:
  496. * -----------
  497. * Tries twice to get a pixmap from a file name
  498. *
  499. * Inputs:
  500. * ------
  501. * screen - ptr to screen
  502. * pchName - image file name
  503. * fg - foreground color
  504. * bg - background color
  505. *
  506. * Outputs:
  507. * -------
  508. * Return - pixmap if found, XmUNSPECIFIED_PIXMAP if not
  509. *
  510. * Comments:
  511. * ---------
  512. * This routine performs some backward compatibility checks.
  513. *
  514. * Do a two stage lookup for backdrop files. If a full path
  515. * is specified, but XmGetPixmap fails, the get the basename
  516. * of the file and try again.
  517. *
  518. *************************************<->***********************************/
  519. static Pixmap
  520. WmXmGetPixmap2 (
  521. Screen *screen,
  522. char *pchName,
  523. Pixel fg,
  524. Pixel bg)
  525. {
  526. Pixmap pixReturn;
  527. char *pch;
  528. if (pchName && *pchName)
  529. {
  530. pixReturn = XmGetPixmap (screen, pchName, fg, bg);
  531. if (pixReturn == XmUNSPECIFIED_PIXMAP)
  532. {
  533. /*
  534. * Use our bitmap lookup paths by using only the
  535. * basename of the file path.
  536. */
  537. pch = strrchr (pchName, '/');
  538. if (pch &&
  539. (pch < (pchName + strlen(pchName) - 1)))
  540. {
  541. pch++;
  542. pixReturn = XmGetPixmap (screen, pch, fg, bg);
  543. }
  544. }
  545. }
  546. else
  547. {
  548. pixReturn = XmUNSPECIFIED_PIXMAP;
  549. }
  550. return (pixReturn);
  551. }
  552. /******************************<->*************************************
  553. *
  554. * FullBitmapFilePath (pch)
  555. *
  556. * Description:
  557. * -----------
  558. * Takes a bitmap file name turns it into a full path name.
  559. *
  560. * Inputs:
  561. * ------
  562. * pch = ptr to bitmap file name
  563. *
  564. * Outputs:
  565. * -------
  566. * Return = ptr to a string containing full path name
  567. * or NULL on failure
  568. *
  569. * Comments:
  570. * ---------
  571. *
  572. *************************************<->***********************************/
  573. String
  574. FullBitmapFilePath(
  575. String pch )
  576. {
  577. String pchR;
  578. struct stat buf;
  579. if (*pch != '/')
  580. {
  581. pchR = (String) BitmapPathName (pch);
  582. if ((stat(pchR, &buf) == -1) &&
  583. (*pch != '~'))
  584. {
  585. /* file not there! */
  586. pchR = pch;
  587. }
  588. }
  589. else
  590. {
  591. pchR = pch;
  592. }
  593. return (pchR);
  594. }
  595. /******************************<->*************************************
  596. *
  597. * SetNewBackdrop (pWS, pixmap, aName, imageType)
  598. *
  599. * Description:
  600. * -----------
  601. * Sets a new backdrop for a workspace
  602. *
  603. * Inputs:
  604. * ------
  605. * pWS = pointer to workspace data
  606. * pixmap = pixmap for the backdrop (if any)
  607. * aName = atomized name for the backdrop (either file name or "none")
  608. * imageType = Style of backdrop, tiled, center, fit or fill
  609. *
  610. * Outputs:
  611. * -------
  612. * Return = ptr to a string containing full path name
  613. * or NULL on failure
  614. *
  615. * Comments:
  616. * ---------
  617. *
  618. *************************************<->***********************************/
  619. void
  620. SetNewBackdrop(
  621. WmWorkspaceData *pWS,
  622. Pixmap pixmap,
  623. String bitmapFile,
  624. DtWsmBackdropImageType imageType )
  625. {
  626. String pchNewBitmap = NULL;
  627. if (!bitmapFile || !strlen(bitmapFile) ||
  628. !strcmp(bitmapFile, DTWM_REQP_BACKDROP_NONE))
  629. {
  630. pixmap = None;
  631. }
  632. if (bitmapFile)
  633. {
  634. pchNewBitmap = (String) XtNewString (bitmapFile);
  635. }
  636. /*
  637. * Free up old resources
  638. */
  639. if ((pWS->backdrop.imagePixmap) &&
  640. (pWS->backdrop.imagePixmap != pixmap))
  641. {
  642. if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
  643. pWS->backdrop.imagePixmap))
  644. {
  645. /* not in Xm pixmap cache */
  646. }
  647. pWS->backdrop.imagePixmap = None;
  648. }
  649. /* free pWS->backdrop.image */
  650. if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
  651. (pWS->backdrop.image))
  652. {
  653. free (pWS->backdrop.image);
  654. }
  655. pWS->backdrop.imagePixmap = pixmap;
  656. pWS->backdrop.image = pchNewBitmap;
  657. pWS->backdrop.imageType = imageType;
  658. ProcessBackdropResources (pWS, CHANGE_BACKDROP);
  659. if (pchNewBitmap)
  660. {
  661. pWS->backdrop.flags |= BACKDROP_IMAGE_ALLOCED;
  662. }
  663. ChangeBackdrop (pWS);
  664. SaveWorkspaceResources (pWS, WM_RES_BACKDROP_IMAGE);
  665. SaveWorkspaceResources (pWS, WM_RES_BACKDROP_IMAGETYPE);
  666. SetWorkspaceInfoProperty (pWS);
  667. /*
  668. * Inform the world of the new workspace title
  669. */
  670. dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id,
  671. DtWSM_REASON_BACKDROP);
  672. }
  673. /******************************<->*************************************
  674. *
  675. * Boolean IsBackdropWindow (pSD, win)
  676. *
  677. * Description:
  678. * -----------
  679. * Tests a window to see if it is a backdrop window
  680. *
  681. * Inputs:
  682. * ------
  683. * pSD = pointer to screen data
  684. * win = window to test.
  685. *
  686. * Outputs:
  687. * -------
  688. * Return = True if win is a backdrop window.
  689. * False otherwise.
  690. *
  691. * Comments:
  692. * ---------
  693. *
  694. *************************************<->***********************************/
  695. Boolean
  696. IsBackdropWindow(
  697. WmScreenData *pSD,
  698. Window win )
  699. {
  700. Boolean rval = False;
  701. int i;
  702. /*
  703. * Is it one of the backdrop windows for a workspace?
  704. */
  705. for (i=0; (i < pSD->numWorkspaces) && !rval; i++)
  706. {
  707. if (pSD->pWS[i].backdrop.window == win)
  708. {
  709. rval = True;
  710. }
  711. }
  712. return (rval);
  713. }
  714. /********************* eof ***************************/