2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: WmBackdrop.c /main/5 1998/08/03 16:19:42 mgreess $ */
26 * (c) Copyright 1987,1988,1989,1990,1992,1993,1994 HEWLETT-PACKARD COMPANY
27 * (c) Copyright 1993, 1994 International Business Machines Corp.
28 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
29 * (c) Copyright 1993, 1994 Novell, Inc.
33 static char rcsid[] = ""
39 #define CHANGE_BACKDROP (1L << 0)
42 #include "WmResource.h"
43 #include "WmResNames.h"
44 #include "WmWrkspace.h"
45 #define DTWM_NEED_BACKBITS
46 #include "WmIBitmap.h"
47 #include "WmBackdrop.h"
49 #include "WmProperty.h"
51 #include <X11/StringDefs.h>
52 #include <X11/Intrinsic.h>
53 #include <X11/Xatom.h>
54 #include <X11/Shell.h>
55 #include <Dt/Message.h>
59 #include <Xm/AtomMgr.h>
63 #include <sys/types.h>
68 #include "WmIPC.h" /* must be after DtP.h */
70 /**************************************
73 /******** Static Function Declarations ********/
75 static Pixmap WmXmGetPixmap2(
82 /******** End Static Function Declarations ********/
88 #include "WmResParse.h"
90 /********************************************
94 /* maximum band width in tile units */
95 #define MAX_BAND_WIDTH 3
96 #define TOP_BAND_WIDTH 2
98 static int bottom = BOTTOM;
100 static int xa_NO_BACKDROP;
105 /******************************<->*************************************
107 * ChangeBackdrop ( pWS )
119 *************************************<->***********************************/
122 WmWorkspaceData *pWS )
127 if (pWS->backdrop.window)
129 if (pWS->backdrop.window == pWS->pSD->lastBackdropWin)
131 /* re-expose the window */
132 XClearWindow (DISPLAY, pWS->backdrop.window);
137 * The old and new backdrops are different.
138 * Map the new backdrop and unmap the old.
140 XLowerWindow(DISPLAY, pWS->backdrop.window);
142 XMapWindow(DISPLAY, pWS->backdrop.window);
146 if (pWS->pSD->lastBackdropWin &&
147 (pWS->backdrop.window != pWS->pSD->lastBackdropWin))
149 XUnmapWindow(DISPLAY, pWS->pSD->lastBackdropWin);
152 pWS->pSD->lastBackdropWin = pWS->backdrop.window;
158 /******************************<->*************************************
160 * ProcessBackdropResources (pWS, callFlags)
164 * Processes a backdrop for a particular workspace
168 * pWS = pointer to screen data (backdrop data in particular)
169 * callFlags = processing flags
170 * CHANGE_BACKDROP - the pixmap has already been created.
174 * pWS = modifies the backdrop data that's part of this structure
178 * This routine interprets the backdrop.image field and converts
179 * it from a string to the appropriate bitmap/pixmap images.
180 * It also creates windows necessary for the backdrop.
182 *************************************<->***********************************/
184 ProcessBackdropResources(
185 WmWorkspaceData *pWS,
186 unsigned long callFlags )
188 XSetWindowAttributes xswa;
189 unsigned int xswamask;
190 unsigned char *pchImageName = NULL;
191 unsigned char *pchL = NULL;
192 unsigned char *pch, *pLine;
195 unsigned int w, h, bw, depth;
197 unsigned long oldFlags;
198 static String none_string = NULL;
199 static String no_backdrop_string = NULL;
200 Boolean bNone = False;
203 #endif /* NO_MULTIBYTE */
205 if (callFlags & CHANGE_BACKDROP)
207 oldFlags = pWS->backdrop.flags;
210 if (!no_backdrop_string &&
211 (no_backdrop_string = XtNewString (DTWM_REQP_BACKDROP_NONE)))
213 ToLower(no_backdrop_string);
214 xa_NO_BACKDROP = XmInternAtom (DISPLAY, no_backdrop_string, False);
216 /* for compatiblity with DT 2.01 */
217 none_string = XtNewString ("none");
219 if (!no_backdrop_string)
221 Warning(((char *)GETMESSAGE(6, 4, "Insufficient memory for backdrop window.")));
225 pWS->backdrop.flags = BACKDROP_NONE; /* by default */
228 * see if we're using a bitmap
230 if (pWS->backdrop.image)
233 * Strip off leading '@', if any
235 pch = (unsigned char *) pWS->backdrop.image;
237 chlen = mblen ((char *)pch, MB_CUR_MAX);
238 if (chlen == 1 && *pch++ == '@')
240 chlen = mblen ((char *)pch, MB_CUR_MAX);
244 int il = 1+strlen ((char *)pch);
245 unsigned char *pchD = (unsigned char *)pWS->backdrop.image;
254 #else /* NO_MULTIBYTE */
255 if (*pch++ == '@' && *pch)
257 int il = 1+strlen ((char *)pch);
258 unsigned char *pchD = (unsigned char *)pWS->backdrop.image;
266 #endif /* NO_MULTIBYTE */
269 * Use a copy of the string because our parsing routines
270 * destroy the thing being parsed.
273 if ((pLine = pchImageName = (unsigned char *)
274 strdup (pWS->backdrop.image)) &&
275 (pch = GetString(&pLine)))
277 pchL = (unsigned char *) strdup ((char *)pch);
280 ToLower((char *)pchL);
282 if (!(strcmp ((char *)pchL, (char *)no_backdrop_string)) ||
283 !(strcmp ((char *)pchL, (char *)none_string)))
286 * No backdrop (root window shows through)
288 pWS->backdrop.window = None;
289 pWS->backdrop.nameAtom = xa_NO_BACKDROP;
297 * Load in the bitmap, create a pixmap of
298 * the right depth, and make the backdrop
299 * window if necessary.
301 if ((callFlags & CHANGE_BACKDROP))
307 unsigned int bw, depth, h, w, junk;
310 * We're changing the backdrop, so the
311 * imagePixmap actually contains a depth 1
312 * pixmap. Convert it into a pixmap of the
315 tmpPix = pWS->backdrop.imagePixmap;
316 if (XmUNSPECIFIED_PIXMAP != tmpPix)
318 display = XtDisplay(pWS->workspaceTopLevelW);
321 &win, &x, &y, &w, &h, &bw, &depth);
322 pWS->backdrop.imagePixmap =
323 XCreatePixmap(display, tmpPix, w, h, depth);
324 gc = XCreateGC(display, tmpPix, 0, NULL);
326 XtDisplay(pWS->workspaceTopLevelW),
327 tmpPix, pWS->backdrop.imagePixmap, gc,
329 XFreeGC(display, gc);
332 if (XmUNSPECIFIED_PIXMAP == tmpPix || BadDrawable == status)
333 pWS->backdrop.imagePixmap =
334 WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
336 pWS->backdrop.foreground,
337 pWS->backdrop.background);
341 pWS->backdrop.imagePixmap =
342 WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
344 pWS->backdrop.foreground,
345 pWS->backdrop.background);
348 if ((callFlags & CHANGE_BACKDROP) &&
349 (pWS->backdrop.window))
351 if (pWS->backdrop.imagePixmap !=
352 XmUNSPECIFIED_PIXMAP)
354 XSetWindowBackgroundPixmap (DISPLAY,
355 pWS->backdrop.window,
356 pWS->backdrop.imagePixmap);
361 * Failed to find bitmap
362 * set background to "background"
364 XSetWindowBackground (DISPLAY,
365 pWS->backdrop.window,
366 pWS->backdrop.background);
371 if (pWS->backdrop.imagePixmap !=
372 XmUNSPECIFIED_PIXMAP)
374 xswa.override_redirect = True;
375 xswa.background_pixmap =
376 pWS->backdrop.imagePixmap;
377 xswamask = CWOverrideRedirect | CWBackPixmap;
381 xswa.override_redirect = True;
382 xswa.background_pixel =
383 pWS->backdrop.background;
384 xswamask = CWOverrideRedirect | CWBackPixel;
387 if ((wmGD.keyboardFocusPolicy ==
388 KEYBOARD_FOCUS_POINTER) ||
389 (wmGD.colormapFocusPolicy ==
393 * Listen for enter/levae events if we
394 * have a pointer tracking focus policy
396 xswamask |= CWEventMask;
397 xswa.event_mask = EnterWindowMask |
401 xswa.backing_store = NotUseful;
402 xswa.save_under = False;
403 xswamask |= (CWBackingStore | CWSaveUnder);
405 pWS->backdrop.window = XCreateWindow(DISPLAY,
406 pWS->pSD->rootWindow,
408 DisplayWidth(DISPLAY, pWS->pSD->screen),
409 DisplayHeight(DISPLAY, pWS->pSD->screen),
411 XDefaultDepth(DISPLAY,pWS->pSD->screen),
420 (pWS->backdrop.imagePixmap != XmUNSPECIFIED_PIXMAP) &&
421 (pWS->backdrop.window))
424 * Succeeded in setting up a bitmap backdrop.
426 pWS->backdrop.flags |= BACKDROP_BITMAP;
428 pWS->backdrop.nameAtom = XmInternAtom (DISPLAY,
429 pWS->backdrop.image, False);
433 char msg[MAXWMPATH+1];
435 sprintf ((char *)msg,
436 ((char *)GETMESSAGE(6, 3, "Unable to get image %s for workspace %s.")),
437 pWS->backdrop.image, pWS->name);
445 free (pchImageName); /* temporary string */
449 free (pchL); /* temporary string */
456 /******************************<->*************************************
458 * static Pixmap WmXmGetPixmap2
462 * Tries twice to get a pixmap from a file name
466 * screen - ptr to screen
467 * pchName - image file name
468 * fg - foreground color
469 * bg - background color
473 * Return - pixmap if found, XmUNSPECIFIED_PIXMAP if not
477 * This routine performs some backward compatibility checks.
479 * Do a two stage lookup for backdrop files. If a full path
480 * is specified, but XmGetPixmap fails, the get the basename
481 * of the file and try again.
483 *************************************<->***********************************/
494 if (pchName && *pchName)
496 pixReturn = XmGetPixmap (screen, pchName, fg, bg);
498 if (pixReturn == XmUNSPECIFIED_PIXMAP)
501 * Use our bitmap lookup paths by using only the
502 * basename of the file path.
504 pch = strrchr (pchName, '/');
506 (pch < (pchName + strlen(pchName) - 1)))
509 pixReturn = XmGetPixmap (screen, pch, fg, bg);
515 pixReturn = XmUNSPECIFIED_PIXMAP;
523 /******************************<->*************************************
525 * FullBitmapFilePath (pch)
529 * Takes a bitmap file name turns it into a full path name.
533 * pch = ptr to bitmap file name
537 * Return = ptr to a string containing full path name
543 *************************************<->***********************************/
553 pchR = (String) BitmapPathName (pch);
555 if ((stat(pchR, &buf) == -1) &&
558 /* file not there! */
570 /******************************<->*************************************
572 * SetNewBackdrop (pWS, pixmap, aName)
576 * Sets a new backdrop for a workspace
580 * pWS = pointer to workspace data
581 * pixmap = pixmap for the backdrop (if any)
582 * aName = atomized name for the backdrop (either file name or "none")
586 * Return = ptr to a string containing full path name
592 *************************************<->***********************************/
595 WmWorkspaceData *pWS,
599 String pchNewBitmap = NULL;
601 if (!bitmapFile || !strlen(bitmapFile) ||
602 !strcmp(bitmapFile, DTWM_REQP_BACKDROP_NONE))
609 pchNewBitmap = (String) XtNewString (bitmapFile);
613 * Free up old resources
615 if ((pWS->backdrop.imagePixmap) &&
616 (pWS->backdrop.imagePixmap != pixmap))
618 if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
619 pWS->backdrop.imagePixmap))
621 /* not in Xm pixmap cache */
623 pWS->backdrop.imagePixmap = None;
626 /* free pWS->backdrop.image */
627 if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
628 (pWS->backdrop.image))
630 free (pWS->backdrop.image);
633 pWS->backdrop.imagePixmap = pixmap;
634 pWS->backdrop.image = pchNewBitmap;
636 ProcessBackdropResources (pWS, CHANGE_BACKDROP);
640 pWS->backdrop.flags |= BACKDROP_IMAGE_ALLOCED;
643 ChangeBackdrop (pWS);
644 SaveWorkspaceResources (pWS, WM_RES_BACKDROP_IMAGE);
647 UpdateWorkspaceInfoProperty (pWS->pSD); /* to be backward compatible */
649 SetWorkspaceInfoProperty (pWS);
652 * Inform the world of the new workspace title
654 dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id,
655 DtWSM_REASON_BACKDROP);
659 /******************************<->*************************************
661 * Boolean IsBackdropWindow (pSD, win)
665 * Tests a window to see if it is a backdrop window
669 * pSD = pointer to screen data
670 * win = window to test.
674 * Return = True if win is a backdrop window.
680 *************************************<->***********************************/
686 Boolean rval = False;
690 * Is it one of the backdrop windows for a workspace?
692 for (i=0; (i < pSD->numWorkspaces) && !rval; i++)
694 if (pSD->pWS[i].backdrop.window == win)
704 /********************* eof ***************************/