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 unsigned char *none_string = NULL;
199 static unsigned char *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 = (unsigned char *)
212 XtNewString (DTWM_REQP_BACKDROP_NONE)))
214 ToLower(no_backdrop_string);
215 xa_NO_BACKDROP = XmInternAtom (DISPLAY, no_backdrop_string, False);
217 /* for compatiblity with DT 2.01 */
218 none_string = (unsigned char *) XtNewString ("none");
220 if (!no_backdrop_string)
222 Warning(((char *)GETMESSAGE(6, 4, "Insufficient memory for backdrop window.")));
226 pWS->backdrop.flags = BACKDROP_NONE; /* by default */
229 * see if we're using a bitmap
231 if (pWS->backdrop.image)
234 * Strip off leading '@', if any
236 pch = (unsigned char *) pWS->backdrop.image;
238 chlen = mblen ((char *)pch, MB_CUR_MAX);
239 if (chlen == 1 && *pch++ == '@')
241 chlen = mblen ((char *)pch, MB_CUR_MAX);
245 int il = 1+strlen ((char *)pch);
246 unsigned char *pchD = (unsigned char *)pWS->backdrop.image;
255 #else /* NO_MULTIBYTE */
256 if (*pch++ == '@' && *pch)
258 int il = 1+strlen ((char *)pch);
259 unsigned char *pchD = (unsigned char *)pWS->backdrop.image;
267 #endif /* NO_MULTIBYTE */
270 * Use a copy of the string because our parsing routines
271 * destroy the thing being parsed.
274 if ((pLine = pchImageName = (unsigned char *)
275 strdup (pWS->backdrop.image)) &&
276 (pch = GetString(&pLine)))
278 pchL = (unsigned char *) strdup ((char *)pch);
283 if (!(strcmp ((char *)pchL, (char *)no_backdrop_string)) ||
284 !(strcmp ((char *)pchL, (char *)none_string)))
287 * No backdrop (root window shows through)
289 pWS->backdrop.window = NULL;
290 pWS->backdrop.nameAtom = xa_NO_BACKDROP;
298 * Load in the bitmap, create a pixmap of
299 * the right depth, and make the backdrop
300 * window if necessary.
302 if ((callFlags & CHANGE_BACKDROP))
308 unsigned int bw, depth, h, w, junk;
311 * We're changing the backdrop, so the
312 * imagePixmap actually contains a depth 1
313 * pixmap. Convert it into a pixmap of the
316 tmpPix = pWS->backdrop.imagePixmap;
317 if (XmUNSPECIFIED_PIXMAP != tmpPix)
319 display = XtDisplay(pWS->workspaceTopLevelW);
322 &win, &x, &y, &w, &h, &bw, &depth);
323 pWS->backdrop.imagePixmap =
324 XCreatePixmap(display, tmpPix, w, h, depth);
325 gc = XCreateGC(display, tmpPix, 0, NULL);
327 XtDisplay(pWS->workspaceTopLevelW),
328 tmpPix, pWS->backdrop.imagePixmap, gc,
330 XFreeGC(display, gc);
333 if (XmUNSPECIFIED_PIXMAP == tmpPix || BadDrawable == status)
334 pWS->backdrop.imagePixmap =
335 WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
337 pWS->backdrop.foreground,
338 pWS->backdrop.background);
342 pWS->backdrop.imagePixmap =
343 WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
345 pWS->backdrop.foreground,
346 pWS->backdrop.background);
349 if ((callFlags & CHANGE_BACKDROP) &&
350 (pWS->backdrop.window))
352 if (pWS->backdrop.imagePixmap !=
353 XmUNSPECIFIED_PIXMAP)
355 XSetWindowBackgroundPixmap (DISPLAY,
356 pWS->backdrop.window,
357 pWS->backdrop.imagePixmap);
362 * Failed to find bitmap
363 * set background to "background"
365 XSetWindowBackground (DISPLAY,
366 pWS->backdrop.window,
367 pWS->backdrop.background);
372 if (pWS->backdrop.imagePixmap !=
373 XmUNSPECIFIED_PIXMAP)
375 xswa.override_redirect = True;
376 xswa.background_pixmap =
377 pWS->backdrop.imagePixmap;
378 xswamask = CWOverrideRedirect | CWBackPixmap;
382 xswa.override_redirect = True;
383 xswa.background_pixel =
384 pWS->backdrop.background;
385 xswamask = CWOverrideRedirect | CWBackPixel;
388 if ((wmGD.keyboardFocusPolicy ==
389 KEYBOARD_FOCUS_POINTER) ||
390 (wmGD.colormapFocusPolicy ==
394 * Listen for enter/levae events if we
395 * have a pointer tracking focus policy
397 xswamask |= CWEventMask;
398 xswa.event_mask = EnterWindowMask |
402 xswa.backing_store = NotUseful;
403 xswa.save_under = False;
404 xswamask |= (CWBackingStore | CWSaveUnder);
406 pWS->backdrop.window = XCreateWindow(DISPLAY,
407 pWS->pSD->rootWindow,
409 DisplayWidth(DISPLAY, pWS->pSD->screen),
410 DisplayHeight(DISPLAY, pWS->pSD->screen),
412 XDefaultDepth(DISPLAY,pWS->pSD->screen),
421 (pWS->backdrop.imagePixmap != XmUNSPECIFIED_PIXMAP) &&
422 (pWS->backdrop.window))
425 * Succeeded in setting up a bitmap backdrop.
427 pWS->backdrop.flags |= BACKDROP_BITMAP;
429 pWS->backdrop.nameAtom = XmInternAtom (DISPLAY,
430 pWS->backdrop.image, False);
434 char msg[MAXWMPATH+1];
436 sprintf ((char *)msg,
437 ((char *)GETMESSAGE(6, 3, "Unable to get image %s for workspace %s.")),
438 pWS->backdrop.image, pWS->name);
446 free (pchImageName); /* temporary string */
450 free (pchL); /* temporary string */
457 /******************************<->*************************************
459 * static Pixmap WmXmGetPixmap2
463 * Tries twice to get a pixmap from a file name
467 * screen - ptr to screen
468 * pchName - image file name
469 * fg - foreground color
470 * bg - background color
474 * Return - pixmap if found, XmUNSPECIFIED_PIXMAP if not
478 * This routine performs some backward compatibility checks.
480 * Do a two stage lookup for backdrop files. If a full path
481 * is specified, but XmGetPixmap fails, the get the basename
482 * of the file and try again.
484 *************************************<->***********************************/
495 if (pchName && *pchName)
497 pixReturn = XmGetPixmap (screen, pchName, fg, bg);
499 if (pixReturn == XmUNSPECIFIED_PIXMAP)
502 * Use our bitmap lookup paths by using only the
503 * basename of the file path.
505 pch = strrchr (pchName, '/');
507 (pch < (pchName + strlen(pchName) - 1)))
510 pixReturn = XmGetPixmap (screen, pch, fg, bg);
516 pixReturn = XmUNSPECIFIED_PIXMAP;
524 /******************************<->*************************************
526 * FullBitmapFilePath (pch)
530 * Takes a bitmap file name turns it into a full path name.
534 * pch = ptr to bitmap file name
538 * Return = ptr to a string containing full path name
544 *************************************<->***********************************/
554 pchR = (String) BitmapPathName (pch);
556 if ((stat(pchR, &buf) == -1) &&
559 /* file not there! */
571 /******************************<->*************************************
573 * SetNewBackdrop (pWS, pixmap, aName)
577 * Sets a new backdrop for a workspace
581 * pWS = pointer to workspace data
582 * pixmap = pixmap for the backdrop (if any)
583 * aName = atomized name for the backdrop (either file name or "none")
587 * Return = ptr to a string containing full path name
593 *************************************<->***********************************/
596 WmWorkspaceData *pWS,
600 String pchNewBitmap = NULL;
602 if (!bitmapFile || !strlen(bitmapFile) ||
603 !strcmp(bitmapFile, DTWM_REQP_BACKDROP_NONE))
610 pchNewBitmap = (String) XtNewString (bitmapFile);
614 * Free up old resources
616 if ((pWS->backdrop.imagePixmap) &&
617 (pWS->backdrop.imagePixmap != pixmap))
619 if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
620 pWS->backdrop.imagePixmap))
622 /* not in Xm pixmap cache */
624 pWS->backdrop.imagePixmap = NULL;
627 /* free pWS->backdrop.image */
628 if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
629 (pWS->backdrop.image))
631 free (pWS->backdrop.image);
634 pWS->backdrop.imagePixmap = pixmap;
635 pWS->backdrop.image = pchNewBitmap;
637 ProcessBackdropResources (pWS, CHANGE_BACKDROP);
641 pWS->backdrop.flags |= BACKDROP_IMAGE_ALLOCED;
644 ChangeBackdrop (pWS);
645 SaveWorkspaceResources (pWS, WM_RES_BACKDROP_IMAGE);
648 UpdateWorkspaceInfoProperty (pWS->pSD); /* to be backward compatible */
650 SetWorkspaceInfoProperty (pWS);
653 * Inform the world of the new workspace title
655 dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id,
656 DtWSM_REASON_BACKDROP);
660 /******************************<->*************************************
662 * Boolean IsBackdropWindow (pSD, win)
666 * Tests a window to see if it is a backdrop window
670 * pSD = pointer to screen data
671 * win = window to test.
675 * Return = True if win is a backdrop window.
681 *************************************<->***********************************/
687 Boolean rval = False;
691 * Is it one of the backdrop windows for a workspace?
693 for (i=0; (i < pSD->numWorkspaces) && !rval; i++)
695 if (pSD->pWS[i].backdrop.window == win)
705 /********************* eof ***************************/