chiark / gitweb /
Import vtwm_5.4.7.orig.tar.gz
[vtwm.git] / util.c
1 /*****************************************************************************/
2 /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
3 /**                          Salt Lake City, Utah                           **/
4 /**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
5 /**                        Cambridge, Massachusetts                         **/
6 /**                                                                         **/
7 /**                           All Rights Reserved                           **/
8 /**                                                                         **/
9 /**    Permission to use, copy, modify, and distribute this software and    **/
10 /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
11 /**    granted, provided that the above copyright notice appear  in  all    **/
12 /**    copies and that both  that  copyright  notice  and  this  permis-    **/
13 /**    sion  notice appear in supporting  documentation,  and  that  the    **/
14 /**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
15 /**    in publicity pertaining to distribution of the  software  without    **/
16 /**    specific, written prior permission.                                  **/
17 /**                                                                         **/
18 /**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
19 /**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
20 /**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
21 /**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
22 /**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
23 /**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
24 /**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
25 /**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
26 /*****************************************************************************/
27
28 /*
29
30 Portions Copyright 1989, 1998  The Open Group
31
32 Permission to use, copy, modify, distribute, and sell this software and its
33 documentation for any purpose is hereby granted without fee, provided that
34 the above copyright notice appear in all copies and that both that
35 copyright notice and this permission notice appear in supporting
36 documentation.
37
38 The above copyright notice and this permission notice shall be included in
39 all copies or substantial portions of the Software.
40
41 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
44 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
45 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
46 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
47
48 Except as contained in this notice, the name of The Open Group shall not be
49 used in advertising or otherwise to promote the sale, use or other dealings
50 in this Software without prior written authorization from The Open Group.
51
52 */
53
54
55 /***********************************************************************
56  *
57  * $XConsortium: util.c,v 1.47 91/07/14 13:40:37 rws Exp $
58  *
59  * utility routines for twm
60  *
61  * 28-Oct-87 Thomas E. LaStrange        File created
62  *
63  ***********************************************************************/
64
65 #include "twm.h"
66 #include "util.h"
67 #include "gram.h"
68 #include "screen.h"
69 #include "list.h"
70 #include <X11/Xos.h>
71 #include <X11/Xatom.h>
72 #include <X11/Xmu/Drawing.h>
73 #include <X11/Xmu/CharSet.h>
74 #ifndef NO_XPM_SUPPORT
75 #include <X11/xpm.h>
76 #endif
77
78 #include <stdio.h>
79 #include <string.h>
80
81 /* see Zoom() - djhjr - 10/11/01 */
82 #ifdef NEED_SELECT_H
83 #include <sys/select.h>
84 #else
85 #include <sys/time.h>
86 #include <sys/types.h>
87 #endif
88 #ifndef ZOOMSLEEP
89 #define ZOOMSLEEP 50000 /* arbitrary, but pleasing, msec value */
90 #endif
91
92 #define strdup Strdup /* avoid conflict with system header files */
93 extern char *strdup(char *);
94
95 /*
96  * All instances of Scr->TitleBevelWidth and Scr->BorderBevelWidth
97  * were a hard value of 2 - djhjr - 4/29/98
98  */
99
100 /* djhjr - 4/18/96 10/29/02 */
101 static void Draw3DMenuImage();
102 static void Draw3DDotImage();
103 static void Draw3DResizeImage();
104 static void Draw3DZoomImage();
105 static void Draw3DBarImage();
106
107 /* djhjr - 6/4/00 10/29/02 */
108 static void Draw3DRArrowImage();
109 static void Draw3DDArrowImage();
110
111 /* djhjr - 1/13/98 10/20/02 */
112 void setBorderGC();
113 #ifdef USE_ORIGINAL_CORNERS
114 void Draw3DCorner();
115 #else
116 GC setBevelGC();
117 void Draw3DBevel();
118 void Draw3DNoBevel();
119 #endif
120
121 /* djhjr - 4/19/96 */
122 static GC     rootGC = (GC) 0;
123
124 /* for trying to clean up BeNiceToColormap - djhjr - 10/20/02 */
125 static int borderdashoffset;
126
127 int HotX, HotY;
128
129 #define questionmark_width 8
130 #define questionmark_height 8
131 static unsigned char questionmark_bits[] = {
132    0x38, 0x7c, 0x64, 0x30, 0x18, 0x00, 0x18, 0x18};
133
134 /***********************************************************************
135  *
136  *  Procedure:
137  *      MoveOutline - move a window outline
138  *
139  *  Inputs:
140  *      root        - the window we are outlining
141  *      x           - upper left x coordinate
142  *      y           - upper left y coordinate
143  *      width       - the width of the rectangle
144  *      height      - the height of the rectangle
145  *      bw          - the border width of the frame
146  *      th          - title height
147  *
148  ***********************************************************************
149  */
150
151 /* ARGSUSED */
152 void MoveOutline(root, x, y, width, height, bw, th)
153     Window root;
154     int x, y, width, height, bw, th;
155 {
156     static int  lastx = 0;
157     static int  lasty = 0;
158     static int  lastWidth = 0;
159     static int  lastHeight = 0;
160     static int  lastBW = 0;
161     static int  lastTH = 0;
162     int         xl, xr, yt, yb, xinnerl, xinnerr, yinnert, yinnerb;
163     int         xthird, ythird;
164     XSegment    outline[18];
165     register XSegment   *r;
166
167     if (x == lastx && y == lasty && width == lastWidth && height == lastHeight
168         && lastBW == bw && th == lastTH)
169         return;
170
171     r = outline;
172
173 #ifdef ORIGINAL_DRAWIT
174 #define DRAWIT() \
175     if (lastWidth || lastHeight)                        \
176     {                                                   \
177         xl = lastx;                                     \
178         xr = lastx + lastWidth - 1;                     \
179         yt = lasty;                                     \
180         yb = lasty + lastHeight - 1;                    \
181         xinnerl = xl + lastBW;                          \
182         xinnerr = xr - lastBW;                          \
183         yinnert = yt + lastTH + lastBW;                 \
184         yinnerb = yb - lastBW;                          \
185         xthird = (xinnerr - xinnerl) / 3;               \
186         ythird = (yinnerb - yinnert) / 3;               \
187                                                         \
188         /* frame outline */                                             \
189         r->x1 = xl;                                     \
190         r->y1 = yt;                                     \
191         r->x2 = xr;                                     \
192         r->y2 = yt;                                     \
193         r++;                                            \
194                                                         \
195         r->x1 = xl;                                     \
196         r->y1 = yb;                                     \
197         r->x2 = xr;                                     \
198         r->y2 = yb;                                     \
199         r++;                                            \
200                                                         \
201         r->x1 = xl;                                     \
202         r->y1 = yt;                                     \
203         r->x2 = xl;                                     \
204         r->y2 = yb;                                     \
205         r++;                                            \
206                                                         \
207         r->x1 = xr;                                     \
208         r->y1 = yt;                                     \
209         r->x2 = xr;                                     \
210         r->y2 = yb;                                     \
211         r++;                                            \
212                                                         \
213         /* left vertical */                                             \
214         r->x1 = xinnerl + xthird;                       \
215         r->y1 = yinnert;                                \
216         r->x2 = r->x1;                                  \
217         r->y2 = yinnerb;                                \
218         r++;                                            \
219                                                         \
220         /* right vertical */                                            \
221         r->x1 = xinnerl + (2 * xthird);                 \
222         r->y1 = yinnert;                                \
223         r->x2 = r->x1;                                  \
224         r->y2 = yinnerb;                                \
225         r++;                                            \
226                                                         \
227         /* top horizontal */                                            \
228         r->x1 = xinnerl;                                \
229         r->y1 = yinnert + ythird;                       \
230         r->x2 = xinnerr;                                \
231         r->y2 = r->y1;                                  \
232         r++;                                            \
233                                                         \
234         /* bottom horizontal */                                         \
235         r->x1 = xinnerl;                                \
236         r->y1 = yinnert + (2 * ythird);                 \
237         r->x2 = xinnerr;                                \
238         r->y2 = r->y1;                                  \
239         r++;                                            \
240                                                         \
241         /* title bar */                                                         \
242         if (lastTH != 0) {                              \
243             r->x1 = xl;                                 \
244             r->y1 = yt + lastTH;                        \
245             r->x2 = xr;                                 \
246             r->y2 = r->y1;                              \
247             r++;                                        \
248         }                                               \
249     }
250
251     /* undraw the old one, if any */
252     DRAWIT ();
253
254     lastx = x;
255     lasty = y;
256     lastWidth = width;
257     lastHeight = height;
258     lastBW = bw;
259     lastTH = th;
260
261     /* draw the new one, if any */
262     DRAWIT ();
263 #else
264 #define DRAWIT() \
265     if (lastWidth || lastHeight)                        \
266     {                                                   \
267         xl = lastx;                                     \
268         xr = lastx + lastWidth - 1;                     \
269         yt = lasty;                                     \
270         yb = lasty + lastHeight - 1;                    \
271         xinnerl = xl + lastBW;                          \
272         xinnerr = xr - lastBW;                          \
273         yinnert = yt + lastTH + lastBW;                 \
274         yinnerb = yb - lastBW;                          \
275         xthird = (xinnerr - xinnerl) / 3;               \
276         ythird = (yinnerb - yinnert) / 3;               \
277                                                         \
278         /* frame outline */                                             \
279         r->x1 = xl;                                     \
280         r->y1 = yt;                                     \
281         r->x2 = xr;                                     \
282         r->y2 = yt;                                     \
283         r++;                                            \
284                                                         \
285         r->x1 = xl;                                     \
286         r->y1 = yb;                                     \
287         r->x2 = xr;                                     \
288         r->y2 = yb;                                     \
289         r++;                                            \
290                                                         \
291         r->x1 = xl;                                     \
292         r->y1 = yt;                                     \
293         r->x2 = xl;                                     \
294         r->y2 = yb;                                     \
295         r++;                                            \
296                                                         \
297         r->x1 = xr;                                     \
298         r->y1 = yt;                                     \
299         r->x2 = xr;                                     \
300         r->y2 = yb;                                     \
301         r++;                                            \
302                                                         \
303         /* top-left to bottom-right */          \
304         r->x1 = xinnerl;                        \
305         r->y1 = yinnert;                        \
306         r->x2 = xinnerr;                        \
307         r->y2 = yinnerb;                        \
308         r++;                            \
309                                                         \
310         /* bottom-left to top-right */          \
311         r->x1 = xinnerl;                        \
312         r->y1 = yinnerb;                        \
313         r->x2 = xinnerr;                        \
314         r->y2 = yinnert;                        \
315         r++;                            \
316                                                         \
317         /* title bar */                                         \
318         if (lastTH != 0) {                              \
319             r->x1 = xl;                                 \
320             r->y1 = yt + lastTH;                        \
321             r->x2 = xr;                                 \
322             r->y2 = r->y1;                              \
323             r++;                                        \
324         }                                               \
325     }
326
327     /* undraw the old one, if any */
328     DRAWIT ();
329
330     lastx = x;
331     lasty = y;
332     lastWidth = width;
333     lastHeight = height;
334     lastBW = bw;
335     lastTH = th;
336
337     /* draw the new one, if any */
338     DRAWIT ();
339 #endif
340
341 #undef DRAWIT
342
343     if (r != outline)
344     {
345         XDrawSegments(dpy, root, Scr->DrawGC, outline, r - outline);
346     }
347 }
348
349 /***********************************************************************
350  *
351  *  Procedure:
352  *      Zoom - zoom in or out of an icon
353  *
354  *  Inputs:
355  *      wf      - window to zoom from
356  *      ipf     - icon manager of window to zoom from
357  *      wt      - window to zoom to
358  *      ipt     - icon manager of window to zoom to
359  *
360  *      Patched to make sure a "None" window generates coordinates *INSIDE*
361  *      the screen. -- DSE 
362  *
363  *      Added args to icon managers so zooms from and to the window's
364  *      entry use that icon manager's coordinates - djhjr - 10/11/01 
365  *
366  ***********************************************************************
367  */
368
369 void
370 Zoom(wf, ipf, wt, ipt)
371     Window wf, wt;
372     IconMgr *ipf, *ipt;
373 {
374     int fx, fy, tx, ty;                 /* from, to */
375     unsigned int fw, fh, tw, th;        /* from, to */
376     long dx, dy, dw, dh;
377     long z;
378     int j;
379
380     /* djhjr - 10/11/01 */
381     static struct timeval timeoutval = {0, ZOOMSLEEP};
382     struct timeval timeout;
383     
384     void draw_rect(); /* DSE */
385     
386     if (!Scr->DoZoom || Scr->ZoomCount < 1) return;
387
388 #if (0)
389     if (wf == None || wt == None) return;
390
391     XGetGeometry (dpy, wf, &JunkRoot, &fx, &fy, &fw, &fh, &JunkBW, &JunkDepth);
392     XGetGeometry (dpy, wt, &JunkRoot, &tx, &ty, &tw, &th, &JunkBW, &JunkDepth);
393 #else
394
395     /* if (wf == None && wt == None) return; */
396
397         if ( wt == None)
398                 {
399                 if (Scr->LessRandomZoomZoom) /* DSE */
400                         {
401                         int temp,x1,y1,x2,y2;
402                         x1 = ( (int)rand() % (Scr->MyDisplayWidth >> 3) );
403                         x2 = Scr->MyDisplayWidth - 
404                                ( (int)rand() % (Scr->MyDisplayWidth >> 3) );
405                         y1 = ( (int)rand() % (Scr->MyDisplayHeight >> 3) );
406                         y2 = Scr->MyDisplayHeight - 
407                                ( (int)rand() % (Scr->MyDisplayHeight >> 3) );
408                         if(x1>x2){temp=x1;x1=x2;x2=temp;}
409                         if(y1>y2){temp=y1;y1=y2;y2=temp;}
410                         tx = x1; ty = y1;
411                         tw = x2 - x1; th = y2 - y1;
412                         }
413                 else
414                         {
415                         /* Zoom from nowhere, RFBZOOM */
416                         tx = ( (int)rand() % Scr->MyDisplayWidth );
417                         tw = ( (int)rand() % Scr->MyDisplayWidth );
418                         ty = ( (int)rand() % Scr->MyDisplayWidth );
419                         th = ( (int)rand() % Scr->MyDisplayWidth );
420                         }
421                 }
422         else
423                 {       /* Normal. */
424                 XGetGeometry (dpy, wt, &JunkRoot,
425                         &tx, &ty, &tw, &th, &JunkBW, &JunkDepth);
426
427                 if (ipt)
428                 {
429                         tx += (ipt->twm_win->frame_x + ipt->twm_win->title_x);
430                         ty += (ipt->twm_win->frame_y + ipt->twm_win->title_y +
431                                         ipt->twm_win->title_height);
432                 }
433                 }
434
435         if ( wf == None )
436                 {
437                 if (Scr->LessRandomZoomZoom) /* DSE */
438                         {
439                         /* zoom from somewhere on the screen, DSE */
440                         int temp,x1,y1,x2,y2;
441                         do
442                                 {
443                                 x1 = ( (int)rand() % Scr->MyDisplayWidth );
444                                 x2 = ( (int)rand() % Scr->MyDisplayWidth );
445                                 y1 = ( (int)rand() % Scr->MyDisplayHeight );
446                                 y2 = ( (int)rand() % Scr->MyDisplayHeight );
447                                 if(x1>x2){temp=x1;x1=x2;x2=temp;}
448                                 if(y1>y2){temp=y1;y1=y2;y2=temp;}
449                                 fx = x1; fy = y1;
450                                 fw = x2 - x1; fh = y2 - y1;
451                                 }
452                         while ( fw > (Scr->MyDisplayWidth >> 2) || fh > (Scr->MyDisplayHeight >> 2) );
453                         }
454                 else
455                         {
456                         /* Zoom from nowhere, RFB */
457                         /* fx = ( rand() & 1 ) * Scr->MyDisplayWidth; */
458                         fx = ( (int)rand() % Scr->MyDisplayWidth );
459                         fw = ( (int)rand() % Scr->MyDisplayWidth );
460                         fy = ( (int)rand() % Scr->MyDisplayWidth );
461                         fh = ( (int)rand() % Scr->MyDisplayWidth );
462                         }
463                 }
464
465         else
466                 {       /* Normal. */
467                 XGetGeometry (dpy, wf, &JunkRoot,
468                         &fx, &fy, &fw, &fh, &JunkBW, &JunkDepth);
469
470                 if (ipf)
471                 {
472                         fx += (ipf->twm_win->frame_x + ipf->twm_win->title_x);
473                         fy += (ipf->twm_win->frame_y + ipf->twm_win->title_y +
474                                         ipf->twm_win->title_height);
475                 }
476                 }
477 #endif
478
479     dx = ((long) (tx - fx));    /* going from -> to */
480     dy = ((long) (ty - fy));    /* going from -> to */
481     dw = ((long) (tw - fw));    /* going from -> to */
482     dh = ((long) (th - fh));    /* going from -> to */
483     z = (long) (Scr->ZoomCount + 1);
484
485     for (j = 0; j < 2; j++) {
486         long i;
487
488         draw_rect (dpy, Scr->Root, Scr->DrawGC, fx, fy, fw, fh); /* DSE */
489         for (i = 1; i < z; i++)
490                 {
491             int x = fx + (int) ((dx * i) / z);
492             int y = fy + (int) ((dy * i) / z);
493             unsigned width = (unsigned) (((long) fw) + (dw * i) / z);
494             unsigned height = (unsigned) (((long) fh) + (dh * i) / z);
495
496             draw_rect (dpy, Scr->Root, Scr->DrawGC, x, y, width, height); /* DSE */
497                 }
498         draw_rect (dpy, Scr->Root, Scr->DrawGC, tx, ty, tw, th); /* DSE */
499
500         /* djhjr - 10/11/01 */
501         timeout = timeoutval;
502         select(0, 0, 0, 0, &timeout);
503     }
504 }
505
506
507 /*
508  *      Use any routine to draw your own rectangles here. -- DSE
509  */
510 void draw_rect (display,drawable,gc,x,y,width,height) /* DSE */
511                 Display *display;
512                 Drawable drawable;
513                 GC gc;
514                 int x,y;
515                 unsigned int width,height;
516         {
517         void draw_scaled_rect();
518         draw_scaled_rect (display,drawable,gc,x,y,width,height, 20,20);
519         if (Scr->PrettyZoom)
520                 {
521                 draw_scaled_rect (display,drawable,gc,x,y,width,height, 18,20);
522                 draw_scaled_rect (display,drawable,gc,x,y,width,height, 16,20);
523                 }
524         }
525 void draw_scaled_rect (display,drawable,gc,x,y,
526                        width,height,scale,over) /* DSE */
527                 Display *display;
528                 Drawable drawable;
529                 GC gc;
530                 int x,y;
531                 unsigned int width,height;
532                 unsigned int scale,over;
533         {
534         XDrawRectangle(dpy,drawable,gc,
535                 x + ( over + width * (over - scale) ) / (2 * over),
536                   y + ( over  + width * (over - scale) ) / (2 * over),
537                 ( (over / 2) + width * scale ) / over,
538                   ( (over / 2) + height * scale ) / over
539                 );
540         }
541
542 /***********************************************************************
543  *
544  *  Procedure:
545  *      ExpandFilename - expand the tilde character to HOME
546  *              if it is the first character of the filename
547  *
548  *  Returned Value:
549  *      a pointer to the new name
550  *
551  *  Inputs:
552  *      name    - the filename to expand
553  *
554  ***********************************************************************
555  */
556
557 char *
558 ExpandFilename(name)
559 char *name;
560 {
561     char *newname;
562
563     if (name[0] != '~') return name;
564
565     newname = (char *) malloc (HomeLen + strlen(name) + 2);
566     if (!newname) {
567         fprintf (stderr,
568                  "%s:  unable to allocate %d bytes to expand filename %s/%s\n",
569                  ProgramName, HomeLen + strlen(name) + 2, Home, &name[1]);
570     } else {
571         (void) sprintf (newname, "%s/%s", Home, &name[1]);
572     }
573
574     return newname;
575 }
576
577 /***********************************************************************
578  *
579  *  Procedure:
580  *      GetUnknownIcon - read in the bitmap file for the unknown icon
581  *
582  *  Inputs:
583  *      name - the filename to read
584  *
585  ***********************************************************************
586  */
587
588 void
589 GetUnknownIcon(name)
590 char *name;
591 {
592 /* djhjr - 8/13/98 */
593 #ifdef ORIGINAL_PIXMAPS
594     if ((Scr->UnknownPm = GetBitmap(name)) != None)
595     {
596         XGetGeometry(dpy, Scr->UnknownPm, &JunkRoot, &JunkX, &JunkY,
597             (unsigned int *)&Scr->UnknownWidth, (unsigned int *)&Scr->UnknownHeight, &JunkBW, &JunkDepth);
598     }
599 #else
600         Scr->unknownName = name;
601 #endif
602 }
603
604 /***********************************************************************
605  *
606  *  Procedure:
607  *      FindBitmap - read in a bitmap file and return size
608  *
609  *  Returned Value:
610  *      the pixmap associated with the bitmap
611  *      widthp  - pointer to width of bitmap
612  *      heightp - pointer to height of bitmap
613  *
614  *  Inputs:
615  *      name    - the filename to read
616  *
617  ***********************************************************************
618  */
619
620 Pixmap FindBitmap (name, widthp, heightp)
621     char *name;
622     unsigned int *widthp, *heightp;
623 {
624     char *bigname;
625     Pixmap pm;
626
627     if (!name) return None;
628
629     /*
630      * Generate a full pathname if any special prefix characters (such as ~)
631      * are used.  If the bigname is different from name, bigname will need to
632      * be freed.
633      */
634     bigname = ExpandFilename (name);
635     if (!bigname) return None;
636
637     /*
638      * look along bitmapFilePath resource same as toolkit clients
639      */
640     pm = XmuLocateBitmapFile (ScreenOfDisplay(dpy, Scr->screen), bigname, NULL,
641                               0, (int *)widthp, (int *)heightp, &HotX, &HotY);
642     if (pm == None && Scr->IconDirectory && bigname[0] != '/') {
643         if (bigname != name) free (bigname);
644         /*
645          * Attempt to find icon in old IconDirectory (now obsolete)
646          */
647         bigname = (char *) malloc (strlen(name) + strlen(Scr->IconDirectory) +
648                                    2);
649         if (!bigname) {
650             fprintf (stderr,
651                      "%s:  unable to allocate memory for \"%s/%s\"\n",
652                      ProgramName, Scr->IconDirectory, name);
653             return None;
654         }
655         (void) sprintf (bigname, "%s/%s", Scr->IconDirectory, name);
656         if (XReadBitmapFile (dpy, Scr->Root, bigname, widthp, heightp, &pm,
657                              &HotX, &HotY) != BitmapSuccess) {
658             pm = None;
659         }
660     }
661     if (bigname != name) free (bigname);
662
663 #ifdef DEBUG
664     if (pm == None) {
665         fprintf (stderr, "%s:  unable to find bitmap \"%s\"\n",
666                  ProgramName, name);
667     }
668 #endif
669
670     return pm;
671 }
672
673 Pixmap GetBitmap (name)
674     char *name;
675 {
676     return FindBitmap (name, &JunkWidth, &JunkHeight);
677 }
678
679 #ifndef NO_XPM_SUPPORT
680 /*
681  * Submitted by Jason Gloudon
682  * added color argument - djhjr - 9/28/99
683  */
684 Image *FindImage (name, color)
685     char *name;
686     Pixel color;
687 {
688     char *bigname;
689     Pixmap pixmap,mask;
690     Image *newimage = None; /* added intialization - djhjr - 3/21/98 */
691     XpmAttributes attributes;
692         XpmColorSymbol xpmcolor[1]; /* djhjr - 9/28/99 */
693     int ErrorStatus;
694     
695     /*
696      * Generate a full pathname if any special prefix characters (such as ~)
697      * are used.  If the bigname is different from name, bigname will need to
698      * be freed.
699      */
700     bigname = ExpandFilename (name);
701     if (!bigname) return None;
702
703     /* was 'XpmReturnAllocPixels' - Submitted by Takeharu Kato */
704     attributes.valuemask = XpmReturnPixels;
705
706     /* djhjr - 5/10/99 */
707     attributes.valuemask |= XpmCloseness;
708     attributes.closeness = 32768;
709
710         /* djhjr - 9/28/99 */
711         if (color)
712         {
713                 xpmcolor[0].name = NULL;
714                 xpmcolor[0].value = "none";
715                 xpmcolor[0].pixel = color;
716
717                 attributes.colorsymbols = xpmcolor;
718                 attributes.numsymbols = 1;
719                 attributes.valuemask |= XpmColorSymbols;
720         }
721
722     /*
723      * By default, the XPM library assumes screen 0, so we have
724      * to pass in the real values. Submitted by Caveh Frank Jalali
725      */
726     attributes.valuemask |= XpmVisual | XpmColormap | XpmDepth;
727     attributes.visual = Scr->d_visual;
728     attributes.colormap = XDefaultColormap(dpy, Scr->screen);
729     attributes.depth = Scr->d_depth;
730
731     if( (ErrorStatus = XpmReadFileToPixmap(dpy, Scr->Root, bigname, &pixmap,
732                                            &mask, &attributes)) != XpmSuccess){
733       pixmap = None;
734     }
735
736         /*
737          * Do for pixmaps what XmuLocateBitmapFile() does for bitmaps,
738          * because, apparently, XmuLocatePixmapFile() doesn't!
739          *
740          * djhjr - 12/26/98
741          */
742         if (pixmap == None && Scr->BitmapFilePath && bigname[0] != '/')
743         {
744                 char *path = Scr->BitmapFilePath, *term;
745
746                 do
747                 {
748                         if ((term = strchr(path, ':'))) *term = 0;
749
750                         if (bigname != name) free(bigname);
751                         if (!(bigname = (char *)malloc(strlen(name) + strlen(path) + 2)))
752                                 fprintf(stderr, "%s:  unable to allocate memory for \"%s/%s\"\n",
753                                                 ProgramName, path, name);
754                         else
755                         {
756                                 (void)sprintf(bigname, "%s/%s", path, name);
757
758 #ifdef NEVER /* once, at the top, is enough? - djhjr - 12/26/98 */
759                                 /* was 'XpmReturnAllocPixels' - Submitted by Takeharu Kato */
760                                 attributes.valuemask = XpmReturnPixels;
761
762                                 /* djhjr - 5/10/99 */
763                                 attributes.valuemask |= XpmCloseness;
764                                 attributes.closeness = 32768;
765
766                                 /* djhjr - 9/28/99 */
767                                 if (color)
768                                 {
769                                         xpmcolor[0].name = NULL;
770                                         xpmcolor[0].value = "none";
771                                         xpmcolor[0].pixel = color;
772
773                                         attributes.colorsymbols = xpmcolor;
774                                         attributes.numsymbols = 1;
775                                         attributes.valuemask |= XpmColorSymbols;
776                                 }
777
778                                 /*
779                                  * By default, the XPM library assumes screen 0, so we have
780                                  * to pass in the real values. Submitted by Caveh Frank Jalali
781                                  */
782                                 attributes.valuemask |= XpmVisual | XpmColormap | XpmDepth;
783                                 attributes.visual = Scr->d_visual;
784                                 attributes.colormap = XDefaultColormap(dpy, Scr->screen);
785                                 attributes.depth = Scr->d_depth;
786 #endif /* NEVER */
787
788                                 ErrorStatus = XpmReadFileToPixmap(dpy, Scr->Root, bigname,
789                                                 &pixmap, &mask, &attributes);
790                         }
791
792                         if (term)
793                         {
794                                 *term = ':';
795                                 path = term + 1;
796                         }
797                         else
798                                 path = NULL;
799
800                         if (ErrorStatus != XpmSuccess)
801                                 pixmap = None;
802                         else
803                                 break;
804
805                 } while (path);
806         }
807
808     if (pixmap == None && Scr->IconDirectory && bigname[0] != '/') {
809       if (bigname != name) free (bigname);
810       /*
811        * Attempt to find icon pixmap in old IconDirectory (now obsolete)
812        */
813       bigname = (char *) malloc (strlen(name) + strlen(Scr->IconDirectory) + 2);
814       if (!bigname) {
815         fprintf (stderr,
816                  "%s:  unable to allocate memory for \"%s/%s\"\n",
817                  ProgramName, Scr->IconDirectory, name);
818         return None;
819       }
820       (void) sprintf (bigname, "%s/%s", Scr->IconDirectory, name);
821
822 #ifdef NEVER /* once, at the top, is enough? - djhjr - 12/26/98 */
823       /* was 'XpmReturnAllocPixels' - Submitted by Takeharu Kato */
824       attributes.valuemask = XpmReturnPixels;
825
826       /* djhjr - 5/10/99 */
827       attributes.valuemask |= XpmCloseness;
828       attributes.closeness = 32768;
829
830       /*
831        * By default, the XPM library assumes screen 0, so we have
832        * to pass in the real values. Submitted by Caveh Frank Jalali
833        */
834       attributes.valuemask |= XpmVisual | XpmColormap | XpmDepth;
835       attributes.visual = Scr->d_visual;
836       attributes.colormap = XDefaultColormap(dpy, Scr->screen);
837       attributes.depth = Scr->d_depth;
838 #endif /* NEVER */
839
840       ErrorStatus = XpmReadFileToPixmap(dpy, Scr->Root, bigname, &pixmap,
841                                         &mask, &attributes);
842     }
843
844     if(ErrorStatus == XpmSuccess){
845       newimage = (Image *)malloc(sizeof(Image));
846       newimage->pixmap = pixmap;
847       newimage->mask = mask;
848       newimage->height = attributes.height;
849       newimage->width = attributes.width;
850     }
851     else {
852       fprintf (stderr, "%s:  unable to find pixmap \"%s\"\n",
853                ProgramName, name);
854     }
855
856     if (bigname != name) free (bigname);
857     return newimage;
858 }
859 #endif /* NO_XPM_SUPPORT */
860
861 void InsertRGBColormap (a, maps, nmaps, replace)
862     Atom a;
863     XStandardColormap *maps;
864     int nmaps;
865     Bool replace;
866 {
867     StdCmap *sc = NULL;
868
869     if (replace) {                      /* locate existing entry */
870         for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) {
871             if (sc->atom == a) break;
872         }
873     }
874
875     if (!sc) {                          /* no existing, allocate new */
876         sc = (StdCmap *) malloc (sizeof (StdCmap));
877         if (!sc) {
878             fprintf (stderr, "%s:  unable to allocate %d bytes for StdCmap\n",
879                      ProgramName, sizeof (StdCmap));
880             return;
881         }
882     }
883
884     if (replace) {                      /* just update contents */
885         if (sc->maps) XFree ((char *) maps);
886         if (sc == Scr->StdCmapInfo.mru) Scr->StdCmapInfo.mru = NULL;
887     } else {                            /* else appending */
888         sc->next = NULL;
889         sc->atom = a;
890         if (Scr->StdCmapInfo.tail) {
891             Scr->StdCmapInfo.tail->next = sc;
892         } else {
893             Scr->StdCmapInfo.head = sc;
894         }
895         Scr->StdCmapInfo.tail = sc;
896     }
897     sc->nmaps = nmaps;
898     sc->maps = maps;
899
900     return;
901 }
902
903 /*
904  * SetPixmapsPixmap - load the Image structure for the Pixmaps resource images
905  *
906  * djhjr - 5/17/98
907  */
908 Image *SetPixmapsPixmap(filename)
909 char *filename;
910 {
911         Pixmap bm;
912         Image *image = NULL;
913
914         bm = FindBitmap(filename, &JunkWidth, &JunkHeight);
915         if (bm != None)
916         {
917                 image = (Image *)malloc(sizeof(Image));
918             
919                 image->width = JunkWidth;
920                 image->height = JunkHeight;
921                 image->mask = None;
922
923                 image->pixmap = bm;
924         }
925 #ifndef NO_XPM_SUPPORT
926         else /* Try to find a pixmap file with this name */
927
928                 /* added color argument - djhjr - 9/28/99 */
929                 image = FindImage(filename, 0);
930 #endif
931
932         return image;
933 }
934
935 /*
936  * SetPixmapsBackground - set the background for the Pixmaps resource images
937  *
938  * djhjr - 5/23/98
939  * used to receive (int *)numcolors and return (Image *)image - djhjr - 9/2/98
940  */
941 #ifndef NO_XPM_SUPPORT
942 int SetPixmapsBackground(image, drawable, color)
943 Image *image;
944 Drawable drawable;
945 Pixel color;
946 {
947         XpmImage xpmimage;
948         XpmAttributes xpmattr;
949         XpmColorSymbol xpmcolor[1];
950         unsigned int i;
951
952         /* djhjr - 5/10/99 */
953         xpmattr.valuemask = XpmCloseness;
954         xpmattr.closeness = 32768;
955
956         /*
957          * By default, the XPM library assumes screen 0, so we have
958          * to pass in the real values. Submitted by Caveh Frank Jalali
959          */
960         xpmattr.valuemask |= XpmVisual | XpmColormap | XpmDepth;
961         xpmattr.visual = Scr->d_visual;
962         xpmattr.colormap = XDefaultColormap(dpy, Scr->screen);
963         xpmattr.depth = Scr->d_depth;
964
965         if (XpmCreateXpmImageFromPixmap(dpy, image->pixmap, image->mask,
966                         &xpmimage, &xpmattr) != XpmSuccess)
967                 return (0);
968
969         for (i = 0; i < xpmimage.ncolors; i++)
970                 if (!strcmp(xpmimage.colorTable[i].c_color, "None"))
971                         break;
972
973         if (i < xpmimage.ncolors)
974         {
975                 /* djhjr - 9/2/98 */
976                 XFreePixmap(dpy, image->pixmap);
977                 XFreePixmap(dpy, image->mask);
978
979                 xpmcolor[0].name = NULL;
980                 xpmcolor[0].value = "none";
981                 xpmcolor[0].pixel = color;
982
983 #ifdef NEVER /* once, at the top, is enough? - djhjr - 2/13/99 */
984                 xpmattr.colorsymbols = xpmcolor;
985                 xpmattr.numsymbols = 1;
986                 xpmattr.valuemask = XpmColorSymbols;
987
988                 /* djhjr - 5/10/99 */
989                 xpmattr.valuemask |= XpmCloseness;
990                 xpmattr.closeness = 32768;
991
992                 /*
993                  * By default, the XPM library assumes screen 0, so we have
994                  * to pass in the real values. Submitted by Caveh Frank Jalali
995                  */
996                 xpmattr.valuemask |= XpmVisual | XpmColormap | XpmDepth;
997                 xpmattr.visual = Scr->d_visual;
998                 xpmattr.colormap = XDefaultColormap(dpy, Scr->screen);
999                 xpmattr.depth = Scr->d_depth;
1000 #else
1001                 xpmattr.colorsymbols = xpmcolor;
1002                 xpmattr.numsymbols = 1;
1003                 xpmattr.valuemask |= XpmColorSymbols;
1004 #endif /* NEVER */
1005
1006                 XpmCreatePixmapFromXpmImage(dpy, drawable, &xpmimage,
1007                                 &image->pixmap, &image->mask, &xpmattr);
1008         }
1009
1010         i = xpmimage.ncolors;
1011         XpmFreeXpmImage(&xpmimage);
1012
1013         return (i);
1014 }
1015 #endif /* NO_XPM_SUPPORT */
1016
1017 void RemoveRGBColormap (a)
1018     Atom a;
1019 {
1020     StdCmap *sc, *prev;
1021
1022     prev = NULL;
1023     for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) {
1024         if (sc->atom == a) break;
1025         prev = sc;
1026     }
1027     if (sc) {                           /* found one */
1028         if (sc->maps) XFree ((char *) sc->maps);
1029         if (prev) prev->next = sc->next;
1030         if (Scr->StdCmapInfo.head == sc) Scr->StdCmapInfo.head = sc->next;
1031         if (Scr->StdCmapInfo.tail == sc) Scr->StdCmapInfo.tail = prev;
1032         if (Scr->StdCmapInfo.mru == sc) Scr->StdCmapInfo.mru = NULL;
1033     }
1034     return;
1035 }
1036
1037 void LocateStandardColormaps()
1038 {
1039     Atom *atoms;
1040     int natoms;
1041     int i;
1042
1043     atoms = XListProperties (dpy, Scr->Root, &natoms);
1044     for (i = 0; i < natoms; i++) {
1045         XStandardColormap *maps = NULL;
1046         int nmaps;
1047
1048         if (XGetRGBColormaps (dpy, Scr->Root, &maps, &nmaps, atoms[i])) {
1049             /* if got one, then append to current list */
1050             InsertRGBColormap (atoms[i], maps, nmaps, False);
1051         }
1052     }
1053     if (atoms) XFree ((char *) atoms);
1054     return;
1055 }
1056
1057 void GetColor(kind, what, name)
1058 int kind;
1059 Pixel *what;
1060 char *name;
1061 {
1062     XColor color, junkcolor;
1063     Status stat = 0;
1064     Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c;
1065
1066 #ifndef TOM
1067     if (!Scr->FirstTime) return;
1068 #endif
1069
1070     if (Scr->Monochrome != kind) return;
1071
1072 #if ( XlibSpecificationRelease < 5 )
1073     /* eyckmans@imec.be */
1074         if ( ! ( ( name[0] == '#')
1075                         ? ( (stat = XParseColor (dpy, cmap, name, &color))
1076                                 && XAllocColor (dpy, cmap, &color))
1077                         : XAllocNamedColor (dpy, cmap, name, &color, &junkcolor)))
1078 #else
1079     if (!XAllocNamedColor (dpy, cmap, name, &color, &junkcolor))
1080 #endif
1081     {
1082         /* if we could not allocate the color, let's see if this is a
1083          * standard colormap
1084          */
1085         XStandardColormap *stdcmap = NULL;
1086
1087         /* parse the named color */
1088         if (name[0] != '#')
1089             stat = XParseColor (dpy, cmap, name, &color);
1090         if (!stat)
1091         {
1092             fprintf (stderr, "%s:  invalid color name \"%s\"\n",
1093                      ProgramName, name);
1094             return;
1095         }
1096
1097         /*
1098          * look through the list of standard colormaps (check cache first)
1099          */
1100         if (Scr->StdCmapInfo.mru && Scr->StdCmapInfo.mru->maps &&
1101             (Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex].colormap ==
1102              cmap)) {
1103             stdcmap = &(Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex]);
1104         } else {
1105             StdCmap *sc;
1106
1107             for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) {
1108                 int i;
1109
1110                 for (i = 0; i < sc->nmaps; i++) {
1111                     if (sc->maps[i].colormap == cmap) {
1112                         Scr->StdCmapInfo.mru = sc;
1113                         Scr->StdCmapInfo.mruindex = i;
1114                         stdcmap = &(sc->maps[i]);
1115                         goto gotit;
1116                     }
1117                 }
1118             }
1119         }
1120
1121       gotit:
1122         if (stdcmap) {
1123             color.pixel = (stdcmap->base_pixel +
1124                            ((Pixel)(((float)color.red / 65535.0) *
1125                                     stdcmap->red_max + 0.5) *
1126                             stdcmap->red_mult) +
1127                            ((Pixel)(((float)color.green /65535.0) *
1128                                     stdcmap->green_max + 0.5) *
1129                             stdcmap->green_mult) +
1130                            ((Pixel)(((float)color.blue  / 65535.0) *
1131                                     stdcmap->blue_max + 0.5) *
1132                             stdcmap->blue_mult));
1133         } else {
1134             fprintf (stderr, "%s:  unable to allocate color \"%s\"\n",
1135                      ProgramName, name);
1136             return;
1137         }
1138     }
1139
1140     *what = color.pixel;
1141 }
1142
1143 void GetShadeColors (cp)
1144 ColorPair *cp;
1145 {
1146     XColor      xcol;
1147     Colormap    cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c;
1148     int         save;
1149     float       clearfactor;
1150     float       darkfactor;
1151     char        clearcol [32], darkcol [32];
1152
1153     clearfactor = (float) Scr->ClearBevelContrast / 100.0;
1154     darkfactor  = (100.0 - (float) Scr->DarkBevelContrast)  / 100.0;
1155     xcol.pixel = cp->back;
1156     XQueryColor (dpy, cmap, &xcol);
1157
1158     sprintf (clearcol, "#%04x%04x%04x",
1159                 xcol.red   + (unsigned short) ((65535 -   xcol.red) * clearfactor),
1160                 xcol.green + (unsigned short) ((65535 - xcol.green) * clearfactor),
1161                 xcol.blue  + (unsigned short) ((65535 -  xcol.blue) * clearfactor));
1162     sprintf (darkcol,  "#%04x%04x%04x",
1163                 (unsigned short) (xcol.red   * darkfactor),
1164                 (unsigned short) (xcol.green * darkfactor),
1165                 (unsigned short) (xcol.blue  * darkfactor));
1166
1167     save = Scr->FirstTime;
1168     Scr->FirstTime = True;
1169     GetColor (Scr->Monochrome, &cp->shadc, clearcol);
1170     GetColor (Scr->Monochrome, &cp->shadd,  darkcol);
1171     Scr->FirstTime = save;
1172 }
1173
1174 /* 
1175  * The following I18N-oriented functions are adapted from TWM
1176  * as distributed with XFree86 4.2.0 - djhjr - 9/14/03
1177  */
1178
1179 /*
1180  * The following functions are sensible to 'use_fontset'.
1181  * When 'use_fontset' is True,
1182  *  - XFontSet-related internationalized functions are used
1183  *     so as multibyte languages can be displayed.
1184  * When 'use_fontset' is False,
1185  *  - XFontStruct-related conventional functions are used
1186  *     so as 8-bit characters can be displayed even when
1187  *     locale is not set properly.
1188  */
1189 void
1190 GetFont(font)
1191 MyFont *font;
1192 {
1193 #ifndef NO_I18N_SUPPORT
1194     char **missing_charset_list_return;
1195     int missing_charset_count_return;
1196     char *def_string_return;
1197     XFontSetExtents *font_extents;
1198     XFontStruct **xfonts;
1199     char **font_names;
1200     register int i;
1201     int ascent;
1202     int descent;
1203     int fnum;
1204     char *basename2, *basename3 = NULL;
1205
1206     if (use_fontset)
1207     {
1208         if (font->fontset != NULL)
1209             XFreeFontSet(dpy, font->fontset);
1210
1211         if (!font->name)
1212             font->name = Scr->DefaultFont.name;
1213         if ((basename2 = (char *)malloc(strlen(font->name) + 3)))
1214             sprintf(basename2, "%s,*", font->name);
1215         else
1216             basename2 = font->name;
1217         if ((font->fontset = XCreateFontSet(dpy, basename2,
1218                                             &missing_charset_list_return,
1219                                             &missing_charset_count_return,
1220                                             &def_string_return)) == NULL)
1221         {
1222             /* idea from Seth Robertson - djhjr - 9/17/03 */
1223
1224             if ((basename3 = (char *)realloc(basename2,
1225                                         strlen(Scr->DefaultFont.name) + 3)))
1226                 sprintf(basename3, "%s,*", Scr->DefaultFont.name);
1227             else
1228             {
1229                 basename3 = Scr->DefaultFont.name;
1230                 if (basename2 != font->name)
1231                     free(basename2);
1232             }
1233             if ((font->fontset = XCreateFontSet(dpy, basename3,
1234                                                 &missing_charset_list_return,
1235                                                 &missing_charset_count_return,
1236                                                 &def_string_return)) == NULL)
1237             {
1238                 fprintf(stderr,
1239                         "%s: unable to open fontsets \"%s\" or \"%s\"\n",
1240                         ProgramName, font->name, Scr->DefaultFont.name);
1241                 if (basename3 != Scr->DefaultFont.name)
1242                     free(basename3);
1243                 exit(1);
1244             }
1245             basename2 = basename3;
1246         }
1247
1248         if (basename2 != ((basename3) ? Scr->DefaultFont.name : font->name))
1249             free(basename2);
1250
1251         for (i = 0; i < missing_charset_count_return; i++)
1252             fprintf(stderr, "%s: font for charset %s is lacking\n",
1253                    ProgramName, missing_charset_list_return[i]);
1254
1255         font_extents = XExtentsOfFontSet(font->fontset);
1256         fnum = XFontsOfFontSet(font->fontset, &xfonts, &font_names);
1257         for (i = 0, ascent = 0, descent = 0; i<fnum; i++)
1258         {
1259             if (ascent < (*xfonts)->ascent)
1260                 ascent = (*xfonts)->ascent;
1261             if (descent < (*xfonts)->descent)
1262                 descent = (*xfonts)->descent;
1263             xfonts++;
1264         }
1265
1266         font->height = font_extents->max_logical_extent.height;
1267         font->y = ascent;
1268         font->ascent = ascent;
1269         font->descent = descent;
1270         return;
1271     }
1272 #endif
1273
1274     if (font->font != NULL)
1275         XFreeFont(dpy, font->font);
1276
1277     if ((font->font = XLoadQueryFont(dpy, font->name)) == NULL)
1278         if ((font->font = XLoadQueryFont(dpy, Scr->DefaultFont.name)) == NULL)
1279         {
1280             fprintf(stderr, "%s:  unable to open fonts \"%s\" or \"%s\"\n",
1281                     ProgramName, font->name, Scr->DefaultFont.name);
1282             exit(1);
1283         }
1284
1285     font->height = font->font->ascent + font->font->descent;
1286     font->y = font->font->ascent;
1287     font->ascent = font->font->ascent;
1288     font->descent = font->font->descent;
1289 }
1290
1291 #ifndef NO_I18N_SUPPORT
1292 int
1293 MyFont_TextWidth(font, string, len)
1294     MyFont *font;
1295     char *string;
1296     int len;
1297 {
1298     XRectangle ink_rect;
1299     XRectangle logical_rect;
1300
1301     if (use_fontset) {
1302         XmbTextExtents(font->fontset, string, len, &ink_rect, &logical_rect);
1303         return logical_rect.width;
1304     }
1305     return XTextWidth(font->font, string, len);
1306 }
1307
1308 void
1309 MyFont_DrawImageString(dpy, d, font, gc, x, y, string, len)
1310     Display *dpy;
1311     Drawable d;
1312     MyFont *font;
1313     GC gc;
1314     int x,y;
1315     char *string;
1316     int len;
1317 {
1318     if (use_fontset) {
1319         XmbDrawImageString(dpy, d, font->fontset, gc, x, y, string, len);
1320         return;
1321     }
1322     XDrawImageString (dpy, d, gc, x, y, string, len);
1323 }
1324
1325 void
1326 MyFont_DrawString(dpy, d, font, gc, x, y, string, len)
1327     Display *dpy;
1328     Drawable d;
1329     MyFont *font;
1330     GC gc;
1331     int x,y;
1332     char *string;
1333     int len;
1334 {
1335     if (use_fontset) {
1336         XmbDrawString(dpy, d, font->fontset, gc, x, y, string, len);
1337         return;
1338     }
1339     XDrawString (dpy, d, gc, x, y, string, len);
1340 }
1341
1342 void
1343 MyFont_ChangeGC(fix_fore, fix_back, fix_font)
1344     unsigned long fix_fore, fix_back;
1345     MyFont *fix_font;
1346 {
1347     Gcv.foreground = fix_fore;
1348     Gcv.background = fix_back;
1349     if (use_fontset) {
1350         XChangeGC(dpy, Scr->NormalGC, GCForeground|GCBackground, &Gcv);
1351         return;
1352     }
1353     Gcv.font = fix_font->font->fid;
1354     XChangeGC(dpy, Scr->NormalGC, GCFont|GCForeground|GCBackground,&Gcv);
1355 }
1356
1357 /*
1358  * The following functions are internationalized substitutions
1359  * for XFetchName and XGetIconName using XGetWMName and
1360  * XGetWMIconName.  
1361  *
1362  * Please note that the third arguments have to be freed using free(), 
1363  * not XFree().
1364  */
1365 Status
1366 I18N_FetchName(dpy, w, winname)
1367     Display *dpy;
1368     Window w;
1369     char ** winname;
1370 {
1371     int    status;
1372     XTextProperty text_prop;
1373     char **list;
1374     int    num;
1375     
1376     status = XGetWMName(dpy, w, &text_prop);
1377     if (!status || !text_prop.value || !text_prop.nitems) {
1378         *winname = NULL;
1379         return 0;
1380     }
1381     *winname = (char *)strdup(text_prop.value);
1382     status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num);
1383     if (status < Success || !num || !*list) {
1384         *winname = NULL;      
1385         return 0;
1386     }
1387     XFree(text_prop.value);
1388     *winname = (char *)strdup(*list);
1389     XFreeStringList(list);
1390     return 1;
1391 }
1392
1393 Status
1394 I18N_GetIconName(dpy, w, iconname)
1395     Display *dpy;
1396     Window w;
1397     char ** iconname;
1398 {
1399     int    status;
1400     XTextProperty text_prop;
1401     char **list;
1402     int    num;
1403         
1404     status = XGetWMIconName(dpy, w, &text_prop);
1405     if (!status || !text_prop.value || !text_prop.nitems) return 0;
1406     *iconname = (char *)strdup(text_prop.value);
1407     status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num);
1408     if (status < Success || !num || !*list) return 0;
1409     XFree(text_prop.value);
1410     *iconname = (char *)strdup(*list);
1411     XFreeStringList(list);
1412     return 1;
1413 }
1414 #endif
1415
1416
1417 /*
1418  * SetFocus - separate routine to set focus to make things more understandable
1419  * and easier to debug
1420  */
1421 void SetFocus (tmp_win, time)
1422     TwmWindow *tmp_win;
1423     Time        time;
1424 {
1425     Window w = (tmp_win ? tmp_win->w : PointerRoot);
1426
1427 #ifdef TRACE
1428     if (tmp_win) {
1429         printf ("Focusing on window \"%s\"\n", tmp_win->full_name);
1430     } else {
1431         printf ("Unfocusing; Scr->Focus was \"%s\"\n",
1432                 Scr->Focus ? Scr->Focus->full_name : "(nil)");
1433     }
1434 #endif
1435
1436     XSetInputFocus (dpy, w, RevertToPointerRoot, time);
1437 }
1438
1439
1440 #ifdef NEED_PUTENV_F
1441 /*
1442  * define our own putenv() if the system doesn't have one.
1443  * putenv(s): place s (a string of the form "NAME=value") in
1444  * the environment; replacing any existing NAME.  s is placed in
1445  * environment, so if you change s, the environment changes (like
1446  * putenv on a sun).  Binding removed if you putenv something else
1447  * called NAME.
1448  */
1449 int
1450 putenv(s)
1451 /* djhjr - 4/22/98
1452 char *s;
1453 */
1454 const char *s;
1455 {
1456     char *v;
1457     int varlen, idx;
1458     extern char **environ;
1459     char **newenv;
1460     static int virgin = 1; /* true while "environ" is a virgin */
1461
1462     v = index(s, '=');
1463     if(v == 0)
1464         return 0; /* punt if it's not of the right form */
1465     varlen = (v + 1) - s;
1466
1467     for (idx = 0; environ[idx] != 0; idx++) {
1468         if (strncmp(environ[idx], s, varlen) == 0) {
1469             if(v[1] != 0) { /* true if there's a value */
1470                 environ[idx] = (char *)s;
1471                 return 0;
1472             } else {
1473                 do {
1474                     environ[idx] = environ[idx+1];
1475                 } while(environ[++idx] != 0);
1476                 return 0;
1477             }
1478         }
1479     }
1480
1481     /* add to environment (unless no value; then just return) */
1482     if(v[1] == 0)
1483         return 0;
1484     if(virgin) {
1485         register i;
1486
1487         newenv = (char **) malloc((unsigned) ((idx + 2) * sizeof(char*)));
1488         if(newenv == 0)
1489             return -1;
1490         for(i = idx-1; i >= 0; --i)
1491             newenv[i] = environ[i];
1492         virgin = 0;     /* you're not a virgin anymore, sweety */
1493     } else {
1494         newenv = (char **) realloc((char *) environ,
1495                                    (unsigned) ((idx + 2) * sizeof(char*)));
1496         if (newenv == 0)
1497             return -1;
1498     }
1499
1500     environ = newenv;
1501     environ[idx] = (char *)s;
1502     environ[idx+1] = 0;
1503
1504     return 0;
1505 }
1506 #endif /* NEED_PUTENV_F */
1507
1508
1509 /* Returns a blank cursor */
1510 Cursor NoCursor()
1511 {
1512         static Cursor blank = (Cursor) NULL;
1513         Pixmap nopixmap;
1514         XColor nocolor;
1515
1516         if (!blank) {
1517                 nopixmap = XCreatePixmap(dpy, Scr->Root, 1, 1, 1);
1518                 nocolor.red = nocolor.blue = nocolor.green = 0;
1519                 blank = XCreatePixmapCursor(dpy, nopixmap, nopixmap, &nocolor, &nocolor, 1, 1);
1520         }
1521         return(blank);
1522 }
1523
1524 /* djhjr - 10/30/02 */
1525 static void DrawDotImage(d, x, y, w, h, pad, cp, state)
1526 Drawable d;
1527 int x, y, w, h, pad;
1528 ColorPair cp;
1529 int state;
1530 {
1531     XPoint points[5];
1532     int wb, hb, ws, hs, lw;
1533
1534     lw = (w > h) ? h / 16 : w / 16;
1535     if (lw == 1) lw = 0;
1536     XSetForeground(dpy, rootGC, cp.fore);
1537     XSetLineAttributes(dpy, rootGC, lw, LineSolid, CapButt, JoinMiter);
1538
1539     ws = x + (w / 2) - 2;
1540     hs = y + (h / 2) - 2;
1541     wb = ws + 4;
1542     hb = hs + 4;
1543     
1544     points[0].x = points[3].x = points[4].x = ws;
1545     points[0].y = points[1].y = points[4].y = hs;
1546     points[1].x = points[2].x = wb;
1547     points[2].y = points[3].y = hb;
1548     XDrawLines(dpy, d, rootGC, points, 5, CoordModeOrigin);
1549 }
1550
1551 /* djhjr - 10/30/02 */
1552 static void DrawResizeImage(d, x, y, w, h, pad, cp, state)
1553 Drawable d;
1554 int x, y, w, h, pad;
1555 ColorPair cp;
1556 int state;
1557 {
1558     XPoint points[3];
1559     int wb, hb, ws, hs, lw;
1560
1561     lw = (w > h) ? h / 16 : w / 16;
1562     if (lw == 1) lw = 0;
1563     XSetForeground(dpy, rootGC, cp.fore);
1564     XSetLineAttributes(dpy, rootGC, lw, LineSolid, CapButt, JoinMiter);
1565
1566     y--;
1567     wb = w / 4; /* bigger width */
1568     hb = h / 4; /* bigger width */
1569     ws = w / 2; /* smaller width */
1570     hs = h / 2; /* smaller width */
1571
1572     points[0].x = x;
1573     points[0].y = points[1].y = y + hb;
1574     points[1].x = points[2].x = x + w - wb - 1;
1575     points[2].y = y + h;
1576     XDrawLines(dpy, d, rootGC, points, 3, CoordModeOrigin);
1577
1578     points[0].x = x;
1579     points[0].y = points[1].y = y + hs;
1580     points[1].x = points[2].x = x + ws;
1581     points[2].y = y + h;
1582     XDrawLines(dpy, d, rootGC, points, 3, CoordModeOrigin);
1583 }
1584
1585 /* djhjr - 10/30/02 */
1586 static void DrawMenuImage(d, x, y, w, h, pad, cp, state)
1587 Drawable d;
1588 int x, y, w, h, pad;
1589 ColorPair cp;
1590 int state;
1591 {
1592     int ih, iw;
1593     int ix, iy;
1594     int mh, mw;
1595     int tw, th;
1596     int lw, lh;
1597     int lx, ly;
1598     int lines, dly;
1599     /*int off;*/
1600     int bw;
1601
1602     if (h < 1) h = 1;
1603     if (w < 1) w = 1;
1604
1605     ix = iy = pad + 1;
1606     ih = h - iy * 2;
1607     iw = w - ix * 2;
1608     /*off = ih / 8;*/
1609     mh = ih - ih / 8/*off*/;
1610     mw = iw - iw / 8/*off*/;
1611     bw = mh / 16;
1612     if (bw == 0 && mw > 2) bw = 1;
1613     tw = mw - bw * 2;
1614     th = mh - bw * 2;
1615     ix += x;
1616     iy += y;
1617     XSetForeground(dpy, rootGC, cp.fore);
1618     XFillRectangle(dpy, d, rootGC, ix, iy, mw, mh);
1619     XFillRectangle(dpy, d, rootGC, ix + iw - mw, iy + ih - mh, mw, mh);
1620     XSetForeground(dpy, rootGC, cp.back);
1621     XFillRectangle(dpy, d, rootGC, ix + bw, iy + bw, tw, th);
1622
1623     lw = tw / 2;
1624     if ((tw & 1) ^ (lw & 1)) lw++;
1625     lx = ix + bw + (tw - lw) / 2;
1626     lh = th / 2 - bw;
1627     if ((lh & 1) ^ ((th - bw) & 1)) lh++;
1628     ly = iy + bw + (th - bw - lh) / 2;
1629     lines = 3;
1630     if ((lh & 1) && lh < 6) lines--;
1631     dly = lh / (lines - 1);
1632     XSetForeground(dpy, rootGC, cp.fore);
1633     while (lines--)
1634     {
1635         XFillRectangle(dpy, d, rootGC, lx, ly, lw, bw);
1636         ly += dly;
1637     }
1638 }
1639
1640 /* djhjr - 10/30/02 */
1641 static void DrawXLogoImage(d, x, y, w, h, pad, cp, state)
1642 Drawable d;
1643 int x, y, w, h, pad;
1644 ColorPair cp;
1645 int state;
1646 {
1647     GC gcBack;
1648     XGCValues gcvalues;
1649     int lw;
1650
1651     gcBack = XCreateGC(dpy, Scr->Root, 0, &gcvalues);
1652     gcvalues.background = cp.back;
1653     gcvalues.foreground = cp.fore;
1654     XChangeGC(dpy, gcBack, GCForeground | GCBackground, &gcvalues);
1655
1656     lw = (w > h) ? h / 16 : w / 16;
1657     if (lw < 3) lw = 3;
1658     XSetLineAttributes(dpy, gcBack, lw, LineSolid, CapButt, JoinMiter);
1659
1660     /*
1661      * Draw the logo large so that it gets as dense as possible,
1662      * then blank out the edges so that they look crisp.
1663      */
1664
1665     x += pad;
1666     y += pad;
1667     w -= pad * 2;
1668     h -= pad * 2;
1669     XSetForeground(dpy, rootGC, cp.fore);
1670     XSetForeground(dpy, gcBack, cp.back);
1671     XmuDrawLogo(dpy, d, rootGC, gcBack, x - 1, y - 1, w + 2, h + 2);
1672     XDrawRectangle(dpy, d, gcBack, x - 1, y - 1, w + 1, h + 1);
1673
1674     XFreeGC(dpy, gcBack);
1675 }
1676
1677 /* djhjr - 10/30/02 */
1678 static void DrawQuestionImage(d, x, y, w, h, pad, cp, state)
1679 Drawable d;
1680 int x, y, w, h, pad;
1681 ColorPair cp;
1682 int state;
1683 {
1684     Pixmap p;
1685
1686     p = XCreateBitmapFromData(dpy, Scr->Root, questionmark_bits,
1687                               questionmark_width, questionmark_height);
1688
1689     XSetForeground(dpy, rootGC, cp.fore);
1690     XCopyPlane(dpy, p, d, rootGC, 0, 0,
1691                questionmark_width, questionmark_height,
1692                x + (w - questionmark_width) / 2,
1693                y + (h - questionmark_height) / 2,
1694                (unsigned long)1);
1695
1696     XFreePixmap(dpy, p);
1697 }
1698
1699 /* djhjr - 10/30/02 */
1700 static void DrawRArrowImage(d, x, y, w, h, pad, cp, state)
1701 Drawable d;
1702 int x, y, w, h, pad;
1703 ColorPair cp;
1704 int state;
1705 {
1706     XPoint points[4];
1707     int lw, mw, mh;
1708
1709     if (!(h & 1)) h--;
1710     if (h < 1) h = 1;
1711
1712     lw = (w > h) ? h / 16 : w / 16;
1713     if (lw == 1) lw = 0;
1714     XSetForeground(dpy, rootGC, cp.fore);
1715     XSetLineAttributes(dpy, rootGC, lw, LineSolid, CapButt, JoinMiter);
1716
1717     mw = w / 3;
1718     mh = h / 3;
1719     points[0].x = w - mw;
1720     points[0].y = h / 2;
1721     points[1].x = mw - 1;
1722     points[1].y = mh - 1;
1723     points[2].x = mw - 1;
1724     points[2].y = h - mh;
1725     points[3] = points[0];
1726     XDrawLines(dpy, d, rootGC, points, 4, CoordModeOrigin);
1727 }
1728
1729 /* djhjr - 10/30/02 */
1730 static void DrawDArrowImage(d, x, y, w, h, pad, cp, state)
1731 Drawable d;
1732 int x, y, w, h, pad;
1733 ColorPair cp;
1734 int state;
1735 {
1736     XPoint points[4];
1737     int lw, mw, mh;
1738
1739     if (!(h & 1)) h--;
1740     if (h < 1) h = 1;
1741
1742     lw = (w > h) ? h / 16 : w / 16;
1743     if (lw == 1) lw = 0;
1744     XSetForeground(dpy, rootGC, cp.fore);
1745     XSetLineAttributes(dpy, rootGC, lw, LineSolid, CapButt, JoinMiter);
1746
1747     mw = h / 3;
1748     mh = h / 3;
1749     points[0].x = w / 2;
1750     points[0].y = h - mh;
1751     points[1].x = w - mw;
1752     points[1].y = mh - 1;
1753     points[2].x = mw - 1;
1754     points[2].y = mh - 1;
1755     points[3] = points[0];
1756     XDrawLines(dpy, d, rootGC, points, 4, CoordModeOrigin);
1757 }
1758
1759 /* djhjr - 4/19/96 */
1760 /* added d, x, y, w, h, state - djhjr - 10/29/02 */
1761 static void Draw3DDotImage(d, x, y, w, h, pad, cp, state)
1762 Drawable d;
1763 int x, y, w, h, pad;
1764 ColorPair cp;
1765 int state;
1766 {
1767     Draw3DBorder(d, x + (w / 2) - 2, y + (h / 2) - 2, 5, 5,
1768                  Scr->ShallowReliefWindowButton, cp, state, True, False);
1769 }
1770
1771 /* djhjr - 4/19/96 */
1772 /* added d, x, y, w, h, state - djhjr - 10/29/02 */
1773 static void Draw3DBarImage(d, x, y, w, h, pad, cp, state)
1774 Drawable d;
1775 int x, y, w, h, pad;
1776 ColorPair cp;
1777 int state;
1778 {
1779         /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */
1780         Draw3DBorder (d, x + pad + 1, y + (h - 5) / 2,
1781                 w - pad * 2 - 2, 5,
1782                 Scr->ShallowReliefWindowButton, cp, state, True, False);
1783 }
1784
1785 /* djhjr - 4/19/96 */
1786 /* added d, x, y, w, h, state - djhjr - 10/29/02 */
1787 static void Draw3DMenuImage(d, x, y, w, h, pad, cp, state)
1788 Drawable d;
1789 int x, y, w, h, pad;
1790 ColorPair cp;
1791 int state;
1792 {
1793         int i, lines, width, height;
1794
1795         height = Scr->ShallowReliefWindowButton * 2;
1796
1797         /* count the menu lines */
1798         lines = (h - pad * 2 - 2) / height;
1799         /* center 'em */
1800         y += (h - lines * height) / 2;
1801         if (!(y & 1)) y += 1;
1802         /* now draw 'em */
1803         x += pad + 1;
1804         lines = y + lines * height;
1805         width = w - pad * 2 - 2;
1806         for (i = y; i < lines; i += height)
1807                 Draw3DBorder(d, x, i, width, height,
1808                              Scr->ShallowReliefWindowButton,
1809                              cp, state, True, False);
1810 }
1811
1812 /* djhjr - 4/19/96 */
1813 /* added d, x, y, w, h, state - djhjr - 10/29/02 */
1814 static void Draw3DResizeImage(d, x, y, w, h, pad, cp, state)
1815 Drawable d;
1816 int x, y, w, h, pad;
1817 ColorPair cp;
1818 int state;
1819 {
1820     int   i, j;
1821
1822     /* djhjr - 4/29/98 */
1823     /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */
1824     i = w - Scr->ButtonBevelWidth * 2;
1825
1826     /*
1827      * Extend the left and bottom "off-window" by the
1828      * line width for "thick" boxes on "thin" buttons.
1829      */
1830
1831     /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */
1832     j = Scr->ButtonBevelWidth + (i / 4);
1833     Draw3DBorder(d,
1834                 x + -Scr->ShallowReliefWindowButton, y + j - 1,
1835                 x + w - j + 1 + Scr->ShallowReliefWindowButton,
1836                 y + h - j + 1 + Scr->ShallowReliefWindowButton,
1837                 Scr->ShallowReliefWindowButton, cp, state, True, False);
1838
1839     j = Scr->ButtonBevelWidth + (i / 2);
1840     Draw3DBorder(d,
1841                 x + -Scr->ShallowReliefWindowButton, y + j,
1842                 x + w - j + Scr->ShallowReliefWindowButton,
1843                 y + h - j + Scr->ShallowReliefWindowButton,
1844                 Scr->ShallowReliefWindowButton, cp, state, True, False);
1845 }
1846
1847 /* djhjr - 4/19/96 */
1848 /* added d, x, y, w, h, state - djhjr - 10/29/02 */
1849 static void Draw3DZoomImage(d, x, y, w, h, pad, cp, state)
1850 Drawable d;
1851 int x, y, w, h, pad;
1852 ColorPair cp;
1853 int state;
1854 {
1855         /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */
1856         Draw3DBorder (d,
1857                 x + pad + 1, y + pad + 1,
1858                 w - 2 * pad - 2,
1859                 h - 2 * pad - 2,
1860                 Scr->ShallowReliefWindowButton, cp, state, True, False);
1861 }
1862
1863 /* djhjr - 6/4/00 */
1864 /* added d, x, y, w, h, state - djhjr - 10/29/02 */
1865 static void Draw3DRArrowImage(d, x, y, w, h, pad, cp, state)
1866 Drawable d;
1867 int x, y, w, h, pad;
1868 ColorPair cp;
1869 int state;
1870 {
1871     int i, mw, mh;
1872
1873         mw = w / 3;
1874         mh = h / 3;
1875
1876         if (Scr->Monochrome != COLOR)
1877         {
1878                 /* draw highlights */
1879                 setBorderGC(1, Scr->GreyGC, cp, state, False);
1880                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
1881                 {
1882                         XDrawLine(dpy, d, Scr->GreyGC,
1883                                 x + w - mw - i, y + h / 2,
1884                                 x + mw - 1 + i, y + mh - 1 + i);
1885                         XDrawLine (dpy, d, Scr->GreyGC,
1886                                 x + mw - 1 + i, y + mh - 1 + i,
1887                                 x + mw - 1 + i, y + h - mh - i);
1888                 }
1889
1890                 /* draw shadows */
1891                 setBorderGC(2, Scr->GreyGC, cp, state, False);
1892                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
1893                         XDrawLine (dpy, d, Scr->GreyGC,
1894                                 x + mw - 1 + i, y + h - mh - i,
1895                                 x + w - mw - i, y + h / 2);
1896     }
1897         else if (Scr->BeNiceToColormap)
1898         {
1899                 int dashoffset = 0;
1900
1901                 setBorderGC(3, Scr->ShadGC, cp, state, False);
1902             
1903                 /* draw highlights */
1904                 XSetForeground (dpy, Scr->ShadGC, Scr->White);
1905                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
1906                 {
1907                         XDrawLine(dpy, d, Scr->ShadGC,
1908                                 x + w - mw - i, y + h / 2,
1909                                 x + mw - 1 + i, y + mh - 1 + i);
1910                         XDrawLine (dpy, d, Scr->ShadGC,
1911                                 x + mw - 1 + i, y + mh - 1 + i,
1912                                 x + mw - 1 + i, y + h - mh - i);
1913                 }
1914
1915                 /* draw shadows */
1916                 XSetForeground (dpy, Scr->ShadGC, Scr->Black);
1917                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
1918                 {
1919                         XDrawLine (dpy, d, Scr->ShadGC,
1920                                 x + mw - 1 + i, y + h - mh - i + dashoffset,
1921                                 x + w - mw - i, y + h / 2 + dashoffset);
1922                         dashoffset = 1 - dashoffset;
1923                 }
1924         }
1925         else
1926         {
1927                 /* draw highlights */
1928                 if (state)
1929                 { FB (cp.shadc, cp.shadd); }
1930                 else
1931                 { FB (cp.shadd, cp.shadc); }
1932                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
1933                 {
1934                         XDrawLine(dpy, d, Scr->NormalGC,
1935                                 x + w - mw - i, y + h / 2,
1936                                 x + mw - 1 + i, y + mh - 1 + i);
1937                         XDrawLine (dpy, d, Scr->NormalGC,
1938                                 x + mw - 1 + i, y + mh - 1 + i,
1939                                 x + mw - 1 + i, y + h - mh - i);
1940                 }
1941
1942                 /* draw shadows */
1943                 if (state)
1944                 { FB (cp.shadd, cp.shadc); }
1945                 else
1946                 { FB (cp.shadc, cp.shadd); }
1947                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
1948                         XDrawLine (dpy, d, Scr->NormalGC,
1949                                 x + mw - 1 + i, y + h - mw - i,
1950                                 x + w - mw - i, y + h / 2);
1951         }
1952 }
1953
1954 /* djhjr - 6/4/00 */
1955 /* added d, x, y, w, h, state - djhjr - 10/29/02 */
1956 static void Draw3DDArrowImage(d, x, y, w, h, pad, cp, state)
1957 Drawable d;
1958 int x, y, w, h, pad;
1959 ColorPair cp;
1960 int state;
1961 {
1962     int i, mw, mh;
1963
1964         mw = w / 3;
1965         mh = h / 3;
1966
1967         if (Scr->Monochrome != COLOR)
1968         {
1969                 /* draw highlights */
1970                 setBorderGC(1, Scr->GreyGC, cp, state, False);
1971                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
1972                 {
1973                         XDrawLine(dpy, d, Scr->GreyGC,
1974                                 x + w - mw - i, y + mh - 1 + i,
1975                                 x + mw - 1 + i, y + mh - 1 + i);
1976                         XDrawLine (dpy, d, Scr->GreyGC,
1977                                 x + mw - 1 + i, y + mh - 1 + i,
1978                                 x + w / 2, y + mh - 1 - i + h / 2);
1979                 }
1980
1981                 /* draw shadows */
1982                 setBorderGC(2, Scr->GreyGC, cp, state, False);
1983                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
1984                         XDrawLine (dpy, d, Scr->GreyGC,
1985                                 x + w / 2, y + mh - 1 - i + h / 2,
1986                                 x + w - mw - i, y + mh + i);
1987     }
1988         else if (Scr->BeNiceToColormap)
1989         {
1990                 int dashoffset = 0;
1991
1992                 setBorderGC(3, Scr->ShadGC, cp, state, False);
1993             
1994                 /* draw highlights */
1995                 XSetForeground (dpy, Scr->ShadGC, Scr->White);
1996                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
1997                 {
1998                         XDrawLine(dpy, d, Scr->ShadGC,
1999                                 x + w - mw - i, y + mh - 1 + i,
2000                                 x + mw - 1 + i, y + mh - 1 + i);
2001                         XDrawLine (dpy, d, Scr->ShadGC,
2002                                 x + mw - 1 + i, y + mh - 1 + i + dashoffset,
2003                                 x + w / 2, y + mh - 1 - i + h / 2 + dashoffset);
2004                         dashoffset = 1 - dashoffset;
2005                 }
2006
2007                 /* draw shadows */
2008                 XSetForeground (dpy, Scr->ShadGC, Scr->Black);
2009                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
2010                         XDrawLine (dpy, d, Scr->ShadGC,
2011                                 x + w / 2, y + mh - 1 - i + h / 2,
2012                                 x + w - mw - i, y + mh + i);
2013         }
2014         else
2015         {
2016                 /* draw highlights */
2017                 if (state)
2018                 { FB (cp.shadc, cp.shadd); }
2019                 else
2020                 { FB (cp.shadd, cp.shadc); }
2021                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
2022                 {
2023                         XDrawLine(dpy, d, Scr->NormalGC,
2024                                 x + w - mw - i, y + mh - 1 + i,
2025                                 x + mw - 1 + i, y + mh - 1 + i);
2026                         XDrawLine (dpy, d, Scr->NormalGC,
2027                                 x + mw - 1 + i, y + mh - 1 + i,
2028                                 x + w / 2, y + mh - 1 - i + h / 2);
2029                 }
2030
2031                 /* draw shadows */
2032                 if (state)
2033                 { FB (cp.shadd, cp.shadc); }
2034                 else
2035                 { FB (cp.shadc, cp.shadd); }
2036                 for (i = 0; i < Scr->ShallowReliefWindowButton; i++)
2037                         XDrawLine (dpy, d, Scr->NormalGC,
2038                                 x + w / 2, y + mh - 1 - i + h / 2,
2039                                 x + w - mw - i, y + mh + i);
2040         }
2041 }
2042
2043 /* djhjr - 10/25/02 */
2044 static void Draw3DBoxHighlight(d, x, y, w, h, pad, cp, state)
2045 Drawable d;
2046 int x, y, w, h, pad;
2047 ColorPair cp;
2048 int state;
2049 {
2050         Draw3DBorder(d, x, y, w, h,
2051                      Scr->ShallowReliefWindowButton, cp,
2052                      state, True, False);
2053 }
2054
2055 /* djhjr - 10/25/02 */
2056 static void Draw3DLinesHighlight(d, x, y, w, h, pad, cp, state)
2057 Drawable d;
2058 int x, y, w, h, pad;
2059 ColorPair cp;
2060 int state;
2061 {
2062         int p;
2063         
2064         p = (Scr->ShallowReliefWindowButton & 1) ? 3 : 2;
2065         p = (h - Scr->ShallowReliefWindowButton * p - 2) / 2;
2066
2067         y += h / 2 - 1;
2068         y -= (Scr->ShallowReliefWindowButton & 1) ? 0 : 1;
2069         y += (state == on) ? 0 : 1;
2070
2071         h = Scr->ShallowReliefWindowButton * 2;
2072
2073         Draw3DBorder(d, x, y - p, w, h,
2074                      Scr->ShallowReliefWindowButton, cp,
2075                      state, False, False);
2076
2077         if ((Scr->ShallowReliefWindowButton & 1))
2078                 Draw3DBorder(d, x, y, w, h,
2079                              Scr->ShallowReliefWindowButton, cp,
2080                              state, False, False);
2081
2082         Draw3DBorder(d, x, y + p, w, h,
2083                      Scr->ShallowReliefWindowButton, cp,
2084                      state, False, False);
2085 }
2086
2087 /* ick - djhjr - 10/30/02 */
2088 static void DrawBackground(d, x, y, w, h, cp, use_rootGC)
2089 Drawable d;
2090 int x, y, w, h;
2091 ColorPair cp;
2092 int use_rootGC;
2093 {
2094     XGCValues gcvalues;
2095
2096     if (use_rootGC)
2097     {
2098         if (rootGC == (GC)0)
2099             rootGC = XCreateGC(dpy, Scr->Root, 0, &gcvalues);
2100
2101         gcvalues.background = cp.back;
2102         gcvalues.foreground = cp.fore;
2103         XChangeGC(dpy, rootGC, GCForeground | GCBackground, &gcvalues);
2104
2105         XSetForeground(dpy, rootGC, cp.back);
2106         XFillRectangle(dpy, d, rootGC, x, y, w, h);
2107     }
2108     else
2109     {
2110         FB(cp.back, cp.fore);
2111         XFillRectangle(dpy, d, Scr->NormalGC, x, y, w, h);
2112     }
2113 }
2114
2115 /* djhjr - 10/25/02 */
2116 static void DrawTitleHighlight(t, state)
2117 TwmWindow *t;
2118 int state;
2119 {
2120         static const struct {
2121                 char *name;
2122                 void (*proc)();
2123                 Bool use_rootGC;
2124                 int state;
2125         } pmtab[] = {
2126                 /* djhjr - 10/30/02 */
2127                 { TBPM_DOT,             DrawDotImage,           True, off  },
2128                 { TBPM_ICONIFY,         DrawDotImage,           True, off  },
2129                 { TBPM_RESIZE,          DrawResizeImage,        True, off  },
2130                 { TBPM_MENU,            DrawMenuImage,          True, off  },
2131                 { TBPM_XLOGO,           DrawXLogoImage,         True, off  },
2132                 { TBPM_DELETE,          DrawXLogoImage,         True, off  },
2133                 { TBPM_QUESTION,        DrawQuestionImage,      True, off  },
2134
2135                 { TBPM_3DDOT,           Draw3DDotImage,         False, off },
2136                 { TBPM_3DRESIZE,        Draw3DResizeImage,      False, off },
2137                 { TBPM_3DMENU,          Draw3DMenuImage,        False, off },
2138                 { TBPM_3DZOOM,          Draw3DZoomImage,        False, off },
2139                 { TBPM_3DBAR,           Draw3DBarImage,         False, off },
2140
2141                 /* djhjr - 10/30/02 */
2142                 { TBPM_3DBOX,           Draw3DBoxHighlight,     False, off },
2143                 { TBPM_3DLINES,         Draw3DLinesHighlight,   False, off },
2144
2145                 { TBPM_3DRAISEDBOX,     Draw3DBoxHighlight,     False, off },
2146                 { TBPM_3DSUNKENBOX,     Draw3DBoxHighlight,     False, on  },
2147                 { TBPM_3DRAISEDLINES,   Draw3DLinesHighlight,   False, off },
2148                 { TBPM_3DSUNKENLINES,   Draw3DLinesHighlight,   False, on  },
2149         };
2150
2151         XGCValues gcvalues;
2152         ColorPair cp;
2153         register int i;
2154         int h, w;
2155         
2156         cp = t->title;
2157         w = ComputeHighlightWindowWidth(t);
2158         h = Scr->TitleHeight - 2 * Scr->FramePadding - 2;
2159                 
2160         for (i = 0; i < sizeof(pmtab) / sizeof(pmtab[0]); i++)
2161         {
2162                 if (XmuCompareISOLatin1(pmtab[i].name, Scr->hiliteName) == 0)
2163                 {
2164                         if (state == off)
2165                         {
2166                                 DrawBackground(t->title_w,
2167                                                t->highlightx,
2168                                                Scr->FramePadding + 1,
2169                                                w, h, cp,
2170                                                pmtab[i].use_rootGC | (Scr->Monochrome != COLOR));
2171                         }
2172                         else
2173                         {
2174                                 /* ick - djhjr - 10/30/02 */
2175                                 if (pmtab[i].use_rootGC)
2176                                 {
2177                                         if (rootGC == (GC)0)
2178                                                 rootGC = XCreateGC(dpy,
2179                                                                    Scr->Root,
2180                                                                    0,
2181                                                                    &gcvalues);
2182
2183                                         gcvalues.background = cp.back;
2184                                         gcvalues.foreground = cp.fore;
2185                                         XChangeGC(dpy, rootGC,
2186                                                   GCForeground | GCBackground,
2187                                                   &gcvalues);
2188                                 }
2189
2190                                 (*pmtab[i].proc)(t->title_w,
2191                                                  t->highlightx,
2192                                                  Scr->FramePadding + 1,
2193                                                  w, h, 0, cp, pmtab[i].state);
2194                         }
2195
2196                         break;
2197                 }
2198         }
2199 }
2200
2201 /* djhjr - 1/13/98 */
2202 void setBorderGC(type, gc, cp, state, forcebw)
2203 int                     type, state, forcebw;
2204 GC                      gc;
2205 ColorPair       cp;
2206 {
2207         XGCValues               gcv;
2208         unsigned long   gcm;
2209
2210         switch (type)
2211         {
2212                 case 0: /* Monochrome main */
2213                         gcm = GCFillStyle;
2214                         gcv.fill_style = FillOpaqueStippled;
2215                         break;
2216                 case 1: /* Monochrome highlight */
2217                         gcm  = 0;
2218                         gcm |= GCLineStyle;             
2219                         gcv.line_style = (state == on) ? LineSolid : LineDoubleDash;
2220                         gcm |= GCFillStyle;
2221                         gcv.fill_style = FillSolid;
2222                         break;
2223                 case 2: /* Monochrome shadow */
2224                         gcm  = 0;
2225                         gcm |= GCLineStyle;             
2226                         gcv.line_style = (state == on) ? LineDoubleDash : LineSolid;
2227                         gcm |= GCFillStyle;
2228                         gcv.fill_style = FillSolid;
2229                         break;
2230                 case 3: /* BeNiceToColormap */
2231                         gcm  = 0;
2232                         gcm |= GCLineStyle;             
2233                         gcv.line_style = (forcebw) ? LineSolid : LineDoubleDash;
2234                         gcm |= GCBackground;
2235                         gcv.background = cp.back;
2236                         break;
2237                 default:
2238                         return;
2239         }
2240
2241         XChangeGC (dpy, gc, gcm, &gcv);
2242 }
2243
2244 /* djhjr - 4/19/96 */
2245 void Draw3DBorder (w, x, y, width, height, bw, cp, state, fill, forcebw)
2246 Drawable                w;
2247 int                     x, y, width, height, bw;
2248 ColorPair       cp;
2249 int                     state, fill, forcebw;
2250 {
2251         int                             i;
2252
2253         if (width < 1 || height < 1) return;
2254
2255         if (Scr->Monochrome != COLOR)
2256         {
2257                 /* set main color */
2258                 if (fill)
2259                 {
2260                         setBorderGC(0, Scr->GreyGC, cp, state, forcebw);
2261                         XFillRectangle (dpy, w, Scr->GreyGC, x, y, width, height);
2262                 }
2263
2264                 /* draw highlights */
2265                 setBorderGC(1, Scr->GreyGC, cp, state, forcebw);
2266                 for (i = 0; i < bw; i++)
2267                 {
2268                         XDrawLine (dpy, w, Scr->GreyGC, x, y + i,
2269                                 x + width - i - 1, y + i);
2270                         XDrawLine (dpy, w, Scr->GreyGC, x + i, y,
2271                                 x + i, y + height - i - 1);
2272                 }
2273
2274                 /* draw shadows */
2275                 setBorderGC(2, Scr->GreyGC, cp, state, forcebw);
2276                 for (i = 0; i < bw; i++)
2277                 {
2278                         XDrawLine (dpy, w, Scr->GreyGC, x + width - i - 1, y + i,
2279                                 x + width - i - 1, y + height - 1);
2280                         XDrawLine (dpy, w, Scr->GreyGC, x + i, y + height - i - 1,
2281                                 x + width - 1, y + height - i - 1);
2282                 }
2283
2284                 return;
2285     }
2286
2287         /* set main color */
2288         if (fill)
2289         {
2290                 FB (cp.back, cp.fore);
2291                 XFillRectangle (dpy, w, Scr->NormalGC, x, y, width, height);
2292         }
2293
2294         if (Scr->BeNiceToColormap)
2295         {
2296                 setBorderGC(3, Scr->ShadGC, cp, state, forcebw);
2297             
2298                 /* draw highlights */
2299                 if (state == on)
2300                         XSetForeground (dpy, Scr->ShadGC, Scr->Black);
2301                 else
2302                         XSetForeground (dpy, Scr->ShadGC, Scr->White);
2303                 for (i = 0; i < bw; i++)
2304                 {
2305                         XDrawLine (dpy, w, Scr->ShadGC,
2306                                 x + i, y + borderdashoffset,
2307                                 x + i, y + height - i - 1);
2308                         XDrawLine (dpy, w, Scr->ShadGC,
2309                                 x + borderdashoffset, y + i,
2310                                 x + width - i - 1, y + i);
2311                         borderdashoffset = 1 - borderdashoffset;
2312                 }
2313
2314                 /* draw shadows */
2315                 if (state == on)
2316                         XSetForeground (dpy, Scr->ShadGC, Scr->White);
2317                 else
2318                         XSetForeground (dpy, Scr->ShadGC, Scr->Black);
2319                 for (i = 0; i < bw; i++)
2320                 {
2321                         XDrawLine (dpy, w, Scr->ShadGC, x + i, y + height - i - 1,
2322                                 x + width - 1, y + height - i - 1);
2323                         XDrawLine (dpy, w, Scr->ShadGC, x + width - i - 1, y + i,
2324                                 x + width - i - 1, y + height - 1);
2325                 }
2326
2327                 return;
2328         }
2329
2330         /* draw highlights */
2331         if (state == on)
2332                 { FB (cp.shadd, cp.shadc); }
2333         else
2334                 { FB (cp.shadc, cp.shadd); }
2335         for (i = 0; i < bw; i++)
2336         {
2337                 XDrawLine (dpy, w, Scr->NormalGC, x, y + i,
2338                         x + width - i - 1, y + i);
2339                 XDrawLine (dpy, w, Scr->NormalGC, x + i, y,
2340                         x + i, y + height - i - 1);
2341         }
2342
2343         /* draw shadows */
2344         if (state == on)
2345                 { FB (cp.shadc, cp.shadd); }
2346         else
2347                 { FB (cp.shadd, cp.shadc); }
2348         for (i = 0; i < bw; i++)
2349         {
2350                 XDrawLine (dpy, w, Scr->NormalGC, x + width - i - 1, y + i,
2351                         x + width - i - 1, y + height - 1);
2352                 XDrawLine (dpy, w, Scr->NormalGC, x + i, y + height - i - 1,
2353                         x + width - 1, y + height - i - 1);
2354         }
2355 }
2356
2357 #ifdef USE_ORIGINAL_CORNERS
2358 /* djhjr - 4/19/96 */
2359 void Draw3DCorner (w, x, y, width, height, thick, bw, cp, type)
2360 Window          w;
2361 int                     x, y, width, height, thick, bw;
2362 ColorPair       cp;
2363 int                     type;
2364 {
2365         Draw3DBorder (w, x, y, width, height, bw, cp, off, True, False);
2366
2367         switch (type)
2368         {
2369                 /* upper left */
2370                 case 0 :
2371                         Draw3DBorder (w, x + thick - bw, y + thick - bw,
2372                                 width - thick + 2 * bw, height - thick + 2 * bw,
2373                                 bw, cp, on, True, False);
2374                         break;
2375                 /* upper right */
2376                 case 1 :
2377                         Draw3DBorder (w, x - bw, y + thick - bw,
2378                                 width - thick + 2 * bw, height - thick + 2 * bw,
2379                                 bw, cp, on, True, False);
2380                         break;
2381                 /* lower right */
2382                 case 2 :
2383                         Draw3DBorder (w, x - bw, y - bw,
2384                                 width - thick + 2 * bw, height - thick + 2 * bw,
2385                                 bw, cp, on, True, False);
2386                         break;
2387                 /* lower left */
2388                 case 3 :
2389                         Draw3DBorder (w, x + thick - bw, y - bw,
2390                                 width - thick + 2 * bw, height - thick + 2 * bw,
2391                                 bw, cp, on, True, False);
2392                         break;
2393         }
2394 }
2395 #else /* USE_ORIGINAL_CORNERS */
2396 /* djhjr - 1/14/98 */
2397 GC setBevelGC(type, state, cp)
2398 int                     type, state;
2399 ColorPair       cp;
2400 {
2401         GC              gc;
2402
2403         if (Scr->Monochrome != COLOR)
2404         {
2405                 gc = Scr->GreyGC;
2406                 setBorderGC(type, gc, cp, state, False);
2407         }
2408         else if (Scr->BeNiceToColormap)
2409         {
2410                 gc = Scr->ShadGC;
2411                 setBorderGC(3, gc, cp, state, False);
2412                 if (state == on)
2413                         XSetForeground (dpy, gc, Scr->Black);
2414                 else
2415                         XSetForeground (dpy, gc, Scr->White);
2416         }
2417         else
2418         {
2419                 gc = Scr->NormalGC;
2420                 if (state == on)
2421                         { FB (cp.shadc, cp.shadd); }
2422                 else
2423                         { FB (cp.shadd, cp.shadc); }
2424         }
2425
2426         return (gc);
2427 }
2428
2429 /* djhjr - 1/12/98 */
2430 void Draw3DBevel (w, x, y, bw, cp, state, type)
2431 Drawable                w;
2432 int                     x, y, bw;
2433 ColorPair       cp;
2434 int                     state, type;
2435 {
2436         int             i;
2437         GC              gc;
2438
2439         switch (type)
2440         {
2441                 /* vertical */
2442                 case 1 :
2443                 case 11 :
2444                         gc = setBevelGC(1, state, cp);
2445                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2446                                 XDrawLine (dpy, w, gc, x - i - 1, y + i,
2447                                         x - i - 1, y + bw - 2 * i + i);
2448                         if (type == 11) break;
2449                 case 111 :
2450                         gc = setBevelGC(2, !state, cp);
2451                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2452                                 XDrawLine (dpy, w, gc, x + i, y + i - 1,
2453                                         x + i, y + bw - 2 * i + i - 1);
2454                         break;
2455                 /* horizontal */
2456                 case 2 :
2457                 case 22 :
2458                         gc = setBevelGC(1, state, cp);
2459                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2460                                 XDrawLine (dpy, w, gc, x + i, y - i - 1,
2461                                         x + bw - 2 * i + i, y - i - 1);
2462                         if (type == 22) break;
2463                 case 222 :
2464                         gc = setBevelGC(2, !state, cp);
2465                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2466                                 XDrawLine (dpy, w, gc, x + i - 1, y + i,
2467                                         x + bw - 2 * i + i - 1, y + i);
2468                         break;
2469                 /* ulc to lrc */
2470                 case 3 :
2471                         if (Scr->Monochrome != COLOR)
2472                         {
2473                                 gc = Scr->GreyGC;
2474                                 setBorderGC(0, gc, cp, state, False);
2475                         }
2476                         else
2477                         {
2478                                 gc = Scr->NormalGC;
2479                                 FB (cp.back, cp.fore);
2480                         }
2481                         XFillRectangle (dpy, w, gc, x, y, bw, bw);
2482                         gc = setBevelGC(1, (Scr->BeNiceToColormap) ? state : !state, cp);
2483                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2484                                 XDrawLine (dpy, w, gc, x + i, y,
2485                                         x + i, y + Scr->BorderBevelWidth - 1);
2486                         gc = setBevelGC(2, (Scr->BeNiceToColormap) ? !state : state, cp);
2487                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2488                                 XDrawLine (dpy, w, gc, x, y + bw - i - 1,
2489                                         x + bw - 1, y + bw - i - 1);
2490                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2491                                 XDrawLine (dpy, w, gc, x + bw - i - 1, y,
2492                                         x + bw - i - 1, y + bw - 1);
2493                         break;
2494                 /* urc to llc */
2495                 case 4 :
2496                         if (Scr->Monochrome != COLOR)
2497                         {
2498                                 gc = Scr->GreyGC;
2499                                 setBorderGC(0, gc, cp, state, False);
2500                         }
2501                         else
2502                         {
2503                                 gc = Scr->NormalGC;
2504                                 FB (cp.back, cp.fore);
2505                         }
2506                         XFillRectangle (dpy, w, gc, x, y, bw, bw);
2507                         gc = setBevelGC(1, (Scr->BeNiceToColormap) ? state : !state, cp);
2508                         /* top light */
2509                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2510                                 XDrawLine (dpy, w, gc, x + i, y,
2511                                         x + i, y + bw - i);
2512                         /* bottom light */
2513                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2514                                 XDrawLine (dpy, w, gc, x + bw - 1, y + i,
2515                                         x + bw - i - 1, y + i);
2516                         gc = setBevelGC(2, (Scr->BeNiceToColormap) ? !state : state, cp);
2517                         /* top dark */
2518                         for (i = 0; i < Scr->BorderBevelWidth - 1; i++)
2519                                 XDrawLine (dpy, w, gc, x + bw - Scr->BorderBevelWidth, y + i,
2520                                         x + bw - i - 2, y + i);
2521                         /* bottom dark */
2522                         for (i = 0; i < Scr->BorderBevelWidth; i++)
2523                                 XDrawLine (dpy, w, gc, x + i, y + bw - i - 1,
2524                                         x + bw + 1, y + bw - i - 1);
2525                         break;
2526         }
2527 }
2528
2529 /* djhjr - 10/20/02 */
2530 void Draw3DNoBevel(w, x, y, bw, cp, state, forcebw)
2531 Drawable        w;
2532 int             x, y, bw;
2533 ColorPair       cp;
2534 int             state, forcebw;
2535 {
2536         int             i, upr, lwr;
2537
2538         if (bw < 1) return;
2539
2540         upr = y - 2 * Scr->BorderBevelWidth;
2541         if ((upr & 1)) upr--;
2542         lwr = y + 2 * Scr->BorderBevelWidth;
2543         if ((lwr & 1)) lwr++;
2544
2545         if (Scr->Monochrome != COLOR)
2546         {
2547                 /* set main color */
2548                 setBorderGC(0, Scr->GreyGC, cp, state, forcebw);
2549                 XFillRectangle (dpy, w, Scr->GreyGC,
2550                         x + Scr->BorderBevelWidth, upr,
2551                         (unsigned int)(bw - Scr->BorderBevelWidth * 2),
2552                         (unsigned int)(upr * 2));
2553
2554                 /* draw highlight */
2555                 setBorderGC(1, Scr->GreyGC, cp, state, forcebw);
2556                 for (i = 0; i < Scr->BorderBevelWidth; i++)
2557                         XDrawLine (dpy, w, Scr->GreyGC,
2558                                 x + i, upr, x + i, lwr);
2559                 
2560                 /* draw shadow */
2561                 setBorderGC(2, Scr->GreyGC, cp, state, forcebw);
2562                 for (i = bw - Scr->BorderBevelWidth; i < bw; i++)
2563                         XDrawLine (dpy, w, Scr->GreyGC,
2564                                 x + i, upr, x + i, lwr);
2565
2566                 return;
2567         }
2568
2569         /* set main color */
2570         FB (cp.back, cp.fore);
2571         XFillRectangle (dpy, w, Scr->NormalGC,
2572                 x + Scr->BorderBevelWidth, upr,
2573                 (unsigned int)(bw - Scr->BorderBevelWidth * 2),
2574                 (unsigned int)(upr * 2));
2575
2576         if (Scr->BeNiceToColormap)
2577         {
2578                 int dashoffset;
2579
2580                 setBorderGC(3, Scr->ShadGC, cp, state, forcebw);
2581             
2582                 /* draw highlight */
2583                 if (state == on)
2584                         XSetForeground (dpy, Scr->ShadGC, Scr->Black);
2585                 else
2586                         XSetForeground (dpy, Scr->ShadGC, Scr->White);
2587                 dashoffset = 0;
2588                 for (i = 0; i < Scr->BorderBevelWidth; i++)
2589                 {
2590                         XDrawLine (dpy, w, Scr->ShadGC,
2591                                 x + i, upr + dashoffset, x + i, lwr);
2592                         dashoffset = 1 - dashoffset;
2593                 }
2594
2595                 /* draw shadow */
2596                 if (state == on)
2597                         XSetForeground (dpy, Scr->ShadGC, Scr->White);
2598                 else
2599                         XSetForeground (dpy, Scr->ShadGC, Scr->Black);
2600                 dashoffset = 0;
2601                 for (i = bw - Scr->BorderBevelWidth; i < bw; i++)
2602                 {
2603                         XDrawLine (dpy, w, Scr->ShadGC,
2604                                 x + i, upr + dashoffset, x + i, lwr);
2605                         dashoffset = 1 - dashoffset;
2606                 }
2607
2608                 return;
2609         }
2610
2611         /* draw highlight */
2612         if (state == on)
2613                 { FB (cp.shadc, cp.shadd); }
2614         else
2615                 { FB (cp.shadd, cp.shadc); }
2616         for (i = 0; i < Scr->BorderBevelWidth; i++)
2617                 XDrawLine (dpy, w, Scr->NormalGC,
2618                         x + i, upr, x + i, lwr);
2619
2620         /* draw shadow */
2621         if (state == on)
2622                 { FB (cp.shadd, cp.shadc); }
2623         else
2624                 { FB (cp.shadc, cp.shadd); }
2625         for (i = bw - Scr->BorderBevelWidth; i < bw; i++)
2626                 XDrawLine (dpy, w, Scr->NormalGC,
2627                         x + i, upr, x + i, lwr);
2628 }
2629 #endif /* USE_ORIGINAL_CORNERS */
2630
2631 /* djhjr - 4/19/96 */
2632 static Image *LoadBitmapImage (name, cp)
2633 char  *name;
2634 ColorPair cp;
2635 {
2636     Image       *image;
2637     Pixmap      bm;
2638     int         width, height;
2639     XGCValues   gcvalues;
2640
2641     if (rootGC == (GC) 0) rootGC = XCreateGC (dpy, Scr->Root, 0, &gcvalues);
2642     bm = FindBitmap (name, (unsigned int *) &width, (unsigned int *) &height);
2643     if (bm == None) return (None);
2644
2645     image = (Image*) malloc (sizeof (struct _Image));
2646     image->pixmap = XCreatePixmap (dpy, Scr->Root, width, height, Scr->d_depth);
2647     gcvalues.background = cp.back;
2648     gcvalues.foreground = cp.fore;
2649     XChangeGC   (dpy, rootGC, GCForeground | GCBackground, &gcvalues);
2650     XCopyPlane  (dpy, bm, image->pixmap, rootGC, 0, 0, width, height, 0, 0, (unsigned long) 1);
2651     XFreePixmap (dpy, bm);
2652     image->mask   = None;
2653     image->width  = width;
2654     image->height = height;
2655     image->next   = None;
2656     return (image);
2657 }
2658
2659 /* djhjr - 10/30/02 */
2660 static Image *CreateImagePixmap(name, w, h, depth)
2661 char *name;
2662 int w, h, depth;
2663 {
2664     Image *image;
2665
2666     image = (Image *)malloc(sizeof(struct _Image));
2667     if (!image)
2668     {
2669         fprintf(stderr, "%s: cannot allocate %d bytes for Image \"%s\"\n",
2670                         ProgramName, sizeof(struct _Image), name);
2671         return (None);
2672     }
2673
2674     image->pixmap = XCreatePixmap(dpy, Scr->Root, w, h, depth);
2675     if (image->pixmap == None)
2676     {
2677         fprintf(stderr, "%s: cannot allocate %d bytes for pixmap \"%s\"\n",
2678                         ProgramName, sizeof(image->pixmap), name);
2679         free((void *)image);
2680         return (None);
2681     }
2682
2683     return (image);
2684 }
2685
2686 /* djhjr - 4/19/96 10/30/02 */
2687 static Image *ReallyGetImage(name, w, h, pad, cp)
2688 char      *name;
2689 int       w, h, pad;
2690 ColorPair cp;
2691 {
2692     static const struct {
2693         char *name;
2694         void (*proc)();
2695         Bool use_rootGC;
2696         int state;
2697     } pmtab[] = {
2698         { TBPM_DOT,             DrawDotImage,           True, off  },
2699         { TBPM_ICONIFY,         DrawDotImage,           True, off  },
2700         { TBPM_RESIZE,          DrawResizeImage,        True, off  },
2701         { TBPM_MENU,            DrawMenuImage,          True, off  },
2702         { TBPM_XLOGO,           DrawXLogoImage,         True, off  },
2703         { TBPM_DELETE,          DrawXLogoImage,         True, off  },
2704         { TBPM_QUESTION,        DrawQuestionImage,      True, off  },
2705
2706         /* djhjr - 6/4/00 */
2707         { TBPM_RARROW,          DrawRArrowImage,        True, off  },
2708         { TBPM_DARROW,          DrawDArrowImage,        True, off  },
2709
2710         { TBPM_3DDOT,           Draw3DDotImage,         False, off },
2711         { TBPM_3DRESIZE,        Draw3DResizeImage,      False, off },
2712         { TBPM_3DMENU,          Draw3DMenuImage,        False, off },
2713         { TBPM_3DZOOM,          Draw3DZoomImage,        False, off },
2714         { TBPM_3DBAR,           Draw3DBarImage,         False, off },
2715
2716         /* djhjr - 6/4/00 */
2717         { TBPM_3DRARROW,        Draw3DRArrowImage,      False, off },
2718         { TBPM_3DDARROW,        Draw3DDArrowImage,      False, off },
2719
2720         /* djhjr - 10/30/02 */
2721         { TBPM_3DBOX,           Draw3DBoxHighlight,     False, off },
2722         { TBPM_3DLINES,         Draw3DLinesHighlight,   False, off },
2723     };
2724         
2725     Image *image = NULL;
2726     name_list **list;
2727     register int i;
2728     char fullname [256];
2729
2730     if (name == NULL) return (NULL);
2731
2732     list = &Scr->ImageCache;
2733
2734     if (name[0] == ':')
2735     {
2736         /* probably need '"%d", Scr->screen' - Caveh Frank Jalali */
2737         sprintf(fullname, "%s.%dx%d.%Xx%X", name,
2738                 w, h, (int)cp.fore, (int)cp.back);
2739         if ((image = (Image *)LookInNameList(*list, fullname)) == NULL)
2740         {
2741             for (i = 0; i < sizeof(pmtab) / sizeof(pmtab[0]); i++)
2742             {
2743                 if (XmuCompareISOLatin1(pmtab[i].name, name) == 0)
2744                 {
2745                     if (!(image = CreateImagePixmap(name, w, h, Scr->d_depth)))
2746                         return (None);
2747
2748                     DrawBackground(image->pixmap, 0, 0, w, h, cp,
2749                                 pmtab[i].use_rootGC | (Scr->Monochrome != COLOR));
2750
2751                     /* added d, x, y, w, h, pad, state - djhjr - 10/29/02 */
2752                     (*pmtab[i].proc)(image->pixmap, 0, 0, w, h, pad,
2753                                      cp, pmtab[i].state);
2754
2755                     image->mask   = None;
2756                     image->width  = w;
2757                     image->height = h;
2758                     image->next   = None;
2759                     break;
2760                 }
2761             }
2762
2763             if (!image)
2764             {
2765                 fprintf(stderr, "%s:  no such built-in pixmap \"%s\"\n",
2766                                 ProgramName, name);
2767                 return (NULL);
2768             }
2769         }
2770         else
2771             return (image);
2772     }
2773     else
2774     {
2775         /*
2776          * Need screen number in fullname since screens may have different GCs.
2777          * Submitted by Caveh Frank Jalali
2778          */
2779         sprintf(fullname, "%s.%Xx%X.%d",
2780                 name, (int)cp.fore, (int)cp.back, (int)Scr->screen);
2781         if ((image = (Image *)LookInNameList(*list, fullname)) == NULL)
2782         {
2783             if ((image = LoadBitmapImage(name, cp)) == NULL)
2784 #ifndef NO_XPM_SUPPORT
2785                 /* djhjr - 3/20/98 */
2786                 /* added color argument - djhjr - 9/28/99 */
2787                 image = FindImage(name, cp.back);
2788 #else
2789                 ;
2790 #endif
2791
2792             if (!image) return (NULL);
2793         }
2794         else
2795             return (image);
2796     }
2797
2798     /* added 'type' argument - djhjr - 10/20/01 */
2799     AddToList(list, fullname, LTYPE_EXACT_NAME, (char *)image);
2800
2801     return (image);
2802 }
2803
2804 /*
2805  * Wrapper to guarantee something is returned - djhjr - 10/30/02
2806  */
2807 Image *GetImage(name, w, h, pad, cp)
2808 char *name;
2809 int w, h, pad;
2810 ColorPair cp;
2811 {
2812     Image *image = NULL;
2813
2814     if (!(image = ReallyGetImage(name, w, h, pad, cp)))
2815         image = ReallyGetImage(TBPM_QUESTION, w, h, pad, cp);
2816
2817     return (image);
2818 }
2819
2820 /* djhjr - 4/21/96 */
2821 /* djhjr - 1/12/98 */
2822 void PaintBorders (tmp_win, focus)
2823 TwmWindow       *tmp_win;
2824 Bool            focus;
2825 {
2826         GC                      gc;
2827         ColorPair       cp;
2828         int                     i, j, cw, ch, cwbw, chbw;
2829 #ifdef USE_ORIGINAL_CORNERS
2830         int                     THbw, fhbwchbw, fhTHchbw;
2831 #endif
2832
2833         cp = (focus && tmp_win->highlight) ? tmp_win->border : tmp_win->border_tile;
2834
2835         /* no titlebar, no corners */
2836         if (tmp_win->title_height == 0)
2837         {
2838                 Draw3DBorder (tmp_win->frame,
2839                         0,
2840                         0,
2841                         tmp_win->frame_width,
2842                         tmp_win->frame_height,
2843                         Scr->BorderBevelWidth, cp, off, True, False);
2844                 Draw3DBorder (tmp_win->frame,
2845                         tmp_win->frame_bw3D - Scr->BorderBevelWidth,
2846                         tmp_win->frame_bw3D - Scr->BorderBevelWidth,
2847                         tmp_win->frame_width  - 2 * tmp_win->frame_bw3D + 2 * Scr->BorderBevelWidth,
2848                         tmp_win->frame_height - 2 * tmp_win->frame_bw3D + 2 * Scr->BorderBevelWidth,
2849                         Scr->BorderBevelWidth, cp, on, True, False);
2850
2851                 return;
2852         }
2853
2854         cw = ch = Scr->TitleHeight;
2855         if (cw * 2 > tmp_win->attr.width) cw = tmp_win->attr.width / 2;
2856         if (ch * 2 > tmp_win->attr.height) ch = tmp_win->attr.height / 2;
2857         cwbw = cw + tmp_win->frame_bw3D;
2858         chbw = ch + tmp_win->frame_bw3D;
2859
2860 #ifdef USE_ORIGINAL_CORNERS
2861         THbw = Scr->TitleHeight + tmp_win->frame_bw3D;
2862         fhbwchbw = tmp_win->frame_height + tmp_win->frame_bw3D - 3 * chbw;
2863         fhTHchbw = tmp_win->frame_height - (Scr->TitleHeight + ch + 2 * tmp_win->frame_bw3D);
2864
2865         /* client upper left corner */
2866         if (tmp_win->squeeze_info && tmp_win->title_x > tmp_win->frame_bw3D)
2867                 Draw3DCorner (tmp_win->frame,
2868                         0,
2869                         Scr->TitleHeight,
2870                         cwbw,
2871                         chbw,
2872                         tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 0);
2873         /* client top bar */
2874         if (tmp_win->squeeze_info)
2875                 Draw3DBorder (tmp_win->frame,
2876                         THbw,
2877                         tmp_win->title_height,
2878                         tmp_win->frame_width - 2 * cwbw,
2879                         tmp_win->frame_bw3D,
2880                         Scr->BorderBevelWidth, cp, off, True, False);
2881         /* client upper right corner */
2882         if (tmp_win->squeeze_info && tmp_win->title_x + tmp_win->title_width + tmp_win->frame_bw3D < tmp_win->frame_width)
2883                 Draw3DCorner (tmp_win->frame,
2884                         tmp_win->frame_width  - cwbw,
2885                         Scr->TitleHeight,
2886                         cwbw,
2887                         chbw,
2888                         tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 1);
2889         /* client left bar */
2890         if (tmp_win->squeeze_info && tmp_win->title_x > tmp_win->frame_bw3D)
2891                 Draw3DBorder (tmp_win->frame,
2892                         0,
2893                         THbw + ch,
2894                         tmp_win->frame_bw3D,
2895                         fhbwchbw,
2896                         Scr->BorderBevelWidth, cp, off, True, False);
2897         else
2898                 Draw3DBorder (tmp_win->frame,
2899                         0,
2900                         THbw,
2901                         tmp_win->frame_bw3D,
2902                         fhTHchbw,
2903                         Scr->BorderBevelWidth, cp, off, True, False);
2904         /* client right bar */
2905         if (tmp_win->squeeze_info && tmp_win->title_x + tmp_win->title_width + tmp_win->frame_bw3D < tmp_win->frame_width)
2906                 Draw3DBorder (tmp_win->frame,
2907                         tmp_win->frame_width  - tmp_win->frame_bw3D,
2908                         THbw + ch,
2909                         tmp_win->frame_bw3D,
2910                         fhbwchbw,
2911                         Scr->BorderBevelWidth, cp, off, True, False);
2912         else
2913                 Draw3DBorder (tmp_win->frame,
2914                         tmp_win->frame_width  - tmp_win->frame_bw3D,
2915                         THbw,
2916                         tmp_win->frame_bw3D,
2917                         fhTHchbw,
2918                         Scr->BorderBevelWidth, cp, off, True, False);
2919         /* client lower left corner */
2920         Draw3DCorner (tmp_win->frame,
2921                 0,
2922                 tmp_win->frame_height - chbw,
2923                 cwbw,
2924                 chbw,
2925                 tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 3);
2926         /* client bottom bar */
2927         Draw3DBorder (tmp_win->frame,
2928                 THbw,
2929                 tmp_win->frame_height - tmp_win->frame_bw3D,
2930                 tmp_win->frame_width - 2 * cwbw,
2931                 tmp_win->frame_bw3D,
2932                 Scr->BorderBevelWidth, cp, off, True, False);
2933         /* client lower right corner */
2934         Draw3DCorner (tmp_win->frame,
2935                 tmp_win->frame_width  - cwbw,
2936                 tmp_win->frame_height - chbw,
2937                 cwbw,
2938                 chbw,
2939                 tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 2);
2940
2941         /* titlebar upper left corner */
2942         Draw3DCorner (tmp_win->frame,
2943                 tmp_win->title_x - tmp_win->frame_bw3D,
2944                 0,
2945                 cwbw,
2946                 THbw,
2947                 tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 0);
2948         /* titlebar top bar */
2949         Draw3DBorder (tmp_win->frame,
2950                 tmp_win->title_x + cw,
2951                 0,
2952                 tmp_win->title_width - 2 * cw,
2953                 tmp_win->frame_bw3D,
2954                 Scr->BorderBevelWidth, cp, off, True, False);
2955         /* titlebar upper right corner */
2956         Draw3DCorner (tmp_win->frame,
2957                 (tmp_win->title_width > 2 * Scr->TitleHeight)
2958                         ? tmp_win->title_x + tmp_win->title_width - Scr->TitleHeight
2959                         : tmp_win->frame_width - cwbw,
2960                 0,
2961                 cwbw,
2962                 THbw,
2963                 tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 1);
2964 #else /* USE_ORIGINAL_CORNERS */
2965         /* client */
2966         borderdashoffset = 1;
2967         Draw3DBorder (tmp_win->frame,
2968                 0,
2969                 Scr->TitleHeight,
2970                 tmp_win->frame_width,
2971                 tmp_win->frame_height - Scr->TitleHeight,
2972                 Scr->BorderBevelWidth, cp, off, True, False);
2973         borderdashoffset = 1;
2974         Draw3DBorder (tmp_win->frame,
2975                 tmp_win->frame_bw3D - Scr->BorderBevelWidth,
2976                 Scr->TitleHeight + tmp_win->frame_bw3D - Scr->BorderBevelWidth,
2977                 tmp_win->frame_width  - 2 * tmp_win->frame_bw3D + 2 * Scr->BorderBevelWidth,
2978                 tmp_win->frame_height - 2 * tmp_win->frame_bw3D + 2 * Scr->BorderBevelWidth - Scr->TitleHeight,
2979                 Scr->BorderBevelWidth, cp, on, True, False);
2980     if (!Scr->NoBorderDecorations)      /* djhjr - 10/20/02 */
2981     {
2982         /* upper left corner */
2983         if (tmp_win->title_x == tmp_win->frame_bw3D)
2984                 Draw3DBevel (tmp_win->frame,
2985                         0, Scr->TitleHeight + tmp_win->frame_bw3D,
2986                         tmp_win->frame_bw3D, cp,
2987                         (Scr->BeNiceToColormap) ? on : off, 222);
2988         else
2989         {
2990                 if (tmp_win->title_x > tmp_win->frame_bw3D + cwbw)
2991                         Draw3DBevel (tmp_win->frame,
2992                                 cwbw, Scr->TitleHeight,
2993                                 tmp_win->frame_bw3D, cp,
2994                                 (Scr->BeNiceToColormap) ? on : off, 1);
2995                 Draw3DBevel (tmp_win->frame,
2996                         0, Scr->TitleHeight + chbw,
2997                         tmp_win->frame_bw3D, cp,
2998                         (Scr->BeNiceToColormap) ? on : off, 2);
2999         }
3000     }
3001         /* upper right corner */
3002         if ((i = tmp_win->title_x + tmp_win->title_width + tmp_win->frame_bw3D) == tmp_win->frame_width)
3003                 Draw3DBevel (tmp_win->frame,
3004                         tmp_win->frame_width - tmp_win->frame_bw3D, Scr->TitleHeight + tmp_win->frame_bw3D,
3005                         tmp_win->frame_bw3D, cp,
3006                         (Scr->BeNiceToColormap) ? on : off, 222);
3007         else
3008         {
3009             if (!Scr->NoBorderDecorations)      /* djhjr - 10/20/02 */
3010             {
3011                 if (i < tmp_win->frame_width - cwbw)
3012                         Draw3DBevel (tmp_win->frame,
3013                                 tmp_win->frame_width - cwbw, Scr->TitleHeight,
3014                                 tmp_win->frame_bw3D, cp,
3015                                 (Scr->BeNiceToColormap) ? on : off, 1);
3016                 Draw3DBevel (tmp_win->frame,
3017                         tmp_win->frame_width - tmp_win->frame_bw3D,
3018                         Scr->TitleHeight + chbw,
3019                         tmp_win->frame_bw3D, cp,
3020                         (Scr->BeNiceToColormap) ? on : off, 2);
3021             }
3022         }
3023     if (!Scr->NoBorderDecorations)      /* djhjr - 10/20/02 */
3024     {
3025         /* lower left corner */
3026         Draw3DBevel (tmp_win->frame,
3027                 cwbw, tmp_win->frame_height - tmp_win->frame_bw3D,
3028                 tmp_win->frame_bw3D, cp,
3029                 (Scr->BeNiceToColormap) ? on : off, 1);
3030         Draw3DBevel (tmp_win->frame,
3031                 0, tmp_win->frame_height - chbw,
3032                 tmp_win->frame_bw3D, cp,
3033                 (Scr->BeNiceToColormap) ? on : off, 2);
3034         /* lower right corner */
3035         Draw3DBevel (tmp_win->frame,
3036                 tmp_win->frame_width - cwbw,
3037                 tmp_win->frame_height - tmp_win->frame_bw3D,
3038                 tmp_win->frame_bw3D, cp,
3039                 (Scr->BeNiceToColormap) ? on : off, 1);
3040         Draw3DBevel (tmp_win->frame,
3041                 tmp_win->frame_width - tmp_win->frame_bw3D,
3042                 tmp_win->frame_height - chbw,
3043                 tmp_win->frame_bw3D, cp,
3044                 (Scr->BeNiceToColormap) ? on : off, 2);
3045     }
3046         /* title */
3047         borderdashoffset = 0;
3048         Draw3DBorder (tmp_win->frame,
3049                 tmp_win->title_x - tmp_win->frame_bw3D,
3050                 tmp_win->title_y - tmp_win->frame_bw3D,
3051                 tmp_win->title_width + 2 * tmp_win->frame_bw3D,
3052                 Scr->TitleHeight + tmp_win->frame_bw3D,
3053                 Scr->BorderBevelWidth, cp, off, True, False);
3054         borderdashoffset = 0;
3055         Draw3DBorder (tmp_win->frame,
3056                 tmp_win->title_x - Scr->BorderBevelWidth,
3057                 tmp_win->title_y - Scr->BorderBevelWidth,
3058                 tmp_win->title_width + 2 * Scr->BorderBevelWidth,
3059                 Scr->TitleHeight,
3060                 Scr->BorderBevelWidth, cp, on, True, False);
3061         /* upper left corner */
3062         if (tmp_win->title_x == tmp_win->frame_bw3D)
3063         {
3064             /* this 'if (...) else' - djhjr - 10/20/02 */
3065             if (Scr->NoBorderDecorations)
3066             {
3067                 Draw3DNoBevel(tmp_win->frame,
3068                         tmp_win->title_x - tmp_win->frame_bw3D,
3069                         Scr->TitleHeight + tmp_win->frame_bw3D,
3070                         tmp_win->frame_bw3D, cp,
3071                         (Scr->BeNiceToColormap) ? off : on, False);
3072             }
3073             else
3074             {
3075                 gc = setBevelGC(2, (Scr->BeNiceToColormap) ? on : off, cp);
3076
3077 /* djhjr - 4/29/98
3078                 XDrawLine (dpy, tmp_win->frame, gc,
3079                         tmp_win->title_x - 2, Scr->TitleHeight + tmp_win->frame_bw3D - 4,
3080                         tmp_win->title_x - 2, Scr->TitleHeight + tmp_win->frame_bw3D - 1);
3081                 XDrawLine (dpy, tmp_win->frame, gc,
3082                         tmp_win->title_x - 1, Scr->TitleHeight + tmp_win->frame_bw3D - 4,
3083                         tmp_win->title_x - 1, Scr->TitleHeight + tmp_win->frame_bw3D - 1);
3084 */
3085                 for (j = 1; j <= Scr->BorderBevelWidth; j++)
3086                         XDrawLine (dpy, tmp_win->frame, gc,
3087                                 tmp_win->title_x - j,
3088                                 Scr->TitleHeight + tmp_win->frame_bw3D - 2 * Scr->BorderBevelWidth,
3089                                 tmp_win->title_x - j,
3090                                 Scr->TitleHeight + tmp_win->frame_bw3D - Scr->BorderBevelWidth - 1);
3091
3092                 Draw3DBevel (tmp_win->frame,
3093                         tmp_win->title_x + cw, 0,
3094                         tmp_win->frame_bw3D, cp,
3095                         (Scr->BeNiceToColormap) ? on : off, 1);
3096             }
3097         }
3098         else
3099         {
3100                 Draw3DBevel (tmp_win->frame,
3101                         tmp_win->title_x - tmp_win->frame_bw3D, Scr->TitleHeight,
3102                         tmp_win->frame_bw3D, cp, off, 3);
3103         }
3104         /* upper right corner */
3105         if (i == tmp_win->frame_width)
3106         {
3107             /* this 'if (...) else' - djhjr - 10/20/02 */
3108             if (Scr->NoBorderDecorations)
3109             {
3110                 Draw3DNoBevel(tmp_win->frame,
3111                         tmp_win->frame_width - tmp_win->frame_bw3D,
3112                         Scr->TitleHeight + tmp_win->frame_bw3D,
3113                         tmp_win->frame_bw3D, cp,
3114                         (Scr->BeNiceToColormap) ? off : on, False);
3115             }
3116             else
3117             {
3118                 gc = setBevelGC(1, (Scr->BeNiceToColormap) ? off : on, cp);
3119
3120 /* djhjr - 4/29/98
3121                 gc = setBevelGC(1, on, cp);
3122                 XDrawLine (dpy, tmp_win->frame, gc,
3123                         tmp_win->title_x + tmp_win->title_width, Scr->TitleHeight + tmp_win->frame_bw3D - 2,
3124                         tmp_win->title_x + tmp_win->title_width, Scr->TitleHeight + tmp_win->frame_bw3D - 2);
3125 */
3126                 for (j = 0; j < Scr->BorderBevelWidth; j++)
3127                         XDrawLine (dpy, tmp_win->frame, gc,
3128                                 tmp_win->title_x + tmp_win->title_width - 1,
3129                                 Scr->TitleHeight + tmp_win->frame_bw3D - Scr->BorderBevelWidth + j - 1,
3130                                 tmp_win->title_x + tmp_win->title_width + Scr->BorderBevelWidth - j - 1,
3131                                 Scr->TitleHeight + tmp_win->frame_bw3D - Scr->BorderBevelWidth + j - 1);
3132
3133                 Draw3DBevel (tmp_win->frame,
3134                         tmp_win->title_x + tmp_win->title_width - cw, 0,
3135                         tmp_win->frame_bw3D, cp,
3136                         (Scr->BeNiceToColormap) ? on : off, 1);
3137             }
3138         }
3139         else
3140         {
3141                 Draw3DBevel (tmp_win->frame,
3142                         tmp_win->title_x + tmp_win->title_width, Scr->TitleHeight,
3143                         tmp_win->frame_bw3D, cp, off, 4);
3144         }
3145 #endif /* USE_ORIGINAL_CORNERS */
3146 }
3147
3148 /* djhjr - 4/21/96 */
3149 void PaintIcon (tmp_win)
3150 TwmWindow *tmp_win;
3151 {
3152 /* djhjr - 5/5/98
3153     if (Scr->use3Diconmanagers) {
3154 */
3155         /* was 'Scr->use3Dicons' - djhjr - 8/11/98 */
3156     if (Scr->IconBevelWidth > 0) {
3157
3158 /*
3159         Draw3DBorder (tmp_win->icon_w, 0, tmp_win->icon_height,
3160                 tmp_win->icon_w_width, Scr->IconFont.height + 6,
3161                 Scr->BorderBevelWidth, tmp_win->iconc, off, False, False);
3162 */
3163         /* was 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */
3164         Draw3DBorder (tmp_win->icon_w, 0, 0,
3165                 tmp_win->icon_w_width, tmp_win->icon_w_height,
3166                 Scr->IconBevelWidth, tmp_win->iconc, off, False, False);
3167     }
3168
3169     /* font was font.font->fid - djhjr - 9/14/03 */
3170     FBF(tmp_win->iconc.fore, tmp_win->iconc.back, Scr->IconFont);
3171
3172 /* djhjr - 9/14/03 */
3173 #ifndef NO_I18N_SUPPORT
3174         MyFont_DrawString (dpy, tmp_win->icon_w, &Scr->IconFont,
3175 #else
3176         XDrawString (dpy, tmp_win->icon_w,
3177 #endif
3178                 Scr->NormalGC, tmp_win->icon_x, tmp_win->icon_y, 
3179                 tmp_win->icon_name, strlen(tmp_win->icon_name));
3180 }
3181
3182 /* djhjr - 4/20/96 */
3183 void PaintTitle (tmp_win)
3184 TwmWindow *tmp_win;
3185 {
3186         /* made static - djhjr - 6/18/99 */
3187         static int en = 0, dots = 0;
3188
3189         int bwidth = Scr->TBInfo.width + Scr->TBInfo.pad;
3190         int left = (Scr->TBInfo.nleft) ? Scr->TBInfo.leftx +
3191                    (Scr->TBInfo.nleft * bwidth) - Scr->TBInfo.pad :
3192                    0;
3193         int right = (Scr->TBInfo.nright) ?
3194                     (Scr->TBInfo.nright * bwidth) - Scr->TBInfo.pad :
3195                     0;
3196
3197         /* djhjr - 3/29/98 */
3198         int i, j, slen = strlen(tmp_win->name);
3199         char *a = NULL;
3200
3201 /* djhjr - 9/14/03 */
3202 #ifndef NO_I18N_SUPPORT
3203         if (!en) en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1);
3204 #else
3205         if (!en) en = XTextWidth(Scr->TitleBarFont.font, "n", 1);
3206 #endif
3207
3208         /*
3209          * clip the title a couple of characters less than the width of
3210          * the titlebar plus padding, and tack on ellipses - this is a
3211          * little different than the icon manager's...
3212          *
3213          * djhjr - 3/29/98
3214          */
3215         if (Scr->NoPrettyTitles == FALSE) /* for rader - djhjr - 2/9/99 */
3216         {
3217 /* djhjr - 9/14/03 */
3218 #ifndef NO_I18N_SUPPORT
3219                 i = MyFont_TextWidth(&Scr->TitleBarFont, tmp_win->name, slen);
3220 #else
3221                 i = XTextWidth(Scr->TitleBarFont.font, tmp_win->name, slen);
3222 #endif
3223
3224 /* DUH! - djhjr - 6/18/99
3225                 j = tmp_win->title_width - 2 * Scr->TBInfo.rightoff;
3226 */
3227 /* djhjr - 10/18/02
3228                 if (!dots) dots = XTextWidth(Scr->TitleBarFont.font, "...", 3) + en;
3229                 j = tmp_win->title_width - Scr->TBInfo.titlex - Scr->TBInfo.rightoff - dots;
3230 */
3231 /* djhjr - 9/14/03 */
3232 #ifndef NO_I18N_SUPPORT
3233                 if (!dots) dots = MyFont_TextWidth(&Scr->TitleBarFont, "...", 3);
3234 #else
3235                 if (!dots) dots = XTextWidth(Scr->TitleBarFont.font, "...", 3);
3236 #endif
3237                 j = tmp_win->title_width - Scr->TBInfo.titlex - Scr->TBInfo.rightoff - en;
3238
3239 /* djhjr - 10/18/02
3240                 * djhjr - 5/5/98 *
3241                 * was 'Scr->use3Dtitles' - djhjr - 8/11/98 *
3242                 if (Scr->TitleBevelWidth > 0)
3243                         j -= Scr->TitleBevelWidth;
3244 */
3245                 /* reworked this stuff - djhjr - 10/18/02 */
3246                 if (dots >= j)
3247                         slen = 0;
3248                 else if (i > j)
3249                 {
3250                         while (i >= 0)
3251                         {
3252 /* djhjr - 9/14/03 */
3253 #ifndef NO_I18N_SUPPORT
3254                                 if (MyFont_TextWidth(&Scr->TitleBarFont,
3255 #else
3256                                 if (XTextWidth(Scr->TitleBarFont.font,
3257 #endif
3258                                                 tmp_win->name, i) + dots < j)
3259                                 {
3260                                         slen = i;
3261                                         break;
3262                                 }
3263
3264                                 i--;
3265                         }
3266
3267                         a = (char *)malloc(slen + 4);
3268                         memcpy(a, tmp_win->name, slen);
3269                         strcpy(a + slen, "...");
3270                         slen += 3;
3271                 }
3272         }
3273
3274     /* font was font.font->fid - djhjr - 9/14/03 */
3275     FBF(tmp_win->title.fore, tmp_win->title.back, Scr->TitleBarFont);
3276
3277 /* djhjr - 10/18/02 */
3278 #if 0
3279         /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
3280     if (Scr->TitleBevelWidth > 0)
3281         {
3282 /* djhjr - 9/14/03 */
3283 #ifndef NO_I18N_SUPPORT
3284             MyFont_DrawString (dpy, tmp_win->title_w, &Scr->TitleBarFont,
3285 #else
3286             XDrawString (dpy, tmp_win->title_w,
3287 #endif
3288                  Scr->NormalGC,
3289 /* djhjr - 4/29/98
3290                  Scr->TBInfo.titlex + en, Scr->TitleBarFont.y + 2, 
3291 */
3292 /* djhjr - 5/5/98
3293                  Scr->TBInfo.titlex + en, Scr->TitleBarFont.y + Scr->TitleBevelWidth + 1, 
3294 */
3295                  Scr->TBInfo.titlex + Scr->TitleBevelWidth + en, Scr->TitleBarFont.y, 
3296
3297                  (a) ? a : tmp_win->name, slen);
3298         }
3299     else
3300 #endif
3301 /* djhjr - 9/14/03 */
3302 #ifndef NO_I18N_SUPPORT
3303         MyFont_DrawString (dpy, tmp_win->title_w, &Scr->TitleBarFont,
3304 #else
3305         XDrawString (dpy, tmp_win->title_w,
3306 #endif
3307                  Scr->NormalGC, Scr->TBInfo.titlex, Scr->TitleBarFont.y,
3308                  (a) ? a : tmp_win->name, slen);
3309
3310         /* free the clipped title - djhjr - 3/29/98 */
3311         if (a) free(a);
3312
3313         /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
3314         if (Scr->TitleBevelWidth > 0)
3315         {
3316 /*
3317             Draw3DBorder (tmp_win->title_w, Scr->TBInfo.titlex, 0,
3318                 tmp_win->title_width - Scr->TBInfo.titlex - Scr->TBInfo.rightoff,
3319                 Scr->TitleHeight, Scr->TitleBevelWidth, tmp_win->title, off, True, False);
3320 */
3321 /* djhjr - 3/12/97
3322             Draw3DBorder (tmp_win->title_w, Scr->TBInfo.rightoff, Scr->FramePadding,
3323                 tmp_win->title_width - 2 * Scr->TBInfo.rightoff,
3324                 Scr->TitleHeight - 2 * Scr->FramePadding, Scr->TitleBevelWidth, tmp_win->title, off, True, False);
3325 */
3326 /* djhjr - 10/17/02
3327             Draw3DBorder (tmp_win->title_w, Scr->TBInfo.leftx + left,
3328                 Scr->FramePadding, tmp_win->title_width - (left + right),
3329                 Scr->TitleHeight - 2 * Scr->FramePadding, Scr->TitleBevelWidth, tmp_win->title, off, False, False);
3330 */
3331             if (Scr->FramePadding + Scr->ButtonIndent > 0)
3332             {
3333                 Draw3DBorder(tmp_win->title_w, 0, 0,
3334                              tmp_win->title_width, Scr->TitleHeight,
3335                              Scr->TitleBevelWidth, tmp_win->title,
3336                              off, False, False);
3337             }
3338             else
3339             {
3340                 Draw3DBorder(tmp_win->title_w, left, 0,
3341                              tmp_win->title_width - (left + right),
3342                              Scr->TitleHeight,
3343                              Scr->TitleBevelWidth, tmp_win->title,
3344                              off, False, False);
3345             }
3346         }
3347 }
3348
3349 /* djhjr - 11/17/97 */
3350 /* collapsed the two functions PTB() and PTBH() - djhjr - 8/10/98 */
3351 /* djhjr - 10/30/02 */
3352 void PaintTitleButton(tmp_win, tbw, onoroff)
3353 TwmWindow *tmp_win;
3354 TBWindow  *tbw;
3355 int onoroff; /* 0 = no hilite    1 = hilite off    2 = hilite on */
3356 {
3357     Image *image;
3358     TitleButton *tb;
3359     /* djhjr - 5/23/98 8/10/98 */
3360     ColorPair cp;
3361
3362     if (!tbw->window) return;
3363
3364     tb = tbw->info;
3365
3366     /* djhjr - 5/23/98 8/10/98 */
3367     if (Scr->ButtonColorIsFrame)
3368         cp = (onoroff == 2) ? tmp_win->border : tmp_win->border_tile;
3369     else
3370         cp = tmp_win->title;
3371     cp.fore = tmp_win->title.fore;
3372
3373     image = GetImage(tb->name, tb->width, tb->height,
3374                      Scr->ButtonBevelWidth * 2, cp);
3375
3376     XCopyArea(dpy, image->pixmap, tbw->window, Scr->NormalGC,
3377               tb->srcx, tb->srcy, tb->width, tb->height, tb->dstx, tb->dsty);
3378
3379     /* djhjr - 8/10/98 8/18/98 */
3380     /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */
3381     if (Scr->ButtonBevelWidth > 0)
3382         Draw3DBorder(tbw->window, 0, 0, tb->width, tb->height,
3383                      Scr->ButtonBevelWidth, cp, off, False, False);
3384 }
3385
3386 /* djhjr - 4/19/96 */
3387 /* re-arranged - djhjr - 4/5/98 */
3388 void PaintTitleHighlight(tmp_win, onoroff)
3389 TwmWindow *tmp_win;
3390 Bool onoroff;
3391 {
3392         /* djhjr - 4/3/98 */
3393         if (!tmp_win->titlehighlight) return;
3394
3395         if (tmp_win->hilite_w)
3396         {
3397                 if (onoroff == on)
3398                         XMapWindow (dpy, tmp_win->hilite_w);
3399                 else
3400                         XUnmapWindow (dpy, tmp_win->hilite_w);
3401         }
3402         else if (Scr->hiliteName && tmp_win->title_height != 0)
3403                 DrawTitleHighlight(tmp_win, onoroff);   /* djhjr - 10/25/02 */
3404 }
3405
3406 /* djhjr - 4/2/98 10/18/02 */
3407 int ComputeHighlightWindowWidth(tmp_win)
3408 TwmWindow *tmp_win;
3409 {
3410 /* djhjr - 9/14/03 */
3411 #ifndef NO_I18N_SUPPORT
3412         int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1);
3413 #else
3414         int en = XTextWidth(Scr->TitleBarFont.font, "n", 1);
3415 #endif
3416
3417         return (tmp_win->rightx - tmp_win->highlightx - en);
3418 }
3419