ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/main.C
(Generate patch)

Comparing rxvt-unicode/src/main.C (file contents):
Revision 1.108 by root, Wed Aug 25 05:03:33 2004 UTC vs.
Revision 1.121 by root, Wed Dec 15 00:12:58 2004 UTC

155 pointer_ev (this, &rxvt_term::pointer_cb), 155 pointer_ev (this, &rxvt_term::pointer_cb),
156#endif 156#endif
157#ifdef USE_XIM 157#ifdef USE_XIM
158 im_ev (this, &rxvt_term::im_cb), 158 im_ev (this, &rxvt_term::im_cb),
159#endif 159#endif
160 sw_term (this, &rxvt_term::sig_term),
161 sw_chld (this, &rxvt_term::sig_chld),
160 termwin_ev (this, &rxvt_term::x_cb), 162 termwin_ev (this, &rxvt_term::x_cb),
161 vt_ev (this, &rxvt_term::x_cb), 163 vt_ev (this, &rxvt_term::x_cb),
162 check_ev (this, &rxvt_term::check_cb), 164 check_ev (this, &rxvt_term::check_cb),
163 flush_ev (this, &rxvt_term::flush_cb), 165 flush_ev (this, &rxvt_term::flush_cb),
164 destroy_ev (this, &rxvt_term::destroy_cb), 166 destroy_ev (this, &rxvt_term::destroy_cb),
257 free (env_windowid); 259 free (env_windowid);
258 free (env_display); 260 free (env_display);
259 free (env_term); 261 free (env_term);
260 free (env_colorfgbg); 262 free (env_colorfgbg);
261 free (locale); 263 free (locale);
262#if 0 264 free (v_buffer);
263 free (codeset); 265 free (incr_buf);
264#endif
265 266
266 delete envv; 267 delete envv;
267 delete argv; 268 delete argv;
268} 269}
269 270
393static int (*old_xerror_handler) (Display *dpy, XErrorEvent *event); 394static int (*old_xerror_handler) (Display *dpy, XErrorEvent *event);
394 395
395void 396void
396rxvt_init () 397rxvt_init ()
397{ 398{
398 /* install exit handler for cleanup */
399#if 0
400#ifdef HAVE_ATEXIT
401 atexit (rxvt_clean_exit);
402#else
403#endif
404#endif
405 /* 399 /*
406 * Save and then give up any super-user privileges 400 * Save and then give up any super-user privileges
407 * If we need privileges in any area then we must specifically request it. 401 * If we need privileges in any area then we must specifically request it.
408 * We should only need to be root in these cases: 402 * We should only need to be root in these cases:
409 * 1. write utmp entries on some systems 403 * 1. write utmp entries on some systems
410 * 2. chown tty on some systems 404 * 2. chown tty on some systems
411 */ 405 */
412 rxvt_privileges (SAVE); 406 rxvt_privileges (SAVE);
413 rxvt_privileges (IGNORE); 407 rxvt_privileges (IGNORE);
414 408
415 struct sigaction sa; 409 signal (SIGHUP, SIG_IGN);
416 410 signal (SIGPIPE, SIG_IGN);
417 sigfillset (&sa.sa_mask);
418 sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
419 sa.sa_handler = SIG_IGN; sigaction (SIGHUP , &sa, 0);
420 sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, 0);
421 sa.sa_handler = rxvt_Exit_signal; sigaction (SIGINT , &sa, 0);
422 sa.sa_handler = rxvt_Exit_signal; sigaction (SIGQUIT, &sa, 0);
423 sa.sa_handler = rxvt_Exit_signal; sigaction (SIGTERM, &sa, 0);
424 sa.sa_handler = rxvt_Child_signal; sigaction (SIGCHLD, &sa, 0);
425 411
426 /* need to trap SIGURG for SVR4 (Unixware) rlogin */ 412 /* need to trap SIGURG for SVR4 (Unixware) rlogin */
427 /* signal (SIGURG, SIG_DFL); */ 413 /* signal (SIGURG, SIG_DFL); */
428 414
429 old_xerror_handler = XSetErrorHandler ((XErrorHandler) rxvt_xerror_handler); 415 old_xerror_handler = XSetErrorHandler ((XErrorHandler) rxvt_xerror_handler);
416 // TODO: handle this with exceptions and tolerate the memory loss
430 //XSetIOErrorHandler ((XErrorHandler) rxvt_xioerror_handler); 417 //XSetIOErrorHandler ((XErrorHandler) rxvt_xioerror_handler);
431} 418}
432 419
433/* ------------------------------------------------------------------------- * 420/* ------------------------------------------------------------------------- *
434 * SIGNAL HANDLING & EXIT HANDLER * 421 * SIGNAL HANDLING & EXIT HANDLER *
435 * ------------------------------------------------------------------------- */ 422 * ------------------------------------------------------------------------- */
436/* 423/*
437 * Catch a SIGCHLD signal and exit if the direct child has died 424 * Catch a SIGCHLD signal and exit if the direct child has died
438 */ 425 */
439 426
440void rxvt_term::child_exited (int pid) 427void
428rxvt_term::sig_chld (sig_watcher &w)
441{ 429{
442 for (rxvt_term **t = termlist.begin (); t < termlist.end (); t++) 430 // we are being called for every SIGCHLD, not just ours
443 if (pid == (*t)->cmd_pid) 431 int pid;
444 {
445 (*t)->destroy ();
446 break;
447 }
448}
449
450/* ARGSUSED */
451/* INTPROTO */
452RETSIGTYPE
453rxvt_Child_signal (int sig __attribute__ ((unused)))
454{
455 int pid, save_errno = errno;
456 432
457 while ((pid = waitpid (-1, NULL, WNOHANG)) > 0) 433 while ((pid = waitpid (-1, NULL, WNOHANG)) > 0)
458 rxvt_term::child_exited (pid); 434 for (rxvt_term **t = termlist.begin (); t < termlist.end (); t++)
459 435 if (pid == (*t)->cmd_pid)
460 errno = save_errno; 436 {
461} 437 (*t)->destroy ();
462 438 break;
463/* 439 }
464 * Catch a fatal signal and tidy up before quitting
465 */
466/* INTPROTO */
467RETSIGTYPE
468rxvt_Exit_signal (int sig)
469{
470 signal (sig, SIG_DFL);
471#ifdef DEBUG_CMD
472 rxvt_warn ("caught signal %d, exiting.\n", sig);
473#endif
474 rxvt_clean_exit ();
475 kill (getpid (), sig);
476}
477
478/* INTPROTO */
479int
480rxvt_xerror_handler (Display *display, XErrorEvent *event)
481{
482 if (GET_R->allowedxerror == -1)
483 GET_R->allowedxerror = event->error_code;
484 else
485 {
486 old_xerror_handler (display, event);
487 GET_R->destroy ();
488 }
489
490 return 0;
491} 440}
492 441
493/*----------------------------------------------------------------------*/ 442/*----------------------------------------------------------------------*/
494/* 443/*
495 * Exit gracefully, clearing the utmp entry and restoring tty attributes 444 * Exit gracefully, clearing the utmp entry and restoring tty attributes
496 * TODO: if debugging, this should free up any known resources if we can 445 * TODO: if debugging, this should free up any known resources if we can
497 */ 446 */
447void
448rxvt_destroy_all ()
449{
450 // TODO: rxvtd should clean up all ressources
451 for (rxvt_term **t = rxvt_term::termlist.begin (); t < rxvt_term::termlist.end (); t++)
452 (*t)->destroy ();
453}
454
455/*
456 * Catch a fatal signal and tidy up before quitting
457 */
458void
459rxvt_term::sig_term (sig_watcher &w)
460{
461#ifdef DEBUG_CMD
462 rxvt_warn ("caught signal %d, exiting.\n", w.signum);
463#endif
464 rxvt_destroy_all ();
465 signal (w.signum, SIG_DFL);
466 kill (getpid (), w.signum);
467}
468
498/* INTPROTO */ 469/* INTPROTO */
499void 470int
500rxvt_clean_exit () 471rxvt_xerror_handler (Display *display, XErrorEvent *event)
501{ 472{
502 // TODO: rxvtd should clean up all ressources 473 if (GET_R->allowedxerror == -1)
503 if (GET_R) 474 GET_R->allowedxerror = event->error_code;
475 else
476 {
477 old_xerror_handler (display, event);
504 GET_R->destroy (); 478 GET_R->destroy ();
479 }
480
481 return 0;
505} 482}
506 483
507/* ------------------------------------------------------------------------- * 484/* ------------------------------------------------------------------------- *
508 * MEMORY ALLOCATION WRAPPERS * 485 * MEMORY ALLOCATION WRAPPERS *
509 * ------------------------------------------------------------------------- */ 486 * ------------------------------------------------------------------------- */
510/* INTPROTO */ 487void *
511void *
512rxvt_malloc (size_t size) 488rxvt_malloc (size_t size)
513{ 489{
514 void *p;
515
516 p = malloc (size); 490 void *p = malloc (size);
491
517 if (p) 492 if (!p)
518 return p;
519
520 rxvt_fatal ("memory allocation failure. aborting.\n"); 493 rxvt_fatal ("memory allocation failure. aborting.\n");
521 /* NOTREACHED */ 494
495 return p;
522} 496}
523 497
524/* INTPROTO */ 498/* INTPROTO */
525void * 499void *
526rxvt_calloc (size_t number, size_t size) 500rxvt_calloc (size_t number, size_t size)
527{ 501{
528 void *p;
529
530 p = calloc (number, size); 502 void *p = calloc (number, size);
503
531 if (p) 504 if (!p)
532 return p;
533
534 rxvt_fatal ("memory allocation failure. aborting.\n"); 505 rxvt_fatal ("memory allocation failure. aborting.\n");
535 /* NOTREACHED */ 506
507 return p;
536} 508}
537 509
538/* INTPROTO */ 510/* INTPROTO */
539void * 511void *
540rxvt_realloc (void *ptr, size_t size) 512rxvt_realloc (void *ptr, size_t size)
541{ 513{
542 void *p;
543
544 if (ptr)
545 p = realloc (ptr, size); 514 void *p = realloc (ptr, size);
546 else
547 p = malloc (size);
548 515
549 if (p) 516 if (!p)
550 return p;
551
552 rxvt_fatal ("memory allocation failure. aborting.\n"); 517 rxvt_fatal ("memory allocation failure. aborting.\n");
553 /* NOTREACHED */ 518
519 return p;
554} 520}
555 521
556/* ------------------------------------------------------------------------- * 522/* ------------------------------------------------------------------------- *
557 * PRIVILEGED OPERATIONS * 523 * PRIVILEGED OPERATIONS *
558 * ------------------------------------------------------------------------- */ 524 * ------------------------------------------------------------------------- */
798rxvt_term::set_fonts () 764rxvt_term::set_fonts ()
799{ 765{
800 rxvt_fontset *fs = new rxvt_fontset (this); 766 rxvt_fontset *fs = new rxvt_fontset (this);
801 rxvt_fontprop prop; 767 rxvt_fontprop prop;
802 768
803 prop.width = prop.height = prop.weight = prop.slant
804 = rxvt_fontprop::unset;
805
806 if (!fs 769 if (!fs
807 || !fs->populate (rs[Rs_font] ? rs[Rs_font] : "fixed", prop) 770 || !fs->populate (rs[Rs_font] ? rs[Rs_font] : "fixed")
808 || !fs->realize_font (1)) 771 || !fs->realize_font (1))
809 { 772 {
810 delete fs; 773 delete fs;
811 return false; 774 return false;
812 } 775 }
818#endif 781#endif
819 782
820 delete TermWin.fontset[0]; 783 delete TermWin.fontset[0];
821 TermWin.fontset[0] = fs; 784 TermWin.fontset[0] = fs;
822 785
823 fs->prop = prop = (*fs)[1]->properties (); 786 prop = (*fs)[1]->properties ();
787 fs->set_prop (prop);
824 788
825 TermWin.fwidth = prop.width; 789 TermWin.fwidth = prop.width;
826 TermWin.fheight = prop.height; 790 TermWin.fheight = prop.height;
827 TermWin.fweight = prop.weight; 791 TermWin.fweight = prop.weight;
828 TermWin.fslant = prop.slant; 792 TermWin.fslant = prop.slant;
848 812
849 if (SET_STYLE (0, style) & RS_Bold) prop2.weight = rxvt_fontprop::bold; 813 if (SET_STYLE (0, style) & RS_Bold) prop2.weight = rxvt_fontprop::bold;
850 if (SET_STYLE (0, style) & RS_Italic) prop2.slant = rxvt_fontprop::italic; 814 if (SET_STYLE (0, style) & RS_Italic) prop2.slant = rxvt_fontprop::italic;
851 } 815 }
852 816
853 fs->populate (res, prop2); 817 fs->populate (res);
818 fs->set_prop (prop2);
854 } 819 }
855#else 820#else
856 TermWin.fontset[style] = TermWin.fontset[0]; 821 TermWin.fontset[style] = TermWin.fontset[0];
857#endif 822#endif
858 } 823 }
865 } 830 }
866 831
867 return true; 832 return true;
868} 833}
869 834
835void rxvt_term::set_string_property (Atom prop, const char *str, int len)
836{
837 // TODO: SMART_WINDOW_TITLE
838 XChangeProperty (display->display, TermWin.parent[0],
839 prop, XA_STRING, 8, PropModeReplace,
840 (const unsigned char *)str, len >= 0 ? len : strlen (str));
841}
842
843void rxvt_term::set_utf8_property (Atom prop, const char *str, int len)
844{
845 // TODO: SMART_WINDOW_TITLE
846 wchar_t *ws = rxvt_mbstowcs (str, len);
847 char *s = rxvt_wcstoutf8 (ws);
848
849 XChangeProperty (display->display, TermWin.parent[0],
850 prop, xa[XA_UTF8_STRING], 8, PropModeReplace,
851 (const unsigned char *)s, strlen (s));
852
853 free (s);
854 free (ws);
855}
856
870/*----------------------------------------------------------------------*/ 857/*----------------------------------------------------------------------*/
871/*----------------------------------------------------------------------*/ 858/*----------------------------------------------------------------------*/
872/* xterm sequences - title, iconName, color (exptl) */ 859/* xterm sequences - title, iconName, color (exptl) */
873void 860void
874rxvt_term::set_title (const char *str) 861rxvt_term::set_title (const char *str)
875{ 862{
876#ifdef SMART_WINDOW_TITLE 863 set_string_property (XA_WM_NAME, str);
877 char *name; 864#if ENABLE_FRILLS
878 865 set_utf8_property (xa[XA_NET_WM_NAME], str);
879 if (!XFetchName (display->display, TermWin.parent[0], &name))
880 name = NULL;
881
882 if (name == NULL || strcmp (name, str))
883#endif
884 XStoreName (display->display, TermWin.parent[0], str);
885
886#ifdef SMART_WINDOW_TITLE
887 if (name)
888 XFree (name);
889#endif 866#endif
890} 867}
891 868
892void 869void
893rxvt_term::set_icon_name (const char *str) 870rxvt_term::set_icon_name (const char *str)
894{ 871{
895#ifdef SMART_WINDOW_TITLE 872 set_string_property (XA_WM_ICON_NAME, str);
896 char *name; 873#if ENABLE_FRILLS
897 874 set_utf8_property (xa[XA_NET_WM_ICON_NAME], str);
898 if (!XGetIconName (display->display, TermWin.parent[0], &name))
899 name = NULL;
900
901 if (name == NULL || strcmp (name, str))
902#endif
903 XSetIconName (display->display, TermWin.parent[0], str);
904
905#ifdef SMART_WINDOW_TITLE
906 if (name)
907 XFree (name);
908#endif 875#endif
909} 876}
910 877
911#ifdef XTERM_COLOR_CHANGE 878#ifdef XTERM_COLOR_CHANGE
912void 879void
1263} 1230}
1264 1231
1265void 1232void
1266rxvt_term::IMSendSpot () 1233rxvt_term::IMSendSpot ()
1267{ 1234{
1268 XPoint spot; 1235 XPoint nspot;
1269 XVaNestedList preedit_attr; 1236 XVaNestedList preedit_attr;
1270 1237
1271 if (!Input_Context 1238 if (!Input_Context
1272 || !TermWin.focus 1239 || !TermWin.focus
1273 || !(input_style & XIMPreeditPosition) 1240 || !(input_style & XIMPreeditPosition))
1274#if 0
1275 || !(event_type == KeyPress
1276 || event_type == Expose
1277 || event_type == NoExpose
1278 || event_type == SelectionNotify
1279 || event_type == ButtonRelease || event_type == FocusIn)
1280#endif
1281 || !IMisRunning ())
1282 return; 1241 return;
1283 1242
1284 im_set_position (spot); 1243 im_set_position (nspot);
1244
1245 if (nspot.x == spot.x && nspot.y == spot.y)
1246 return;
1247
1248 spot = nspot;
1285 1249
1286 preedit_attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL); 1250 preedit_attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
1287 XSetICValues (Input_Context, XNPreeditAttributes, preedit_attr, NULL); 1251 XSetICValues (Input_Context, XNPreeditAttributes, preedit_attr, NULL);
1288 XFree (preedit_attr); 1252 XFree (preedit_attr);
1289} 1253}
1290 1254
1291void 1255void
1292rxvt_term::im_destroy () 1256rxvt_term::im_destroy ()
1293{ 1257{
1294 if (Input_Context)
1295 {
1296 XDestroyIC (Input_Context);
1297 Input_Context = 0;
1298 }
1299
1300 if (input_method) 1258 if (input_method)
1301 { 1259 {
1260 if (Input_Context && input_method->xim)
1261 XDestroyIC (Input_Context);
1262
1302 display->put_xim (input_method); 1263 display->put_xim (input_method);
1303 input_method = 0; 1264 input_method = 0;
1304 } 1265 }
1266
1267 Input_Context = 0;
1305} 1268}
1306 1269
1307/* 1270/*
1308 * Try to open a XIM with the current modifiers, then see if we can 1271 * Try to open a XIM with the current modifiers, then see if we can
1309 * open a suitable preedit type 1272 * open a suitable preedit type
1327 input_method = display->get_xim (locale, modifiers); 1290 input_method = display->get_xim (locale, modifiers);
1328 if (input_method == NULL) 1291 if (input_method == NULL)
1329 return false; 1292 return false;
1330 1293
1331 xim = input_method->xim; 1294 xim = input_method->xim;
1295 spot.x = spot.y = -1;
1332 1296
1333 xim_styles = NULL; 1297 xim_styles = NULL;
1334 if (XGetIMValues (xim, XNQueryInputStyle, &xim_styles, NULL) 1298 if (XGetIMValues (xim, XNQueryInputStyle, &xim_styles, NULL)
1335 || !xim_styles || !xim_styles->count_styles) 1299 || !xim_styles || !xim_styles->count_styles)
1336 { 1300 {
1337 im_destroy (); 1301 im_destroy ();
1338 return false; 1302 return false;
1339 } 1303 }
1340 1304
1341 p = rs[Rs_preeditType] ? rs[Rs_preeditType] : "OverTheSpot,OffTheSpot,Root"; 1305 const char *pet[] = { rs[Rs_preeditType], "OverTheSpot,OffTheSpot,Root,None" };
1306
1307 for (int pi = 0; pi < 2; pi++)
1308 {
1309 p = pet[pi];
1310
1311 if (!p)
1312 continue;
1313
1342 s = rxvt_splitcommastring (p); 1314 s = rxvt_splitcommastring (p);
1343 1315
1344 for (i = found = 0; !found && s[i]; i++) 1316 for (i = found = 0; !found && s[i]; i++)
1345 { 1317 {
1346 if (!strcmp (s[i], "OverTheSpot")) 1318 if (!strcmp (s[i], "OverTheSpot"))
1347 input_style = (XIMPreeditPosition | XIMStatusNothing); 1319 input_style = (XIMPreeditPosition | XIMStatusNothing);
1348 else if (!strcmp (s[i], "OffTheSpot")) 1320 else if (!strcmp (s[i], "OffTheSpot"))
1349 input_style = (XIMPreeditArea | XIMStatusArea); 1321 input_style = (XIMPreeditArea | XIMStatusArea);
1350 else if (!strcmp (s[i], "Root")) 1322 else if (!strcmp (s[i], "Root"))
1351 input_style = (XIMPreeditNothing | XIMStatusNothing); 1323 input_style = (XIMPreeditNothing | XIMStatusNothing);
1324 else if (!strcmp (s[i], "None"))
1325 input_style = (XIMPreeditNone | XIMStatusNone);
1352 1326
1353 for (j = 0; j < xim_styles->count_styles; j++) 1327 for (j = 0; j < xim_styles->count_styles; j++)
1354 if (input_style == xim_styles->supported_styles[j]) 1328 if (input_style == xim_styles->supported_styles[j])
1355 { 1329 {
1330 rxvt_freecommastring (s);
1331
1356 found = 1; 1332 found = 1;
1357 break; 1333 goto foundpet;
1334 }
1335
1358 } 1336 }
1359 }
1360 1337
1361 for (i = 0; s[i]; i++) 1338 rxvt_freecommastring (s);
1362 free (s[i]); 1339 }
1363 1340
1364 free (s); 1341foundpet:
1342
1365 XFree (xim_styles); 1343 XFree (xim_styles);
1366 1344
1367 if (!found) 1345 if (!found)
1368 { 1346 {
1369 im_destroy (); 1347 im_destroy ();
1494 if (p && *p) 1472 if (p && *p)
1495 { 1473 {
1496 bool found = false; 1474 bool found = false;
1497 1475
1498 s = rxvt_splitcommastring (p); 1476 s = rxvt_splitcommastring (p);
1477
1499 for (i = 0; s[i]; i++) 1478 for (i = 0; s[i]; i++)
1500 { 1479 {
1501 if (*s[i]) 1480 if (*s[i])
1502 { 1481 {
1503 strcpy (buf, "@im="); 1482 strcpy (buf, "@im=");
1507 found = true; 1486 found = true;
1508 break; 1487 break;
1509 } 1488 }
1510 } 1489 }
1511 } 1490 }
1512 for (i = 0; s[i]; i++) 1491
1513 free (s[i]); 1492 rxvt_freecommastring (s);
1514 free (s);
1515 1493
1516 if (found) 1494 if (found)
1517 goto done; 1495 goto done;
1518 } 1496 }
1519 1497

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines