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.114 by root, Tue Sep 7 06:19:45 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),
393static int (*old_xerror_handler) (Display *dpy, XErrorEvent *event); 395static int (*old_xerror_handler) (Display *dpy, XErrorEvent *event);
394 396
395void 397void
396rxvt_init () 398rxvt_init ()
397{ 399{
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 /* 400 /*
406 * Save and then give up any super-user privileges 401 * Save and then give up any super-user privileges
407 * If we need privileges in any area then we must specifically request it. 402 * If we need privileges in any area then we must specifically request it.
408 * We should only need to be root in these cases: 403 * We should only need to be root in these cases:
409 * 1. write utmp entries on some systems 404 * 1. write utmp entries on some systems
410 * 2. chown tty on some systems 405 * 2. chown tty on some systems
411 */ 406 */
412 rxvt_privileges (SAVE); 407 rxvt_privileges (SAVE);
413 rxvt_privileges (IGNORE); 408 rxvt_privileges (IGNORE);
414 409
415 struct sigaction sa; 410 signal (SIGHUP, SIG_IGN);
416 411 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 412
426 /* need to trap SIGURG for SVR4 (Unixware) rlogin */ 413 /* need to trap SIGURG for SVR4 (Unixware) rlogin */
427 /* signal (SIGURG, SIG_DFL); */ 414 /* signal (SIGURG, SIG_DFL); */
428 415
429 old_xerror_handler = XSetErrorHandler ((XErrorHandler) rxvt_xerror_handler); 416 old_xerror_handler = XSetErrorHandler ((XErrorHandler) rxvt_xerror_handler);
417 // TODO: handle this with exceptions and tolerate the memory loss
430 //XSetIOErrorHandler ((XErrorHandler) rxvt_xioerror_handler); 418 //XSetIOErrorHandler ((XErrorHandler) rxvt_xioerror_handler);
431} 419}
432 420
433/* ------------------------------------------------------------------------- * 421/* ------------------------------------------------------------------------- *
434 * SIGNAL HANDLING & EXIT HANDLER * 422 * SIGNAL HANDLING & EXIT HANDLER *
435 * ------------------------------------------------------------------------- */ 423 * ------------------------------------------------------------------------- */
436/* 424/*
437 * Catch a SIGCHLD signal and exit if the direct child has died 425 * Catch a SIGCHLD signal and exit if the direct child has died
438 */ 426 */
439 427
440void rxvt_term::child_exited (int pid) 428void
429rxvt_term::sig_chld (sig_watcher &w)
441{ 430{
442 for (rxvt_term **t = termlist.begin (); t < termlist.end (); t++) 431 // we are being called for every SIGCHLD, not just ours
443 if (pid == (*t)->cmd_pid) 432 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 433
457 while ((pid = waitpid (-1, NULL, WNOHANG)) > 0) 434 while ((pid = waitpid (-1, NULL, WNOHANG)) > 0)
458 rxvt_term::child_exited (pid); 435 for (rxvt_term **t = termlist.begin (); t < termlist.end (); t++)
459 436 if (pid == (*t)->cmd_pid)
460 errno = save_errno; 437 {
461} 438 (*t)->destroy ();
462 439 break;
463/* 440 }
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} 441}
492 442
493/*----------------------------------------------------------------------*/ 443/*----------------------------------------------------------------------*/
494/* 444/*
495 * Exit gracefully, clearing the utmp entry and restoring tty attributes 445 * Exit gracefully, clearing the utmp entry and restoring tty attributes
496 * TODO: if debugging, this should free up any known resources if we can 446 * TODO: if debugging, this should free up any known resources if we can
497 */ 447 */
448void
449rxvt_destroy_all ()
450{
451 // TODO: rxvtd should clean up all ressources
452 for (rxvt_term **t = rxvt_term::termlist.begin (); t < rxvt_term::termlist.end (); t++)
453 (*t)->destroy ();
454}
455
456/*
457 * Catch a fatal signal and tidy up before quitting
458 */
459void
460rxvt_term::sig_term (sig_watcher &w)
461{
462#ifdef DEBUG_CMD
463 rxvt_warn ("caught signal %d, exiting.\n", w.signum);
464#endif
465 rxvt_destroy_all ();
466 signal (w.signum, SIG_DFL);
467 kill (getpid (), w.signum);
468}
469
498/* INTPROTO */ 470/* INTPROTO */
499void 471int
500rxvt_clean_exit () 472rxvt_xerror_handler (Display *display, XErrorEvent *event)
501{ 473{
502 // TODO: rxvtd should clean up all ressources 474 if (GET_R->allowedxerror == -1)
503 if (GET_R) 475 GET_R->allowedxerror = event->error_code;
476 else
477 {
478 old_xerror_handler (display, event);
504 GET_R->destroy (); 479 GET_R->destroy ();
480 }
481
482 return 0;
505} 483}
506 484
507/* ------------------------------------------------------------------------- * 485/* ------------------------------------------------------------------------- *
508 * MEMORY ALLOCATION WRAPPERS * 486 * MEMORY ALLOCATION WRAPPERS *
509 * ------------------------------------------------------------------------- */ 487 * ------------------------------------------------------------------------- */
510/* INTPROTO */ 488void *
511void *
512rxvt_malloc (size_t size) 489rxvt_malloc (size_t size)
513{ 490{
514 void *p;
515
516 p = malloc (size); 491 void *p = malloc (size);
492
517 if (p) 493 if (!p)
518 return p;
519
520 rxvt_fatal ("memory allocation failure. aborting.\n"); 494 rxvt_fatal ("memory allocation failure. aborting.\n");
521 /* NOTREACHED */ 495
496 return p;
522} 497}
523 498
524/* INTPROTO */ 499/* INTPROTO */
525void * 500void *
526rxvt_calloc (size_t number, size_t size) 501rxvt_calloc (size_t number, size_t size)
527{ 502{
528 void *p;
529
530 p = calloc (number, size); 503 void *p = calloc (number, size);
504
531 if (p) 505 if (!p)
532 return p;
533
534 rxvt_fatal ("memory allocation failure. aborting.\n"); 506 rxvt_fatal ("memory allocation failure. aborting.\n");
535 /* NOTREACHED */ 507
508 return p;
536} 509}
537 510
538/* INTPROTO */ 511/* INTPROTO */
539void * 512void *
540rxvt_realloc (void *ptr, size_t size) 513rxvt_realloc (void *ptr, size_t size)
541{ 514{
542 void *p;
543
544 if (ptr)
545 p = realloc (ptr, size); 515 void *p = realloc (ptr, size);
546 else
547 p = malloc (size);
548 516
549 if (p) 517 if (!p)
550 return p;
551
552 rxvt_fatal ("memory allocation failure. aborting.\n"); 518 rxvt_fatal ("memory allocation failure. aborting.\n");
553 /* NOTREACHED */ 519
520 return p;
554} 521}
555 522
556/* ------------------------------------------------------------------------- * 523/* ------------------------------------------------------------------------- *
557 * PRIVILEGED OPERATIONS * 524 * PRIVILEGED OPERATIONS *
558 * ------------------------------------------------------------------------- */ 525 * ------------------------------------------------------------------------- */
798rxvt_term::set_fonts () 765rxvt_term::set_fonts ()
799{ 766{
800 rxvt_fontset *fs = new rxvt_fontset (this); 767 rxvt_fontset *fs = new rxvt_fontset (this);
801 rxvt_fontprop prop; 768 rxvt_fontprop prop;
802 769
803 prop.width = prop.height = prop.weight = prop.slant
804 = rxvt_fontprop::unset;
805
806 if (!fs 770 if (!fs
807 || !fs->populate (rs[Rs_font] ? rs[Rs_font] : "fixed", prop) 771 || !fs->populate (rs[Rs_font] ? rs[Rs_font] : "fixed")
808 || !fs->realize_font (1)) 772 || !fs->realize_font (1))
809 { 773 {
810 delete fs; 774 delete fs;
811 return false; 775 return false;
812 } 776 }
818#endif 782#endif
819 783
820 delete TermWin.fontset[0]; 784 delete TermWin.fontset[0];
821 TermWin.fontset[0] = fs; 785 TermWin.fontset[0] = fs;
822 786
823 fs->prop = prop = (*fs)[1]->properties (); 787 prop = (*fs)[1]->properties ();
788 fs->set_prop (prop);
824 789
825 TermWin.fwidth = prop.width; 790 TermWin.fwidth = prop.width;
826 TermWin.fheight = prop.height; 791 TermWin.fheight = prop.height;
827 TermWin.fweight = prop.weight; 792 TermWin.fweight = prop.weight;
828 TermWin.fslant = prop.slant; 793 TermWin.fslant = prop.slant;
848 813
849 if (SET_STYLE (0, style) & RS_Bold) prop2.weight = rxvt_fontprop::bold; 814 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; 815 if (SET_STYLE (0, style) & RS_Italic) prop2.slant = rxvt_fontprop::italic;
851 } 816 }
852 817
853 fs->populate (res, prop2); 818 fs->populate (res);
819 fs->set_prop (prop2);
854 } 820 }
855#else 821#else
856 TermWin.fontset[style] = TermWin.fontset[0]; 822 TermWin.fontset[style] = TermWin.fontset[0];
857#endif 823#endif
858 } 824 }
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 p = rs[Rs_preeditType] ? rs[Rs_preeditType] : "OverTheSpot,OffTheSpot,Root,None";
1342 s = rxvt_splitcommastring (p); 1305 s = rxvt_splitcommastring (p);
1343 1306
1344 for (i = found = 0; !found && s[i]; i++) 1307 for (i = found = 0; !found && s[i]; i++)
1345 { 1308 {
1346 if (!strcmp (s[i], "OverTheSpot")) 1309 if (!strcmp (s[i], "OverTheSpot"))
1347 input_style = (XIMPreeditPosition | XIMStatusNothing); 1310 input_style = (XIMPreeditPosition | XIMStatusNothing);
1348 else if (!strcmp (s[i], "OffTheSpot")) 1311 else if (!strcmp (s[i], "OffTheSpot"))
1349 input_style = (XIMPreeditArea | XIMStatusArea); 1312 input_style = (XIMPreeditArea | XIMStatusArea);
1350 else if (!strcmp (s[i], "Root")) 1313 else if (!strcmp (s[i], "Root"))
1351 input_style = (XIMPreeditNothing | XIMStatusNothing); 1314 input_style = (XIMPreeditNothing | XIMStatusNothing);
1315 else if (!strcmp (s[i], "None"))
1316 input_style = (XIMPreeditNone | XIMStatusNone);
1352 1317
1353 for (j = 0; j < xim_styles->count_styles; j++) 1318 for (j = 0; j < xim_styles->count_styles; j++)
1354 if (input_style == xim_styles->supported_styles[j]) 1319 if (input_style == xim_styles->supported_styles[j])
1355 { 1320 {
1356 found = 1; 1321 found = 1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines