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 <X11/StringDefs.h>
50 #include <X11/Intrinsic.h>
51 #include <X11/Xatom.h>
52 #include <X11/Shell.h>
53 #include <Dt/Message.h>
60 #include <sys/types.h>
65 #include "WmIPC.h" /* must be after DtP.h */
67 /**************************************
70 /******** Static Function Declarations ********/
72 static Pixmap WmXmGetPixmap2(
79 /******** End Static Function Declarations ********/
85 #include "WmResParse.h"
87 /********************************************
91 /* maximum band width in tile units */
92 #define MAX_BAND_WIDTH 3
93 #define TOP_BAND_WIDTH 2
95 static int bottom = BOTTOM;
97 static int xa_NO_BACKDROP;
102 /******************************<->*************************************
104 * ChangeBackdrop ( pWS )
116 *************************************<->***********************************/
119 WmWorkspaceData *pWS )
124 if (pWS->backdrop.window)
126 if (pWS->backdrop.window == pWS->pSD->lastBackdropWin)
128 /* re-expose the window */
129 XClearWindow (DISPLAY, pWS->backdrop.window);
134 * The old and new backdrops are different.
135 * Map the new backdrop and unmap the old.
137 XLowerWindow(DISPLAY, pWS->backdrop.window);
139 XMapWindow(DISPLAY, pWS->backdrop.window);
143 if (pWS->pSD->lastBackdropWin &&
144 (pWS->backdrop.window != pWS->pSD->lastBackdropWin))
146 XUnmapWindow(DISPLAY, pWS->pSD->lastBackdropWin);
149 pWS->pSD->lastBackdropWin = pWS->backdrop.window;
155 /******************************<->*************************************
157 * ProcessBackdropResources (pWS, callFlags)
161 * Processes a backdrop for a particular workspace
165 * pWS = pointer to screen data (backdrop data in particular)
166 * callFlags = processing flags
167 * CHANGE_BACKDROP - the pixmap has already been created.
171 * pWS = modifies the backdrop data that's part of this structure
175 * This routine interprets the backdrop.image field and converts
176 * it from a string to the appropriate bitmap/pixmap images.
177 * It also creates windows necessary for the backdrop.
179 *************************************<->***********************************/
181 ProcessBackdropResources(
182 WmWorkspaceData *pWS,
183 unsigned long callFlags )
185 XSetWindowAttributes xswa;
186 unsigned int xswamask;
187 unsigned char *pchImageName = NULL;
188 unsigned char *pchL = NULL;
189 unsigned char *pch, *pLine;
192 unsigned int w, h, bw, depth;
194 unsigned long oldFlags;
195 static unsigned char *none_string = NULL;
196 static unsigned char *no_backdrop_string = NULL;
197 Boolean bNone = False;
200 #endif /* NO_MULTIBYTE */
202 if (callFlags & CHANGE_BACKDROP)
204 oldFlags = pWS->backdrop.flags;
207 if (!no_backdrop_string &&
208 (no_backdrop_string = (unsigned char *)
209 XtNewString (DTWM_REQP_BACKDROP_NONE)))
211 ToLower(no_backdrop_string);
212 xa_NO_BACKDROP = XmInternAtom (DISPLAY, no_backdrop_string, False);
214 /* for compatiblity with DT 2.01 */
215 none_string = (unsigned char *) XtNewString ("none");
217 if (!no_backdrop_string)
219 Warning(((char *)GETMESSAGE(6, 4, "Insufficient memory for backdrop window.")));
223 pWS->backdrop.flags = BACKDROP_NONE; /* by default */
226 * see if we're using a bitmap
228 if (pWS->backdrop.image)
231 * Strip off leading '@', if any
233 pch = (unsigned char *) pWS->backdrop.image;
235 chlen = mblen ((char *)pch, MB_CUR_MAX);
236 if (chlen == 1 && *pch++ == '@')
238 chlen = mblen ((char *)pch, MB_CUR_MAX);
242 int il = 1+strlen ((char *)pch);
243 unsigned char *pchD = (unsigned char *)pWS->backdrop.image;
252 #else /* NO_MULTIBYTE */
253 if (*pch++ == '@' && *pch)
255 int il = 1+strlen ((char *)pch);
256 unsigned char *pchD = (unsigned char *)pWS->backdrop.image;
264 #endif /* NO_MULTIBYTE */
267 * Use a copy of the string because our parsing routines
268 * destroy the thing being parsed.
271 if ((pLine = pchImageName = (unsigned char *)
272 strdup (pWS->backdrop.image)) &&
273 (pch = GetString(&pLine)))
275 pchL = (unsigned char *) strdup ((char *)pch);
280 if (!(strcmp ((char *)pchL, (char *)no_backdrop_string)) ||
281 !(strcmp ((char *)pchL, (char *)none_string)))
284 * No backdrop (root window shows through)
286 pWS->backdrop.window = NULL;
287 pWS->backdrop.nameAtom = xa_NO_BACKDROP;
295 * Load in the bitmap, create a pixmap of
296 * the right depth, and make the backdrop
297 * window if necessary.
299 if ((callFlags & CHANGE_BACKDROP))
305 unsigned int bw, depth, h, w, junk;
308 * We're changing the backdrop, so the
309 * imagePixmap actually contains a depth 1
310 * pixmap. Convert it into a pixmap of the
313 tmpPix = pWS->backdrop.imagePixmap;
314 if (XmUNSPECIFIED_PIXMAP != tmpPix)
316 display = XtDisplay(pWS->workspaceTopLevelW);
319 &win, &x, &y, &w, &h, &bw, &depth);
320 pWS->backdrop.imagePixmap =
321 XCreatePixmap(display, tmpPix, w, h, depth);
322 gc = XCreateGC(display, tmpPix, 0, NULL);
324 XtDisplay(pWS->workspaceTopLevelW),
325 tmpPix, pWS->backdrop.imagePixmap, gc,
327 XFreeGC(display, gc);
330 if (XmUNSPECIFIED_PIXMAP == tmpPix || BadDrawable == status)
331 pWS->backdrop.imagePixmap =
332 WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
334 pWS->backdrop.foreground,
335 pWS->backdrop.background);
339 pWS->backdrop.imagePixmap =
340 WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
342 pWS->backdrop.foreground,
343 pWS->backdrop.background);
346 if ((callFlags & CHANGE_BACKDROP) &&
347 (pWS->backdrop.window))
349 if (pWS->backdrop.imagePixmap !=
350 XmUNSPECIFIED_PIXMAP)
352 XSetWindowBackgroundPixmap (DISPLAY,
353 pWS->backdrop.window,
354 pWS->backdrop.imagePixmap);
359 * Failed to find bitmap
360 * set background to "background"
362 XSetWindowBackground (DISPLAY,
363 pWS->backdrop.window,
364 pWS->backdrop.background);
369 if (pWS->backdrop.imagePixmap !=
370 XmUNSPECIFIED_PIXMAP)
372 xswa.override_redirect = True;
373 xswa.background_pixmap =
374 pWS->backdrop.imagePixmap;
375 xswamask = CWOverrideRedirect | CWBackPixmap;
379 xswa.override_redirect = True;
380 xswa.background_pixel =
381 pWS->backdrop.background;
382 xswamask = CWOverrideRedirect | CWBackPixel;
385 if ((wmGD.keyboardFocusPolicy ==
386 KEYBOARD_FOCUS_POINTER) ||
387 (wmGD.colormapFocusPolicy ==
391 * Listen for enter/levae events if we
392 * have a pointer tracking focus policy
394 xswamask |= CWEventMask;
395 xswa.event_mask = EnterWindowMask |
399 xswa.backing_store = NotUseful;
400 xswa.save_under = False;
401 xswamask |= (CWBackingStore | CWSaveUnder);
403 pWS->backdrop.window = XCreateWindow(DISPLAY,
404 pWS->pSD->rootWindow,
406 DisplayWidth(DISPLAY, pWS->pSD->screen),
407 DisplayHeight(DISPLAY, pWS->pSD->screen),
409 XDefaultDepth(DISPLAY,pWS->pSD->screen),
418 (pWS->backdrop.imagePixmap != XmUNSPECIFIED_PIXMAP) &&
419 (pWS->backdrop.window))
422 * Succeeded in setting up a bitmap backdrop.
424 pWS->backdrop.flags |= BACKDROP_BITMAP;
426 pWS->backdrop.nameAtom = XmInternAtom (DISPLAY,
427 pWS->backdrop.image, False);
431 char msg[MAXWMPATH+1];
433 sprintf ((char *)msg,
434 ((char *)GETMESSAGE(6, 3, "Unable to get image %s for workspace %s.")),
435 pWS->backdrop.image, pWS->name);
443 free (pchImageName); /* temporary string */
447 free (pchL); /* temporary string */
454 /******************************<->*************************************
456 * static Pixmap WmXmGetPixmap2
460 * Tries twice to get a pixmap from a file name
464 * screen - ptr to screen
465 * pchName - image file name
466 * fg - foreground color
467 * bg - background color
471 * Return - pixmap if found, XmUNSPECIFIED_PIXMAP if not
475 * This routine performs some backward compatibility checks.
477 * Do a two stage lookup for backdrop files. If a full path
478 * is specified, but XmGetPixmap fails, the get the basename
479 * of the file and try again.
481 *************************************<->***********************************/
492 if (pchName && *pchName)
494 pixReturn = XmGetPixmap (screen, pchName, fg, bg);
496 if (pixReturn == XmUNSPECIFIED_PIXMAP)
499 * Use our bitmap lookup paths by using only the
500 * basename of the file path.
502 pch = strrchr (pchName, '/');
504 (pch < (pchName + strlen(pchName) - 1)))
507 pixReturn = XmGetPixmap (screen, pch, fg, bg);
513 pixReturn = XmUNSPECIFIED_PIXMAP;
521 /******************************<->*************************************
523 * FullBitmapFilePath (pch)
527 * Takes a bitmap file name turns it into a full path name.
531 * pch = ptr to bitmap file name
535 * Return = ptr to a string containing full path name
541 *************************************<->***********************************/
551 pchR = (String) BitmapPathName (pch);
553 if ((stat(pchR, &buf) == -1) &&
556 /* file not there! */
568 /******************************<->*************************************
570 * SetNewBackdrop (pWS, pixmap, aName)
574 * Sets a new backdrop for a workspace
578 * pWS = pointer to workspace data
579 * pixmap = pixmap for the backdrop (if any)
580 * aName = atomized name for the backdrop (either file name or "none")
584 * Return = ptr to a string containing full path name
590 *************************************<->***********************************/
593 WmWorkspaceData *pWS,
597 String pchNewBitmap = NULL;
599 if (!bitmapFile || !strlen(bitmapFile) ||
600 !strcmp(bitmapFile, DTWM_REQP_BACKDROP_NONE))
607 pchNewBitmap = (String) XtNewString (bitmapFile);
611 * Free up old resources
613 if ((pWS->backdrop.imagePixmap) &&
614 (pWS->backdrop.imagePixmap != pixmap))
616 if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
617 pWS->backdrop.imagePixmap))
619 /* not in Xm pixmap cache */
621 pWS->backdrop.imagePixmap = NULL;
624 /* free pWS->backdrop.image */
625 if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
626 (pWS->backdrop.image))
628 free (pWS->backdrop.image);
631 pWS->backdrop.imagePixmap = pixmap;
632 pWS->backdrop.image = pchNewBitmap;
634 ProcessBackdropResources (pWS, CHANGE_BACKDROP);
638 pWS->backdrop.flags |= BACKDROP_IMAGE_ALLOCED;
641 ChangeBackdrop (pWS);
642 SaveWorkspaceResources (pWS, WM_RES_BACKDROP_IMAGE);
645 UpdateWorkspaceInfoProperty (pWS->pSD); /* to be backward compatible */
647 SetWorkspaceInfoProperty (pWS);
650 * Inform the world of the new workspace title
652 dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id,
653 DtWSM_REASON_BACKDROP);
657 /******************************<->*************************************
659 * Boolean IsBackdropWindow (pSD, win)
663 * Tests a window to see if it is a backdrop window
667 * pSD = pointer to screen data
668 * win = window to test.
672 * Return = True if win is a backdrop window.
678 *************************************<->***********************************/
684 Boolean rval = False;
688 * Is it one of the backdrop windows for a workspace?
690 for (i=0; (i < pSD->numWorkspaces) && !rval; i++)
692 if (pSD->pWS[i].backdrop.window == win)
702 /********************* eof ***************************/