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