From 03cb750f7935722ab77b77128ca5221c5baf8818 Mon Sep 17 00:00:00 2001 From: Kaleb Keithley Date: Fri, 14 Nov 2003 15:54:53 +0000 Subject: R6.6 is the Xorg base-line --- src/util.c | 959 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 959 insertions(+) create mode 100644 src/util.c (limited to 'src/util.c') diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..0082a4d --- /dev/null +++ b/src/util.c @@ -0,0 +1,959 @@ +/*****************************************************************************/ +/* + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** name of Evans & Sutherland not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND DISCLAIMs ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND **/ +/** BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $Xorg: util.c,v 1.5 2001/02/09 02:05:37 xorgcvs Exp $ + * + * utility routines for twm + * + * 28-Oct-87 Thomas E. LaStrange File created + * + ***********************************************************************/ + +#include "twm.h" +#include "util.h" +#include "gram.h" +#include "screen.h" +#include +#include +#include +#include +#include + +static Pixmap CreateXLogoPixmap(), CreateResizePixmap(); +static Pixmap CreateQuestionPixmap(), CreateMenuPixmap(); +static Pixmap CreateDotPixmap(); +int HotX, HotY; + +/*********************************************************************** + * + * Procedure: + * MoveOutline - move a window outline + * + * Inputs: + * root - the window we are outlining + * x - upper left x coordinate + * y - upper left y coordinate + * width - the width of the rectangle + * height - the height of the rectangle + * bw - the border width of the frame + * th - title height + * + *********************************************************************** + */ + +/* ARGSUSED */ +void MoveOutline(root, x, y, width, height, bw, th) + Window root; + int x, y, width, height, bw, th; +{ + static int lastx = 0; + static int lasty = 0; + static int lastWidth = 0; + static int lastHeight = 0; + static int lastBW = 0; + static int lastTH = 0; + int xl, xr, yt, yb, xinnerl, xinnerr, yinnert, yinnerb; + int xthird, ythird; + XSegment outline[18]; + register XSegment *r; + + if (x == lastx && y == lasty && width == lastWidth && height == lastHeight + && lastBW == bw && th == lastTH) + return; + + r = outline; + +#define DRAWIT() \ + if (lastWidth || lastHeight) \ + { \ + xl = lastx; \ + xr = lastx + lastWidth - 1; \ + yt = lasty; \ + yb = lasty + lastHeight - 1; \ + xinnerl = xl + lastBW; \ + xinnerr = xr - lastBW; \ + yinnert = yt + lastTH + lastBW; \ + yinnerb = yb - lastBW; \ + xthird = (xinnerr - xinnerl) / 3; \ + ythird = (yinnerb - yinnert) / 3; \ + \ + r->x1 = xl; \ + r->y1 = yt; \ + r->x2 = xr; \ + r->y2 = yt; \ + r++; \ + \ + r->x1 = xl; \ + r->y1 = yb; \ + r->x2 = xr; \ + r->y2 = yb; \ + r++; \ + \ + r->x1 = xl; \ + r->y1 = yt; \ + r->x2 = xl; \ + r->y2 = yb; \ + r++; \ + \ + r->x1 = xr; \ + r->y1 = yt; \ + r->x2 = xr; \ + r->y2 = yb; \ + r++; \ + \ + r->x1 = xinnerl + xthird; \ + r->y1 = yinnert; \ + r->x2 = r->x1; \ + r->y2 = yinnerb; \ + r++; \ + \ + r->x1 = xinnerl + (2 * xthird); \ + r->y1 = yinnert; \ + r->x2 = r->x1; \ + r->y2 = yinnerb; \ + r++; \ + \ + r->x1 = xinnerl; \ + r->y1 = yinnert + ythird; \ + r->x2 = xinnerr; \ + r->y2 = r->y1; \ + r++; \ + \ + r->x1 = xinnerl; \ + r->y1 = yinnert + (2 * ythird); \ + r->x2 = xinnerr; \ + r->y2 = r->y1; \ + r++; \ + \ + if (lastTH != 0) { \ + r->x1 = xl; \ + r->y1 = yt + lastTH; \ + r->x2 = xr; \ + r->y2 = r->y1; \ + r++; \ + } \ + } + + /* undraw the old one, if any */ + DRAWIT (); + + lastx = x; + lasty = y; + lastWidth = width; + lastHeight = height; + lastBW = bw; + lastTH = th; + + /* draw the new one, if any */ + DRAWIT (); + +#undef DRAWIT + + + if (r != outline) + { + XDrawSegments(dpy, root, Scr->DrawGC, outline, r - outline); + } +} + +/*********************************************************************** + * + * Procedure: + * Zoom - zoom in or out of an icon + * + * Inputs: + * wf - window to zoom from + * wt - window to zoom to + * + *********************************************************************** + */ + +void +Zoom(wf, wt) + Window wf, wt; +{ + int fx, fy, tx, ty; /* from, to */ + unsigned int fw, fh, tw, th; /* from, to */ + long dx, dy, dw, dh; + long z; + int j; + + if (!Scr->DoZoom || Scr->ZoomCount < 1) return; + + if (wf == None || wt == None) return; + + XGetGeometry (dpy, wf, &JunkRoot, &fx, &fy, &fw, &fh, &JunkBW, &JunkDepth); + XGetGeometry (dpy, wt, &JunkRoot, &tx, &ty, &tw, &th, &JunkBW, &JunkDepth); + + dx = ((long) (tx - fx)); /* going from -> to */ + dy = ((long) (ty - fy)); /* going from -> to */ + dw = ((long) (tw - fw)); /* going from -> to */ + dh = ((long) (th - fh)); /* going from -> to */ + z = (long) (Scr->ZoomCount + 1); + + for (j = 0; j < 2; j++) { + long i; + + XDrawRectangle (dpy, Scr->Root, Scr->DrawGC, fx, fy, fw, fh); + for (i = 1; i < z; i++) { + int x = fx + (int) ((dx * i) / z); + int y = fy + (int) ((dy * i) / z); + unsigned width = (unsigned) (((long) fw) + (dw * i) / z); + unsigned height = (unsigned) (((long) fh) + (dh * i) / z); + + XDrawRectangle (dpy, Scr->Root, Scr->DrawGC, + x, y, width, height); + } + XDrawRectangle (dpy, Scr->Root, Scr->DrawGC, tx, ty, tw, th); + } +} + + +/*********************************************************************** + * + * Procedure: + * ExpandFilename - expand the tilde character to HOME + * if it is the first character of the filename + * + * Returned Value: + * a pointer to the new name + * + * Inputs: + * name - the filename to expand + * + *********************************************************************** + */ + +char * +ExpandFilename(name) +char *name; +{ + char *newname; + + if (name[0] != '~') return name; + + newname = (char *) malloc (HomeLen + strlen(name) + 2); + if (!newname) { + fprintf (stderr, + "%s: unable to allocate %d bytes to expand filename %s/%s\n", + ProgramName, HomeLen + strlen(name) + 2, Home, &name[1]); + } else { + (void) sprintf (newname, "%s/%s", Home, &name[1]); + } + + return newname; +} + +/*********************************************************************** + * + * Procedure: + * GetUnknownIcon - read in the bitmap file for the unknown icon + * + * Inputs: + * name - the filename to read + * + *********************************************************************** + */ + +void +GetUnknownIcon(name) +char *name; +{ + if ((Scr->UnknownPm = GetBitmap(name)) != None) + { + XGetGeometry(dpy, Scr->UnknownPm, &JunkRoot, &JunkX, &JunkY, + (unsigned int *)&Scr->UnknownWidth, (unsigned int *)&Scr->UnknownHeight, &JunkBW, &JunkDepth); + } +} + +/*********************************************************************** + * + * Procedure: + * FindBitmap - read in a bitmap file and return size + * + * Returned Value: + * the pixmap associated with the bitmap + * widthp - pointer to width of bitmap + * heightp - pointer to height of bitmap + * + * Inputs: + * name - the filename to read + * + *********************************************************************** + */ + +Pixmap FindBitmap (name, widthp, heightp) + char *name; + unsigned int *widthp, *heightp; +{ + char *bigname; + Pixmap pm; + + if (!name) return None; + + /* + * Names of the form :name refer to hardcoded images that are scaled to + * look nice in title buttons. Eventually, it would be nice to put in a + * menu symbol as well.... + */ + if (name[0] == ':') { + int i; + static struct { + char *name; + Pixmap (*proc)(); + } pmtab[] = { + { TBPM_DOT, CreateDotPixmap }, + { TBPM_ICONIFY, CreateDotPixmap }, + { TBPM_RESIZE, CreateResizePixmap }, + { TBPM_XLOGO, CreateXLogoPixmap }, + { TBPM_DELETE, CreateXLogoPixmap }, + { TBPM_MENU, CreateMenuPixmap }, + { TBPM_QUESTION, CreateQuestionPixmap }, + }; + + for (i = 0; i < (sizeof pmtab)/(sizeof pmtab[0]); i++) { + if (XmuCompareISOLatin1 (pmtab[i].name, name) == 0) + return (*pmtab[i].proc) (widthp, heightp); + } + fprintf (stderr, "%s: no such built-in bitmap \"%s\"\n", + ProgramName, name); + return None; + } + + /* + * Generate a full pathname if any special prefix characters (such as ~) + * are used. If the bigname is different from name, bigname will need to + * be freed. + */ + bigname = ExpandFilename (name); + if (!bigname) return None; + + /* + * look along bitmapFilePath resource same as toolkit clients + */ + pm = XmuLocateBitmapFile (ScreenOfDisplay(dpy, Scr->screen), bigname, NULL, + 0, (int *)widthp, (int *)heightp, &HotX, &HotY); + if (pm == None && Scr->IconDirectory && bigname[0] != '/') { + if (bigname != name) free (bigname); + /* + * Attempt to find icon in old IconDirectory (now obsolete) + */ + bigname = (char *) malloc (strlen(name) + strlen(Scr->IconDirectory) + + 2); + if (!bigname) { + fprintf (stderr, + "%s: unable to allocate memory for \"%s/%s\"\n", + ProgramName, Scr->IconDirectory, name); + return None; + } + (void) sprintf (bigname, "%s/%s", Scr->IconDirectory, name); + if (XReadBitmapFile (dpy, Scr->Root, bigname, widthp, heightp, &pm, + &HotX, &HotY) != BitmapSuccess) { + pm = None; + } + } + if (bigname != name) free (bigname); + if (pm == None) { + fprintf (stderr, "%s: unable to find bitmap \"%s\"\n", + ProgramName, name); + } + + return pm; +} + +Pixmap GetBitmap (name) + char *name; +{ + return FindBitmap (name, &JunkWidth, &JunkHeight); +} + + +InsertRGBColormap (a, maps, nmaps, replace) + Atom a; + XStandardColormap *maps; + int nmaps; + Bool replace; +{ + StdCmap *sc = NULL; + + if (replace) { /* locate existing entry */ + for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) { + if (sc->atom == a) break; + } + } + + if (!sc) { /* no existing, allocate new */ + sc = (StdCmap *) malloc (sizeof (StdCmap)); + if (!sc) { + fprintf (stderr, "%s: unable to allocate %d bytes for StdCmap\n", + ProgramName, sizeof (StdCmap)); + return; + } + } + + if (replace) { /* just update contents */ + if (sc->maps) XFree ((char *) maps); + if (sc == Scr->StdCmapInfo.mru) Scr->StdCmapInfo.mru = NULL; + } else { /* else appending */ + sc->next = NULL; + sc->atom = a; + if (Scr->StdCmapInfo.tail) { + Scr->StdCmapInfo.tail->next = sc; + } else { + Scr->StdCmapInfo.head = sc; + } + Scr->StdCmapInfo.tail = sc; + } + sc->nmaps = nmaps; + sc->maps = maps; + + return; +} + +RemoveRGBColormap (a) + Atom a; +{ + StdCmap *sc, *prev; + + prev = NULL; + for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) { + if (sc->atom == a) break; + prev = sc; + } + if (sc) { /* found one */ + if (sc->maps) XFree ((char *) sc->maps); + if (prev) prev->next = sc->next; + if (Scr->StdCmapInfo.head == sc) Scr->StdCmapInfo.head = sc->next; + if (Scr->StdCmapInfo.tail == sc) Scr->StdCmapInfo.tail = prev; + if (Scr->StdCmapInfo.mru == sc) Scr->StdCmapInfo.mru = NULL; + } + return; +} + +LocateStandardColormaps() +{ + Atom *atoms; + int natoms; + int i; + + atoms = XListProperties (dpy, Scr->Root, &natoms); + for (i = 0; i < natoms; i++) { + XStandardColormap *maps = NULL; + int nmaps; + + if (XGetRGBColormaps (dpy, Scr->Root, &maps, &nmaps, atoms[i])) { + /* if got one, then append to current list */ + InsertRGBColormap (atoms[i], maps, nmaps, False); + } + } + if (atoms) XFree ((char *) atoms); + return; +} + +GetColor(kind, what, name) +int kind; +Pixel *what; +char *name; +{ + XColor color, junkcolor; + Status stat = 0; + Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c; + +#ifndef TOM + if (!Scr->FirstTime) + return; +#endif + + if (Scr->Monochrome != kind) + return; + + if (!XAllocNamedColor (dpy, cmap, name, &color, &junkcolor)) + { + /* if we could not allocate the color, let's see if this is a + * standard colormap + */ + XStandardColormap *stdcmap = NULL; + + /* parse the named color */ + if (name[0] != '#') + stat = XParseColor (dpy, cmap, name, &color); + if (!stat) + { + fprintf (stderr, "%s: invalid color name \"%s\"\n", + ProgramName, name); + return; + } + + /* + * look through the list of standard colormaps (check cache first) + */ + if (Scr->StdCmapInfo.mru && Scr->StdCmapInfo.mru->maps && + (Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex].colormap == + cmap)) { + stdcmap = &(Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex]); + } else { + StdCmap *sc; + + for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) { + int i; + + for (i = 0; i < sc->nmaps; i++) { + if (sc->maps[i].colormap == cmap) { + Scr->StdCmapInfo.mru = sc; + Scr->StdCmapInfo.mruindex = i; + stdcmap = &(sc->maps[i]); + goto gotit; + } + } + } + } + + gotit: + if (stdcmap) { + color.pixel = (stdcmap->base_pixel + + ((Pixel)(((float)color.red / 65535.0) * + stdcmap->red_max + 0.5) * + stdcmap->red_mult) + + ((Pixel)(((float)color.green /65535.0) * + stdcmap->green_max + 0.5) * + stdcmap->green_mult) + + ((Pixel)(((float)color.blue / 65535.0) * + stdcmap->blue_max + 0.5) * + stdcmap->blue_mult)); + } else { + fprintf (stderr, "%s: unable to allocate color \"%s\"\n", + ProgramName, name); + return; + } + } + + *what = color.pixel; +} + +GetColorValue(kind, what, name) +int kind; +XColor *what; +char *name; +{ + XColor junkcolor; + Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c; + +#ifndef TOM + if (!Scr->FirstTime) + return; +#endif + + if (Scr->Monochrome != kind) + return; + + if (!XLookupColor (dpy, cmap, name, what, &junkcolor)) + { + fprintf (stderr, "%s: invalid color name \"%s\"\n", + ProgramName, name); + } + else + { + what->pixel = AllPlanes; + } +} + +GetFont(font) +MyFont *font; +{ + char *deffontname = "fixed"; + + if (font->font != NULL) + XFreeFont(dpy, font->font); + + if ((font->font = XLoadQueryFont(dpy, font->name)) == NULL) + { + if (Scr->DefaultFont.name) { + deffontname = Scr->DefaultFont.name; + } + if ((font->font = XLoadQueryFont(dpy, deffontname)) == NULL) + { + fprintf (stderr, "%s: unable to open fonts \"%s\" or \"%s\"\n", + ProgramName, font->name, deffontname); + exit(1); + } + + } + font->height = font->font->ascent + font->font->descent; + font->y = font->font->ascent; +} + + +/* + * SetFocus - separate routine to set focus to make things more understandable + * and easier to debug + */ +SetFocus (tmp_win, time) + TwmWindow *tmp_win; + Time time; +{ + Window w = (tmp_win ? tmp_win->w : PointerRoot); + +#ifdef TRACE + if (tmp_win) { + printf ("Focusing on window \"%s\"\n", tmp_win->full_name); + } else { + printf ("Unfocusing; Scr->Focus was \"%s\"\n", + Scr->Focus ? Scr->Focus->full_name : "(nil)"); + } +#endif + + XSetInputFocus (dpy, w, RevertToPointerRoot, time); +} + + +#ifdef NOPUTENV +/* + * define our own putenv() if the system doesn't have one. + * putenv(s): place s (a string of the form "NAME=value") in + * the environment; replacing any existing NAME. s is placed in + * environment, so if you change s, the environment changes (like + * putenv on a sun). Binding removed if you putenv something else + * called NAME. + */ +int +putenv(s) + char *s; +{ + char *v; + int varlen, idx; + extern char **environ; + char **newenv; + static int virgin = 1; /* true while "environ" is a virgin */ + + v = index(s, '='); + if(v == 0) + return 0; /* punt if it's not of the right form */ + varlen = (v + 1) - s; + + for (idx = 0; environ[idx] != 0; idx++) { + if (strncmp(environ[idx], s, varlen) == 0) { + if(v[1] != 0) { /* true if there's a value */ + environ[idx] = s; + return 0; + } else { + do { + environ[idx] = environ[idx+1]; + } while(environ[++idx] != 0); + return 0; + } + } + } + + /* add to environment (unless no value; then just return) */ + if(v[1] == 0) + return 0; + if(virgin) { + register i; + + newenv = (char **) malloc((unsigned) ((idx + 2) * sizeof(char*))); + if(newenv == 0) + return -1; + for(i = idx-1; i >= 0; --i) + newenv[i] = environ[i]; + virgin = 0; /* you're not a virgin anymore, sweety */ + } else { + newenv = (char **) realloc((char *) environ, + (unsigned) ((idx + 2) * sizeof(char*))); + if (newenv == 0) + return -1; + } + + environ = newenv; + environ[idx] = s; + environ[idx+1] = 0; + + return 0; +} +#endif /* NOPUTENV */ + + +static Pixmap CreateXLogoPixmap (widthp, heightp) + unsigned int *widthp, *heightp; +{ + int h = Scr->TBInfo.width - Scr->TBInfo.border * 2; + if (h < 0) h = 0; + + *widthp = *heightp = (unsigned int) h; + if (Scr->tbpm.xlogo == None) { + GC gc, gcBack; + + Scr->tbpm.xlogo = XCreatePixmap (dpy, Scr->Root, h, h, 1); + gc = XCreateGC (dpy, Scr->tbpm.xlogo, 0L, NULL); + XSetForeground (dpy, gc, 0); + XFillRectangle (dpy, Scr->tbpm.xlogo, gc, 0, 0, h, h); + XSetForeground (dpy, gc, 1); + gcBack = XCreateGC (dpy, Scr->tbpm.xlogo, 0L, NULL); + XSetForeground (dpy, gcBack, 0); + + /* + * draw the logo large so that it gets as dense as possible; then white + * out the edges so that they look crisp + */ + XmuDrawLogo (dpy, Scr->tbpm.xlogo, gc, gcBack, -1, -1, h + 2, h + 2); + XDrawRectangle (dpy, Scr->tbpm.xlogo, gcBack, 0, 0, h - 1, h - 1); + + /* + * done drawing + */ + XFreeGC (dpy, gc); + XFreeGC (dpy, gcBack); + } + return Scr->tbpm.xlogo; +} + + +static Pixmap CreateResizePixmap (widthp, heightp) + unsigned int *widthp, *heightp; +{ + int h = Scr->TBInfo.width - Scr->TBInfo.border * 2; + if (h < 1) h = 1; + + *widthp = *heightp = (unsigned int) h; + if (Scr->tbpm.resize == None) { + XPoint points[3]; + GC gc; + int w; + int lw; + + /* + * create the pixmap + */ + Scr->tbpm.resize = XCreatePixmap (dpy, Scr->Root, h, h, 1); + gc = XCreateGC (dpy, Scr->tbpm.resize, 0L, NULL); + XSetForeground (dpy, gc, 0); + XFillRectangle (dpy, Scr->tbpm.resize, gc, 0, 0, h, h); + XSetForeground (dpy, gc, 1); + lw = h / 16; + if (lw == 1) + lw = 0; + XSetLineAttributes (dpy, gc, lw, LineSolid, CapButt, JoinMiter); + + /* + * draw the resize button, + */ + w = (h * 2) / 3; + points[0].x = w; + points[0].y = 0; + points[1].x = w; + points[1].y = w; + points[2].x = 0; + points[2].y = w; + XDrawLines (dpy, Scr->tbpm.resize, gc, points, 3, CoordModeOrigin); + w = w / 2; + points[0].x = w; + points[0].y = 0; + points[1].x = w; + points[1].y = w; + points[2].x = 0; + points[2].y = w; + XDrawLines (dpy, Scr->tbpm.resize, gc, points, 3, CoordModeOrigin); + + /* + * done drawing + */ + XFreeGC(dpy, gc); + } + return Scr->tbpm.resize; +} + + +static Pixmap CreateDotPixmap (widthp, heightp) + unsigned int *widthp, *heightp; +{ + int h = Scr->TBInfo.width - Scr->TBInfo.border * 2; + + h = h * 3 / 4; + if (h < 1) h = 1; + if (!(h & 1)) + h--; + *widthp = *heightp = (unsigned int) h; + if (Scr->tbpm.delete == None) { + GC gc; + Pixmap pix; + + pix = Scr->tbpm.delete = XCreatePixmap (dpy, Scr->Root, h, h, 1); + gc = XCreateGC (dpy, pix, 0L, NULL); + XSetLineAttributes (dpy, gc, h, LineSolid, CapRound, JoinRound); + XSetForeground (dpy, gc, 0L); + XFillRectangle (dpy, pix, gc, 0, 0, h, h); + XSetForeground (dpy, gc, 1L); + XDrawLine (dpy, pix, gc, h/2, h/2, h/2, h/2); + XFreeGC (dpy, gc); + } + return Scr->tbpm.delete; +} + +#define questionmark_width 8 +#define questionmark_height 8 +static char questionmark_bits[] = { + 0x38, 0x7c, 0x64, 0x30, 0x18, 0x00, 0x18, 0x18}; + +static Pixmap CreateQuestionPixmap (widthp, heightp) + unsigned int *widthp, *heightp; +{ + *widthp = questionmark_width; + *heightp = questionmark_height; + if (Scr->tbpm.question == None) { + Scr->tbpm.question = XCreateBitmapFromData (dpy, Scr->Root, + questionmark_bits, + questionmark_width, + questionmark_height); + } + /* + * this must succeed or else we are in deep trouble elsewhere + */ + return Scr->tbpm.question; +} + + +static Pixmap CreateMenuPixmap (widthp, heightp) + int *widthp, *heightp; +{ + return CreateMenuIcon (Scr->TBInfo.width - Scr->TBInfo.border * 2, + widthp,heightp); +} + +Pixmap CreateMenuIcon (height, widthp, heightp) + int height; + int *widthp, *heightp; +{ + int h, w; + int ih, iw; + int ix, iy; + int mh, mw; + int tw, th; + int lw, lh; + int lx, ly; + int lines, dly; + int off; + int bw; + + h = height; + w = h * 7 / 8; + if (h < 1) + h = 1; + if (w < 1) + w = 1; + *widthp = w; + *heightp = h; + if (Scr->tbpm.menu == None) { + Pixmap pix; + GC gc; + + pix = Scr->tbpm.menu = XCreatePixmap (dpy, Scr->Root, w, h, 1); + gc = XCreateGC (dpy, pix, 0L, NULL); + XSetForeground (dpy, gc, 0L); + XFillRectangle (dpy, pix, gc, 0, 0, w, h); + XSetForeground (dpy, gc, 1L); + ix = 1; + iy = 1; + ih = h - iy * 2; + iw = w - ix * 2; + off = ih / 8; + mh = ih - off; + mw = iw - off; + bw = mh / 16; + if (bw == 0 && mw > 2) + bw = 1; + tw = mw - bw * 2; + th = mh - bw * 2; + XFillRectangle (dpy, pix, gc, ix, iy, mw, mh); + XFillRectangle (dpy, pix, gc, ix + iw - mw, iy + ih - mh, mw, mh); + XSetForeground (dpy, gc, 0L); + XFillRectangle (dpy, pix, gc, ix+bw, iy+bw, tw, th); + XSetForeground (dpy, gc, 1L); + lw = tw / 2; + if ((tw & 1) ^ (lw & 1)) + lw++; + lx = ix + bw + (tw - lw) / 2; + + lh = th / 2 - bw; + if ((lh & 1) ^ ((th - bw) & 1)) + lh++; + ly = iy + bw + (th - bw - lh) / 2; + + lines = 3; + if ((lh & 1) && lh < 6) + { + lines--; + } + dly = lh / (lines - 1); + while (lines--) + { + XFillRectangle (dpy, pix, gc, lx, ly, lw, bw); + ly += dly; + } + XFreeGC (dpy, gc); + } + return Scr->tbpm.menu; +} + +void +Bell(type,percent,win) + int type; + int percent; + Window win; +{ +#ifdef XKB + XkbStdBell(dpy, win, percent, type); +#else + XBell(dpy, percent); +#endif + return; +} -- cgit v1.2.3