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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines