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 libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
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.
32 #define CHANGE_BACKDROP (1L << 0)
35 #include "WmResource.h"
36 #include "WmResNames.h"
37 #include "WmWrkspace.h"
38 #define DTWM_NEED_BACKBITS
39 #include "WmIBitmap.h"
40 #include "WmBackdrop.h"
42 #include "WmProperty.h"
44 #include <X11/StringDefs.h>
45 #include <X11/Intrinsic.h>
46 #include <X11/Xatom.h>
47 #include <X11/Shell.h>
48 #include <Dt/Message.h>
52 #include <Xm/AtomMgr.h>
56 #include <sys/types.h>
59 #include "WmIPC.h" /* must be after DtP.h */
61 /**************************************
64 /******** Static Function Declarations ********/
66 static Pixmap WmXmGetPixmap2(
73 /******** End Static Function Declarations ********/
79 #include "WmResParse.h"
81 /********************************************
85 /* maximum band width in tile units */
86 #define MAX_BAND_WIDTH 3
87 #define TOP_BAND_WIDTH 2
89 static int bottom = BOTTOM;
91 static int xa_NO_BACKDROP;
96 /******************************<->*************************************
98 * ChangeBackdrop ( pWS )
110 *************************************<->***********************************/
113 WmWorkspaceData *pWS )
118 if (pWS->backdrop.window)
120 if (pWS->backdrop.window == pWS->pSD->lastBackdropWin)
122 /* re-expose the window */
123 XClearWindow (DISPLAY, pWS->backdrop.window);
128 * The old and new backdrops are different.
129 * Map the new backdrop and unmap the old.
131 XLowerWindow(DISPLAY, pWS->backdrop.window);
133 XMapWindow(DISPLAY, pWS->backdrop.window);
137 if (pWS->pSD->lastBackdropWin &&
138 (pWS->backdrop.window != pWS->pSD->lastBackdropWin))
140 XUnmapWindow(DISPLAY, pWS->pSD->lastBackdropWin);
143 pWS->pSD->lastBackdropWin = pWS->backdrop.window;
149 /******************************<->*************************************
151 * ProcessBackdropResources (pWS, callFlags)
155 * Processes a backdrop for a particular workspace
159 * pWS = pointer to screen data (backdrop data in particular)
160 * callFlags = processing flags
161 * CHANGE_BACKDROP - the pixmap has already been created.
165 * pWS = modifies the backdrop data that's part of this structure
169 * This routine interprets the backdrop.image field and converts
170 * it from a string to the appropriate bitmap/pixmap images.
171 * It also creates windows necessary for the backdrop.
173 *************************************<->***********************************/
175 ProcessBackdropResources(
176 WmWorkspaceData *pWS,
177 unsigned long callFlags )
179 XSetWindowAttributes xswa;
180 unsigned int xswamask;
181 unsigned char *pchImageName = NULL;
182 unsigned char *pchL = NULL;
183 unsigned char *pch, *pLine;
186 unsigned int w, h, bw, depth;
188 unsigned long oldFlags;
189 static String none_string = NULL;
190 static String no_backdrop_string = NULL;
191 Boolean bNone = False;
194 if (callFlags & CHANGE_BACKDROP)
196 oldFlags = pWS->backdrop.flags;
199 if (!no_backdrop_string &&
200 (no_backdrop_string = XtNewString (DTWM_REQP_BACKDROP_NONE)))
202 ToLower(no_backdrop_string);
203 xa_NO_BACKDROP = XmInternAtom (DISPLAY, no_backdrop_string, False);
205 /* for compatiblity with DT 2.01 */
206 none_string = XtNewString ("none");
208 if (!no_backdrop_string)
210 Warning(((char *)GETMESSAGE(6, 4, "Insufficient memory for backdrop window.")));
214 pWS->backdrop.flags = BACKDROP_NONE; /* by default */
217 * see if we're using a bitmap
219 if (pWS->backdrop.image)
222 * Strip off leading '@', if any
224 pch = (unsigned char *) pWS->backdrop.image;
225 chlen = mblen ((char *)pch, MB_CUR_MAX);
226 if (chlen == 1 && *pch++ == '@')
228 chlen = mblen ((char *)pch, MB_CUR_MAX);
232 int il = 1+strlen ((char *)pch);
233 unsigned char *pchD = (unsigned char *)pWS->backdrop.image;
244 * Use a copy of the string because our parsing routines
245 * destroy the thing being parsed.
248 if ((pLine = pchImageName = (unsigned char *)
249 strdup (pWS->backdrop.image)) &&
250 (pch = GetString(&pLine)))
252 pchL = (unsigned char *) strdup ((char *)pch);
255 ToLower((char *)pchL);
257 if (!(strcmp ((char *)pchL, (char *)no_backdrop_string)) ||
258 !(strcmp ((char *)pchL, (char *)none_string)))
261 * No backdrop (root window shows through)
263 pWS->backdrop.window = None;
264 pWS->backdrop.nameAtom = xa_NO_BACKDROP;
272 * Load in the bitmap, create a pixmap of
273 * the right depth, and make the backdrop
274 * window if necessary.
276 if ((callFlags & CHANGE_BACKDROP))
282 unsigned int bw, depth, h, w, junk;
285 * We're changing the backdrop, so the
286 * imagePixmap actually contains a depth 1
287 * pixmap. Convert it into a pixmap of the
290 tmpPix = pWS->backdrop.imagePixmap;
291 if (XmUNSPECIFIED_PIXMAP != tmpPix)
293 display = XtDisplay(pWS->workspaceTopLevelW);
296 &win, &x, &y, &w, &h, &bw, &depth);
297 pWS->backdrop.imagePixmap =
298 XCreatePixmap(display, tmpPix, w, h, depth);
299 gc = XCreateGC(display, tmpPix, 0, NULL);
301 XtDisplay(pWS->workspaceTopLevelW),
302 tmpPix, pWS->backdrop.imagePixmap, gc,
304 XFreeGC(display, gc);
307 if (XmUNSPECIFIED_PIXMAP == tmpPix || BadDrawable == status)
308 pWS->backdrop.imagePixmap =
309 WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
311 pWS->backdrop.foreground,
312 pWS->backdrop.background);
316 pWS->backdrop.imagePixmap =
317 WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW),
319 pWS->backdrop.foreground,
320 pWS->backdrop.background);
323 if ((callFlags & CHANGE_BACKDROP) &&
324 (pWS->backdrop.window))
326 if (pWS->backdrop.imagePixmap !=
327 XmUNSPECIFIED_PIXMAP)
329 XSetWindowBackgroundPixmap (DISPLAY,
330 pWS->backdrop.window,
331 pWS->backdrop.imagePixmap);
336 * Failed to find bitmap
337 * set background to "background"
339 XSetWindowBackground (DISPLAY,
340 pWS->backdrop.window,
341 pWS->backdrop.background);
346 if (pWS->backdrop.imagePixmap !=
347 XmUNSPECIFIED_PIXMAP)
349 xswa.override_redirect = True;
350 xswa.background_pixmap =
351 pWS->backdrop.imagePixmap;
352 xswamask = CWOverrideRedirect | CWBackPixmap;
356 xswa.override_redirect = True;
357 xswa.background_pixel =
358 pWS->backdrop.background;
359 xswamask = CWOverrideRedirect | CWBackPixel;
362 if ((wmGD.keyboardFocusPolicy ==
363 KEYBOARD_FOCUS_POINTER) ||
364 (wmGD.colormapFocusPolicy ==
368 * Listen for enter/levae events if we
369 * have a pointer tracking focus policy
371 xswamask |= CWEventMask;
372 xswa.event_mask = EnterWindowMask |
376 xswa.backing_store = NotUseful;
377 xswa.save_under = False;
378 xswamask |= (CWBackingStore | CWSaveUnder);
380 pWS->backdrop.window = XCreateWindow(DISPLAY,
381 pWS->pSD->rootWindow,
383 DisplayWidth(DISPLAY, pWS->pSD->screen),
384 DisplayHeight(DISPLAY, pWS->pSD->screen),
386 XDefaultDepth(DISPLAY,pWS->pSD->screen),
395 (pWS->backdrop.imagePixmap != XmUNSPECIFIED_PIXMAP) &&
396 (pWS->backdrop.window))
399 * Succeeded in setting up a bitmap backdrop.
401 pWS->backdrop.flags |= BACKDROP_BITMAP;
403 pWS->backdrop.nameAtom = XmInternAtom (DISPLAY,
404 pWS->backdrop.image, False);
408 char msg[MAXWMPATH+1];
410 sprintf ((char *)msg,
411 ((char *)GETMESSAGE(6, 3, "Unable to get image %s for workspace %s.")),
412 pWS->backdrop.image, pWS->name);
418 free (pchImageName); /* temporary string */
420 free (pchL); /* temporary string */
428 /******************************<->*************************************
430 * static Pixmap WmXmGetPixmap2
434 * Tries twice to get a pixmap from a file name
438 * screen - ptr to screen
439 * pchName - image file name
440 * fg - foreground color
441 * bg - background color
445 * Return - pixmap if found, XmUNSPECIFIED_PIXMAP if not
449 * This routine performs some backward compatibility checks.
451 * Do a two stage lookup for backdrop files. If a full path
452 * is specified, but XmGetPixmap fails, the get the basename
453 * of the file and try again.
455 *************************************<->***********************************/
466 if (pchName && *pchName)
468 pixReturn = XmGetPixmap (screen, pchName, fg, bg);
470 if (pixReturn == XmUNSPECIFIED_PIXMAP)
473 * Use our bitmap lookup paths by using only the
474 * basename of the file path.
476 pch = strrchr (pchName, '/');
478 (pch < (pchName + strlen(pchName) - 1)))
481 pixReturn = XmGetPixmap (screen, pch, fg, bg);
487 pixReturn = XmUNSPECIFIED_PIXMAP;
495 /******************************<->*************************************
497 * FullBitmapFilePath (pch)
501 * Takes a bitmap file name turns it into a full path name.
505 * pch = ptr to bitmap file name
509 * Return = ptr to a string containing full path name
515 *************************************<->***********************************/
525 pchR = (String) BitmapPathName (pch);
527 if ((stat(pchR, &buf) == -1) &&
530 /* file not there! */
542 /******************************<->*************************************
544 * SetNewBackdrop (pWS, pixmap, aName)
548 * Sets a new backdrop for a workspace
552 * pWS = pointer to workspace data
553 * pixmap = pixmap for the backdrop (if any)
554 * aName = atomized name for the backdrop (either file name or "none")
558 * Return = ptr to a string containing full path name
564 *************************************<->***********************************/
567 WmWorkspaceData *pWS,
571 String pchNewBitmap = NULL;
573 if (!bitmapFile || !strlen(bitmapFile) ||
574 !strcmp(bitmapFile, DTWM_REQP_BACKDROP_NONE))
581 pchNewBitmap = (String) XtNewString (bitmapFile);
585 * Free up old resources
587 if ((pWS->backdrop.imagePixmap) &&
588 (pWS->backdrop.imagePixmap != pixmap))
590 if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
591 pWS->backdrop.imagePixmap))
593 /* not in Xm pixmap cache */
595 pWS->backdrop.imagePixmap = None;
598 /* free pWS->backdrop.image */
599 if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
600 (pWS->backdrop.image))
602 free (pWS->backdrop.image);
605 pWS->backdrop.imagePixmap = pixmap;
606 pWS->backdrop.image = pchNewBitmap;
608 ProcessBackdropResources (pWS, CHANGE_BACKDROP);
612 pWS->backdrop.flags |= BACKDROP_IMAGE_ALLOCED;
615 ChangeBackdrop (pWS);
616 SaveWorkspaceResources (pWS, WM_RES_BACKDROP_IMAGE);
619 UpdateWorkspaceInfoProperty (pWS->pSD); /* to be backward compatible */
621 SetWorkspaceInfoProperty (pWS);
624 * Inform the world of the new workspace title
626 dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id,
627 DtWSM_REASON_BACKDROP);
631 /******************************<->*************************************
633 * Boolean IsBackdropWindow (pSD, win)
637 * Tests a window to see if it is a backdrop window
641 * pSD = pointer to screen data
642 * win = window to test.
646 * Return = True if win is a backdrop window.
652 *************************************<->***********************************/
658 Boolean rval = False;
662 * Is it one of the backdrop windows for a workspace?
664 for (i=0; (i < pSD->numWorkspaces) && !rval; i++)
666 if (pSD->pWS[i].backdrop.window == win)
675 /********************* eof ***************************/