#include "twm.h"
#include "util.h"
#include "gram.h"
#include "screen.h"
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <X11/Xmu/Drawing.h>
#include <X11/Xmu/CharSet.h>
static Pixmap CreateXLogoPixmap ( unsigned int *widthp,
unsigned int *heightp );
static Pixmap CreateResizePixmap ( unsigned int *widthp,
unsigned int *heightp );
static Pixmap CreateDotPixmap ( unsigned int *widthp,
unsigned int *heightp );
static Pixmap CreateQuestionPixmap ( unsigned int *widthp,
unsigned int *heightp );
static Pixmap CreateMenuPixmap ( unsigned int *widthp,
unsigned int *heightp );
int HotX, HotY;
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++; \
} \
}
DRAWIT ();
lastx = x;
lasty = y;
lastWidth = width;
lastHeight = height;
lastBW = bw;
lastTH = th;
DRAWIT ();
#undef DRAWIT
if (r != outline)
{
XDrawSegments(dpy, root, Scr->DrawGC, outline, r - outline);
}
}
void
Zoom(wf, wt)
Window wf, wt;
{
int fx, fy, tx, ty;
unsigned int fw, fh, tw, th;
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));
dy = ((long) (ty - fy));
dw = ((long) (tw - fw));
dh = ((long) (th - fh));
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);
}
}
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 %ld bytes to expand filename %s/%s\n",
ProgramName, HomeLen + (unsigned long)strlen(name) + 2,
Home, &name[1]);
} else {
(void) sprintf (newname, "%s/%s", Home, &name[1]);
}
return newname;
}
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);
}
}
Pixmap
FindBitmap (name, widthp, heightp)
char *name;
unsigned int *widthp, *heightp;
{
char *bigname;
Pixmap pm;
if (!name) return None;
if (name[0] == ':') {
int i;
static struct {
char *name;
Pixmap (*proc)(unsigned int *, unsigned int *);
} 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;
}
bigname = ExpandFilename (name);
if (!bigname) return None;
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);
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);
}
void
InsertRGBColormap (a, maps, nmaps, replace)
Atom a;
XStandardColormap *maps;
int nmaps;
Bool replace;
{
StdCmap *sc = NULL;
if (replace) {
for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) {
if (sc->atom == a) break;
}
}
if (!sc) {
sc = (StdCmap *) malloc (sizeof (StdCmap));
if (!sc) {
fprintf (stderr, "%s: unable to allocate %ld bytes for StdCmap\n",
ProgramName, (unsigned long)sizeof (StdCmap));
return;
}
}
if (replace) {
if (sc->maps) XFree ((char *) maps);
if (sc == Scr->StdCmapInfo.mru) Scr->StdCmapInfo.mru = NULL;
} else {
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;
}
void
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) {
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;
}
void
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])) {
InsertRGBColormap (atoms[i], maps, nmaps, False);
}
}
if (atoms) XFree ((char *) atoms);
return;
}
void
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))
{
XStandardColormap *stdcmap = NULL;
if (name[0] != '#')
stat = XParseColor (dpy, cmap, name, &color);
if (!stat)
{
fprintf (stderr, "%s: invalid color name \"%s\"\n",
ProgramName, name);
return;
}
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;
}
void
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;
}
}
void
GetFont(font)
MyFont *font;
{
char *deffontname = "fixed";
char **missing_charset_list_return;
int missing_charset_count_return;
char *def_string_return;
XFontSetExtents *font_extents;
XFontStruct **xfonts;
char **font_names;
register int i;
int ascent;
int descent;
int fnum;
char *basename2;
if (use_fontset) {
if (font->fontset != NULL){
XFreeFontSet(dpy, font->fontset);
}
basename2 = (char *)malloc(strlen(font->name) + 3);
if (basename2) sprintf(basename2, "%s,*", font->name);
else basename2 = font->name;
if( (font->fontset = XCreateFontSet(dpy, basename2,
&missing_charset_list_return,
&missing_charset_count_return,
&def_string_return)) == NULL) {
fprintf (stderr, "%s: unable to open fontset \"%s\"\n",
ProgramName, font->name);
exit(1);
}
if (basename2 != font->name) free(basename2);
for(i=0; i<missing_charset_count_return; i++){
printf("%s: warning: font for charset %s is lacking.\n",
ProgramName, missing_charset_list_return[i]);
}
font_extents = XExtentsOfFontSet(font->fontset);
fnum = XFontsOfFontSet(font->fontset, &xfonts, &font_names);
for( i = 0, ascent = 0, descent = 0; i<fnum; i++){
if (ascent < (*xfonts)->ascent) ascent = (*xfonts)->ascent;
if (descent < (*xfonts)->descent) descent = (*xfonts)->descent;
xfonts++;
}
font->height = font_extents->max_logical_extent.height;
font->y = ascent;
font->ascent = ascent;
font->descent = descent;
return;
}
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;
font->ascent = font->font->ascent;
font->descent = font->font->descent;
}
int
MyFont_TextWidth(font, string, len)
MyFont *font;
char *string;
int len;
{
XRectangle ink_rect;
XRectangle logical_rect;
if (use_fontset) {
XmbTextExtents(font->fontset, string, len,
&ink_rect, &logical_rect);
return logical_rect.width;
}
return XTextWidth(font->font, string, len);
}
void
MyFont_DrawImageString(dpy, d, font, gc, x, y, string, len)
Display *dpy;
Drawable d;
MyFont *font;
GC gc;
int x,y;
char *string;
int len;
{
if (use_fontset) {
XmbDrawImageString(dpy, d, font->fontset, gc, x, y, string, len);
return;
}
XDrawImageString (dpy, d, gc, x, y, string, len);
}
void
MyFont_DrawString(dpy, d, font, gc, x, y, string, len)
Display *dpy;
Drawable d;
MyFont *font;
GC gc;
int x,y;
char *string;
int len;
{
if (use_fontset) {
XmbDrawString(dpy, d, font->fontset, gc, x, y, string, len);
return;
}
XDrawString (dpy, d, gc, x, y, string, len);
}
void
MyFont_ChangeGC(fix_fore, fix_back, fix_font)
unsigned long fix_fore, fix_back;
MyFont *fix_font;
{
Gcv.foreground = fix_fore;
Gcv.background = fix_back;
if (use_fontset) {
XChangeGC(dpy, Scr->NormalGC, GCForeground|GCBackground, &Gcv);
return;
}
Gcv.font = fix_font->font->fid;
XChangeGC(dpy, Scr->NormalGC, GCFont|GCForeground|GCBackground,&Gcv);
}
Status
I18N_FetchName(dpy, w, winname)
Display *dpy;
Window w;
char ** winname;
{
int status;
XTextProperty text_prop;
char **list;
int num;
status = XGetWMName(dpy, w, &text_prop);
if (!status || !text_prop.value || !text_prop.nitems) {
*winname = NULL;
return 0;
}
status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num);
if (status < Success || !num || !*list) {
*winname = NULL;
return 0;
}
XFree(text_prop.value);
*winname = (char *)strdup(*list);
XFreeStringList(list);
return 1;
}
Status
I18N_GetIconName(dpy, w, iconname)
Display *dpy;
Window w;
char ** iconname;
{
int status;
XTextProperty text_prop;
char **list;
int num;
status = XGetWMIconName(dpy, w, &text_prop);
if (!status || !text_prop.value || !text_prop.nitems) return 0;
status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num);
if (status < Success || !num || !*list) return 0;
XFree(text_prop.value);
*iconname = (char *)strdup(*list);
XFreeStringList(list);
return 1;
}
void
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
int
putenv(s)
char *s;
{
char *v;
int varlen, idx;
extern char **environ;
char **newenv;
static int virgin = 1;
v = index(s, '=');
if(v == 0)
return 0;
varlen = (v + 1) - s;
for (idx = 0; environ[idx] != 0; idx++) {
if (strncmp(environ[idx], s, varlen) == 0) {
if(v[1] != 0) {
environ[idx] = s;
return 0;
} else {
do {
environ[idx] = environ[idx+1];
} while(environ[++idx] != 0);
return 0;
}
}
}
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;
} 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
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);
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);
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;
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);
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);
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);
}
return Scr->tbpm.question;
}
static Pixmap
CreateMenuPixmap (widthp, heightp)
unsigned int *widthp, *heightp;
{
return CreateMenuIcon (Scr->TBInfo.width - Scr->TBInfo.border * 2,
widthp,heightp);
}
Pixmap
CreateMenuIcon (height, widthp, heightp)
int height;
unsigned 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;
}