1 /*--------------------------------*-C-*---------------------------------*
2  * File:	main.c
3  *----------------------------------------------------------------------*
4  * Copyright (C) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *---------------------------------------------------------------------*/
20 /*---------------------------------------------------------------------*
21  * Originally written:
22  *    1992      John Boyey, University of Canterbury
23  * Modifications:
24  *    1994      Robert Nation <nation@rocket.sanders.lockheed.com>
25  *              - extensive modifications
26  *    1995      Garrett D'Amore <garrett@netcom.com>
27  *    1997      mj olesen <olesen@me.QueensU.CA>
28  *              - extensive modifications
29  *    1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de>
30  *    1998      Geoff Wing <gcw@pobox.com>
31  *    1998      Sasha Vasko <sasha at aftercode.net>
32  *----------------------------------------------------------------------*/
33 
34 #ifndef lint
35 static const char rcsid[] = "$Id: main.c,v 1.33 2007/08/01 14:08:29 vae Exp $";
36 #endif
37 
38 #define INTERN			/* assign all global vars to me */
39 #include "rxvt.h"		/* NECESSARY */
40 #include "X11/Xatom.h"
41 #include "X11/Xproto.h"
42 #include <locale.h>
43 
44 Window ParentWin[PARENTS_NUM] = PARENTS_INIT;
45 int    ParentWinNum = 0;
46 
47 #ifdef HAVE_AFTERIMAGE
48 ASVisual *asv = NULL ;
49 #endif
50 
51 #ifdef HAVE_AFTERSTEP
DeadPipe(int unused)52 void DeadPipe( int unused )
53 {
54 }
55 #else
56 Atom 			_XA_MwmAtom = None;
57 Atom 			_XA_NET_WM_PID = None;
58 Atom  			_XROOTPMAP_ID = None;
59 Atom  			_XA_NET_SUPPORTING_WM_CHECK = None;
60 Atom  			_XA_NET_SUPPORTED           = None;
61 Atom  			_XA_NET_CURRENT_DESKTOP     = None;
62 Atom 			_XA_NET_WM_DESKTOP			= None;
63 Atom 			_XA_NET_WM_STATE			= None;
64 Atom 			_XA_NET_WM_STATE_STICKY		= None;
65 Atom 			_XA_NET_WM_STATE_SHADED		= None;
66 Atom 			_XA_NET_WM_STATE_HIDDEN		= None;
67 
68 #endif
69 
70 /*{{{ extern functions referenced */
71 #ifdef DISPLAY_IS_IP
72 extern char    *network_display(const char *display);
73 #endif
74 /*}}} */
75 
76 /*{{{ local variables */
77 static Cursor   TermWin_cursor;	/* cursor for vt window */
78 
79 static XSizeHints szHint =
80 {
81     PMinSize | PResizeInc | PBaseSize | PWinGravity,
82     0, 0, 80, 24,		/* x, y, width, height */
83     1, 1,			/* Min width, height */
84     0, 0,			/* Max width, height - unused */
85     1, 1,			/* increments: width, height */
86     {1, 1},			/* increments: x, y */
87     {0, 0},			/* Aspect ratio - unused */
88     0, 0,			/* base size: width, height */
89     NorthWestGravity		/* gravity */
90 };
91 
92 static const char *def_colorName[] =
93 {
94     "White", "Black", 		/* fg/bg */
95 /* low-intensity colors */
96     "Black",			/* 0: black             (#000000) */
97 #ifndef NO_BRIGHTCOLOR
98     "Red3",			/* 1: red               (#CD0000) */
99     "Green3",			/* 2: green             (#00CD00) */
100     "Yellow3",			/* 3: yellow            (#CDCD00) */
101     "Blue3",			/* 4: blue              (#0000CD) */
102     "Magenta3",			/* 5: magenta           (#CD00CD) */
103     "Cyan3",			/* 6: cyan              (#00CDCD) */
104     "AntiqueWhite",		/* 7: white             (#FAEBD7) */
105 /* high-intensity colors */
106     "Grey25",			/* 8: bright black      (#404040) */
107 #endif				/* NO_BRIGHTCOLOR */
108     "Red",			/* 1/9: bright red      (#FF0000) */
109     "Green",			/* 2/10: bright green   (#00FF00) */
110     "Yellow",			/* 3/11: bright yellow  (#FFFF00) */
111     "Blue",			/* 4/12: bright blue    (#0000FF) */
112     "Magenta",			/* 5/13: bright magenta (#FF00FF) */
113     "Cyan",			/* 6/14: bright cyan    (#00FFFF) */
114     "White",			/* 7/15: bright white   (#FFFFFF) */
115 #ifndef NO_CURSORCOLOR
116     NULL, NULL,
117 #endif				/* NO_CURSORCOLOR */
118     NULL,			/* pointerColor                   */
119     NULL			/* borderColor                    */
120 #if defined(TRANSPARENT) || defined(BACKGROUND_IMAGE)
121     ,NULL
122 #endif
123 #ifndef NO_BOLDUNDERLINE
124   , NULL, NULL
125 #endif				/* NO_BOLDUNDERLINE */
126 #ifdef KEEP_SCROLLCOLOR
127   , "#B2B2B2",			/* scrollColor: `match' Netscape color */
128     "#969696"			/* troughColor */
129 #endif
130 };
131 
132 #ifdef MULTICHAR_SET
133 /* Multicharacter font names, roman fonts sized to match */
134 static const char *def_mfontName[] =
135 {
136     MFONT_LIST
137 };
138 #endif				/* MULTICHAR_SET */
139 
140 static const char *def_fontName[] =
141 {
142     NFONT_LIST
143 };
144 
145 /*}}} */
146 
147 #if 0
148 /*----------------------------------------------------------------------*/
149 /* ARGSUSED */
150 /* PROTO */
151 XErrorHandler
152 xerror_handler(Display * display, XErrorEvent * event)
153 {
154     print_error("XError: Request: %d . %d, Error: %d", event->request_code,
155 		event->minor_code, event->error_code);
156 /*
157     if( *p )
158 	return 1 ;
159 */
160     if(  ( event->request_code != X_GetAtomName ) &&
161 	     ( event->request_code != X_GetGeometry || event->error_code != BadDrawable ) )
162 		exit(EXIT_FAILURE);
163     return 0;
164 }
165 
166 #else
167 
168 XErrorHandler
xerror_handler(Display * dpy,XErrorEvent * event)169 xerror_handler (Display * dpy, XErrorEvent * event)
170 {
171 	char         *err_text;
172 
173     fprintf (stderr, "aterm has encountered the following problem interacting with X Windows :\n");
174 	if (event && dpy)
175 	{
176         err_text = malloc (128);
177 		strcpy (err_text, "unknown error");
178 		XGetErrorText (dpy, event->error_code, err_text, 120);
179 		fprintf (stderr, "      Request: %d,    Error: %d(%s)\n", event->request_code, event->error_code, err_text);
180 		free (err_text);
181 		fprintf (stderr, "      in resource: 0x%lX\n", event->resourceid);
182     }
183 	return 0;
184 }
185 #endif
186 
187 
188 
189 #ifdef DEBUG_X
190 #define XGetGeometry(dpy,win,r,x,y,w,h,b,d) \
191 	trace_XGetGeometry(__FILE__,__LINE__,dpy,win,r,x,y,w,h,b,d)
192 #endif
193 
194 /*{{{ color aliases, fg/bg bright-bold */
195 /* PROTO */
196 void
color_aliases(int idx)197 color_aliases(int idx)
198 {
199     if (rs_color[idx] && isdigit(*rs_color[idx])) {
200 	int             i = atoi(rs_color[idx]);
201 
202 	if (i >= 8 && i <= 15) {	/* bright colors */
203 	    i -= 8;
204 #ifndef NO_BRIGHTCOLOR
205 	    rs_color[idx] = rs_color[minBrightCOLOR + i];
206 	    return;
207 #endif
208 	}
209 	if (i >= 0 && i <= 7)	/* normal colors */
210 	    rs_color[idx] = rs_color[minCOLOR + i];
211     }
212 }
213 
214 /*
215  * find if fg/bg matches any of the normal (low-intensity) colors
216  */
217 #ifndef NO_BRIGHTCOLOR
218 /* PROTO */
219 void
set_colorfgbg(void)220 set_colorfgbg(void)
221 {
222     unsigned int    i;
223     static char     colorfgbg_env[] = "COLORFGBG=default;default;bg";
224     char           *p;
225     int             fg = -1, bg = -1;
226 
227     for (i = Color_Black; i <= Color_White; i++)
228 	{
229 		if (PixColors[Color_fg] == PixColors[i]) {
230 	    	fg = (i - Color_Black);
231 	    	break;
232 		}
233     }
234     for (i = Color_Black; i <= Color_White; i++)
235 	{
236 		if (PixColors[Color_bg] == PixColors[i]) {
237 	    	bg = (i - Color_Black);
238 	    	break;
239 		}
240     }
241 
242     p = strchr(colorfgbg_env, '=');
243     p++;
244     if (fg >= 0)
245 	sprintf(p, "%d;", fg);
246     else
247 	STRCPY(p, "default;");
248     p = strchr(p, '\0');
249     if (bg >= 0)
250 	sprintf(p,"%d", bg);
251     else
252 	STRCPY(p, "default");
253 
254     putenv(colorfgbg_env);
255 
256     colorfgbg = DEFAULT_RSTYLE;
257     for (i = minCOLOR; i <= maxCOLOR; i++) {
258 	if (PixColors[Color_fg] == PixColors[i]
259 # ifndef NO_BOLDUNDERLINE
260 	    && PixColors[Color_fg] == PixColors[Color_BD]
261 # endif				/* NO_BOLDUNDERLINE */
262     /* if we wanted boldFont to have precedence */
263 # if 0				/* ifndef NO_BOLDFONT */
264 	    && TermWin.boldFont == NULL
265 # endif				/* NO_BOLDFONT */
266 	    )
267 	    colorfgbg = SET_FGCOLOR(colorfgbg, i);
268 	if (PixColors[Color_bg] == PixColors[i])
269 	    colorfgbg = SET_BGCOLOR(colorfgbg, i);
270     }
271 }
272 #else				/* NO_BRIGHTCOLOR */
273 # define set_colorfgbg() ((void)0)
274 #endif				/* NO_BRIGHTCOLOR */
275 /*}}} */
276 
277 /* PROTO */
278 void
set_terminal_size(unsigned int new_ncol,unsigned int new_nrow)279 set_terminal_size( unsigned int new_ncol, unsigned int new_nrow )
280 {
281     if( new_nrow <= 0) new_nrow = 24 ;
282     if( new_ncol <= 0) new_ncol = 80 ;
283     TermWin.ncol = new_ncol;
284     TermWin.nrow = new_nrow;
285     TermWin.bcol = new_ncol;
286     MAX_IT(TermWin.bcol, TermWin.min_bcol);
287 }
288 
289 
290 /*{{{ set_cursor_color() - Updates color of the TerWin_cursor */
291 /* PROTO */
292 void
set_cursor_color()293 set_cursor_color()
294 {
295     XColor          fg, bg;
296 
297     fg.pixel = PixColorsFocused[Color_pointer];
298     XQueryColor(Xdisplay, Xcmap, &fg);
299     bg.pixel = PixColorsFocused[Color_bg];
300     XQueryColor(Xdisplay, Xcmap, &bg);
301     XRecolorCursor(Xdisplay, TermWin_cursor, &fg, &bg);
302 }
303 /*}}} */
304 #if defined(BACKGROUND_IMAGE)
SetBackgroundPixmap(char * PixmapSpec)305 int SetBackgroundPixmap(char* PixmapSpec)
306 {
307   char *geometry = strchr(PixmapSpec, ';');
308   int bChanged = 0 ;
309 
310     if (geometry != NULL)
311     {
312         *geometry = '\0' ; /* so to get clean pixmap filename */
313         bChanged = parse_pixmap_geom(geometry+1);
314     }
315     LoadBGPixmap(PixmapSpec);
316 #ifdef _MYSTYLE_
317     if( TermWin.background.trgType == BGT_MyStyle )
318 		TermWin.background.trgType = BGT_Tile ;
319 #endif
320 
321     if( geometry ) *geometry = ';' ;
322     return bChanged ;
323 }
324 #endif
325 
326 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT) || defined(_MYSTYLE_)
327 
SetBackgroundType(const char * type)328 void SetBackgroundType( const char *type )
329 {
330 
331 #ifdef _MYSTYLE_
332     if( TermWin.background.trgType != BGT_MyStyle )
333 #endif
334 	TermWin.background.trgType = BGT_Tile ;
335 
336 #ifdef TRANSPARENT
337     if( (Options & Opt_transparent) )
338     {
339 		if( TermWin.background.Shading.shading != 100)
340 	    	TermWin.background.trgType = BGT_Cut ;
341 		else
342 	    	TermWin.background.trgType = BGT_None ;
343     }
344 #endif
345     if( type == NULL || TermWin.background.trgType != BGT_Tile)
346 		return ;
347 
348     if( strcmp( type, BGT_CENTER ) == 0 )
349 		TermWin.background.trgType = BGT_Center ;
350     else if( strcmp( type, BGT_SCALE ) == 0 )
351 		TermWin.background.trgType = BGT_Scale ;
352     else if( strcmp( type, BGT_SCALEH ) == 0 )
353 		TermWin.background.trgType = BGT_ScaleH ;
354     else if( strcmp( type, BGT_SCALEV ) == 0 )
355 		TermWin.background.trgType = BGT_ScaleV ;
356     else if( strcmp( type, BGT_NO_TILE ) == 0 )
357 		TermWin.background.trgType = BGT_NoTile ;
358     else if( strcmp( type, BGT_NO_TILE_H ) == 0 )
359 		TermWin.background.trgType = BGT_NoTileH ;
360     else if( strcmp( type, BGT_NO_TILE_V ) == 0 )
361 		TermWin.background.trgType = BGT_NoTileV ;
362     else if( strcmp( type, BGT_CUT ) == 0 )
363 		TermWin.background.trgType = BGT_Cut ;
364 }
365 
InitBackground()366 void InitBackground()
367 {
368     TermWin.background.srcPixmap = None ;
369     TermWin.background.mystyle = NULL ;
370     TermWin.background.user_flags = 0 ;
371     TermWin.background.bMySource = 0 ;
372     TermWin.background.trgPixmap = None ;
373     TermWin.background.trgPixmapSet = 0 ;
374     TermWin.background.Width = 0 ;
375     TermWin.background.Height = 0 ;
376     TermWin.background.srcWidth = -1 ;
377     TermWin.background.srcHeight = -1 ;
378     TermWin.background.srcX = -1 ;
379     TermWin.background.srcY = -1 ;
380 #ifdef SCALING_GEOM_ENABLED
381     TermWin.background.trgWidth = -1 ;
382     TermWin.background.trgHeight = -1 ;
383     TermWin.background.trgX = -1 ;
384     TermWin.background.trgY = -1 ;
385 #endif
386     TermWin.background.finWidth = 0 ;
387     TermWin.background.finHeight = 0 ;
388     TermWin.background.cutX = -1 ;
389     TermWin.background.cutY = -1 ;
390 
391     /* some defaults here */
392     INIT_SHADING(TermWin.background.Shading)
393 
394 }
395 #endif
396 
ParseGCType(const char * type,int def_type)397 int ParseGCType( const char* type, int def_type )
398 {
399     if( !type ) return def_type ;
400 
401     if( strcmp( type, GC_TYPE_AND )== 0 ) return GXand;
402     else if( strcmp( type, GC_TYPE_AND_REV )== 0 ) return GXandReverse;
403     else if( strcmp( type, GC_TYPE_AND_INV )== 0 ) return GXandInverted;
404     else if( strcmp( type, GC_TYPE_XOR	)== 0 ) return GXxor;
405     else if( strcmp( type, GC_TYPE_OR	)== 0 ) return GXor;
406     else if( strcmp( type, GC_TYPE_NOR )== 0 ) return GXnor;
407     else if( strcmp( type, GC_TYPE_INVERT )== 0 ) return GXinvert;
408     else if( strcmp( type, GC_TYPE_EQUIV )== 0 ) return GXequiv;
409     else if( strcmp( type, GC_TYPE_INVERT )== 0 ) return GXinvert ;
410     else if( strcmp( type, GC_TYPE_OR_REV )== 0 ) return GXorReverse;
411     else if( strcmp( type, GC_TYPE_OR_INV )== 0 ) return GXorInverted ;
412     else if( strcmp( type, GC_TYPE_NAND )== 0 ) return GXnand	;
413     return def_type ;
414 }
415 
416 #ifdef OFF_FOCUS_FADING
fade_color(unsigned long pixel)417 unsigned long fade_color(unsigned long pixel)
418 {
419     if( rs_fade )
420     {/* make unfocused colors here */
421       XColor          faded_xcol;
422       int fade = 0;
423 
424         fade = atoi( rs_fade );
425         faded_xcol.pixel = pixel ;
426 	XQueryColor( Xdisplay, Xcmap, &faded_xcol );
427         faded_xcol.red   = (faded_xcol.red/100)*fade ;
428         faded_xcol.green = (faded_xcol.green/100)*fade ;
429         faded_xcol.blue  = (faded_xcol.blue/100)*fade ;
430 
431         if( XAllocColor(Xdisplay, Xcmap, &faded_xcol) )
432     	    return faded_xcol.pixel ;
433     }
434     return pixel ;
435 }
436 #endif
437 
438 /*{{{ Create_Windows() - Open and map the window */
439 /* PROTO */
440 void
Create_Windows(int argc,char * argv[])441 Create_Windows(int argc, char *argv[])
442 {
443     Cursor          cursor;
444     XClassHint      classHint;
445     XWMHints        wmHint;
446     MwmHints 		mwmhints;
447     int             i, x, y, flags;
448     unsigned int    width, height;
449     XSetWindowAttributes attributes;
450 	unsigned long attr_mask ;
451 
452 #ifdef PREFER_24BIT
453     XWindowAttributes gattr;
454         Xcmap = DefaultColormap(Xdisplay, Xscreen);
455         Xvisual = DefaultVisual(Xdisplay, Xscreen);
456 
457     if (Options & Opt_transparent) {
458         XGetWindowAttributes(Xdisplay, RootWindow(Xdisplay, Xscreen), &gattr);
459         Xdepth = gattr.depth;
460     } else {
461         Xdepth = DefaultDepth(Xdisplay, Xscreen);
462  /*
463   * If depth is not 24, look for a 24bit visual.
464   */
465         if (Xdepth != 24) {
466              XVisualInfo        vinfo;
467 
468              if (XMatchVisualInfo(Xdisplay, Xscreen, 24, TrueColor, &vinfo)) {
469                 Xdepth = 24;
470                 Xvisual = vinfo.visual;
471                 Xcmap = XCreateColormap(Xdisplay,
472                                         RootWindow(Xdisplay, Xscreen), Xvisual,
473                                         AllocNone);
474              }
475 	}
476     }
477 #endif
478 
479     if (Options & Opt_borderLess)
480 	{
481     	if (_XA_MwmAtom == None) {
482 /*     print_warning("Window Manager does not support MWM hints.  Bypassing window manager control for borderless window.\n");*/
483        		attributes.override_redirect = TRUE;
484        		mwmhints.flags = 0;
485     	} else
486 		{
487     		mwmhints.flags = MWM_HINTS_DECORATIONS;
488 			mwmhints.decorations = 0;
489     	}
490     } else
491 	{
492     	mwmhints.flags = 0;
493     }
494 
495 
496 /*
497  * grab colors before netscape does
498  */
499     PixColors = &(PixColorsFocused[0]);
500 
501     for (i = 0;
502 	 i < (Xdepth <= 2 ? 2 : NRS_COLORS);
503 	 i++) {
504 	const char     *const msg = "can't load color \"%s\", colorID = %d, (%d)";
505 	XColor          xcol;
506 
507 	if (!rs_color[i])
508 	    continue;
509 
510 	if (!XParseColor(Xdisplay, Xcmap, rs_color[i], &xcol) ||
511 	    !XAllocColor(Xdisplay, Xcmap, &xcol))
512 	{
513 	    print_error(msg, rs_color[i], i, TOTAL_COLORS);
514 	    rs_color[i] = def_colorName[i];
515 	    if (!rs_color[i])
516 		continue;
517 	    if (!XParseColor(Xdisplay, Xcmap, rs_color[i], &xcol) ||
518 		!XAllocColor(Xdisplay, Xcmap, &xcol))
519 	    {
520 		print_error(msg, rs_color[i], i, TOTAL_COLORS);
521 		switch (i) {
522 		case Color_fg:
523 		case Color_bg:
524 		/* fatal: need bg/fg color */
525 		    print_error("aborting");
526 		    exit(EXIT_FAILURE);
527 		    break;
528 #ifndef NO_CURSORCOLOR
529 		case Color_cursor:
530 		    xcol.pixel = PixColors[Color_bg];
531 		    break;
532 		case Color_cursor2:
533 		    xcol.pixel = PixColors[Color_fg];
534 		    break;
535 #endif				/* NO_CURSORCOLOR */
536 		case Color_pointer:
537 		    xcol.pixel = PixColors[Color_fg];
538 		    break;
539 #if defined(TRANSPARENT) || defined(BACKGROUND_IMAGE)
540 		case Color_tint:
541 		    xcol.pixel = PixColors[Color_bg];
542 		    break;
543 #endif
544 		default:
545 		    xcol.pixel = PixColors[Color_bg];	/* None */
546 		    break;
547 		}
548 		XQueryColor( Xdisplay, Xcmap,&xcol);
549 	    }
550 	}
551 	PixColors[i] = xcol.pixel;
552 #ifdef OFF_FOCUS_FADING
553 	PixColorsUnFocused[i] = fade_color(xcol.pixel);
554 #endif
555 #if defined(TRANSPARENT) || defined(BACKGROUND_IMAGE)
556 	if( i == Color_tint )
557 	{
558 	    TermWin.background.Shading.tintColor.pixel = xcol.pixel ;
559 	    TermWin.background.Shading.tintColor.red = xcol.red ;
560 	    TermWin.background.Shading.tintColor.green = xcol.green ;
561 	    TermWin.background.Shading.tintColor.blue = xcol.blue ;
562 	    TermWin.background.Shading.tintColor.flags = xcol.flags ;
563 	}
564 #endif
565 
566     }
567 
568     if (Xdepth <= 2 || !rs_color[Color_pointer])
569 	PixColors[Color_pointer] = PixColors[Color_fg];
570     if (Xdepth <= 2 || !rs_color[Color_border])
571 	PixColors[Color_border] = PixColors[Color_fg];
572 
573 /*
574  * get scrollBar/menuBar shadow colors
575  *
576  * The calculations of topShadow/bottomShadow values are adapted
577  * from the fvwm window manager.
578  */
579 #ifdef KEEP_SCROLLCOLOR
580     if (Xdepth <= 2) {		/* Monochrome */
581 	PixColors[Color_scroll] = PixColors[Color_fg];
582 	PixColors[Color_topShadow] = PixColors[Color_bg];
583 	PixColors[Color_bottomShadow] = PixColors[Color_bg];
584     } else {
585 	XColor          xcol, white;
586 
587     /* bottomShadowColor */
588 	xcol.pixel = PixColors[Color_scroll];
589 	XQueryColor(Xdisplay, Xcmap, &xcol);
590 
591 	xcol.red = ((xcol.red) / 2);
592 	xcol.green = ((xcol.green) / 2);
593 	xcol.blue = ((xcol.blue) / 2);
594 
595 	if (!XAllocColor(Xdisplay, Xcmap, &xcol)) {
596 	    print_error("can't allocate %s", "Color_bottomShadow");
597 	    xcol.pixel = PixColors[minCOLOR];
598 	}
599 	PixColors[Color_bottomShadow] = xcol.pixel;
600 
601     /* topShadowColor */
602 # ifdef PREFER_24BIT
603 	white.red = white.green = white.blue = (unsigned short) ~0;
604 	XAllocColor(Xdisplay, Xcmap, &white);
605 /*        XFreeColors(Xdisplay, Xcmap, &white.pixel, 1, ~0); */
606 # else
607 	white.pixel = WhitePixel(Xdisplay, Xscreen);
608 	XQueryColor(Xdisplay, Xcmap, &white);
609 # endif
610 
611 	xcol.pixel = PixColors[Color_scroll];
612 	XQueryColor(Xdisplay, Xcmap, &xcol);
613 
614 	xcol.red = max((white.red / 5), (int)xcol.red);
615 	xcol.green = max((white.green / 5), (int)xcol.green);
616 	xcol.blue = max((white.blue / 5), (int)xcol.blue);
617 
618 	xcol.red = min((int)white.red, (xcol.red * 7) / 5);
619 	xcol.green = min((int)white.green, (xcol.green * 7) / 5);
620 	xcol.blue = min((int)white.blue, (xcol.blue * 7) / 5);
621 
622 	if (!XAllocColor(Xdisplay, Xcmap, &xcol)) {
623 	    print_error("can't allocate %s", "Color_topShadow");
624 	    xcol.pixel = PixColors[Color_White];
625 	}
626 	PixColors[Color_topShadow] = xcol.pixel;
627     }
628 #endif				/* KEEP_SCROLLCOLOR */
629 
630     szHint.base_width = (2 * TermWin_internalBorder +
631 			 (Options & Opt_scrollBar ? (SB_WIDTH + 2 * sb_shadow)
632 			  : 0));
633     szHint.base_height = (2 * TermWin_internalBorder);
634 
635     flags = (rs_geometry ?
636 	     XParseGeometry(rs_geometry, &x, &y, &width, &height) : 0);
637 
638     if (flags & WidthValue) {
639 	szHint.width = width;
640 	szHint.flags |= USSize;
641     }
642     if (flags & HeightValue) {
643 	szHint.height = height;
644 	szHint.flags |= USSize;
645     }
646 
647     set_terminal_size( szHint.width, szHint.height );
648 
649     change_font(1, NULL);
650 
651     { /* ONLYIF MENUBAR */
652 	szHint.base_height += (delay_menu_drawing ? menuBar_TotalHeight() : 0);
653     }
654 
655     if (flags & XValue) {
656 	if (flags & XNegative) {
657 	    x += (DisplayWidth(Xdisplay, Xscreen)
658 		  - (szHint.width + TermWin_internalBorder));
659 	    szHint.win_gravity = NorthEastGravity;
660 	}
661 	szHint.x = x;
662 	szHint.flags |= USPosition;
663     }
664     if (flags & YValue) {
665 	if (flags & YNegative) {
666 	    y += (DisplayHeight(Xdisplay, Xscreen)
667 		  - (szHint.height + TermWin_internalBorder));
668 	    szHint.win_gravity = (szHint.win_gravity == NorthEastGravity ?
669 				  SouthEastGravity : SouthWestGravity);
670 	}
671 	szHint.y = y;
672 	szHint.flags |= USPosition;
673     }
674 /* parent window - reverse video so we can see placement errors
675  * sub-window placement & size in resize_subwindows()
676  */
677     attributes.background_pixel = PixColors[Color_bg];
678     attributes.border_pixel = PixColors[Color_fg];
679 	attributes.event_mask = ( KeyPressMask |
680 							  FocusChangeMask |
681 		  					  StructureNotifyMask |
682 							  VisibilityChangeMask |
683 							  PropertyChangeMask);
684     attributes.colormap = Xcmap;
685 	attributes.background_pixmap = ParentRelative;
686 	attr_mask = CWBorderPixel | CWEventMask ;
687 #ifdef HAVE_AFTERSTEP
688 	if( TermWin.background.trgType == BGT_MyStyle )
689 		attr_mask |= CWBackPixmap ;
690 #endif
691 #ifdef TRANSPARENT
692 	if( get_flags(Options, Opt_transparent) )
693 		attr_mask |= CWBackPixmap ;
694 #endif
695 	if( (attr_mask & CWBackPixmap ) == 0 )
696 	  	attr_mask |= CWBackPixel ;
697 
698 #ifdef HAVE_AFTERIMAGE
699     TermWin.parent = create_visual_window( asv, Xroot,
700 					   szHint.x, szHint.y,
701 					   szHint.width, szHint.height,
702                        TermWin.borderWidth,
703 					   InputOutput,
704 					   attr_mask,
705 					   &attributes);
706 
707 #else
708 	attr_mask |= CWColormap ;
709     TermWin.parent = XCreateWindow(Xdisplay, Xroot,
710 				   szHint.x, szHint.y,
711 				   szHint.width, szHint.height,
712                                    TermWin.borderWidth,
713 				   Xdepth, InputOutput,
714 				   Xvisual,
715 				   attr_mask,
716 				   &attributes);
717 #endif
718     TermWin.bMapped = 0 ;
719     ParentWin[0] = TermWin.parent ;
720     ParentWinNum = 1 ;
721 
722     xterm_seq(XTerm_title, rs_title);
723     xterm_seq(XTerm_iconName, rs_iconName);
724 /* ignore warning about discarded `const' */
725     classHint.res_name = (char *)rs_name;
726     classHint.res_class = APL_CLASS;
727     wmHint.input = True;
728     wmHint.initial_state = (Options & Opt_iconic ? IconicState : NormalState);
729     wmHint.window_group = TermWin.parent;
730     wmHint.flags = (InputHint | StateHint | WindowGroupHint);
731 
732     XSetWMProperties(Xdisplay, TermWin.parent, NULL, NULL, argv, argc,
733 		     &szHint, &wmHint, &classHint);
734 
735 	/* publish our PID : */
736 	{
737 		long ldata = getpid();
738         XChangeProperty (Xdisplay, TermWin.parent, _XA_NET_WM_PID, XA_CARDINAL, 32,
739                          PropModeReplace, (unsigned char *)&ldata, 1);
740 	}
741 
742 
743     if (mwmhints.flags && _XA_MwmAtom) {
744     	XChangeProperty(Xdisplay, TermWin.parent, _XA_MwmAtom, _XA_MwmAtom, 32, PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS);
745     }
746 
747 
748 /* vt cursor: Black-on-White is standard, but this is more popular */
749     TermWin_cursor = XCreateFontCursor(Xdisplay, XC_xterm);
750     {
751 		XColor          fg, bg;
752 
753 		fg.pixel = PixColors[Color_pointer];
754 		XQueryColor(Xdisplay, Xcmap, &fg);
755 		bg.pixel = PixColors[Color_bg];
756 		XQueryColor(Xdisplay, Xcmap, &bg);
757 		XRecolorCursor(Xdisplay, TermWin_cursor, &fg, &bg);
758     }
759 
760 /* cursor (menuBar/scrollBar): Black-on-White */
761     cursor = XCreateFontCursor(Xdisplay, XC_left_ptr);
762 	attributes.event_mask = (ExposureMask |
763 							 ButtonPressMask |
764 							 ButtonReleaseMask |
765 		  					 Button1MotionMask |
766 							 Button3MotionMask);
767 	attributes.cursor = TermWin_cursor ;
768 /* the vt window */
769 #ifdef HAVE_AFTERIMAGE
770     TermWin.vt = create_visual_window( asv, TermWin.parent,
771 				     	0, 0,
772 				     	szHint.width, szHint.height,
773 					   	0,
774 					   	InputOutput,
775 					   	attr_mask|CWCursor,
776 					   	&attributes);
777 #else
778     TermWin.vt = XCreateSimpleWindow(Xdisplay, TermWin.parent,
779 				     0, 0,
780 				     szHint.width, szHint.height,
781 				     0,
782 				     PixColors[Color_fg],
783 				     PixColors[Color_bg]);
784     XSelectInput(Xdisplay, TermWin.vt, attributes.event_mask );
785 	XDefineCursor(Xdisplay, TermWin.vt, TermWin_cursor);
786 #endif
787 
788 
789 #ifdef TRANSPARENT
790     if (get_flags(Options, Opt_transparent)) {
791 		if( TermWin.background.trgType != BGT_None )
792 		    SetSrcPixmap(GetRootPixmap(None));
793 		else
794 			XSetWindowBackgroundPixmap(Xdisplay, TermWin.vt, ParentRelative);
795     }
796 #endif
797     /* added by Sasha Vasko to enabling Tracking of the Background changes */
798 #if defined(TRANSPARENT)||defined(_MYSTYLE_)
799 #if !defined(_MYSTYLE_)
800     if ((Options & Opt_transparent)||(Options&Opt_transparent_sb))
801 #endif
802 	XSelectInput( Xdisplay, Xroot, PropertyChangeMask );
803 
804 #endif
805 
806 /* scrollBar: size doesn't matter */
807 #ifdef HAVE_AFTERIMAGE
808     scrollBar.win = create_visual_window( asv, TermWin.parent,
809 						0, 0,
810 						1, 1,
811 						0,
812 					   	InputOutput,
813 					   	CWBackPixel | CWBorderPixel,
814 					   	&attributes);
815 #else
816 	scrollBar.win = XCreateSimpleWindow(Xdisplay, TermWin.parent,
817 						0, 0,
818 						1, 1,
819 						0,
820 					PixColors[Color_fg],
821 					PixColors[Color_bg]);
822 #endif
823 
824     XDefineCursor(Xdisplay, scrollBar.win, cursor);
825     XSelectInput(Xdisplay, scrollBar.win,
826 		 (ExposureMask | ButtonPressMask | ButtonReleaseMask |
827 		  Button1MotionMask | Button2MotionMask | Button3MotionMask)
828 	);
829 
830     { /* ONLYIF MENUBAR */
831 	create_menuBar(cursor);
832     }
833 #if defined(BACKGROUND_IMAGE)
834     if (rs_backgroundPixmap != NULL
835 #ifdef TRANSPARENT
836          && !(Options & Opt_transparent)
837 #endif
838        )
839         SetBackgroundPixmap((char*)rs_backgroundPixmap);
840 #endif
841 /* graphics context for the vt window */
842     {
843 	XGCValues       gcvalue;
844 	gcvalue.font = TermWin.font->fid;
845 	gcvalue.foreground = PixColors[Color_fg];
846 	gcvalue.background = PixColors[Color_bg];
847 	gcvalue.function = ParseGCType(rs_textType, GXcopy);
848 	gcvalue.graphics_exposures = 0;
849 #ifdef HAVE_AFTERIMAGE
850 	TermWin.gc = create_visual_gc(asv, TermWin.vt,
851 			       GCFunction|
852 			       GCForeground | GCBackground |
853 			       GCFont | GCGraphicsExposures,
854 			       &gcvalue);
855 #else
856 	TermWin.gc = XCreateGC(Xdisplay, TermWin.vt,
857 			       GCFunction|
858 			       GCForeground | GCBackground |
859 			       GCFont | GCGraphicsExposures,
860 			       &gcvalue);
861 #endif
862 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT)
863 	if( rs_color[Color_tint] )
864         {
865 	    if( rs_tintType )
866 	    {
867 		if( strcmp( rs_tintType, TINT_TYPE_TRUE) == 0 )
868 		{
869 		    TermWin.tintGC = None ;
870 		    if( TermWin.background.trgType == BGT_None )
871 				TermWin.background.trgType = BGT_Cut ;
872 		}
873 
874 	    }
875 	    if( TermWin.background.trgType == BGT_None )
876 	    {
877 	        gcvalue.function = ParseGCType(rs_tintType, GXand);
878 	        gcvalue.foreground = PixColors[Color_tint];
879 #ifdef HAVE_AFTERIMAGE
880     	        TermWin.tintGC = create_visual_gc( asv, TermWin.vt,
881 							    			GCFunction|GCForeground|GCGraphicsExposures,
882 											&gcvalue);
883 #else
884     	        TermWin.tintGC = XCreateGC(	Xdisplay, TermWin.vt,
885 							    			GCFunction|GCForeground|GCGraphicsExposures,
886 											&gcvalue);
887 #endif
888 	    }
889         }
890 #endif
891     }
892 }
893 /*}}} */
894 /*{{{ window resizing - assuming the parent window is the correct size */
895 /* PROTO */
896 Bool
resize_subwindows(int width,int height)897 resize_subwindows(int width, int height)
898 {
899     int             x = 0, y = 0;
900     int             old_width = TermWin.width;
901     int             old_height = TermWin.height;
902 
903     TermWin.width = TermWin.ncol * TermWin.fwidth;
904     TermWin.height = TermWin.nrow * TermWin.fheight;
905 
906 /* size and placement */
907     if (scrollbar_visible()) {
908 	scrollBar.beg = 0;
909 	scrollBar.end = height;
910 #ifndef XTERM_SCROLLBAR
911 # ifdef NEXT_SCROLLBAR
912     /* arrows can be different */
913 	scrollBar.end -= GetScrollArrowsHeight();
914 # else
915     /* arrows are as high as wide - leave 1 pixel gap */
916 	scrollBar.beg += (SB_WIDTH + 1) + sb_shadow;
917 	scrollBar.end -= (SB_WIDTH + 1) + sb_shadow;
918 # endif
919 #endif
920 
921 	width -= (SB_WIDTH + 2 * sb_shadow);
922 	if (Options & Opt_scrollBar_right)
923 	    XMoveResizeWindow(Xdisplay, scrollBar.win, width, 0,
924 			      (SB_WIDTH + 2 * sb_shadow), height);
925 	else {
926 	    XMoveResizeWindow(Xdisplay, scrollBar.win, 0, 0,
927 			      (SB_WIDTH + 2 * sb_shadow), height);
928 	    x = (SB_WIDTH + 2 * sb_shadow);	/* placement of vt window */
929 	}
930     }
931     { /* ONLYIF MENUBAR */
932 	if (menubar_visible()) {
933 	    y = menuBar_TotalHeight();	/* for placement of vt window */
934 	    Resize_menuBar(x, 0, width, y);
935 	}
936     }
937     XMoveResizeWindow(Xdisplay, TermWin.vt, x, y, width, height + 1);
938 
939 	request_background_update();
940 
941     if (old_width)
942 	Gr_Resize(old_width, old_height);
943 
944     XSync(Xdisplay, 0);
945 	return (width != old_width || height != old_height );
946 }
947 
948 /* PROTO */
949 void
resize(void)950 resize(void)
951 {
952     szHint.base_width = (2 * TermWin_internalBorder);
953     szHint.base_height = (2 * TermWin_internalBorder);
954 
955     szHint.base_width += (scrollbar_visible() ? (SB_WIDTH + 2 * sb_shadow) : 0);
956     { /* ONLYIF MENUBAR */
957 	szHint.base_height += (menubar_visible() ? menuBar_TotalHeight() : 0);
958     }
959 
960     szHint.min_width = szHint.base_width + szHint.width_inc;
961     szHint.min_height = szHint.base_height + szHint.height_inc;
962 
963     szHint.width = szHint.base_width + TermWin.width;
964     szHint.height = szHint.base_height + TermWin.height;
965 
966     szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity;
967 
968     XSetWMNormalHints(Xdisplay, TermWin.parent, &szHint);
969     XResizeWindow(Xdisplay, TermWin.parent, szHint.width, szHint.height);
970 
971     resize_subwindows(szHint.width, szHint.height);
972     scr_clear();
973 
974 }
975 
976 /*
977  * Redraw window after exposure or size change
978  */
979 /* PROTO */
980 void
resize_window1(unsigned int width,unsigned int height)981 resize_window1(unsigned int width, unsigned int height)
982 {
983     static short    first_time = 1;
984     int             new_ncol = (width - szHint.base_width) / TermWin.fwidth;
985     int             new_nrow = (height - szHint.base_height) / TermWin.fheight;
986 
987     if (first_time ||
988 	(new_ncol != TermWin.ncol) ||
989 	(new_nrow != TermWin.nrow)) {
990 	int             curr_screen = -1;
991 
992     /* scr_reset only works on the primary screen */
993 	if (!first_time) {	/* this is not the first time thru */
994 	    selection_clear();
995 	    curr_screen = scr_change_screen(PRIMARY);
996 	}
997 
998 	set_terminal_size( new_ncol, new_nrow);
999 
1000 	resize_subwindows(width, height);
1001 	scr_reset();
1002 
1003 	if (curr_screen >= 0)	/* this is not the first time thru */
1004 	    scr_change_screen(curr_screen);
1005 	first_time = 0;
1006     }
1007 }
1008 
1009 /*
1010  * good for toggling 80/132 columns
1011  */
1012 /* PROTO */
1013 void
set_width(unsigned short width)1014 set_width(unsigned short width)
1015 {
1016     unsigned short  height = TermWin.nrow;
1017 
1018     if (width != TermWin.ncol) {
1019 	width = szHint.base_width + width * TermWin.fwidth;
1020 	height = szHint.base_height + height * TermWin.fheight;
1021 
1022 	XResizeWindow(Xdisplay, TermWin.parent, width, height);
1023 	resize_window1(width, height);
1024 #ifdef USE_XIM
1025         IMSetStatusPosition();
1026 #endif
1027 	scr_clear();
1028     }
1029 }
1030 
1031 /*
1032  * Redraw window after exposure or size change
1033  */
1034 /* PROTO */
1035 void
resize_window(XEvent * ev)1036 resize_window(XEvent* ev)
1037 {
1038 	int root_x = 0, root_y = 0;
1039 	Window        wdumm;
1040 	XConfigureEvent *xconf = &(ev->xconfigure);
1041 
1042 	while( XCheckTypedWindowEvent( Xdisplay, TermWin.parent, ConfigureNotify, ev ) );
1043 	/*fprintf( stderr, "config_geom = %dx%d\n", xconf->width, xconf->height );*/
1044     resize_window1(xconf->width, xconf->height);
1045 #if 1
1046 	XTranslateCoordinates (Xdisplay, TermWin.parent, Xroot, 0, 0, &root_x, &root_y, &wdumm);
1047 
1048 	/*fprintf( stderr, "root_geom = %dx%d%+d%+d, root_size = %dx%d\n", xconf->width, xconf->height, root_x, root_y, XdisplayWidth, XdisplayHeight ); */
1049 	TermWin.root_x = root_x ;
1050 	TermWin.root_y = root_y ;
1051 	TermWin.root_width = xconf->width ;
1052 	TermWin.root_height = xconf->height ;
1053 
1054 	if( TransparentPixmapNeedsUpdate() )
1055 		request_background_update();
1056 	else
1057 	{
1058 		Bool cancel = True ;
1059 		Bool request = False ;
1060 
1061 #ifdef _MYSTYLE_
1062 		if( TermWin.background.trgType == BGT_MyStyle )
1063 		{
1064 			cancel = False ;
1065 			if( TermWin.LastPixmap_width  != TermWin.root_width ||
1066 				TermWin.LastPixmap_height != TermWin.root_height )
1067 				request = True;
1068 		}
1069 
1070 #endif
1071 #ifdef HAVE_AFTERIMAGE
1072 		if( TermWin.background.trgType == BGT_Scale ||
1073 			TermWin.background.trgType == BGT_ScaleH ||
1074 			TermWin.background.trgType == BGT_ScaleV ||
1075 			TermWin.background.trgType == BGT_Cut )
1076 		{
1077 			cancel = False ;
1078 			if( TermWin.LastPixmap_width  != TermWin.root_width ||
1079 				TermWin.LastPixmap_height != TermWin.root_height )
1080 				request = True;
1081 		}
1082 #endif
1083 		if( cancel )
1084 			cancel_background_update();
1085 		else if( request )
1086 			request_background_update();
1087 	}
1088 
1089 #else
1090 	request_background_update();
1091 #endif
1092 #if 0
1093 #if defined(TRANSPARENT) || defined(BACKGROUND_IMAGE) || defined(_MYSTYLE_)
1094     XGetGeometry(Xdisplay, TermWin.vt,
1095 		 &root, &x, &y, &vt_width, &vt_height, &border, &depth);
1096 
1097     refresh_transparent_scrollbar();
1098 
1099     if( (TermWin.bMapped && (Options & Opt_transparent)) ||
1100          TermWin.background.trgType != BGT_None )
1101     {
1102 	  int abs_x, abs_y;
1103           static int old_abs_x=0, old_abs_y=0,
1104 	             old_width=0, old_height=0;
1105 
1106 	    if( GetMyPosition(&abs_x, &abs_y))
1107 	    {
1108 /*	    fprintf( stderr, "\naterm:resize_windows():old = %dx%d+%d+%d, new = %dx%d+%d+%d",
1109 		     old_width, old_height, old_abs_x, old_abs_y,
1110 		     vt_width, vt_height, abs_x, abs_y   );
1111 */
1112 #ifdef _MYSTYLE_
1113 	        if( TermWin.background.trgType == BGT_MyStyle )
1114 		{ /* we want to avoid unneeded redraws if we
1115 		     only have gradients */
1116 		    if( TransparentMS(TermWin.background.mystyle) || vt_width != old_width || vt_height!= old_height )
1117 			{
1118 			    RenderPixmap(1);
1119 			    old_width = vt_width ;
1120 			    old_height = vt_height ;
1121 			}
1122 		    RenderPixmap(1);
1123 	        scr_clear();
1124 			scr_touch();
1125 			return ;
1126 		}
1127 #endif
1128 		if( TermWin.background.trgType != BGT_None )
1129 		{
1130 		    ValidateSrcPixmap( 1 );
1131 	    	    if( abs_x != old_abs_x || abs_y != old_abs_y ||
1132 	    		vt_width != old_width || vt_height!= old_height ||
1133 			TermWin.LastPixmapUsed != TermWin.background.srcPixmap )
1134 		    {
1135     			RenderPixmap(1);
1136 			/* we've already validated source pixmap
1137 			   of course user can change it in any time
1138 			   but for performance considerations we
1139 			   don't want to recheck it*/
1140     			scr_clear();
1141             		scr_touch();
1142 
1143 			old_width = vt_width ;
1144 			old_height = vt_height ;
1145             		old_abs_x = abs_x ;
1146 			old_abs_y = abs_y ;
1147 		    }
1148 		}
1149 #ifdef TRANSPARENT
1150 		else if( abs_x != old_abs_x || abs_y != old_abs_y )
1151 		{
1152 		    scr_clear();
1153         	    scr_touch();
1154 
1155         	    old_abs_x = abs_x ;
1156 		    old_abs_y = abs_y ;
1157 		}
1158 #endif
1159 	    }
1160         }
1161     }
1162     else
1163 #endif
1164 #endif
1165     {
1166         scr_clear();
1167         scr_touch();
1168     }
1169 }
1170 /*}}} */
1171 /*{{{ xterm sequences - title, iconName, color (exptl) */
1172 #ifdef SMART_WINDOW_TITLE
1173 /* PROTO */
1174 void
set_title(const char * str)1175 set_title(const char *str)
1176 {
1177     char           *name;
1178 
1179     if (XFetchName(Xdisplay, TermWin.parent, &name))
1180 	name = NULL;
1181     if (name == NULL || strcmp(name, str))
1182 	XStoreName(Xdisplay, TermWin.parent, str);
1183     if (name)
1184 	XFree(name);
1185 }
1186 #else
1187 # define set_title(str)	XStoreName (Xdisplay, TermWin.parent, str)
1188 #endif
1189 
1190 #ifdef SMART_WINDOW_TITLE
1191 /* PROTO */
1192 void
set_iconName(const char * str)1193 set_iconName(const char *str)
1194 {
1195     char           *name;
1196 
1197     if (XGetIconName(Xdisplay, TermWin.parent, &name))
1198 	name = NULL;
1199     if (name == NULL || strcmp(name, str))
1200 	XSetIconName(Xdisplay, TermWin.parent, str);
1201     if (name)
1202 	XFree(name);
1203 }
1204 #else
1205 # define set_iconName(str) XSetIconName (Xdisplay, TermWin.parent, str)
1206 #endif
1207 
1208 #ifdef XTERM_COLOR_CHANGE
1209 /* PROTO */
1210 void
set_window_color(int idx,const char * color)1211 set_window_color(int idx, const char *color)
1212 {
1213     const char     *const msg = "can't load color \"%s\"";
1214     XColor          xcol;
1215     int             i;
1216 
1217     if (color == NULL || *color == '\0')
1218 	return;
1219 
1220 /* handle color aliases */
1221     if (isdigit(*color)) {
1222 	i = atoi(color);
1223 	if (i >= 8 && i <= 15) {	/* bright colors */
1224 	    i -= 8;
1225 # ifndef NO_BRIGHTCOLOR
1226 	    PixColorsFocused[idx] = PixColorsFocused[minBrightCOLOR + i];
1227 	    goto Done;
1228 # endif
1229 	}
1230 	if (i >= 0 && i <= 7) {	/* normal colors */
1231 	    PixColorsFocused[idx] = PixColorsFocused[minCOLOR + i];
1232 	    goto Done;
1233 	}
1234     }
1235     if (!XParseColor(Xdisplay, Xcmap, color, &xcol) ||
1236 	!XAllocColor(Xdisplay, Xcmap, &xcol)) {
1237 	print_error(msg, color);
1238 	return;
1239     }
1240 /* XStoreColor (Xdisplay, Xcmap, XColor*); */
1241 
1242 /*
1243  * FIXME: should free colors here, but no idea how to do it so instead,
1244  * so just keep gobbling up the colormap
1245  */
1246 # if 0
1247     for (i = Color_Black; i <= Color_White; i++)
1248 	if (PixColorsFocused[idx] == PixColorsFocused[i])
1249 	    break;
1250     if (i > Color_White) {
1251     /* fprintf (stderr, "XFreeColors: PixColors [%d] = %lu\n", idx, PixColors [idx]); */
1252 	XFreeColors(Xdisplay, Xcmap, (PixColorsFocused + idx), 1,
1253 		    DisplayPlanes(Xdisplay, Xscreen));
1254     }
1255 # endif
1256 
1257     PixColorsFocused[idx] = xcol.pixel;
1258 
1259 /* XSetWindowAttributes attr; */
1260 /* Cursor cursor; */
1261   Done:
1262 #ifdef OFF_FOCUS_FADING
1263     PixColorsUnFocused[idx] = fade_color(PixColorsFocused[idx]);
1264 #endif
1265     on_colors_changed(idx);
1266 }
1267 #else
1268 # define set_window_color(idx,color)	((void)0)
1269 #endif				/* XTERM_COLOR_CHANGE */
1270 
1271 /*
1272  * XTerm escape sequences: ESC ] Ps;Pt BEL
1273  *       0 = change iconName/title
1274  *       1 = change iconName
1275  *       2 = change title
1276  *       4 = change color
1277  *      12 = change cursor color
1278  *      13 = change mouse foreground color
1279  *      18 = change bold character color
1280  *      19 = change underlined character color
1281  *      46 = change logfile (not implemented)
1282  *      50 = change font
1283  *
1284  * rxvt extensions:
1285  *      10 = menu
1286  *      20 = bg pixmap
1287  *      39 = change default fg color
1288  *      49 = change default bg color
1289  */
1290 /* PROTO */
1291 void
xterm_seq(int op,const char * str)1292 xterm_seq(int op, const char *str)
1293 {
1294     int color;
1295     char *buf, *name;
1296 
1297     assert(str != NULL);
1298     switch (op) {
1299     case XTerm_name:
1300 	set_title(str);		/* drop */
1301     case XTerm_iconName:
1302 	set_iconName(str);
1303 	break;
1304     case XTerm_title:
1305 	set_title(str);
1306 	break;
1307     case XTerm_Color:
1308 	for (buf = (char *)str; buf && *buf;) {
1309 	    if ((name = strchr(buf, ';')) == NULL)
1310 		break;
1311 	    *name++ = '\0';
1312 	    color = atoi(buf);
1313 	    if (color < 0 || color >= TOTAL_COLORS)
1314 		break;
1315 	    if ((buf = strchr(name, ';')) != NULL)
1316 		*buf++ = '\0';
1317 	    set_window_color(color + minCOLOR, name);
1318 	}
1319 	break;
1320 #ifndef NO_CURSORCOLOR
1321     case XTerm_Color_cursor:
1322 	set_window_color(Color_cursor, str);
1323 	break;
1324 #endif
1325     case XTerm_Color_pointer:
1326 	set_window_color(Color_pointer, str);
1327 	break;
1328 #ifndef NO_BOLD_UNDERLINE
1329     case XTerm_Color_BD:
1330 	set_window_color(Color_BD, str);
1331 	break;
1332     case XTerm_Color_UL:
1333 	set_window_color(Color_UL, str);
1334 	break;
1335 #endif
1336 
1337     case XTerm_Menu:
1338     /*
1339      * menubar_dispatch() violates the constness of the string,
1340      * so DON'T do it here
1341      */
1342 	break;
1343     case XTerm_Pixmap:
1344 #if defined(BACKGROUND_IMAGE)
1345         if( SetBackgroundPixmap((char*)str) )
1346 			request_background_update();
1347 #endif
1348 	break;
1349 
1350     case XTerm_restoreFG:
1351 	set_window_color(Color_fg, str);
1352 	break;
1353     case XTerm_restoreBG:
1354 	set_window_color(Color_bg, str);
1355 	break;
1356     case XTerm_logfile:
1357 	break;
1358     case XTerm_font:
1359 	change_font(0, str);
1360 	break;
1361     }
1362 }
1363 /*}}} */
1364 
1365 
get_proportion_font_width(XFontStruct * font)1366 unsigned int get_proportion_font_width( XFontStruct *font )
1367 {
1368   int i, cw ;
1369   unsigned int fw = 0;
1370     if( font != NULL )
1371     {
1372 	for (i = font->max_char_or_byte2 -
1373 	         font->min_char_or_byte2 ;
1374 	     i >= 0; i--)
1375 	{
1376 	    cw = font->per_char[i].width;
1377 	    if( cw > 0 )
1378     	        MAX_IT(fw, cw);
1379 	}
1380     }
1381     return fw ;
1382 }
1383 /*{{{ change_font() - Switch to a new font */
1384 /*
1385  * init = 1   - initialize
1386  *
1387  * fontname == FONT_UP  - switch to bigger font
1388  * fontname == FONT_DN  - switch to smaller font
1389  */
1390 /* PROTO */
1391 void
change_font(int init,const char * fontname)1392 change_font(int init, const char *fontname)
1393 {
1394     const char     *const msg = "can't load font \"%s\"";
1395     XFontStruct    *xfont;
1396     static char    *newfont[NFONTS];
1397 
1398 #ifndef NO_BOLDFONT
1399     static XFontStruct *boldFont = NULL;
1400 
1401 #endif
1402     static int      fnum = FONT0_IDX;	/* logical font number */
1403     int             idx = 0;	/* index into rs_font[] */
1404 
1405 #if (FONT0_IDX == 0)
1406 # define IDX2FNUM(i)	(i)
1407 # define FNUM2IDX(f)	(f)
1408 #else
1409 # define IDX2FNUM(i)	(i == 0 ? FONT0_IDX : (i <= FONT0_IDX ? (i-1) : i))
1410 # define FNUM2IDX(f)	(f == FONT0_IDX ? 0 : (f < FONT0_IDX  ? (f+1) : f))
1411 #endif
1412 /*#define FNUM_RANGE(i)	(i <= 0 ? 0 : (i >= NFONTS ? (NFONTS-1) : i))*/
1413 /* so to make it working on Sun Ultra  thanks to Hari Nair */
1414 #define FNUM_RANGE(i)	(i < 0 ? (NFONTS-1) : (i >= NFONTS ? 0 : i))
1415 
1416     if (!init) {
1417 	switch (fontname[0]) {
1418 	case '\0':
1419 	    fnum = FONT0_IDX;
1420 	    fontname = NULL;
1421 	    break;
1422 
1423 	/* special (internal) prefix for font commands */
1424 	case FONT_CMD:
1425 	    idx = atoi(fontname + 1);
1426 	    switch (fontname[1]) {
1427 	    case '+':		/* corresponds to FONT_UP */
1428 		fnum += (idx ? idx : 1);
1429 		fnum = FNUM_RANGE(fnum);
1430 		break;
1431 
1432 	    case '-':		/* corresponds to FONT_DN */
1433 		fnum += (idx ? idx : -1);
1434 		fnum = FNUM_RANGE(fnum);
1435 		break;
1436 
1437 	    default:
1438 		if (fontname[1] != '\0' && !isdigit(fontname[1]))
1439 		    return;
1440 		if (idx < 0 || idx >= (NFONTS))
1441 		    return;
1442 		fnum = IDX2FNUM(idx);
1443 		break;
1444 	    }
1445 	    fontname = NULL;
1446 	    break;
1447 
1448 	default:
1449 	    if (fontname != NULL) {
1450 	    /* search for existing fontname */
1451 		for (idx = 0; idx < NFONTS; idx++) {
1452 		    if (!strcmp(rs_font[idx], fontname)) {
1453 			fnum = IDX2FNUM(idx);
1454 			fontname = NULL;
1455 			break;
1456 		    }
1457 		}
1458 	    } else
1459 		return;
1460 	    break;
1461 	}
1462     /* re-position around the normal font */
1463 	idx = FNUM2IDX(fnum);
1464 
1465 	if (fontname != NULL) {
1466 	    char           *name;
1467 
1468 	    xfont = XLoadQueryFont(Xdisplay, fontname);
1469 	    if (!xfont)
1470 		return;
1471 
1472 	    name = MALLOC(strlen(fontname + 1) * sizeof(char));
1473 
1474 	    if (name == NULL) {
1475 		XFreeFont(Xdisplay, xfont);
1476 		return;
1477 	    }
1478 	    STRCPY(name, fontname);
1479 	    if (newfont[idx] != NULL)
1480 		FREE(newfont[idx]);
1481 	    newfont[idx] = name;
1482 	    rs_font[idx] = newfont[idx];
1483 	}
1484     }
1485     if (TermWin.font)
1486 	XFreeFont(Xdisplay, TermWin.font);
1487 
1488 /* load font or substitute */
1489     xfont = XLoadQueryFont(Xdisplay, rs_font[idx]);
1490     if (!xfont) {
1491 	print_error(msg, rs_font[idx]);
1492 	rs_font[idx] = "fixed";
1493 	xfont = XLoadQueryFont(Xdisplay, rs_font[idx]);
1494 	if (!xfont) {
1495 	    print_error(msg, rs_font[idx]);
1496 	    goto Abort;
1497 	}
1498     }
1499     TermWin.font = xfont;
1500 
1501 #ifndef NO_BOLDFONT
1502 /* fail silently */
1503     if (init && rs_boldFont != NULL)
1504 	boldFont = XLoadQueryFont(Xdisplay, rs_boldFont);
1505 #endif
1506 
1507 #ifdef MULTICHAR_SET
1508     if (TermWin.mfont)
1509 	XFreeFont(Xdisplay, TermWin.mfont);
1510 
1511 /* load font or substitute */
1512     xfont = XLoadQueryFont(Xdisplay, rs_mfont[idx]);
1513     if (!xfont) {
1514 	print_error(msg, rs_mfont[idx]);
1515 	rs_mfont[idx] = "k14";
1516 	xfont = XLoadQueryFont(Xdisplay, rs_mfont[idx]);
1517 	if (!xfont) {
1518 	    print_error(msg, rs_mfont[idx]);
1519 	    goto Abort;
1520 	}
1521     }
1522     TermWin.mfont = xfont;
1523 #endif				/* MULTICHAR_SET */
1524 
1525 /* alter existing GC */
1526     if (!init) {
1527 	XSetFont(Xdisplay, TermWin.gc, TermWin.font->fid);
1528 	menubar_expose();
1529     }
1530 /* set the sizes */
1531     {
1532 	int             fh, fw = 0;
1533 
1534 	fw = TermWin.font->min_bounds.width; /* can be error !!!! */
1535 	if( fw > 1000 ) fw = 0 ;  /* added by suggestion from <suchness>*/
1536 
1537 #ifdef USE_LINESPACE
1538       fh = TermWin.font->ascent + TermWin.font->descent + TermWin.lineSpace;
1539 #else
1540       fh = TermWin.font->ascent + TermWin.font->descent;
1541 #endif
1542 
1543 	if (TermWin.font->min_bounds.width == TermWin.font->max_bounds.width)
1544 	    TermWin.fprop = 0;	/* Mono-spaced (fixed width) font */
1545 	else
1546 	    TermWin.fprop = 1;	/* Proportional font */
1547 
1548 	if (TermWin.fprop == 1)	/* also, if == 0, per_char[] might be NULL */
1549 	    fw = get_proportion_font_width( TermWin.font );
1550     /* not the first time thru and sizes haven't changed */
1551 	if (fw == TermWin.fwidth && fh == TermWin.fheight)
1552 	    return;		/* TODO: not return; check MULTI if needed */
1553 
1554 	TermWin.fwidth = fw;
1555 	TermWin.fheight = fh;
1556     }
1557 
1558 /* check that size of boldFont is okay */
1559 #ifndef NO_BOLDFONT
1560     TermWin.boldFont = NULL;
1561     if (boldFont != NULL) {
1562 	int             fh, fw = 0;
1563 
1564 	fw = boldFont->min_bounds.width; /* can be error !!!! */
1565 	if( fw > 1000 ) fw = 0 ;
1566 
1567 	fh = boldFont->ascent + boldFont->descent;
1568 	if (TermWin.fprop == 0) {	/* bold font must also be monospaced */
1569 	    if (fw != boldFont->max_bounds.width)
1570 		fw = -1;
1571 	} else
1572 	    fw = get_proportion_font_width( boldFont );
1573 
1574 	if (fw == TermWin.fwidth && fh == TermWin.fheight)
1575 	    TermWin.boldFont = boldFont;
1576     }
1577 #endif				/* NO_BOLDFONT */
1578 
1579 /* TODO: check that size of Kanji font is okay */
1580 
1581     set_colorfgbg();
1582 
1583     TermWin.width = TermWin.ncol * TermWin.fwidth;
1584     TermWin.height = TermWin.nrow * TermWin.fheight;
1585 
1586     szHint.width_inc = TermWin.fwidth;
1587     szHint.height_inc = TermWin.fheight;
1588 
1589     szHint.min_width = szHint.base_width + szHint.width_inc;
1590     szHint.min_height = szHint.base_height + szHint.height_inc;
1591 
1592     szHint.width = szHint.base_width + TermWin.width;
1593     szHint.height = szHint.base_height + TermWin.height;
1594     { /* ONLYIF MENUBAR */
1595 	szHint.height += (delay_menu_drawing ? menuBar_TotalHeight() : 0);
1596     }
1597 
1598     szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity;
1599 
1600     if (!init) {
1601 	resize();
1602     }
1603     return;
1604   Abort:
1605     print_error("aborting");	/* fatal problem */
1606     exit(EXIT_FAILURE);
1607 #undef IDX2FNUM
1608 #undef FNUM2IDX
1609 #undef FNUM_RANGE
1610 }
1611 /*}}} */
1612 
1613 #ifdef _MYSTYLE_
1614 char *DefaultMyStyle = NULL ;
1615 
1616 /* PROTO */
1617 const char*
GetDefaultMyStyle()1618 GetDefaultMyStyle()
1619 {
1620     if( DefaultMyStyle == NULL )
1621     {
1622 		DefaultMyStyle = malloc( 1+strlen(MyName)+1 );
1623 		sprintf( DefaultMyStyle, "*%s", MyName );
1624     }
1625     return DefaultMyStyle ;
1626 }
1627 
pixel2string(unsigned long pixel,char * old_string)1628 char* pixel2string( unsigned long pixel, char* old_string )
1629 {
1630   XColor xcol ;
1631     xcol.pixel = pixel ;
1632     XQueryColor( Xdisplay, DefaultColormap( Xdisplay, Xscreen), &xcol );
1633     if( xcol.flags != 0 )
1634     {
1635       old_string = realloc( old_string, 1+2+2+2+1 );
1636       sprintf( old_string, "#%2.2X%2.2X%2.2X", (xcol.red)>>8, xcol.green>>8, xcol.blue>>8 );
1637     }
1638     return old_string ;
1639 }
1640 
argb2string(unsigned long argb,char * old_string)1641 char* argb2string( unsigned long argb, char* old_string )
1642 {
1643 	old_string = realloc( old_string, 1+2+2+2+1 );
1644     sprintf( old_string, "#%2.2lX%2.2lX%2.2lX", (argb>>16)&0x000000FF, (argb>>8)&0x000000FF, argb&0x000000FF );
1645     return old_string ;
1646 }
1647 
1648 
font2string(XFontStruct * font,char * old_string)1649 char* font2string( XFontStruct *font, char* old_string )
1650 {
1651   char* font_name ;
1652   Atom name_value ;
1653     if(XGetFontProperty(font, XA_FONT, &name_value)) {
1654 	font_name=XGetAtomName(Xdisplay, name_value);
1655 	if( font_name )
1656 	{
1657           /*fprintf( stderr, " font found : [%s]\n", font_name ); */
1658 	    old_string = realloc( old_string, strlen( font_name)+1 );
1659 	    strcpy( old_string, font_name );
1660 	}
1661 	XFree( font_name );
1662     }
1663     return old_string ;
1664 }
1665 
1666 static const char *
translate_tint_color(ARGB32 tint)1667 translate_tint_color( ARGB32 tint )
1668 {
1669 	ARGB32 clean_tint = (tint<<1)|0xFF000000;
1670 	static struct
1671 	{
1672 	 	ARGB32 tint;
1673 		const char *name;
1674 	}tint_names[6] = {{0xFFFF0000, "red"},{0xFFFFFF00, "yellow"},{0xFFFF00FF, "magenta"},
1675 					  {0xFF00FF00, "green"},{0xFF00FFFF, "cyan"},{0xFF0000FF, "blue"}};
1676 	int i ;
1677 
1678 	if( ARGB32_RED8(clean_tint) > 0 )
1679 		clean_tint |= 0x00030000;
1680 	if( ARGB32_GREEN8(clean_tint) > 0 )
1681 		clean_tint |= 0x00000300;
1682 	if( ARGB32_BLUE8(clean_tint) > 0 )
1683 		clean_tint |= 0x00000003;
1684 
1685 	for( i = 0 ; i < 6 ; ++i )
1686 		if( tint_names[i].tint == clean_tint )
1687 			return tint_names[i].name;
1688 	return NULL;
1689 }
1690 
1691 /* PROTO */
1692 void
set_mystyle(struct MyStyle * mystyle,Bool reset)1693 set_mystyle( struct MyStyle* mystyle, Bool reset )
1694 {
1695   int repaint = 0 ;
1696   static char* fg_color = NULL, *bg_color = NULL;
1697 
1698     TermWin.background.mystyle = mystyle ;
1699     if( mystyle == NULL )
1700     {
1701 		if( TermWin.background.trgType == BGT_MyStyle )
1702 		{
1703 	    	if( TermWin.background.trgPixmap != None &&
1704 			TermWin.background.trgPixmap != TermWin.background.srcPixmap )
1705 			XFreePixmap( Xdisplay, TermWin.background.trgPixmap );
1706 	    	TermWin.background.trgType = BGT_None ;
1707 		}
1708 		return ;
1709     }
1710 
1711     if( mystyle->texture_type > TEXTURE_SOLID &&
1712 		( !reset
1713 #ifdef TRANSPARENT
1714           || ( !(Options & Opt_transparent) && TermWin.background.srcPixmap == None )
1715 #endif
1716 		)
1717       )
1718 	{
1719 #ifdef TRANSPARENT
1720 		const char *tint_color = translate_tint_color( mystyle->tint );
1721 		if( mystyle->texture_type == TEXTURE_TRANSPARENT &&
1722 			(tint_color != NULL || mystyle->tint == 0) )
1723 		{
1724 			Options |= Opt_transparent ;
1725 			rs_color[Color_tint] = tint_color ;
1726 			TermWin.background.mystyle = NULL ;
1727 			TermWin.background.trgType = BGT_None ;
1728 		}else
1729 #endif
1730         	TermWin.background.trgType = BGT_MyStyle ;
1731 	}
1732 
1733     if( mystyle && !get_flags(Options, Opt_transparent) )
1734     {
1735 		if(  (mystyle->set_flags & F_FORECOLOR) &&
1736 	    	!(TermWin.background.user_flags & F_FORECOLOR)  )
1737 		{
1738 	    	rs_color[Color_fg] = fg_color = argb2string(mystyle->colors.fore, fg_color ) ;
1739 			/* fprintf( stderr, "mystyle.fore = 0x%lX, text = \"%s\"", mystyle->colors.fore, rs_color[Color_fg] ); */
1740 	    	if( reset )
1741 	    	{
1742 				PixColorsFocused[Color_fg] = mystyle->colors.fore ;
1743 #ifdef OFF_FOCUS_FADING
1744 				PixColorsUnFocused[Color_fg] = fade_color(mystyle->colors.fore);
1745 #endif
1746 	    	}
1747 	    	repaint++ ;
1748 		}
1749 		if(  (mystyle->set_flags & F_BACKCOLOR) &&
1750 	    	!(TermWin.background.user_flags & F_BACKCOLOR)  )
1751 		{
1752 	    	rs_color[Color_bg] = bg_color = argb2string(mystyle->colors.back, bg_color ) ;
1753 	    	if( reset )
1754 	    	{
1755 			PixColorsFocused[Color_bg] = mystyle->colors.back ;
1756 #ifdef OFF_FOCUS_FADING
1757 			PixColorsUnFocused[Color_bg] = fade_color(mystyle->colors.back);
1758 #endif
1759 	    	}
1760 	    	repaint++ ;
1761 		}
1762 	/*if( mystyle->set_flags & F_BACKPIXMAP )      */
1763 
1764         if( reset )
1765 		{
1766 			if( repaint > 0 )
1767 	    	{ /* we want to repaint ourselves */
1768 				on_colors_changed( Color_bg );
1769 				if(  (mystyle->set_flags & F_FONT) &&
1770 		    		!(TermWin.background.user_flags & F_FONT)  )
1771 		    		change_font( False, rs_font[0] );
1772 	    	}
1773 	    	if( mystyle->texture_type > TEXTURE_SOLID )
1774 	    	{
1775 				RenderPixmap(True);
1776 				scr_clear();
1777     				scr_touch();
1778 	    	}
1779 		}
1780     }
1781 }
1782 #endif
1783 
1784 #ifndef HAVE_AFTERSTEP
1785 
1786 /* PROTO */
1787 Bool
read_32bit_property(Window w,Atom property,CARD32 * trg)1788 read_32bit_property (Window w, Atom property, CARD32* trg)
1789 {
1790 	Bool          res = False;
1791 
1792 	if (w != None && property != None && trg)
1793 	{
1794 		Atom          actual_type;
1795 		int           actual_format;
1796         unsigned long bytes_after;
1797 		union
1798 		{
1799 			unsigned char *uc_ptr ;
1800 			long 		  *long_ptr ;
1801 		}data;
1802 		unsigned long nitems;
1803 
1804 		data.long_ptr = NULL ;
1805 		res =
1806 			(XGetWindowProperty
1807 			 (Xdisplay, w, property, 0, 1, False, AnyPropertyType, &actual_type,
1808 			  &actual_format, &nitems, &bytes_after, &data.uc_ptr) == 0);
1809 
1810 		/* checking property sanity */
1811 		res = (res && nitems > 0 && actual_format == 32);
1812 
1813 		if (res)
1814 			trg[0] = data.long_ptr[0];
1815 		if (data.long_ptr && nitems > 0)
1816 			XFree (data.long_ptr);
1817 	}
1818 	return res;
1819 }
1820 
1821 /* PROTO */
1822 Bool
read_32bit_proplist(Window w,Atom property,long estimate,CARD32 ** list,long * nitems)1823 read_32bit_proplist (Window w, Atom property, long estimate, CARD32 ** list, long *nitems)
1824 {
1825 	Bool          res = False;
1826 
1827 #ifndef X_DISPLAY_MISSING
1828 	if (w != None && property != None && list && nitems)
1829 	{
1830 		Atom          actual_type;
1831 		int           actual_format;
1832         unsigned long bytes_after;
1833 		unsigned long unitems = 0 ;
1834 		union
1835 		{
1836 		 	unsigned char *uc_ptr ;
1837 		 	long *long_ptr ;
1838 		}buffer;
1839 
1840 		buffer.long_ptr = NULL ;
1841 		if (estimate <= 0)
1842 			estimate = 1;
1843 		res =
1844 			(XGetWindowProperty
1845 			 (Xdisplay, w, property, 0, estimate, False, AnyPropertyType,
1846 			  &actual_type, &actual_format, &unitems, &bytes_after, &buffer.uc_ptr) == 0);
1847 		/* checking property sanity */
1848 		res = (res && unitems > 0 && actual_format == 32);
1849 
1850 		if (bytes_after > 0 && res)
1851 		{
1852 			XFree (buffer.long_ptr);
1853 			res =
1854 				(XGetWindowProperty
1855 				 (Xdisplay, w, property, 0, estimate + (bytes_after >> 2), False,
1856 				  actual_type, &actual_type, &actual_format, &unitems, &bytes_after, &buffer.uc_ptr) == 0);
1857 			res = (res && (unitems > 0));	   /* bad property */
1858 		}
1859 
1860 		if (!res)
1861 		{
1862 			*nitems = 0;
1863 			*list = NULL ;
1864 		}else
1865 		{
1866 			register int i = unitems ;
1867 			register CARD32 *data32  = malloc(unitems*sizeof(CARD32));
1868 			while( --i >= 0 )
1869 				data32[i] = buffer.long_ptr[i] ;
1870 			*list = data32 ;
1871 			*nitems = unitems ;
1872 		}
1873 		if ( buffer.long_ptr )
1874 			XFree (buffer.long_ptr);
1875 	}
1876 #endif
1877 	return res;
1878 }
1879 
1880 #endif
1881 
1882 /* PROTO */
1883 Bool
check_extended_wm_state()1884 check_extended_wm_state()
1885 {
1886 	CARD32         *items;
1887 	long          nitems = 0;
1888 	unsigned long new_state = 0;
1889 	Bool changed = False ;
1890 
1891 	if (read_32bit_proplist (TermWin.parent, _XA_NET_WM_STATE, 6, &items, &nitems))
1892 	{
1893 		int i ;
1894 		for( i = 0 ; i < nitems ; ++i )
1895 		{
1896 			if( items[i] == _XA_NET_WM_STATE_STICKY )
1897 				set_flags( new_state, WM_AtermStateSticky	);
1898 			else if( items[i] == _XA_NET_WM_STATE_SHADED )
1899 				set_flags( new_state, WM_AtermStateShaded );
1900 			else if( items[i] == _XA_NET_WM_STATE_HIDDEN )
1901 				set_flags( new_state, WM_AtermStateHidden );
1902 		}
1903 		free (items);
1904 		changed = (get_flags(ExtWM.flags, WM_AtermStateSticky|WM_AtermStateShaded|WM_AtermStateHidden) != new_state) ;
1905 		clear_flags(ExtWM.flags, WM_AtermStateSticky|WM_AtermStateShaded|WM_AtermStateHidden);
1906 		set_flags( ExtWM.flags, new_state );
1907 	}else
1908 	{
1909 		changed = get_flags(ExtWM.flags, WM_AtermStateSticky|WM_AtermStateShaded|WM_AtermStateHidden);
1910 		clear_flags(ExtWM.flags, WM_AtermStateSticky|WM_AtermStateShaded|WM_AtermStateHidden);
1911 	}
1912 
1913 	return changed;
1914 }
1915 
1916 /* PROTO */
1917 void
check_extended_wm_hints_support()1918 check_extended_wm_hints_support()
1919 {
1920 	memset( &ExtWM, 0x00, sizeof(ExtWM));
1921 
1922 	if( read_32bit_property (Xroot, _XA_NET_SUPPORTING_WM_CHECK, &ExtWM.supporting_wm_check) )
1923 		if( ExtWM.supporting_wm_check != None )
1924 		{
1925 			Window w;
1926 			if( !read_32bit_property (ExtWM.supporting_wm_check, _XA_NET_SUPPORTING_WM_CHECK, &w) )
1927 				ExtWM.supporting_wm_check = None ;
1928 			else if( w != ExtWM.supporting_wm_check )
1929 				ExtWM.supporting_wm_check = None ;
1930 			else
1931 			{
1932 				CARD32 *supported_props = NULL;
1933 				long nitems	= 0 ;
1934 				Bool curr_desk = False ;
1935 				Bool app_desk = False ;
1936 				if( read_32bit_proplist (Xroot, _XA_NET_SUPPORTED, 20, &supported_props, &nitems) )
1937 				{
1938 					int i ;
1939 					for( i = 0 ; i < nitems; ++i )
1940 					{
1941 						if( supported_props[i] == _XA_NET_CURRENT_DESKTOP )
1942 							curr_desk = True ;
1943 						else if( supported_props[i] == _XA_NET_WM_DESKTOP )
1944 							app_desk = True ;
1945 					}
1946 				}
1947 				if( curr_desk && app_desk )
1948 				{
1949 					set_flags( ExtWM.flags, WM_ClaimSupportsDesktops );
1950 					if( read_32bit_property (Xroot, _XA_NET_CURRENT_DESKTOP, &ExtWM.current_desktop) )
1951 						set_flags( ExtWM.flags, WM_SupportsDesktops	);
1952 				}
1953 			}
1954 		}
1955 
1956 }
1957 
1958 
1959 
1960 /*{{{ main() */
1961 /* PROTO */
1962 int
main(int argc,char * argv[])1963 main(int argc, char *argv[])
1964 {
1965     int i, t;
1966     char           *val, **cmd_argv = NULL;
1967 
1968 /* "WINDOWID=\0" = 10 chars, UINT_MAX = 10 chars */
1969     static char     windowid_string[20], *display_string, *term_string;
1970 
1971 /* Hops - save original arglist for wdw property WM_COMMAND */
1972     int             saved_argc = argc;
1973     char          **saved_argv = (char **)MALLOC((argc + 1) * sizeof(char *));
1974 
1975     PixColors = &(PixColorsFocused[0]);
1976 
1977     for (i = 0; i < argc; i++)
1978 	saved_argv[i] = argv[i];
1979     saved_argv[i] = NULL;	/* NULL terminate that sucker. */
1980     for (i = 0; i < argc; i++) {
1981 	if (!strcmp(argv[i], "-e") || !strcmp(argv[i], "-exec")) {
1982 	    argc = i;
1983 	    argv[argc] = NULL;
1984 	    if (argv[argc + 1] != NULL)
1985 		cmd_argv = (argv + argc + 1);
1986 	    break;
1987 	}
1988     }
1989 
1990 /*
1991  * Save and then give up any super-user privileges
1992  * If we need privileges in any area then we must specifically request it.
1993  * We should only need to be root in these cases:
1994  *  1.  write utmp entries on some systems
1995  *  2.  chown tty on some systems
1996  */
1997     privileges(SAVE);
1998     privileges(IGNORE);
1999 
2000     Options = Opt_scrollBar | Opt_scrollTtyOutput;
2001     Xdisplay = NULL;
2002     display_name = NULL;
2003     rs_term_name = NULL;
2004     rs_cutchars = NULL;
2005 #ifndef NO_BOLDFONT
2006     rs_boldFont = NULL;
2007 #endif
2008 #ifdef PRINTPIPE
2009     rs_print_pipe = NULL;
2010 #endif
2011     rs_title = NULL;		/* title name for window */
2012     rs_iconName = NULL;		/* icon name for window */
2013     rs_geometry = NULL;		/* window geometry */
2014     rs_minBufferWidth = NULL;
2015     rs_saveLines = NULL;	/* scrollback buffer [lines] */
2016 #ifdef USE_LINESPACE
2017     rs_lineSpace = NULL;
2018 #endif
2019     rs_borderWidth = NULL;
2020     rs_internal_border = NULL;
2021     rs_modifier = NULL;	/* modifier */
2022 #if defined (HOTKEY_CTRL) || defined (HOTKEY_META)
2023 /* recognized when combined with HOTKEY */
2024     ks_bigfont = XK_greater;
2025     ks_smallfont = XK_less;
2026 #endif
2027 
2028     rs_menu = NULL;
2029     rs_path = NULL;
2030 #ifdef BACKGROUND_IMAGE
2031     rs_backgroundPixmap = NULL;
2032 #endif
2033 
2034 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT)
2035 	rs_backgroundType = NULL;
2036     rs_shade = NULL;
2037     rs_tintType = NULL;
2038 #endif
2039 
2040 
2041 #ifndef NO_BACKSPACE_KEY
2042     rs_backspace_key = NULL;
2043 #endif
2044 #ifndef NO_DELETE_KEY
2045     rs_delete_key = NULL;
2046 #endif
2047 #ifndef NO_BRIGHTCOLOR
2048     colorfgbg = DEFAULT_RSTYLE;
2049 #endif
2050 
2051     rs_name = my_basename(argv[0]);
2052     if (cmd_argv != NULL && cmd_argv[0] != NULL)
2053 	rs_iconName = rs_title = my_basename(cmd_argv[0]);
2054 
2055 /*
2056  * Open display, get options/resources and create the window
2057  */
2058     get_options(argc, argv);
2059 
2060 	if( display_name == NULL )
2061     	if ((display_name = getenv("DISPLAY")) == NULL)
2062 			display_name = ":0";
2063 
2064 #ifdef HAVE_AFTERSTEP
2065 #ifdef MyArgs_IS_MACRO
2066     MyArgsPtr = safecalloc(1, sizeof(ASProgArgs) );
2067 #else
2068 	memset( &MyArgs, 0x00, sizeof(ASProgArgs) );
2069 #endif
2070 #ifdef Scr_IS_MACRO
2071 	ASDefaultScr = safecalloc(1, sizeof(ScreenInfo));
2072 #else
2073     memset( &Scr, 0x00, sizeof(ScreenInfo) );
2074 #endif
2075 
2076 	Scr.RootClipArea.width = 1 ;
2077 	Scr.RootClipArea.height = 1;
2078 
2079 
2080 	MyArgs.verbosity_level = OUTPUT_DEFAULT_THRESHOLD ;
2081 	set_output_threshold( MyArgs.verbosity_level );
2082 
2083 	MyArgs.display_name = (char*)display_name ;
2084 	SetMyName( argv[0] );
2085 #ifdef NO_DEBUG_OUTPUT
2086 	set_output_threshold( 0 );
2087 #endif
2088 
2089 	ConnectX ( &Scr, 0 );
2090     Xdisplay = dpy ;
2091     Xscreen = Scr.screen ;
2092 	asv = Scr.asv ;
2093 
2094 	Xcmap = asv->colormap;
2095 	Xdepth = asv->visual_info.depth;
2096 	Xvisual = asv->visual_info.visual;
2097 
2098 	XdisplayWidth = Scr.MyDisplayWidth ;
2099 	XdisplayHeight = Scr.MyDisplayHeight ;
2100 
2101 #else
2102 	Xdisplay = XOpenDisplay(display_name);
2103 
2104 	if (!Xdisplay) {
2105 		print_error("can't open display %s", display_name);
2106 		exit(EXIT_FAILURE);
2107     }
2108   /* changed from _MOTIF_WM_INFO - Vaevictus - gentoo bug #139554 */
2109 	_XA_MwmAtom = XInternAtom(Xdisplay, "_MOTIF_WM_HINTS", True);
2110 	_XA_NET_WM_PID = XInternAtom(Xdisplay, "_NET_WM_PID", False);
2111 	_XROOTPMAP_ID = XInternAtom(Xdisplay, "_XROOTPMAP_ID", False);
2112 	_XA_NET_SUPPORTING_WM_CHECK = XInternAtom(Xdisplay, "_NET_SUPPORTING_WM_CHECK", False);
2113 	_XA_NET_SUPPORTED           = XInternAtom(Xdisplay, "_NET_SUPPORTED", False);
2114 	_XA_NET_CURRENT_DESKTOP     = XInternAtom(Xdisplay, "_NET_CURRENT_DESKTOP", False);
2115 	_XA_NET_WM_DESKTOP			= XInternAtom(Xdisplay, "_NET_WM_DESKTOP", False);
2116 	_XA_NET_WM_STATE			= XInternAtom(Xdisplay, "_XA_NET_WM_STATE", False);
2117 	_XA_NET_WM_STATE_STICKY		= XInternAtom(Xdisplay, "_XA_NET_WM_STATE_STICKY", False);
2118 	_XA_NET_WM_STATE_SHADED		= XInternAtom(Xdisplay, "_XA_NET_WM_STATE_SHADED", False);
2119 	_XA_NET_WM_STATE_HIDDEN		= XInternAtom(Xdisplay, "_XA_NET_WM_STATE_HIDDEN", False);
2120 
2121 	Xdepth = DefaultDepth(Xdisplay, Xscreen);
2122     Xcmap = DefaultColormap(Xdisplay, Xscreen);
2123     Xvisual = DefaultVisual(Xdisplay, Xscreen);
2124 	XdisplayWidth = DisplayWidth (Xdisplay, Xscreen);
2125 	XdisplayHeight = DisplayHeight (Xdisplay, Xscreen);
2126 
2127 #ifdef HAVE_AFTERIMAGE
2128 	dpy = Xdisplay ;
2129 	asv = create_asvisual (Xdisplay, Xscreen, Xdepth, NULL);
2130 	Xcmap = asv->colormap;
2131 	Xdepth = asv->visual_info.depth;
2132 	Xvisual = asv->visual_info.visual;
2133 #else
2134 #ifdef PREFER_24BIT
2135 /* If depth is not 24, look for a 24bit visual. */
2136     if (Xdepth != 24)
2137 	{
2138 		XVisualInfo     vinfo;
2139 		if (XMatchVisualInfo(Xdisplay, Xscreen, 24, TrueColor, &vinfo))
2140 		{
2141 	    	Xdepth = 24;
2142 	    	Xvisual = vinfo.visual;
2143 	    	Xcmap = XCreateColormap(Xdisplay, RootWindow(Xdisplay, Xscreen),
2144 				    	Xvisual, AllocNone);
2145 		}
2146     }
2147 #endif
2148 #endif
2149 
2150 #endif                         /* HAVE_AFTERSTEP */
2151 
2152 	aterm_XA_TARGETS = XInternAtom(Xdisplay, "TARGETS", False);
2153 	_XA_COMPAUND_TEXT = XInternAtom(Xdisplay, "COMPOUND_TEXT", False);
2154 	aterm_XA_TEXT = XInternAtom(Xdisplay, "TEXT", False);
2155 	aterm_XA_UTF8_STRING = XInternAtom(Xdisplay, "UTF8_STRING", False);
2156 	aterm_XA_CLIPBOARD = XInternAtom(Xdisplay, "CLIPBOARD", False);
2157 	aterm_XA_VT_SELECTION = XInternAtom(Xdisplay, "VT_SELECTION", False);
2158 	aterm_XA_INCR		  = XInternAtom(Xdisplay, "INCR", False);
2159 
2160 	check_extended_wm_hints_support();
2161 
2162 #ifdef DEBUG_X
2163     XSynchronize(Xdisplay, True);
2164     XSetErrorHandler((XErrorHandler) abort);
2165 #else
2166     XSetErrorHandler((XErrorHandler) xerror_handler);
2167 #endif
2168 
2169     extract_resources(Xdisplay, rs_name);
2170 
2171 
2172 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT) || defined(_MYSTYLE_)
2173     InitBackground();
2174 #endif
2175 
2176 #ifdef HAVE_AFTERSTEP
2177     mystyle_get_property(Scr.wmprops );
2178     /* lets see what options user chosen to override with other
2179        command line parameters : */
2180     if( rs_font[0] != NULL )
2181 		TermWin.background.user_flags |= F_FONT ;
2182     if( rs_color[Color_fg] != NULL )
2183 		TermWin.background.user_flags |= F_FORECOLOR ;
2184     if( rs_color[Color_bg] != NULL )
2185 		TermWin.background.user_flags |= F_BACKCOLOR ;
2186 
2187     /* reading everything we can from default MyStyle : */
2188     set_mystyle(mystyle_find( GetDefaultMyStyle()), False);
2189 
2190     /* overriding it with user specifyed MyStyle : */
2191     if( rs_mystyle )
2192     {
2193       	MyStyle * mystyle = mystyle_find( rs_mystyle );
2194         if( mystyle == NULL )
2195 	    	fprintf( stderr, "%s: AfterStep MyStyle \"%s\" not available - check your look file.\n", MyName, rs_mystyle );
2196 		else
2197 	    	set_mystyle( mystyle, False );
2198     }
2199 #endif
2200 
2201 
2202 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT)
2203     if( rs_shade )
2204         TermWin.background.Shading.shading = atoi(rs_shade);
2205     SetBackgroundType(rs_backgroundType);
2206 #endif
2207 
2208 #if defined(XTERM_SCROLLBAR) || defined(NEXT_SCROLLBAR)
2209     sb_shadow = 0;
2210 #else
2211     sb_shadow = (Options & Opt_scrollBar_floating) ? 0 : SHADOW;
2212 #endif
2213 
2214 /*
2215  * set any defaults not already set
2216  */
2217 
2218     if (!rs_title)
2219 	rs_title = rs_name;
2220     if (!rs_iconName)
2221 	rs_iconName = rs_title;
2222 
2223     if (!rs_minBufferWidth || (t = atoi(rs_minBufferWidth)) < 0)
2224 	TermWin.min_bcol = 1;
2225     else
2226     	TermWin.min_bcol = t;
2227 
2228     if (!rs_saveLines || (t = atoi(rs_saveLines)) < 0)
2229     	TermWin.saveLines = SAVELINES;
2230     else
2231         TermWin.saveLines = t;
2232 #ifdef USE_LINESPACE
2233     if (!rs_lineSpace || (TermWin.lineSpace = atoi(rs_lineSpace)) < 0)
2234         TermWin.lineSpace = LINESPACE;
2235 #endif
2236 
2237     if (!rs_borderWidth || (t = atoi(rs_borderWidth)) < 0)
2238         TermWin.borderWidth = BORDERWIDTH;
2239     else
2240         TermWin.borderWidth = t;
2241 
2242     if (!rs_internal_border|| (t = atoi(rs_internal_border)) < 0)
2243         TermWin_internalBorder = 2;
2244     else
2245         TermWin_internalBorder = t;
2246     TermWin_internalBorders = 2 * TermWin_internalBorder;
2247 
2248 /* no point having a scrollbar without having any scrollback! */
2249     if (!TermWin.saveLines)
2250 	Options &= ~Opt_scrollBar;
2251 
2252 #ifdef PRINTPIPE
2253     if (!rs_print_pipe)
2254 	rs_print_pipe = PRINTPIPE;
2255 #endif
2256     if (!rs_cutchars)
2257 	rs_cutchars = CUTCHARS;
2258 #ifndef NO_BACKSPACE_KEY
2259     if (!rs_backspace_key)
2260 # ifdef DEFAULT_BACKSPACE
2261 	rs_backspace_key = DEFAULT_BACKSPACE;
2262 # else
2263 	rs_backspace_key = "DEC";	/* can toggle between \033 or \177 */
2264 # endif
2265     else
2266 	(void) Str_escaped((char*)rs_backspace_key);
2267 #endif
2268 #ifndef NO_DELETE_KEY
2269     if (!rs_delete_key)
2270 # ifdef DEFAULT_DELETE
2271 	rs_delete_key = DEFAULT_DELETE;
2272 # else
2273 	rs_delete_key = "\033[3~";
2274 # endif
2275     else
2276 	(void) Str_escaped((char*)rs_delete_key);
2277 #endif
2278 #ifndef NO_BOLDFONT
2279     if (rs_font[0] == NULL && rs_boldFont != NULL) {
2280 	rs_font[0] = rs_boldFont;
2281 	rs_boldFont = NULL;
2282     }
2283 #endif
2284     for (i = 0; i < NFONTS; i++) {
2285 	if (!rs_font[i])
2286 	    rs_font[i] = def_fontName[i];
2287 #ifdef MULTICHAR_SET
2288 	if (!rs_mfont[i])
2289 	    rs_mfont[i] = def_mfontName[i];
2290 #endif
2291     }
2292 #ifdef USE_XIM
2293     TermWin.fontset = NULL;
2294 #endif
2295 
2296 #ifdef XTERM_REVERSE_VIDEO
2297 /* this is how xterm implements reverseVideo */
2298     if (Options & Opt_reverseVideo) {
2299 	if (!rs_color[Color_fg])
2300 	    rs_color[Color_fg] = def_colorName[Color_bg];
2301 	if (!rs_color[Color_bg])
2302 	    rs_color[Color_bg] = def_colorName[Color_fg];
2303     }
2304 #endif
2305 
2306     for ( i = 0 ; i < NRS_COLORS; i++)
2307 		if (!rs_color[i])
2308 	    	rs_color[i] = def_colorName[i];
2309 
2310 #ifndef XTERM_REVERSE_VIDEO
2311 /* this is how we implement reverseVideo */
2312     if (Options & Opt_reverseVideo) {
2313 	const char     *name;
2314 
2315     /* swap foreground/background colors */
2316 
2317 	name = rs_color[Color_fg];
2318 	rs_color[Color_fg] = rs_color[Color_bg];
2319 	rs_color[Color_bg] = name;
2320 
2321 	name = def_colorName[Color_fg];
2322 	def_colorName[Color_fg] = def_colorName[Color_bg];
2323 	def_colorName[Color_bg] = name;
2324     }
2325 #endif
2326 
2327 /* convenient aliases for setting fg/bg to colors */
2328     color_aliases(Color_fg);
2329     color_aliases(Color_bg);
2330 #ifndef NO_CURSORCOLOR
2331     color_aliases(Color_cursor);
2332     color_aliases(Color_cursor2);
2333 #endif				/* NO_CURSORCOLOR */
2334     color_aliases(Color_pointer);
2335     color_aliases(Color_border);
2336 #ifndef NO_BOLDUNDERLINE
2337     color_aliases(Color_BD);
2338     color_aliases(Color_UL);
2339 #endif				/* NO_BOLDUNDERLINE */
2340 
2341 /* add startup-menu: */
2342     { /* ONLYIF MENUBAR */
2343 	delay_menu_drawing = 1;
2344 	menubar_read(rs_menu);
2345 	delay_menu_drawing--;
2346     }
2347 
2348     Create_Windows(saved_argc, saved_argv);
2349     scr_reset();		/* initialize screen */
2350     Gr_reset();			/* reset graphics */
2351 
2352 /* add scrollBar, do it directly to avoid resize() */
2353     scrollbar_mapping(Options & Opt_scrollBar);
2354 /* we can now add menuBar */
2355     { /* ONLYIF MENUBAR */
2356 	if (delay_menu_drawing) {
2357 	    delay_menu_drawing = 0;
2358 	    menubar_mapping(1);
2359 	}
2360     }
2361 /* do it now to avoid unneccessary redrawing */
2362     XMapWindow(Xdisplay, TermWin.vt);
2363     XMapWindow(Xdisplay, TermWin.parent);
2364 
2365 #if 0
2366 #if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT) || defined(_MYSTYLE_)
2367     if( TermWin.background.trgType != BGT_None )
2368     {
2369         refresh_transparent_scrollbar();
2370         RenderPixmap(1);
2371 	scr_clear();
2372 	scr_touch();
2373     }
2374 #endif
2375 #endif
2376 
2377 #ifdef DISPLAY_IS_IP
2378 /* Fixup display_name for export over pty to any interested terminal
2379  * clients via "ESC[7n" (e.g. shells).  Note we use the pure IP number
2380  * (for the first non-loopback interface) that we get from
2381  * network_display().  This is more "name-resolution-portable", if you
2382  * will, and probably allows for faster x-client startup if your name
2383  * server is beyond a slow link or overloaded at client startup.  Of
2384  * course that only helps the shell's child processes, not us.
2385  *
2386  * Giving out the display_name also affords a potential security hole
2387  */
2388     val = display_name = network_display(display_name);
2389     if (val == NULL)
2390 #endif				/* DISPLAY_IS_IP */
2391 	val = XDisplayString(Xdisplay);
2392     if (display_name == NULL)
2393 	display_name = val;	/* use broken `:0' value */
2394 
2395     i = strlen(val);
2396     display_string = MALLOC((i + 9) * sizeof(char));
2397 
2398     sprintf(display_string, "DISPLAY=%s", val);
2399     sprintf(windowid_string, "WINDOWID=%u", (unsigned int)TermWin.parent);
2400 
2401 /* add entries to the environment:
2402  * @ DISPLAY:   in case we started with -display
2403  * @ WINDOWID:  X window id number of the window
2404  * @ COLORTERM: terminal sub-name and also indicates its color
2405  * @ TERM:      terminal name
2406  */
2407     putenv(display_string);
2408     putenv(windowid_string);
2409 /*    FREE(display_string); this cannot be freed */
2410 
2411 #ifdef RXVT_TERMINFO
2412     putenv("TERMINFO=" RXVT_TERMINFO);
2413 #endif
2414 
2415     if (Xdepth <= 2)
2416 	putenv("COLORTERM=" COLORTERMENV "-mono");
2417     else
2418 	putenv("COLORTERM=" COLORTERMENVFULL);
2419     if (rs_term_name != NULL) {
2420 	i = strlen(rs_term_name);
2421 	term_string = MALLOC((i + 6) * sizeof(char));
2422 
2423 	sprintf(term_string, "TERM=%s", rs_term_name);
2424 	putenv(term_string);
2425     } else {
2426 	putenv("TERM=" TERMENV);
2427     }
2428 
2429     if (!setlocale(LC_CTYPE, "")) print_error("Cannot set locale");
2430 
2431     init_command(cmd_argv);
2432 
2433     main_loop();		/* main processing loop */
2434     return EXIT_SUCCESS;
2435 }
2436 
2437 #undef XGetGeometry
trace_XGetGeometry(char * file,int line,Display * dpy,Window w,Window * r,int * x,int * y,unsigned int * width,unsigned int * height,unsigned int * bw,unsigned int * depth)2438 Status trace_XGetGeometry( char *file, int line, Display *dpy, Window w, Window *r, int *x, int *y,
2439                            unsigned int *width,unsigned int *height,unsigned int *bw,unsigned int *depth)
2440 {
2441     Status res ;
2442     fprintf( stderr, "%s(%d):XGetGeometry(%lX) = ",file,line,w);
2443     res = XGetGeometry(dpy,w,r,x,y,width,height,bw,depth);
2444     fprintf( stderr, "(%ux%u%+d%+d),%d\n", *width, *height, *x, *y, res );
2445     return res ;
2446 }
2447 
2448 
2449 /*}}} */
2450 /*----------------------- end-of-file (C source) -----------------------*/
2451