util.c revision ffd25bca
13e747e6dSmrg/*****************************************************************************/ 23e747e6dSmrg/* 33e747e6dSmrg 43e747e6dSmrgCopyright 1989, 1998 The Open Group 53e747e6dSmrg 63e747e6dSmrgPermission to use, copy, modify, distribute, and sell this software and its 73e747e6dSmrgdocumentation for any purpose is hereby granted without fee, provided that 83e747e6dSmrgthe above copyright notice appear in all copies and that both that 93e747e6dSmrgcopyright notice and this permission notice appear in supporting 103e747e6dSmrgdocumentation. 113e747e6dSmrg 123e747e6dSmrgThe above copyright notice and this permission notice shall be included in 133e747e6dSmrgall copies or substantial portions of the Software. 143e747e6dSmrg 153e747e6dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 163e747e6dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 173e747e6dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 183e747e6dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 193e747e6dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 203e747e6dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 213e747e6dSmrg 223e747e6dSmrgExcept as contained in this notice, the name of The Open Group shall not be 233e747e6dSmrgused in advertising or otherwise to promote the sale, use or other dealings 243e747e6dSmrgin this Software without prior written authorization from The Open Group. 253e747e6dSmrg 263e747e6dSmrg*/ 273e747e6dSmrg/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ 283e747e6dSmrg/** Salt Lake City, Utah **/ 293e747e6dSmrg/** Cambridge, Massachusetts **/ 303e747e6dSmrg/** **/ 313e747e6dSmrg/** All Rights Reserved **/ 323e747e6dSmrg/** **/ 333e747e6dSmrg/** Permission to use, copy, modify, and distribute this software and **/ 343e747e6dSmrg/** its documentation for any purpose and without fee is hereby **/ 353e747e6dSmrg/** granted, provided that the above copyright notice appear in all **/ 363e747e6dSmrg/** copies and that both that copyright notice and this permis- **/ 373e747e6dSmrg/** sion notice appear in supporting documentation, and that the **/ 383e747e6dSmrg/** name of Evans & Sutherland not be used in advertising **/ 393e747e6dSmrg/** in publicity pertaining to distribution of the software without **/ 403e747e6dSmrg/** specific, written prior permission. **/ 413e747e6dSmrg/** **/ 423e747e6dSmrg/** EVANS & SUTHERLAND DISCLAIMs ALL WARRANTIES WITH REGARD **/ 433e747e6dSmrg/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ 443e747e6dSmrg/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND **/ 453e747e6dSmrg/** BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ 463e747e6dSmrg/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ 473e747e6dSmrg/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ 483e747e6dSmrg/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ 493e747e6dSmrg/** OR PERFORMANCE OF THIS SOFTWARE. **/ 503e747e6dSmrg/*****************************************************************************/ 513e747e6dSmrg 523e747e6dSmrg 533e747e6dSmrg/*********************************************************************** 543e747e6dSmrg * 553e747e6dSmrg * utility routines for twm 563e747e6dSmrg * 573e747e6dSmrg * 28-Oct-87 Thomas E. LaStrange File created 583e747e6dSmrg * 593e747e6dSmrg ***********************************************************************/ 603e747e6dSmrg 613e747e6dSmrg#include "twm.h" 623e747e6dSmrg#include "util.h" 633e747e6dSmrg#include "gram.h" 643e747e6dSmrg#include "screen.h" 653e747e6dSmrg#include <X11/Xos.h> 663e747e6dSmrg#include <X11/Xatom.h> 673e747e6dSmrg#include <stdio.h> 683e747e6dSmrg#include <X11/Xmu/Drawing.h> 693e747e6dSmrg#include <X11/Xmu/CharSet.h> 703e747e6dSmrg 71ffd25bcaSmrgstatic Pixmap CreateXLogoPixmap ( unsigned int *widthp, 723e747e6dSmrg unsigned int *heightp ); 73ffd25bcaSmrgstatic Pixmap CreateResizePixmap ( unsigned int *widthp, 743e747e6dSmrg unsigned int *heightp ); 75ffd25bcaSmrgstatic Pixmap CreateDotPixmap ( unsigned int *widthp, 763e747e6dSmrg unsigned int *heightp ); 77ffd25bcaSmrgstatic Pixmap CreateQuestionPixmap ( unsigned int *widthp, 783e747e6dSmrg unsigned int *heightp ); 79ffd25bcaSmrgstatic Pixmap CreateMenuPixmap ( unsigned int *widthp, 803e747e6dSmrg unsigned int *heightp ); 813e747e6dSmrg 823e747e6dSmrgint HotX, HotY; 833e747e6dSmrg 84ffd25bcaSmrg/** 853e747e6dSmrg * move a window outline 863e747e6dSmrg * 873e747e6dSmrg * \param root window we are outlining 883e747e6dSmrg * \param x,y upper left coordinate 893e747e6dSmrg * \param width,height size of the rectangle 903e747e6dSmrg * \param bw border width of the frame 913e747e6dSmrg * \param th title height 923e747e6dSmrg */ 933e747e6dSmrgvoid MoveOutline(Window root, int x, int y, int width, int height, int bw, int th) 943e747e6dSmrg{ 953e747e6dSmrg static int lastx = 0; 963e747e6dSmrg static int lasty = 0; 973e747e6dSmrg static int lastWidth = 0; 983e747e6dSmrg static int lastHeight = 0; 993e747e6dSmrg static int lastBW = 0; 1003e747e6dSmrg static int lastTH = 0; 1013e747e6dSmrg int xl, xr, yt, yb, xinnerl, xinnerr, yinnert, yinnerb; 1023e747e6dSmrg int xthird, ythird; 1033e747e6dSmrg XSegment outline[18]; 1043e747e6dSmrg register XSegment *r; 1053e747e6dSmrg 1063e747e6dSmrg if (x == lastx && y == lasty && width == lastWidth && height == lastHeight 1073e747e6dSmrg && lastBW == bw && th == lastTH) 1083e747e6dSmrg return; 109ffd25bcaSmrg 1103e747e6dSmrg r = outline; 1113e747e6dSmrg 1123e747e6dSmrg#define DRAWIT() \ 1133e747e6dSmrg if (lastWidth || lastHeight) \ 1143e747e6dSmrg { \ 1153e747e6dSmrg xl = lastx; \ 1163e747e6dSmrg xr = lastx + lastWidth - 1; \ 1173e747e6dSmrg yt = lasty; \ 1183e747e6dSmrg yb = lasty + lastHeight - 1; \ 1193e747e6dSmrg xinnerl = xl + lastBW; \ 1203e747e6dSmrg xinnerr = xr - lastBW; \ 1213e747e6dSmrg yinnert = yt + lastTH + lastBW; \ 1223e747e6dSmrg yinnerb = yb - lastBW; \ 1233e747e6dSmrg xthird = (xinnerr - xinnerl) / 3; \ 1243e747e6dSmrg ythird = (yinnerb - yinnert) / 3; \ 1253e747e6dSmrg \ 1263e747e6dSmrg r->x1 = xl; \ 1273e747e6dSmrg r->y1 = yt; \ 1283e747e6dSmrg r->x2 = xr; \ 1293e747e6dSmrg r->y2 = yt; \ 1303e747e6dSmrg r++; \ 1313e747e6dSmrg \ 1323e747e6dSmrg r->x1 = xl; \ 1333e747e6dSmrg r->y1 = yb; \ 1343e747e6dSmrg r->x2 = xr; \ 1353e747e6dSmrg r->y2 = yb; \ 1363e747e6dSmrg r++; \ 1373e747e6dSmrg \ 1383e747e6dSmrg r->x1 = xl; \ 1393e747e6dSmrg r->y1 = yt; \ 1403e747e6dSmrg r->x2 = xl; \ 1413e747e6dSmrg r->y2 = yb; \ 1423e747e6dSmrg r++; \ 1433e747e6dSmrg \ 1443e747e6dSmrg r->x1 = xr; \ 1453e747e6dSmrg r->y1 = yt; \ 1463e747e6dSmrg r->x2 = xr; \ 1473e747e6dSmrg r->y2 = yb; \ 1483e747e6dSmrg r++; \ 1493e747e6dSmrg \ 1503e747e6dSmrg r->x1 = xinnerl + xthird; \ 1513e747e6dSmrg r->y1 = yinnert; \ 1523e747e6dSmrg r->x2 = r->x1; \ 1533e747e6dSmrg r->y2 = yinnerb; \ 1543e747e6dSmrg r++; \ 1553e747e6dSmrg \ 1563e747e6dSmrg r->x1 = xinnerl + (2 * xthird); \ 1573e747e6dSmrg r->y1 = yinnert; \ 1583e747e6dSmrg r->x2 = r->x1; \ 1593e747e6dSmrg r->y2 = yinnerb; \ 1603e747e6dSmrg r++; \ 1613e747e6dSmrg \ 1623e747e6dSmrg r->x1 = xinnerl; \ 1633e747e6dSmrg r->y1 = yinnert + ythird; \ 1643e747e6dSmrg r->x2 = xinnerr; \ 1653e747e6dSmrg r->y2 = r->y1; \ 1663e747e6dSmrg r++; \ 1673e747e6dSmrg \ 1683e747e6dSmrg r->x1 = xinnerl; \ 1693e747e6dSmrg r->y1 = yinnert + (2 * ythird); \ 1703e747e6dSmrg r->x2 = xinnerr; \ 1713e747e6dSmrg r->y2 = r->y1; \ 1723e747e6dSmrg r++; \ 1733e747e6dSmrg \ 1743e747e6dSmrg if (lastTH != 0) { \ 1753e747e6dSmrg r->x1 = xl; \ 1763e747e6dSmrg r->y1 = yt + lastTH; \ 1773e747e6dSmrg r->x2 = xr; \ 1783e747e6dSmrg r->y2 = r->y1; \ 1793e747e6dSmrg r++; \ 1803e747e6dSmrg } \ 1813e747e6dSmrg } 1823e747e6dSmrg 1833e747e6dSmrg /* undraw the old one, if any */ 1843e747e6dSmrg DRAWIT (); 1853e747e6dSmrg 1863e747e6dSmrg lastx = x; 1873e747e6dSmrg lasty = y; 1883e747e6dSmrg lastWidth = width; 1893e747e6dSmrg lastHeight = height; 1903e747e6dSmrg lastBW = bw; 1913e747e6dSmrg lastTH = th; 1923e747e6dSmrg 1933e747e6dSmrg /* draw the new one, if any */ 1943e747e6dSmrg DRAWIT (); 1953e747e6dSmrg 1963e747e6dSmrg#undef DRAWIT 1973e747e6dSmrg 1983e747e6dSmrg 1993e747e6dSmrg if (r != outline) 2003e747e6dSmrg { 2013e747e6dSmrg XDrawSegments(dpy, root, Scr->DrawGC, outline, r - outline); 2023e747e6dSmrg } 2033e747e6dSmrg} 2043e747e6dSmrg 2053e747e6dSmrg/** 2063e747e6dSmrg * zoom in or out of an icon 2073e747e6dSmrg * 2083e747e6dSmrg * \param wf window to zoom from 2093e747e6dSmrg * \param wt window to zoom to 2103e747e6dSmrg */ 2113e747e6dSmrgvoid 2123e747e6dSmrgZoom(Window wf, Window wt) 2133e747e6dSmrg{ 2143e747e6dSmrg int fx, fy, tx, ty; /* from, to */ 2153e747e6dSmrg unsigned int fw, fh, tw, th; /* from, to */ 2163e747e6dSmrg long dx, dy, dw, dh; 2173e747e6dSmrg long z; 2183e747e6dSmrg int j; 2193e747e6dSmrg 2203e747e6dSmrg if (!Scr->DoZoom || Scr->ZoomCount < 1) return; 2213e747e6dSmrg 2223e747e6dSmrg if (wf == None || wt == None) return; 2233e747e6dSmrg 2243e747e6dSmrg XGetGeometry (dpy, wf, &JunkRoot, &fx, &fy, &fw, &fh, &JunkBW, &JunkDepth); 2253e747e6dSmrg XGetGeometry (dpy, wt, &JunkRoot, &tx, &ty, &tw, &th, &JunkBW, &JunkDepth); 2263e747e6dSmrg 2273e747e6dSmrg dx = ((long) (tx - fx)); /* going from -> to */ 2283e747e6dSmrg dy = ((long) (ty - fy)); /* going from -> to */ 2293e747e6dSmrg dw = ((long) (tw - fw)); /* going from -> to */ 2303e747e6dSmrg dh = ((long) (th - fh)); /* going from -> to */ 2313e747e6dSmrg z = (long) (Scr->ZoomCount + 1); 2323e747e6dSmrg 2333e747e6dSmrg for (j = 0; j < 2; j++) { 2343e747e6dSmrg long i; 2353e747e6dSmrg 2363e747e6dSmrg XDrawRectangle (dpy, Scr->Root, Scr->DrawGC, fx, fy, fw, fh); 2373e747e6dSmrg for (i = 1; i < z; i++) { 2383e747e6dSmrg int x = fx + (int) ((dx * i) / z); 2393e747e6dSmrg int y = fy + (int) ((dy * i) / z); 2403e747e6dSmrg unsigned width = (unsigned) (((long) fw) + (dw * i) / z); 2413e747e6dSmrg unsigned height = (unsigned) (((long) fh) + (dh * i) / z); 242ffd25bcaSmrg 2433e747e6dSmrg XDrawRectangle (dpy, Scr->Root, Scr->DrawGC, 2443e747e6dSmrg x, y, width, height); 2453e747e6dSmrg } 2463e747e6dSmrg XDrawRectangle (dpy, Scr->Root, Scr->DrawGC, tx, ty, tw, th); 2473e747e6dSmrg } 2483e747e6dSmrg} 2493e747e6dSmrg 2503e747e6dSmrg/** 251ffd25bcaSmrg * expand the tilde character to HOME if it is the first 2523e747e6dSmrg * character of the filename 2533e747e6dSmrg * 2543e747e6dSmrg * \return a pointer to the new name 2553e747e6dSmrg * 2563e747e6dSmrg * \param name the filename to expand 2573e747e6dSmrg */ 2583e747e6dSmrgchar * 2593e747e6dSmrgExpandFilename(char *name) 2603e747e6dSmrg{ 2613e747e6dSmrg char *newname; 2623e747e6dSmrg 2633e747e6dSmrg if (name[0] != '~') return name; 2643e747e6dSmrg 2653e747e6dSmrg newname = (char *) malloc (HomeLen + strlen(name) + 2); 2663e747e6dSmrg if (!newname) { 267ffd25bcaSmrg fprintf (stderr, 2683e747e6dSmrg "%s: unable to allocate %ld bytes to expand filename %s/%s\n", 2693e747e6dSmrg ProgramName, HomeLen + (unsigned long)strlen(name) + 2, 2703e747e6dSmrg Home, &name[1]); 2713e747e6dSmrg } else { 2723e747e6dSmrg (void) sprintf (newname, "%s/%s", Home, &name[1]); 2733e747e6dSmrg } 2743e747e6dSmrg 2753e747e6dSmrg return newname; 2763e747e6dSmrg} 2773e747e6dSmrg 2783e747e6dSmrg/** 2793e747e6dSmrg * read in the bitmap file for the unknown icon 2803e747e6dSmrg * 2813e747e6dSmrg * \param name the filename to read 2823e747e6dSmrg */ 2833e747e6dSmrgvoid 2843e747e6dSmrgGetUnknownIcon(char *name) 2853e747e6dSmrg{ 2863e747e6dSmrg if ((Scr->UnknownPm = GetBitmap(name)) != None) 2873e747e6dSmrg { 2883e747e6dSmrg XGetGeometry(dpy, Scr->UnknownPm, &JunkRoot, &JunkX, &JunkY, 2893e747e6dSmrg (unsigned int *)&Scr->UnknownWidth, (unsigned int *)&Scr->UnknownHeight, &JunkBW, &JunkDepth); 2903e747e6dSmrg } 2913e747e6dSmrg} 2923e747e6dSmrg 2933e747e6dSmrg/** 2943e747e6dSmrg * FindBitmap - read in a bitmap file and return size 2953e747e6dSmrg * 2963e747e6dSmrg * \return pixmap associated with bitmap 2973e747e6dSmrg * 2983e747e6dSmrg * \param name filename to read 2993e747e6dSmrg * \param[out] widthp pointer to width of bitmap 3003e747e6dSmrg * \param[out] heightp pointer to height of bitmap 3013e747e6dSmrg */ 302ffd25bcaSmrgPixmap 3033e747e6dSmrgFindBitmap (char *name, unsigned *widthp, unsigned *heightp) 3043e747e6dSmrg{ 3053e747e6dSmrg char *bigname; 3063e747e6dSmrg Pixmap pm; 3073e747e6dSmrg 3083e747e6dSmrg if (!name) return None; 3093e747e6dSmrg 3103e747e6dSmrg /* 3113e747e6dSmrg * Names of the form :name refer to hardcoded images that are scaled to 3123e747e6dSmrg * look nice in title buttons. Eventually, it would be nice to put in a 3133e747e6dSmrg * menu symbol as well.... 3143e747e6dSmrg */ 3153e747e6dSmrg if (name[0] == ':') { 3163e747e6dSmrg int i; 3173e747e6dSmrg static struct { 3183e747e6dSmrg char *name; 3193e747e6dSmrg Pixmap (*proc)(unsigned int *, unsigned int *); 3203e747e6dSmrg } pmtab[] = { 3213e747e6dSmrg { TBPM_DOT, CreateDotPixmap }, 3223e747e6dSmrg { TBPM_ICONIFY, CreateDotPixmap }, 3233e747e6dSmrg { TBPM_RESIZE, CreateResizePixmap }, 3243e747e6dSmrg { TBPM_XLOGO, CreateXLogoPixmap }, 3253e747e6dSmrg { TBPM_DELETE, CreateXLogoPixmap }, 3263e747e6dSmrg { TBPM_MENU, CreateMenuPixmap }, 3273e747e6dSmrg { TBPM_QUESTION, CreateQuestionPixmap }, 3283e747e6dSmrg }; 329ffd25bcaSmrg 3303e747e6dSmrg for (i = 0; i < (sizeof pmtab)/(sizeof pmtab[0]); i++) { 3313e747e6dSmrg if (XmuCompareISOLatin1 (pmtab[i].name, name) == 0) 3323e747e6dSmrg return (*pmtab[i].proc) (widthp, heightp); 3333e747e6dSmrg } 3343e747e6dSmrg fprintf (stderr, "%s: no such built-in bitmap \"%s\"\n", 3353e747e6dSmrg ProgramName, name); 3363e747e6dSmrg return None; 3373e747e6dSmrg } 3383e747e6dSmrg 3393e747e6dSmrg /* 3403e747e6dSmrg * Generate a full pathname if any special prefix characters (such as ~) 3413e747e6dSmrg * are used. If the bigname is different from name, bigname will need to 3423e747e6dSmrg * be freed. 3433e747e6dSmrg */ 3443e747e6dSmrg bigname = ExpandFilename (name); 3453e747e6dSmrg if (!bigname) return None; 3463e747e6dSmrg 3473e747e6dSmrg /* 3483e747e6dSmrg * look along bitmapFilePath resource same as toolkit clients 3493e747e6dSmrg */ 3503e747e6dSmrg pm = XmuLocateBitmapFile (ScreenOfDisplay(dpy, Scr->screen), bigname, NULL, 3513e747e6dSmrg 0, (int *)widthp, (int *)heightp, &HotX, &HotY); 3523e747e6dSmrg if (pm == None && Scr->IconDirectory && bigname[0] != '/') { 3533e747e6dSmrg if (bigname != name) free (bigname); 3543e747e6dSmrg /* 3553e747e6dSmrg * Attempt to find icon in old IconDirectory (now obsolete) 3563e747e6dSmrg */ 3573e747e6dSmrg bigname = (char *) malloc (strlen(name) + strlen(Scr->IconDirectory) + 3583e747e6dSmrg 2); 3593e747e6dSmrg if (!bigname) { 3603e747e6dSmrg fprintf (stderr, 3613e747e6dSmrg "%s: unable to allocate memory for \"%s/%s\"\n", 3623e747e6dSmrg ProgramName, Scr->IconDirectory, name); 3633e747e6dSmrg return None; 3643e747e6dSmrg } 3653e747e6dSmrg (void) sprintf (bigname, "%s/%s", Scr->IconDirectory, name); 3663e747e6dSmrg if (XReadBitmapFile (dpy, Scr->Root, bigname, widthp, heightp, &pm, 3673e747e6dSmrg &HotX, &HotY) != BitmapSuccess) { 3683e747e6dSmrg pm = None; 3693e747e6dSmrg } 3703e747e6dSmrg } 3713e747e6dSmrg if (bigname != name) free (bigname); 3723e747e6dSmrg if (pm == None) { 373ffd25bcaSmrg fprintf (stderr, "%s: unable to find bitmap \"%s\"\n", 3743e747e6dSmrg ProgramName, name); 3753e747e6dSmrg } 3763e747e6dSmrg 3773e747e6dSmrg return pm; 3783e747e6dSmrg} 3793e747e6dSmrg 380ffd25bcaSmrgPixmap 3813e747e6dSmrgGetBitmap (char *name) 3823e747e6dSmrg{ 3833e747e6dSmrg return FindBitmap (name, &JunkWidth, &JunkHeight); 3843e747e6dSmrg} 3853e747e6dSmrg 3863e747e6dSmrgvoid 3873e747e6dSmrgInsertRGBColormap (Atom a, XStandardColormap *maps, int nmaps, Bool replace) 3883e747e6dSmrg{ 3893e747e6dSmrg StdCmap *sc = NULL; 3903e747e6dSmrg 3913e747e6dSmrg if (replace) { /* locate existing entry */ 3923e747e6dSmrg for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) { 3933e747e6dSmrg if (sc->atom == a) break; 3943e747e6dSmrg } 3953e747e6dSmrg } 3963e747e6dSmrg 3973e747e6dSmrg if (!sc) { /* no existing, allocate new */ 3983e747e6dSmrg sc = (StdCmap *) malloc (sizeof (StdCmap)); 3993e747e6dSmrg if (!sc) { 4003e747e6dSmrg fprintf (stderr, "%s: unable to allocate %ld bytes for StdCmap\n", 4013e747e6dSmrg ProgramName, (unsigned long)sizeof (StdCmap)); 4023e747e6dSmrg return; 4033e747e6dSmrg } 4043e747e6dSmrg } 4053e747e6dSmrg 4063e747e6dSmrg if (replace) { /* just update contents */ 4073e747e6dSmrg if (sc->maps) XFree ((char *) maps); 4083e747e6dSmrg if (sc == Scr->StdCmapInfo.mru) Scr->StdCmapInfo.mru = NULL; 4093e747e6dSmrg } else { /* else appending */ 4103e747e6dSmrg sc->next = NULL; 4113e747e6dSmrg sc->atom = a; 4123e747e6dSmrg if (Scr->StdCmapInfo.tail) { 4133e747e6dSmrg Scr->StdCmapInfo.tail->next = sc; 4143e747e6dSmrg } else { 4153e747e6dSmrg Scr->StdCmapInfo.head = sc; 4163e747e6dSmrg } 4173e747e6dSmrg Scr->StdCmapInfo.tail = sc; 4183e747e6dSmrg } 4193e747e6dSmrg sc->nmaps = nmaps; 4203e747e6dSmrg sc->maps = maps; 4213e747e6dSmrg 4223e747e6dSmrg return; 4233e747e6dSmrg} 4243e747e6dSmrg 4253e747e6dSmrgvoid 4263e747e6dSmrgRemoveRGBColormap (Atom a) 4273e747e6dSmrg{ 4283e747e6dSmrg StdCmap *sc, *prev; 4293e747e6dSmrg 4303e747e6dSmrg prev = NULL; 431ffd25bcaSmrg for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) { 4323e747e6dSmrg if (sc->atom == a) break; 4333e747e6dSmrg prev = sc; 4343e747e6dSmrg } 4353e747e6dSmrg if (sc) { /* found one */ 4363e747e6dSmrg if (sc->maps) XFree ((char *) sc->maps); 4373e747e6dSmrg if (prev) prev->next = sc->next; 4383e747e6dSmrg if (Scr->StdCmapInfo.head == sc) Scr->StdCmapInfo.head = sc->next; 4393e747e6dSmrg if (Scr->StdCmapInfo.tail == sc) Scr->StdCmapInfo.tail = prev; 4403e747e6dSmrg if (Scr->StdCmapInfo.mru == sc) Scr->StdCmapInfo.mru = NULL; 4413e747e6dSmrg } 4423e747e6dSmrg return; 4433e747e6dSmrg} 4443e747e6dSmrg 4453e747e6dSmrgvoid 4463e747e6dSmrgLocateStandardColormaps() 4473e747e6dSmrg{ 4483e747e6dSmrg Atom *atoms; 4493e747e6dSmrg int natoms; 4503e747e6dSmrg int i; 4513e747e6dSmrg 4523e747e6dSmrg atoms = XListProperties (dpy, Scr->Root, &natoms); 4533e747e6dSmrg for (i = 0; i < natoms; i++) { 4543e747e6dSmrg XStandardColormap *maps = NULL; 4553e747e6dSmrg int nmaps; 4563e747e6dSmrg 4573e747e6dSmrg if (XGetRGBColormaps (dpy, Scr->Root, &maps, &nmaps, atoms[i])) { 4583e747e6dSmrg /* if got one, then append to current list */ 4593e747e6dSmrg InsertRGBColormap (atoms[i], maps, nmaps, False); 4603e747e6dSmrg } 4613e747e6dSmrg } 4623e747e6dSmrg if (atoms) XFree ((char *) atoms); 4633e747e6dSmrg return; 4643e747e6dSmrg} 4653e747e6dSmrg 4663e747e6dSmrgvoid 4673e747e6dSmrgGetColor(int kind, Pixel *what, char *name) 4683e747e6dSmrg{ 4693e747e6dSmrg XColor color, junkcolor; 4703e747e6dSmrg Status stat = 0; 4713e747e6dSmrg Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c; 4723e747e6dSmrg 4733e747e6dSmrg#ifndef TOM 4743e747e6dSmrg if (!Scr->FirstTime) 4753e747e6dSmrg return; 4763e747e6dSmrg#endif 4773e747e6dSmrg 4783e747e6dSmrg if (Scr->Monochrome != kind) 4793e747e6dSmrg return; 4803e747e6dSmrg 4813e747e6dSmrg if (!XAllocNamedColor (dpy, cmap, name, &color, &junkcolor)) 4823e747e6dSmrg { 4833e747e6dSmrg /* if we could not allocate the color, let's see if this is a 4843e747e6dSmrg * standard colormap 4853e747e6dSmrg */ 4863e747e6dSmrg XStandardColormap *stdcmap = NULL; 4873e747e6dSmrg 4883e747e6dSmrg /* parse the named color */ 4893e747e6dSmrg if (name[0] != '#') 4903e747e6dSmrg stat = XParseColor (dpy, cmap, name, &color); 4913e747e6dSmrg if (!stat) 4923e747e6dSmrg { 493ffd25bcaSmrg fprintf (stderr, "%s: invalid color name \"%s\"\n", 4943e747e6dSmrg ProgramName, name); 4953e747e6dSmrg return; 4963e747e6dSmrg } 4973e747e6dSmrg 4983e747e6dSmrg /* 4993e747e6dSmrg * look through the list of standard colormaps (check cache first) 5003e747e6dSmrg */ 5013e747e6dSmrg if (Scr->StdCmapInfo.mru && Scr->StdCmapInfo.mru->maps && 5023e747e6dSmrg (Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex].colormap == 5033e747e6dSmrg cmap)) { 5043e747e6dSmrg stdcmap = &(Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex]); 5053e747e6dSmrg } else { 5063e747e6dSmrg StdCmap *sc; 5073e747e6dSmrg 5083e747e6dSmrg for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) { 5093e747e6dSmrg int i; 5103e747e6dSmrg 5113e747e6dSmrg for (i = 0; i < sc->nmaps; i++) { 5123e747e6dSmrg if (sc->maps[i].colormap == cmap) { 5133e747e6dSmrg Scr->StdCmapInfo.mru = sc; 5143e747e6dSmrg Scr->StdCmapInfo.mruindex = i; 5153e747e6dSmrg stdcmap = &(sc->maps[i]); 5163e747e6dSmrg goto gotit; 5173e747e6dSmrg } 5183e747e6dSmrg } 5193e747e6dSmrg } 5203e747e6dSmrg } 5213e747e6dSmrg 5223e747e6dSmrg gotit: 5233e747e6dSmrg if (stdcmap) { 5243e747e6dSmrg color.pixel = (stdcmap->base_pixel + 5253e747e6dSmrg ((Pixel)(((float)color.red / 65535.0) * 5263e747e6dSmrg stdcmap->red_max + 0.5) * 5273e747e6dSmrg stdcmap->red_mult) + 5283e747e6dSmrg ((Pixel)(((float)color.green /65535.0) * 5293e747e6dSmrg stdcmap->green_max + 0.5) * 5303e747e6dSmrg stdcmap->green_mult) + 5313e747e6dSmrg ((Pixel)(((float)color.blue / 65535.0) * 5323e747e6dSmrg stdcmap->blue_max + 0.5) * 5333e747e6dSmrg stdcmap->blue_mult)); 5343e747e6dSmrg } else { 535ffd25bcaSmrg fprintf (stderr, "%s: unable to allocate color \"%s\"\n", 5363e747e6dSmrg ProgramName, name); 5373e747e6dSmrg return; 5383e747e6dSmrg } 5393e747e6dSmrg } 5403e747e6dSmrg 5413e747e6dSmrg *what = color.pixel; 5423e747e6dSmrg} 5433e747e6dSmrg 5443e747e6dSmrgvoid 5453e747e6dSmrgGetColorValue(int kind, XColor *what, char *name) 5463e747e6dSmrg{ 5473e747e6dSmrg XColor junkcolor; 5483e747e6dSmrg Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c; 5493e747e6dSmrg 5503e747e6dSmrg#ifndef TOM 5513e747e6dSmrg if (!Scr->FirstTime) 5523e747e6dSmrg return; 5533e747e6dSmrg#endif 5543e747e6dSmrg 5553e747e6dSmrg if (Scr->Monochrome != kind) 5563e747e6dSmrg return; 5573e747e6dSmrg 5583e747e6dSmrg if (!XLookupColor (dpy, cmap, name, what, &junkcolor)) 5593e747e6dSmrg { 560ffd25bcaSmrg fprintf (stderr, "%s: invalid color name \"%s\"\n", 5613e747e6dSmrg ProgramName, name); 5623e747e6dSmrg } 5633e747e6dSmrg else 5643e747e6dSmrg { 5653e747e6dSmrg what->pixel = AllPlanes; 5663e747e6dSmrg } 5673e747e6dSmrg} 5683e747e6dSmrg 569ffd25bcaSmrg/* 5703e747e6dSmrg * The following functions are sensible to 'use_fontset'. 5713e747e6dSmrg * When 'use_fontset' is True, 5723e747e6dSmrg * - XFontSet-related internationalized functions are used 5733e747e6dSmrg * so as multibyte languages can be displayed. 5743e747e6dSmrg * When 'use_fontset' is False, 5753e747e6dSmrg * - XFontStruct-related conventional functions are used 5763e747e6dSmrg * so as 8-bit characters can be displayed even when 5773e747e6dSmrg * locale is not set properly. 5783e747e6dSmrg */ 5793e747e6dSmrgvoid 5803e747e6dSmrgGetFont(MyFont *font) 5813e747e6dSmrg{ 5823e747e6dSmrg char *deffontname = "fixed"; 5833e747e6dSmrg char **missing_charset_list_return; 5843e747e6dSmrg int missing_charset_count_return; 5853e747e6dSmrg char *def_string_return; 5863e747e6dSmrg XFontSetExtents *font_extents; 5873e747e6dSmrg XFontStruct **xfonts; 5883e747e6dSmrg char **font_names; 5893e747e6dSmrg register int i; 5903e747e6dSmrg int ascent; 5913e747e6dSmrg int descent; 5923e747e6dSmrg int fnum; 5933e747e6dSmrg char *basename2; 5943e747e6dSmrg 5953e747e6dSmrg if (use_fontset) { 5963e747e6dSmrg if (font->fontset != NULL){ 5973e747e6dSmrg XFreeFontSet(dpy, font->fontset); 5983e747e6dSmrg } 5993e747e6dSmrg 6003e747e6dSmrg basename2 = (char *)malloc(strlen(font->name) + 3); 6013e747e6dSmrg if (basename2) sprintf(basename2, "%s,*", font->name); 6023e747e6dSmrg else basename2 = font->name; 6033e747e6dSmrg if( (font->fontset = XCreateFontSet(dpy, basename2, 6043e747e6dSmrg &missing_charset_list_return, 6053e747e6dSmrg &missing_charset_count_return, 6063e747e6dSmrg &def_string_return)) == NULL) { 6073e747e6dSmrg fprintf (stderr, "%s: unable to open fontset \"%s\"\n", 6083e747e6dSmrg ProgramName, font->name); 6093e747e6dSmrg exit(1); 6103e747e6dSmrg } 6113e747e6dSmrg if (basename2 != font->name) free(basename2); 6123e747e6dSmrg for(i=0; i<missing_charset_count_return; i++){ 6133e747e6dSmrg printf("%s: warning: font for charset %s is lacking.\n", 6143e747e6dSmrg ProgramName, missing_charset_list_return[i]); 6153e747e6dSmrg } 6163e747e6dSmrg 6173e747e6dSmrg font_extents = XExtentsOfFontSet(font->fontset); 6183e747e6dSmrg fnum = XFontsOfFontSet(font->fontset, &xfonts, &font_names); 6193e747e6dSmrg for( i = 0, ascent = 0, descent = 0; i<fnum; i++){ 6203e747e6dSmrg if (ascent < (*xfonts)->ascent) ascent = (*xfonts)->ascent; 6213e747e6dSmrg if (descent < (*xfonts)->descent) descent = (*xfonts)->descent; 6223e747e6dSmrg xfonts++; 6233e747e6dSmrg } 6243e747e6dSmrg font->height = font_extents->max_logical_extent.height; 6253e747e6dSmrg font->y = ascent; 6263e747e6dSmrg font->ascent = ascent; 6273e747e6dSmrg font->descent = descent; 6283e747e6dSmrg return; 6293e747e6dSmrg } 6303e747e6dSmrg 6313e747e6dSmrg if (font->font != NULL) 6323e747e6dSmrg XFreeFont(dpy, font->font); 6333e747e6dSmrg 6343e747e6dSmrg if ((font->font = XLoadQueryFont(dpy, font->name)) == NULL) 6353e747e6dSmrg { 6363e747e6dSmrg if (Scr->DefaultFont.name) { 6373e747e6dSmrg deffontname = Scr->DefaultFont.name; 6383e747e6dSmrg } 6393e747e6dSmrg if ((font->font = XLoadQueryFont(dpy, deffontname)) == NULL) 6403e747e6dSmrg { 6413e747e6dSmrg fprintf (stderr, "%s: unable to open fonts \"%s\" or \"%s\"\n", 6423e747e6dSmrg ProgramName, font->name, deffontname); 6433e747e6dSmrg exit(1); 6443e747e6dSmrg } 6453e747e6dSmrg 6463e747e6dSmrg } 6473e747e6dSmrg font->height = font->font->ascent + font->font->descent; 6483e747e6dSmrg font->y = font->font->ascent; 6493e747e6dSmrg font->ascent = font->font->ascent; 6503e747e6dSmrg font->descent = font->font->descent; 6513e747e6dSmrg} 6523e747e6dSmrg 6533e747e6dSmrgint 6543e747e6dSmrgMyFont_TextWidth(MyFont *font, char *string, int len) 6553e747e6dSmrg{ 6563e747e6dSmrg XRectangle ink_rect; 6573e747e6dSmrg XRectangle logical_rect; 6583e747e6dSmrg 6593e747e6dSmrg if (use_fontset) { 6603e747e6dSmrg XmbTextExtents(font->fontset, string, len, 6613e747e6dSmrg &ink_rect, &logical_rect); 6623e747e6dSmrg return logical_rect.width; 6633e747e6dSmrg } 6643e747e6dSmrg return XTextWidth(font->font, string, len); 6653e747e6dSmrg} 6663e747e6dSmrg 6673e747e6dSmrgvoid 668ffd25bcaSmrgMyFont_DrawImageString(Display *dpy, Drawable d, MyFont *font, GC gc, 6693e747e6dSmrg int x, int y, char *string, int len) 6703e747e6dSmrg{ 6713e747e6dSmrg if (use_fontset) { 6723e747e6dSmrg XmbDrawImageString(dpy, d, font->fontset, gc, x, y, string, len); 6733e747e6dSmrg return; 6743e747e6dSmrg } 6753e747e6dSmrg XDrawImageString (dpy, d, gc, x, y, string, len); 6763e747e6dSmrg} 6773e747e6dSmrg 6783e747e6dSmrgvoid 679ffd25bcaSmrgMyFont_DrawString(Display *dpy, Drawable d, MyFont *font, GC gc, 6803e747e6dSmrg int x, int y, char *string, int len) 6813e747e6dSmrg{ 6823e747e6dSmrg if (use_fontset) { 6833e747e6dSmrg XmbDrawString(dpy, d, font->fontset, gc, x, y, string, len); 6843e747e6dSmrg return; 6853e747e6dSmrg } 6863e747e6dSmrg XDrawString (dpy, d, gc, x, y, string, len); 6873e747e6dSmrg} 6883e747e6dSmrg 6893e747e6dSmrgvoid 690ffd25bcaSmrgMyFont_ChangeGC(unsigned long fix_fore, unsigned long fix_back, 6913e747e6dSmrg MyFont *fix_font) 6923e747e6dSmrg{ 6933e747e6dSmrg Gcv.foreground = fix_fore; 6943e747e6dSmrg Gcv.background = fix_back; 6953e747e6dSmrg if (use_fontset) { 6963e747e6dSmrg XChangeGC(dpy, Scr->NormalGC, GCForeground|GCBackground, &Gcv); 6973e747e6dSmrg return; 6983e747e6dSmrg } 6993e747e6dSmrg Gcv.font = fix_font->font->fid; 7003e747e6dSmrg XChangeGC(dpy, Scr->NormalGC, GCFont|GCForeground|GCBackground,&Gcv); 7013e747e6dSmrg} 7023e747e6dSmrg 7033e747e6dSmrg/* 7043e747e6dSmrg * The following functions are internationalized substitutions 7053e747e6dSmrg * for XFetchName and XGetIconName using XGetWMName and 706ffd25bcaSmrg * XGetWMIconName. 7073e747e6dSmrg * 708ffd25bcaSmrg * Please note that the third arguments have to be freed using free(), 7093e747e6dSmrg * not XFree(). 7103e747e6dSmrg */ 7113e747e6dSmrgStatus 7123e747e6dSmrgI18N_FetchName(Display *dpy, Window w, char **winname) 7133e747e6dSmrg{ 7143e747e6dSmrg int status; 7153e747e6dSmrg XTextProperty text_prop; 7163e747e6dSmrg char **list; 7173e747e6dSmrg int num; 718ffd25bcaSmrg 7193e747e6dSmrg status = XGetWMName(dpy, w, &text_prop); 7203e747e6dSmrg if (!status || !text_prop.value || !text_prop.nitems) { 7213e747e6dSmrg *winname = NULL; 7223e747e6dSmrg return 0; 7233e747e6dSmrg } 7243e747e6dSmrg status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num); 7253e747e6dSmrg if (status < Success || !num || !*list) { 726ffd25bcaSmrg *winname = NULL; 7273e747e6dSmrg return 0; 7283e747e6dSmrg } 7293e747e6dSmrg XFree(text_prop.value); 7303e747e6dSmrg *winname = (char *)strdup(*list); 7313e747e6dSmrg XFreeStringList(list); 7323e747e6dSmrg return 1; 7333e747e6dSmrg} 7343e747e6dSmrg 7353e747e6dSmrgStatus 7363e747e6dSmrgI18N_GetIconName(Display *dpy, Window w, char **iconname) 7373e747e6dSmrg{ 7383e747e6dSmrg int status; 7393e747e6dSmrg XTextProperty text_prop; 7403e747e6dSmrg char **list; 7413e747e6dSmrg int num; 742ffd25bcaSmrg 7433e747e6dSmrg status = XGetWMIconName(dpy, w, &text_prop); 7443e747e6dSmrg if (!status || !text_prop.value || !text_prop.nitems) return 0; 7453e747e6dSmrg status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num); 7463e747e6dSmrg if (status < Success || !num || !*list) return 0; 7473e747e6dSmrg XFree(text_prop.value); 7483e747e6dSmrg *iconname = (char *)strdup(*list); 7493e747e6dSmrg XFreeStringList(list); 7503e747e6dSmrg return 1; 7513e747e6dSmrg} 7523e747e6dSmrg 7533e747e6dSmrg/** 7543e747e6dSmrg * separate routine to set focus to make things more understandable 7553e747e6dSmrg * and easier to debug 7563e747e6dSmrg */ 7573e747e6dSmrgvoid 7583e747e6dSmrgSetFocus (TwmWindow *tmp_win, Time time) 7593e747e6dSmrg{ 7603e747e6dSmrg Window w = (tmp_win ? tmp_win->w : PointerRoot); 7613e747e6dSmrg 7623e747e6dSmrg#ifdef TRACE 7633e747e6dSmrg if (tmp_win) { 7643e747e6dSmrg printf ("Focusing on window \"%s\"\n", tmp_win->full_name); 7653e747e6dSmrg } else { 7663e747e6dSmrg printf ("Unfocusing; Scr->Focus was \"%s\"\n", 7673e747e6dSmrg Scr->Focus ? Scr->Focus->full_name : "(nil)"); 7683e747e6dSmrg } 7693e747e6dSmrg#endif 7703e747e6dSmrg 7713e747e6dSmrg XSetInputFocus (dpy, w, RevertToPointerRoot, time); 7723e747e6dSmrg} 7733e747e6dSmrg 774ffd25bcaSmrgstatic Pixmap 7753e747e6dSmrgCreateXLogoPixmap (unsigned *widthp, unsigned *heightp) 7763e747e6dSmrg{ 7773e747e6dSmrg int h = Scr->TBInfo.width - Scr->TBInfo.border * 2; 7783e747e6dSmrg if (h < 0) h = 0; 7793e747e6dSmrg 7803e747e6dSmrg *widthp = *heightp = (unsigned int) h; 7813e747e6dSmrg if (Scr->tbpm.xlogo == None) { 7823e747e6dSmrg GC gc, gcBack; 7833e747e6dSmrg 7843e747e6dSmrg Scr->tbpm.xlogo = XCreatePixmap (dpy, Scr->Root, h, h, 1); 7853e747e6dSmrg gc = XCreateGC (dpy, Scr->tbpm.xlogo, 0L, NULL); 7863e747e6dSmrg XSetForeground (dpy, gc, 0); 7873e747e6dSmrg XFillRectangle (dpy, Scr->tbpm.xlogo, gc, 0, 0, h, h); 7883e747e6dSmrg XSetForeground (dpy, gc, 1); 7893e747e6dSmrg gcBack = XCreateGC (dpy, Scr->tbpm.xlogo, 0L, NULL); 7903e747e6dSmrg XSetForeground (dpy, gcBack, 0); 7913e747e6dSmrg 7923e747e6dSmrg /* 7933e747e6dSmrg * draw the logo large so that it gets as dense as possible; then white 7943e747e6dSmrg * out the edges so that they look crisp 7953e747e6dSmrg */ 7963e747e6dSmrg XmuDrawLogo (dpy, Scr->tbpm.xlogo, gc, gcBack, -1, -1, h + 2, h + 2); 7973e747e6dSmrg XDrawRectangle (dpy, Scr->tbpm.xlogo, gcBack, 0, 0, h - 1, h - 1); 7983e747e6dSmrg 7993e747e6dSmrg /* 8003e747e6dSmrg * done drawing 8013e747e6dSmrg */ 8023e747e6dSmrg XFreeGC (dpy, gc); 8033e747e6dSmrg XFreeGC (dpy, gcBack); 8043e747e6dSmrg } 8053e747e6dSmrg return Scr->tbpm.xlogo; 8063e747e6dSmrg} 8073e747e6dSmrg 8083e747e6dSmrg 809ffd25bcaSmrgstatic Pixmap 8103e747e6dSmrgCreateResizePixmap (unsigned *widthp, unsigned *heightp) 8113e747e6dSmrg{ 8123e747e6dSmrg int h = Scr->TBInfo.width - Scr->TBInfo.border * 2; 8133e747e6dSmrg if (h < 1) h = 1; 8143e747e6dSmrg 8153e747e6dSmrg *widthp = *heightp = (unsigned int) h; 8163e747e6dSmrg if (Scr->tbpm.resize == None) { 8173e747e6dSmrg XPoint points[3]; 8183e747e6dSmrg GC gc; 8193e747e6dSmrg int w; 8203e747e6dSmrg int lw; 8213e747e6dSmrg 8223e747e6dSmrg /* 8233e747e6dSmrg * create the pixmap 8243e747e6dSmrg */ 8253e747e6dSmrg Scr->tbpm.resize = XCreatePixmap (dpy, Scr->Root, h, h, 1); 8263e747e6dSmrg gc = XCreateGC (dpy, Scr->tbpm.resize, 0L, NULL); 8273e747e6dSmrg XSetForeground (dpy, gc, 0); 8283e747e6dSmrg XFillRectangle (dpy, Scr->tbpm.resize, gc, 0, 0, h, h); 8293e747e6dSmrg XSetForeground (dpy, gc, 1); 8303e747e6dSmrg lw = h / 16; 8313e747e6dSmrg if (lw == 1) 8323e747e6dSmrg lw = 0; 8333e747e6dSmrg XSetLineAttributes (dpy, gc, lw, LineSolid, CapButt, JoinMiter); 8343e747e6dSmrg 8353e747e6dSmrg /* 836ffd25bcaSmrg * draw the resize button, 8373e747e6dSmrg */ 8383e747e6dSmrg w = (h * 2) / 3; 8393e747e6dSmrg points[0].x = w; 8403e747e6dSmrg points[0].y = 0; 8413e747e6dSmrg points[1].x = w; 8423e747e6dSmrg points[1].y = w; 8433e747e6dSmrg points[2].x = 0; 8443e747e6dSmrg points[2].y = w; 8453e747e6dSmrg XDrawLines (dpy, Scr->tbpm.resize, gc, points, 3, CoordModeOrigin); 8463e747e6dSmrg w = w / 2; 8473e747e6dSmrg points[0].x = w; 8483e747e6dSmrg points[0].y = 0; 8493e747e6dSmrg points[1].x = w; 8503e747e6dSmrg points[1].y = w; 8513e747e6dSmrg points[2].x = 0; 8523e747e6dSmrg points[2].y = w; 8533e747e6dSmrg XDrawLines (dpy, Scr->tbpm.resize, gc, points, 3, CoordModeOrigin); 8543e747e6dSmrg 8553e747e6dSmrg /* 8563e747e6dSmrg * done drawing 8573e747e6dSmrg */ 8583e747e6dSmrg XFreeGC(dpy, gc); 8593e747e6dSmrg } 8603e747e6dSmrg return Scr->tbpm.resize; 8613e747e6dSmrg} 8623e747e6dSmrg 8633e747e6dSmrg 864ffd25bcaSmrgstatic Pixmap 8653e747e6dSmrgCreateDotPixmap (unsigned *widthp, unsigned *heightp) 8663e747e6dSmrg{ 8673e747e6dSmrg int h = Scr->TBInfo.width - Scr->TBInfo.border * 2; 8683e747e6dSmrg 8693e747e6dSmrg h = h * 3 / 4; 8703e747e6dSmrg if (h < 1) h = 1; 8713e747e6dSmrg if (!(h & 1)) 8723e747e6dSmrg h--; 8733e747e6dSmrg *widthp = *heightp = (unsigned int) h; 8743e747e6dSmrg if (Scr->tbpm.delete == None) { 8753e747e6dSmrg GC gc; 8763e747e6dSmrg Pixmap pix; 8773e747e6dSmrg 8783e747e6dSmrg pix = Scr->tbpm.delete = XCreatePixmap (dpy, Scr->Root, h, h, 1); 8793e747e6dSmrg gc = XCreateGC (dpy, pix, 0L, NULL); 8803e747e6dSmrg XSetLineAttributes (dpy, gc, h, LineSolid, CapRound, JoinRound); 8813e747e6dSmrg XSetForeground (dpy, gc, 0L); 8823e747e6dSmrg XFillRectangle (dpy, pix, gc, 0, 0, h, h); 8833e747e6dSmrg XSetForeground (dpy, gc, 1L); 8843e747e6dSmrg XDrawLine (dpy, pix, gc, h/2, h/2, h/2, h/2); 8853e747e6dSmrg XFreeGC (dpy, gc); 8863e747e6dSmrg } 8873e747e6dSmrg return Scr->tbpm.delete; 8883e747e6dSmrg} 8893e747e6dSmrg 8903e747e6dSmrg#define questionmark_width 8 8913e747e6dSmrg#define questionmark_height 8 8923e747e6dSmrgstatic char questionmark_bits[] = { 8933e747e6dSmrg 0x38, 0x7c, 0x64, 0x30, 0x18, 0x00, 0x18, 0x18}; 8943e747e6dSmrg 895ffd25bcaSmrgstatic Pixmap 8963e747e6dSmrgCreateQuestionPixmap (unsigned *widthp, unsigned *heightp) 8973e747e6dSmrg{ 8983e747e6dSmrg *widthp = questionmark_width; 8993e747e6dSmrg *heightp = questionmark_height; 9003e747e6dSmrg if (Scr->tbpm.question == None) { 9013e747e6dSmrg Scr->tbpm.question = XCreateBitmapFromData (dpy, Scr->Root, 9023e747e6dSmrg questionmark_bits, 9033e747e6dSmrg questionmark_width, 9043e747e6dSmrg questionmark_height); 9053e747e6dSmrg } 9063e747e6dSmrg /* 9073e747e6dSmrg * this must succeed or else we are in deep trouble elsewhere 9083e747e6dSmrg */ 9093e747e6dSmrg return Scr->tbpm.question; 9103e747e6dSmrg} 9113e747e6dSmrg 9123e747e6dSmrg 913ffd25bcaSmrgstatic Pixmap 9143e747e6dSmrgCreateMenuPixmap (unsigned *widthp, unsigned *heightp) 9153e747e6dSmrg{ 9163e747e6dSmrg return CreateMenuIcon (Scr->TBInfo.width - Scr->TBInfo.border * 2, 9173e747e6dSmrg widthp,heightp); 9183e747e6dSmrg} 9193e747e6dSmrg 920ffd25bcaSmrgPixmap 9213e747e6dSmrgCreateMenuIcon (int height, unsigned *widthp, unsigned *heightp) 9223e747e6dSmrg{ 9233e747e6dSmrg int h, w; 9243e747e6dSmrg int ih, iw; 9253e747e6dSmrg int ix, iy; 9263e747e6dSmrg int mh, mw; 9273e747e6dSmrg int tw, th; 9283e747e6dSmrg int lw, lh; 9293e747e6dSmrg int lx, ly; 9303e747e6dSmrg int lines, dly; 9313e747e6dSmrg int off; 9323e747e6dSmrg int bw; 9333e747e6dSmrg 9343e747e6dSmrg h = height; 9353e747e6dSmrg w = h * 7 / 8; 9363e747e6dSmrg if (h < 1) 9373e747e6dSmrg h = 1; 9383e747e6dSmrg if (w < 1) 9393e747e6dSmrg w = 1; 9403e747e6dSmrg *widthp = w; 9413e747e6dSmrg *heightp = h; 9423e747e6dSmrg if (Scr->tbpm.menu == None) { 9433e747e6dSmrg Pixmap pix; 9443e747e6dSmrg GC gc; 9453e747e6dSmrg 9463e747e6dSmrg pix = Scr->tbpm.menu = XCreatePixmap (dpy, Scr->Root, w, h, 1); 9473e747e6dSmrg gc = XCreateGC (dpy, pix, 0L, NULL); 9483e747e6dSmrg XSetForeground (dpy, gc, 0L); 9493e747e6dSmrg XFillRectangle (dpy, pix, gc, 0, 0, w, h); 9503e747e6dSmrg XSetForeground (dpy, gc, 1L); 9513e747e6dSmrg ix = 1; 9523e747e6dSmrg iy = 1; 9533e747e6dSmrg ih = h - iy * 2; 9543e747e6dSmrg iw = w - ix * 2; 9553e747e6dSmrg off = ih / 8; 9563e747e6dSmrg mh = ih - off; 9573e747e6dSmrg mw = iw - off; 9583e747e6dSmrg bw = mh / 16; 9593e747e6dSmrg if (bw == 0 && mw > 2) 9603e747e6dSmrg bw = 1; 9613e747e6dSmrg tw = mw - bw * 2; 9623e747e6dSmrg th = mh - bw * 2; 9633e747e6dSmrg XFillRectangle (dpy, pix, gc, ix, iy, mw, mh); 9643e747e6dSmrg XFillRectangle (dpy, pix, gc, ix + iw - mw, iy + ih - mh, mw, mh); 9653e747e6dSmrg XSetForeground (dpy, gc, 0L); 9663e747e6dSmrg XFillRectangle (dpy, pix, gc, ix+bw, iy+bw, tw, th); 9673e747e6dSmrg XSetForeground (dpy, gc, 1L); 9683e747e6dSmrg lw = tw / 2; 9693e747e6dSmrg if ((tw & 1) ^ (lw & 1)) 9703e747e6dSmrg lw++; 9713e747e6dSmrg lx = ix + bw + (tw - lw) / 2; 9723e747e6dSmrg 9733e747e6dSmrg lh = th / 2 - bw; 9743e747e6dSmrg if ((lh & 1) ^ ((th - bw) & 1)) 9753e747e6dSmrg lh++; 9763e747e6dSmrg ly = iy + bw + (th - bw - lh) / 2; 9773e747e6dSmrg 9783e747e6dSmrg lines = 3; 9793e747e6dSmrg if ((lh & 1) && lh < 6) 9803e747e6dSmrg { 9813e747e6dSmrg lines--; 9823e747e6dSmrg } 9833e747e6dSmrg dly = lh / (lines - 1); 9843e747e6dSmrg while (lines--) 9853e747e6dSmrg { 9863e747e6dSmrg XFillRectangle (dpy, pix, gc, lx, ly, lw, bw); 9873e747e6dSmrg ly += dly; 9883e747e6dSmrg } 9893e747e6dSmrg XFreeGC (dpy, gc); 9903e747e6dSmrg } 9913e747e6dSmrg return Scr->tbpm.menu; 9923e747e6dSmrg} 9933e747e6dSmrg 9943e747e6dSmrgvoid 9953e747e6dSmrgBell(int type, int percent, Window win) 9963e747e6dSmrg{ 9973e747e6dSmrg#ifdef XKB 9983e747e6dSmrg XkbStdBell(dpy, win, percent, type); 9993e747e6dSmrg#else 10003e747e6dSmrg XBell(dpy, percent); 10013e747e6dSmrg#endif 10023e747e6dSmrg return; 10033e747e6dSmrg} 1004