/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* * (c) Copyright 1987,1988,1989,1990,1992,1993,1994 HEWLETT-PACKARD COMPANY * (c) Copyright 1993, 1994 International Business Machines Corp. * (c) Copyright 1993, 1994 Sun Microsystems, Inc. * (c) Copyright 1993, 1994 Novell, Inc. */ #define BANDWIDTH 16 #define BOTTOM 0 #define CHANGE_BACKDROP (1L << 0) #include "WmGlobal.h" #include "WmResource.h" #include "WmResNames.h" #include "WmWrkspace.h" #define DTWM_NEED_BACKBITS #include "WmIBitmap.h" #include "WmBackdrop.h" #include "WmError.h" #include "WmProperty.h" #include #include #include #include #include #include
#include
#include
#include #include #include #include #include #include #include #include #include "WmIPC.h" /* must be after DtP.h */ /************************************** Functions **/ /******** Static Function Declarations ********/ static Pixmap WmXmGetPixmap2( Screen *screen, char *pchName, Pixel fg, Pixel bg ) ; /******** End Static Function Declarations ********/ /* * externals */ #include "WmImage.h" #include "WmResParse.h" /******************************************** Globals **/ /* maximum band width in tile units */ #define MAX_BAND_WIDTH 3 #define TOP_BAND_WIDTH 2 static int bottom = BOTTOM; static int xa_NO_BACKDROP; /******************************<->************************************* * * ChangeBackdrop ( pWS ) * * * Description: * ----------- * * Inputs: * ------ * * Outputs: * ------- * *************************************<->***********************************/ void ChangeBackdrop( WmWorkspaceData *pWS ) { int iwin; if (pWS->backdrop.window) { if (pWS->backdrop.window == pWS->pSD->lastBackdropWin) { /* re-expose the window */ XClearWindow (DISPLAY, pWS->backdrop.window); } else { /* * The old and new backdrops are different. * Map the new backdrop and unmap the old. */ XLowerWindow(DISPLAY, pWS->backdrop.window); XMapWindow(DISPLAY, pWS->backdrop.window); } } if (pWS->pSD->lastBackdropWin && (pWS->backdrop.window != pWS->pSD->lastBackdropWin)) { XUnmapWindow(DISPLAY, pWS->pSD->lastBackdropWin); } pWS->pSD->lastBackdropWin = pWS->backdrop.window; } /******************************<->************************************* * * ProcessBackdropResources (pWS, callFlags) * * Description: * ----------- * Processes a backdrop for a particular workspace * * Inputs: * ------ * pWS = pointer to screen data (backdrop data in particular) * callFlags = processing flags * CHANGE_BACKDROP - the pixmap has already been created. * * Outputs: * ------- * pWS = modifies the backdrop data that's part of this structure * * Comments: * --------- * This routine interprets the backdrop.image field and converts * it from a string to the appropriate bitmap/pixmap images. * It also creates windows necessary for the backdrop. * *************************************<->***********************************/ void ProcessBackdropResources( WmWorkspaceData *pWS, unsigned long callFlags ) { XSetWindowAttributes xswa; unsigned int xswamask; unsigned char *pchImageName = NULL; unsigned char *pchL = NULL; unsigned char *pch, *pLine; Pixmap tmpPix; int x, y; unsigned int w, h, bw, depth; Window root; unsigned long oldFlags; static String none_string = NULL; static String no_backdrop_string = NULL; Boolean bNone = False; unsigned int chlen; if (callFlags & CHANGE_BACKDROP) { oldFlags = pWS->backdrop.flags; } if (!no_backdrop_string && (no_backdrop_string = XtNewString (DTWM_REQP_BACKDROP_NONE))) { ToLower(no_backdrop_string); xa_NO_BACKDROP = XmInternAtom (DISPLAY, no_backdrop_string, False); /* for compatiblity with DT 2.01 */ none_string = XtNewString ("none"); } if (!no_backdrop_string) { Warning(((char *)GETMESSAGE(6, 4, "Insufficient memory for backdrop window."))); return; } pWS->backdrop.flags = BACKDROP_NONE; /* by default */ /* * see if we're using a bitmap */ if (pWS->backdrop.image) { /* * Strip off leading '@', if any */ pch = (unsigned char *) pWS->backdrop.image; chlen = mblen ((char *)pch, MB_CUR_MAX); if (chlen == 1 && *pch++ == '@') { chlen = mblen ((char *)pch, MB_CUR_MAX); if (chlen >= 1) { int j; int il = 1+strlen ((char *)pch); unsigned char *pchD = (unsigned char *)pWS->backdrop.image; while (il) { *pchD++ = *pch++; il--; } } } /* * Use a copy of the string because our parsing routines * destroy the thing being parsed. */ if ((pLine = pchImageName = (unsigned char *) strdup (pWS->backdrop.image)) && (pch = GetString(&pLine))) { pchL = (unsigned char *) strdup ((char *)pch); if (*pchL) ToLower((char *)pchL); if (!(strcmp ((char *)pchL, (char *)no_backdrop_string)) || !(strcmp ((char *)pchL, (char *)none_string))) { /* * No backdrop (root window shows through) */ pWS->backdrop.window = None; pWS->backdrop.nameAtom = xa_NO_BACKDROP; bNone = True; } if (pch && !bNone) { /* * Bitmap backdrop * Load in the bitmap, create a pixmap of * the right depth, and make the backdrop * window if necessary. */ if ((callFlags & CHANGE_BACKDROP)) { GC gc; Display *display; Window win; int status, x, y; unsigned int bw, depth, h, w, junk; /* * We're changing the backdrop, so the * imagePixmap actually contains a depth 1 * pixmap. Convert it into a pixmap of the * proper depth. */ tmpPix = pWS->backdrop.imagePixmap; if (XmUNSPECIFIED_PIXMAP != tmpPix) { display = XtDisplay(pWS->workspaceTopLevelW); XGetGeometry( display, tmpPix, &win, &x, &y, &w, &h, &bw, &depth); pWS->backdrop.imagePixmap = XCreatePixmap(display, tmpPix, w, h, depth); gc = XCreateGC(display, tmpPix, 0, NULL); status = XCopyArea( XtDisplay(pWS->workspaceTopLevelW), tmpPix, pWS->backdrop.imagePixmap, gc, 0, 0, w, h, 0, 0); XFreeGC(display, gc); } if (XmUNSPECIFIED_PIXMAP == tmpPix || BadDrawable == status) pWS->backdrop.imagePixmap = WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW), (char *)pch, pWS->backdrop.foreground, pWS->backdrop.background); } else { pWS->backdrop.imagePixmap = WmXmGetPixmap2 (XtScreen(pWS->workspaceTopLevelW), (char *)pch, pWS->backdrop.foreground, pWS->backdrop.background); } if ((callFlags & CHANGE_BACKDROP) && (pWS->backdrop.window)) { if (pWS->backdrop.imagePixmap != XmUNSPECIFIED_PIXMAP) { XSetWindowBackgroundPixmap (DISPLAY, pWS->backdrop.window, pWS->backdrop.imagePixmap); } else { /* * Failed to find bitmap * set background to "background" */ XSetWindowBackground (DISPLAY, pWS->backdrop.window, pWS->backdrop.background); } } else { if (pWS->backdrop.imagePixmap != XmUNSPECIFIED_PIXMAP) { xswa.override_redirect = True; xswa.background_pixmap = pWS->backdrop.imagePixmap; xswamask = CWOverrideRedirect | CWBackPixmap; } else { xswa.override_redirect = True; xswa.background_pixel = pWS->backdrop.background; xswamask = CWOverrideRedirect | CWBackPixel; } if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER) || (wmGD.colormapFocusPolicy == CMAP_FOCUS_POINTER)) { /* * Listen for enter/levae events if we * have a pointer tracking focus policy */ xswamask |= CWEventMask; xswa.event_mask = EnterWindowMask | LeaveWindowMask; } xswa.backing_store = NotUseful; xswa.save_under = False; xswamask |= (CWBackingStore | CWSaveUnder); pWS->backdrop.window = XCreateWindow(DISPLAY, pWS->pSD->rootWindow, 0, 0, DisplayWidth(DISPLAY, pWS->pSD->screen), DisplayHeight(DISPLAY, pWS->pSD->screen), 0, XDefaultDepth(DISPLAY,pWS->pSD->screen), CopyFromParent, CopyFromParent, xswamask, &xswa); } if (pch && (pWS->backdrop.imagePixmap != XmUNSPECIFIED_PIXMAP) && (pWS->backdrop.window)) { /* * Succeeded in setting up a bitmap backdrop. */ pWS->backdrop.flags |= BACKDROP_BITMAP; pWS->backdrop.nameAtom = XmInternAtom (DISPLAY, pWS->backdrop.image, False); } else { char msg[MAXWMPATH+1]; sprintf ((char *)msg, ((char *)GETMESSAGE(6, 3, "Unable to get image %s for workspace %s.")), pWS->backdrop.image, pWS->name); Warning(msg); } pch = NULL; } free (pchImageName); /* temporary string */ pchImageName = NULL; free (pchL); /* temporary string */ } } free (pchImageName); } /******************************<->************************************* * * static Pixmap WmXmGetPixmap2 * * Description: * ----------- * Tries twice to get a pixmap from a file name * * Inputs: * ------ * screen - ptr to screen * pchName - image file name * fg - foreground color * bg - background color * * Outputs: * ------- * Return - pixmap if found, XmUNSPECIFIED_PIXMAP if not * * Comments: * --------- * This routine performs some backward compatibility checks. * * Do a two stage lookup for backdrop files. If a full path * is specified, but XmGetPixmap fails, the get the basename * of the file and try again. * *************************************<->***********************************/ static Pixmap WmXmGetPixmap2 ( Screen *screen, char *pchName, Pixel fg, Pixel bg) { Pixmap pixReturn; char *pch; if (pchName && *pchName) { pixReturn = XmGetPixmap (screen, pchName, fg, bg); if (pixReturn == XmUNSPECIFIED_PIXMAP) { /* * Use our bitmap lookup paths by using only the * basename of the file path. */ pch = strrchr (pchName, '/'); if (pch && (pch < (pchName + strlen(pchName) - 1))) { pch++; pixReturn = XmGetPixmap (screen, pch, fg, bg); } } } else { pixReturn = XmUNSPECIFIED_PIXMAP; } return (pixReturn); } /******************************<->************************************* * * FullBitmapFilePath (pch) * * Description: * ----------- * Takes a bitmap file name turns it into a full path name. * * Inputs: * ------ * pch = ptr to bitmap file name * * Outputs: * ------- * Return = ptr to a string containing full path name * or NULL on failure * * Comments: * --------- * *************************************<->***********************************/ String FullBitmapFilePath( String pch ) { String pchR; struct stat buf; if (*pch != '/') { pchR = (String) BitmapPathName (pch); if ((stat(pchR, &buf) == -1) && (*pch != '~')) { /* file not there! */ pchR = pch; } } else { pchR = pch; } return (pchR); } /******************************<->************************************* * * SetNewBackdrop (pWS, pixmap, aName) * * Description: * ----------- * Sets a new backdrop for a workspace * * Inputs: * ------ * pWS = pointer to workspace data * pixmap = pixmap for the backdrop (if any) * aName = atomized name for the backdrop (either file name or "none") * * Outputs: * ------- * Return = ptr to a string containing full path name * or NULL on failure * * Comments: * --------- * *************************************<->***********************************/ void SetNewBackdrop( WmWorkspaceData *pWS, Pixmap pixmap, String bitmapFile ) { String pchNewBitmap = NULL; if (!bitmapFile || !strlen(bitmapFile) || !strcmp(bitmapFile, DTWM_REQP_BACKDROP_NONE)) { pixmap = None; } if (bitmapFile) { pchNewBitmap = (String) XtNewString (bitmapFile); } /* * Free up old resources */ if ((pWS->backdrop.imagePixmap) && (pWS->backdrop.imagePixmap != pixmap)) { if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW), pWS->backdrop.imagePixmap)) { /* not in Xm pixmap cache */ } pWS->backdrop.imagePixmap = None; } /* free pWS->backdrop.image */ if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) && (pWS->backdrop.image)) { free (pWS->backdrop.image); } pWS->backdrop.imagePixmap = pixmap; pWS->backdrop.image = pchNewBitmap; ProcessBackdropResources (pWS, CHANGE_BACKDROP); if (pchNewBitmap) { pWS->backdrop.flags |= BACKDROP_IMAGE_ALLOCED; } ChangeBackdrop (pWS); SaveWorkspaceResources (pWS, WM_RES_BACKDROP_IMAGE); SetWorkspaceInfoProperty (pWS); /* * Inform the world of the new workspace title */ dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id, DtWSM_REASON_BACKDROP); } /******************************<->************************************* * * Boolean IsBackdropWindow (pSD, win) * * Description: * ----------- * Tests a window to see if it is a backdrop window * * Inputs: * ------ * pSD = pointer to screen data * win = window to test. * * Outputs: * ------- * Return = True if win is a backdrop window. * False otherwise. * * Comments: * --------- * *************************************<->***********************************/ Boolean IsBackdropWindow( WmScreenData *pSD, Window win ) { Boolean rval = False; int i; /* * Is it one of the backdrop windows for a workspace? */ for (i=0; (i < pSD->numWorkspaces) && !rval; i++) { if (pSD->pWS[i].backdrop.window == win) { rval = True; } } return (rval); } /********************* eof ***************************/