--- rxvt-unicode/src/main.C 2004/08/15 22:09:24 1.94 +++ rxvt-unicode/src/main.C 2004/12/15 00:12:58 1.121 @@ -125,21 +125,6 @@ } #endif -void * -rxvt_term::operator new (size_t s) -{ - void *p = malloc (s); - - memset (p, 0, s); - return p; -} - -void -rxvt_term::operator delete (void *p, size_t s) -{ - free (p); -} - rxvt_term::rxvt_term () : #if TRANSPARENT @@ -172,6 +157,8 @@ #ifdef USE_XIM im_ev (this, &rxvt_term::im_cb), #endif + sw_term (this, &rxvt_term::sig_term), + sw_chld (this, &rxvt_term::sig_chld), termwin_ev (this, &rxvt_term::x_cb), vt_ev (this, &rxvt_term::x_cb), check_ev (this, &rxvt_term::check_cb), @@ -198,7 +185,12 @@ privileged_utmp (RESTORE); #endif - delete TermWin.fontset; +#if ENABLE_STYLES + for (int i = RS_styleCount; --i; ) + if (TermWin.fontset[i] != TermWin.fontset[0]) + delete TermWin.fontset[i]; +#endif + delete TermWin.fontset[0]; if (display) { @@ -269,9 +261,8 @@ free (env_term); free (env_colorfgbg); free (locale); -#if 0 - free (codeset); -#endif + free (v_buffer); + free (incr_buf); delete envv; delete argv; @@ -389,6 +380,8 @@ XMapWindow (display->display, TermWin.vt); XMapWindow (display->display, TermWin.parent[0]); + set_colorfgbg (); + init_command (cmd_argv); pty_ev.start (pty.pty, EVENT_READ); @@ -403,13 +396,6 @@ void rxvt_init () { - /* install exit handler for cleanup */ -#if 0 -#ifdef HAVE_ATEXIT - atexit (rxvt_clean_exit); -#else -#endif -#endif /* * Save and then give up any super-user privileges * If we need privileges in any area then we must specifically request it. @@ -420,21 +406,14 @@ rxvt_privileges (SAVE); rxvt_privileges (IGNORE); - struct sigaction sa; - - sigfillset (&sa.sa_mask); - sa.sa_flags = SA_NOCLDSTOP | SA_RESTART; - sa.sa_handler = SIG_IGN; sigaction (SIGHUP , &sa, 0); - sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, 0); - sa.sa_handler = rxvt_Exit_signal; sigaction (SIGINT , &sa, 0); - sa.sa_handler = rxvt_Exit_signal; sigaction (SIGQUIT, &sa, 0); - sa.sa_handler = rxvt_Exit_signal; sigaction (SIGTERM, &sa, 0); - sa.sa_handler = rxvt_Child_signal; sigaction (SIGCHLD, &sa, 0); + signal (SIGHUP, SIG_IGN); + signal (SIGPIPE, SIG_IGN); /* need to trap SIGURG for SVR4 (Unixware) rlogin */ /* signal (SIGURG, SIG_DFL); */ old_xerror_handler = XSetErrorHandler ((XErrorHandler) rxvt_xerror_handler); + // TODO: handle this with exceptions and tolerate the memory loss //XSetIOErrorHandler ((XErrorHandler) rxvt_xioerror_handler); } @@ -445,42 +424,46 @@ * Catch a SIGCHLD signal and exit if the direct child has died */ -void rxvt_term::child_exited (int pid) -{ - for (rxvt_term **t = termlist.begin (); t < termlist.end (); t++) - if (pid == (*t)->cmd_pid) - { - (*t)->destroy (); - break; - } -} - -/* ARGSUSED */ -/* INTPROTO */ -RETSIGTYPE -rxvt_Child_signal (int sig __attribute__ ((unused))) +void +rxvt_term::sig_chld (sig_watcher &w) { - int pid, save_errno = errno; + // we are being called for every SIGCHLD, not just ours + int pid; while ((pid = waitpid (-1, NULL, WNOHANG)) > 0) - rxvt_term::child_exited (pid); + for (rxvt_term **t = termlist.begin (); t < termlist.end (); t++) + if (pid == (*t)->cmd_pid) + { + (*t)->destroy (); + break; + } +} - errno = save_errno; +/*----------------------------------------------------------------------*/ +/* + * Exit gracefully, clearing the utmp entry and restoring tty attributes + * TODO: if debugging, this should free up any known resources if we can + */ +void +rxvt_destroy_all () +{ + // TODO: rxvtd should clean up all ressources + for (rxvt_term **t = rxvt_term::termlist.begin (); t < rxvt_term::termlist.end (); t++) + (*t)->destroy (); } /* * Catch a fatal signal and tidy up before quitting */ -/* INTPROTO */ -RETSIGTYPE -rxvt_Exit_signal (int sig) +void +rxvt_term::sig_term (sig_watcher &w) { - signal (sig, SIG_DFL); #ifdef DEBUG_CMD - rxvt_warn ("caught signal %d, exiting.\n", sig); + rxvt_warn ("caught signal %d, exiting.\n", w.signum); #endif - rxvt_clean_exit (); - kill (getpid (), sig); + rxvt_destroy_all (); + signal (w.signum, SIG_DFL); + kill (getpid (), w.signum); } /* INTPROTO */ @@ -498,67 +481,42 @@ return 0; } -/*----------------------------------------------------------------------*/ -/* - * Exit gracefully, clearing the utmp entry and restoring tty attributes - * TODO: if debugging, this should free up any known resources if we can - */ -/* INTPROTO */ -void -rxvt_clean_exit () -{ - // TODO: rxvtd should clean up all ressources - if (GET_R) - GET_R->destroy (); -} - /* ------------------------------------------------------------------------- * * MEMORY ALLOCATION WRAPPERS * * ------------------------------------------------------------------------- */ -/* INTPROTO */ -void * +void * rxvt_malloc (size_t size) { - void *p; + void *p = malloc (size); - p = malloc (size); - if (p) - return p; + if (!p) + rxvt_fatal ("memory allocation failure. aborting.\n"); - rxvt_fatal ("memory allocation failure. aborting.\n"); - /* NOTREACHED */ + return p; } /* INTPROTO */ void * rxvt_calloc (size_t number, size_t size) { - void *p; + void *p = calloc (number, size); - p = calloc (number, size); - if (p) - return p; + if (!p) + rxvt_fatal ("memory allocation failure. aborting.\n"); - rxvt_fatal ("memory allocation failure. aborting.\n"); - /* NOTREACHED */ + return p; } /* INTPROTO */ void * rxvt_realloc (void *ptr, size_t size) { - void *p; + void *p = realloc (ptr, size); - if (ptr) - p = realloc (ptr, size); - else - p = malloc (size); + if (!p) + rxvt_fatal ("memory allocation failure. aborting.\n"); - if (p) - return p; - - rxvt_fatal ("memory allocation failure. aborting.\n"); - /* NOTREACHED */ + return p; } /* ------------------------------------------------------------------------- * @@ -795,7 +753,7 @@ } /*----------------------------------------------------------------------*/ -/* rxvt_change_font () - Switch to a new font */ +/* set_fonts () - load and set the various fonts /* * init = 1 - initialize * @@ -803,49 +761,97 @@ * fontname == FONT_DN - switch to smaller font */ bool -rxvt_term::change_font (const char *fontname) +rxvt_term::set_fonts () { - if (fontname == FONT_UP) - { - // TODO - } - else if (fontname == FONT_DN) + rxvt_fontset *fs = new rxvt_fontset (this); + rxvt_fontprop prop; + + if (!fs + || !fs->populate (rs[Rs_font] ? rs[Rs_font] : "fixed") + || !fs->realize_font (1)) { - // TODO + delete fs; + return false; } - else + +#if ENABLE_STYLES + for (int i = RS_styleCount; --i; ) + if (TermWin.fontset[i] != TermWin.fontset[0]) + delete TermWin.fontset[i]; +#endif + + delete TermWin.fontset[0]; + TermWin.fontset[0] = fs; + + prop = (*fs)[1]->properties (); + fs->set_prop (prop); + + TermWin.fwidth = prop.width; + TermWin.fheight = prop.height; + TermWin.fweight = prop.weight; + TermWin.fslant = prop.slant; + TermWin.fbase = (*fs)[1]->ascent; + + for (int style = 1; style < 4; style++) { - rxvt_fontset *fs = new rxvt_fontset (this); +#if ENABLE_STYLES + const char *res = rs[Rs_font + style]; - if (fs && fs->populate (fontname ? fontname : "fixed")) + if (res && !*res) + TermWin.fontset[style] = TermWin.fontset[0]; + else { - delete TermWin.fontset; - TermWin.fontset = fs; - TermWin.fwidth = fs->base_font ()->width; - TermWin.fheight = fs->base_font ()->height; - TermWin.fbase = fs->base_font ()->ascent; + TermWin.fontset[style] = fs = new rxvt_fontset (this); + rxvt_fontprop prop2 = prop; - if (TermWin.parent[0]) + if (res) + prop2.weight = prop2.slant = rxvt_fontprop::unset; + else { - resize_all_windows (0, 0, 0); - scr_remap_chars (); - scr_touch (true); - } + res = TermWin.fontset[0]->fontdesc; - for (unicode_t ch = 0x20; ch <= 0x7f; ch++) - TermWin.ascii_map [ch - 0x20] = fs->find_font (ch); + if (SET_STYLE (0, style) & RS_Bold) prop2.weight = rxvt_fontprop::bold; + if (SET_STYLE (0, style) & RS_Italic) prop2.slant = rxvt_fontprop::italic; + } - return true; + fs->populate (res); + fs->set_prop (prop2); } +#else + TermWin.fontset[style] = TermWin.fontset[0]; +#endif } - return false; + if (TermWin.parent[0]) + { + resize_all_windows (0, 0, 0); + scr_remap_chars (); + scr_touch (true); + } + + return true; } -bool -rxvt_term::font_up_down (int n, int direction) +void rxvt_term::set_string_property (Atom prop, const char *str, int len) +{ + // TODO: SMART_WINDOW_TITLE + XChangeProperty (display->display, TermWin.parent[0], + prop, XA_STRING, 8, PropModeReplace, + (const unsigned char *)str, len >= 0 ? len : strlen (str)); +} + +void rxvt_term::set_utf8_property (Atom prop, const char *str, int len) { - return false; + // TODO: SMART_WINDOW_TITLE + wchar_t *ws = rxvt_mbstowcs (str, len); + char *s = rxvt_wcstoutf8 (ws); + + XChangeProperty (display->display, TermWin.parent[0], + prop, xa[XA_UTF8_STRING], 8, PropModeReplace, + (const unsigned char *)s, strlen (s)); + + free (s); + free (ws); } /*----------------------------------------------------------------------*/ @@ -854,38 +860,18 @@ void rxvt_term::set_title (const char *str) { -#ifdef SMART_WINDOW_TITLE - char *name; - - if (!XFetchName (display->display, TermWin.parent[0], &name)) - name = NULL; - - if (name == NULL || strcmp (name, str)) -#endif - XStoreName (display->display, TermWin.parent[0], str); - -#ifdef SMART_WINDOW_TITLE - if (name) - XFree (name); + set_string_property (XA_WM_NAME, str); +#if ENABLE_FRILLS + set_utf8_property (xa[XA_NET_WM_NAME], str); #endif } void rxvt_term::set_icon_name (const char *str) { -#ifdef SMART_WINDOW_TITLE - char *name; - - if (!XGetIconName (display->display, TermWin.parent[0], &name)) - name = NULL; - - if (name == NULL || strcmp (name, str)) -#endif - XSetIconName (display->display, TermWin.parent[0], str); - -#ifdef SMART_WINDOW_TITLE - if (name) - XFree (name); + set_string_property (XA_WM_ICON_NAME, str); +#if ENABLE_FRILLS + set_utf8_property (xa[XA_NET_WM_ICON_NAME], str); #endif } @@ -949,16 +935,14 @@ /* Cursor cursor; */ Done: #ifdef OFF_FOCUS_FADING - pix_colors_unfocused[idx] = pix_colors_focused[idx].fade (display, atoi (rs[Rs_fade])); + if (rs[Rs_fade]) + pix_colors_unfocused[idx] = pix_colors_focused[idx].fade (display, atoi (rs[Rs_fade])); #endif - if (idx == Color_bg && ! (options & Opt_transparent)) - XSetWindowBackground (display->display, TermWin.vt, pix_colors[Color_bg]); - /* handle Color_BD, scrollbar background, etc. */ + /*TODO: handle Color_BD, scrollbar background, etc. */ - set_colorfgbg (); recolour_cursor (); - scr_touch (true); + scr_recolour (); } #else @@ -970,8 +954,13 @@ { XColor xcol[2]; - xcol[0].pixel = ISSET_PIXCOLOR (Color_pointer_fg) ? pix_colors_focused[Color_pointer_fg] : pix_colors_focused[Color_fg]; - xcol[1].pixel = ISSET_PIXCOLOR (Color_pointer_bg) ? pix_colors_focused[Color_pointer_bg] : pix_colors_focused[Color_bg]; + xcol[0].pixel = ISSET_PIXCOLOR (Color_pointer_fg) + ? pix_colors_focused[Color_pointer_fg] + : pix_colors_focused[Color_fg]; + xcol[1].pixel = ISSET_PIXCOLOR (Color_pointer_bg) + ? pix_colors_focused[Color_pointer_bg] + : pix_colors_focused[Color_bg]; + XQueryColors (display->display, display->cmap, xcol, 2); XRecolorCursor (display->display, TermWin_cursor, xcol + 0, xcol + 1); } @@ -983,12 +972,11 @@ void rxvt_term::set_colorfgbg () { - unsigned int i; - const char *xpmb = "\0"; - char fstr[sizeof ("default") + 1], bstr[sizeof ("default") + 1]; + unsigned int i; + const char *xpmb = "\0"; + char fstr[sizeof ("default") + 1], bstr[sizeof ("default") + 1]; - env_colorfgbg = - (char *)rxvt_malloc (sizeof ("COLORFGBG=default;default;bg") + 1); + env_colorfgbg = (char *)rxvt_malloc (sizeof ("COLORFGBG=default;default;bg") + 1); strcpy (fstr, "default"); strcpy (bstr, "default"); for (i = Color_Black; i <= Color_White; i++) @@ -997,6 +985,7 @@ sprintf (fstr, "%d", (i - Color_Black)); break; } + for (i = Color_Black; i <= Color_White; i++) if (pix_colors[Color_bg] == pix_colors[i]) { @@ -1008,17 +997,6 @@ } sprintf (env_colorfgbg, "COLORFGBG=%s;%s%s", fstr, xpmb, bstr); - -#ifndef NO_BRIGHTCOLOR - colorfgbg = DEFAULT_RSTYLE; - for (i = minCOLOR; i <= maxCOLOR; i++) - { - if (pix_colors[Color_fg] == pix_colors[i]) - colorfgbg = SET_FGCOLOR (colorfgbg, i); - if (pix_colors[Color_bg] == pix_colors[i]) - colorfgbg = SET_BGCOLOR (colorfgbg, i); - } -#endif } /*----------------------------------------------------------------------*/ @@ -1254,23 +1232,20 @@ void rxvt_term::IMSendSpot () { - XPoint spot; + XPoint nspot; XVaNestedList preedit_attr; if (!Input_Context || !TermWin.focus - || !(input_style & XIMPreeditPosition) -#if 0 - || !(event_type == KeyPress - || event_type == Expose - || event_type == NoExpose - || event_type == SelectionNotify - || event_type == ButtonRelease || event_type == FocusIn) -#endif - || !IMisRunning ()) + || !(input_style & XIMPreeditPosition)) + return; + + im_set_position (nspot); + + if (nspot.x == spot.x && nspot.y == spot.y) return; - im_set_position (spot); + spot = nspot; preedit_attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL); XSetICValues (Input_Context, XNPreeditAttributes, preedit_attr, NULL); @@ -1280,17 +1255,16 @@ void rxvt_term::im_destroy () { - if (Input_Context) - { - XDestroyIC (Input_Context); - Input_Context = 0; - } - if (input_method) { + if (Input_Context && input_method->xim) + XDestroyIC (Input_Context); + display->put_xim (input_method); input_method = 0; } + + Input_Context = 0; } /* @@ -1318,6 +1292,7 @@ return false; xim = input_method->xim; + spot.x = spot.y = -1; xim_styles = NULL; if (XGetIMValues (xim, XNQueryInputStyle, &xim_styles, NULL) @@ -1327,30 +1302,44 @@ return false; } - p = rs[Rs_preeditType] ? rs[Rs_preeditType] : "OverTheSpot,OffTheSpot,Root"; - s = rxvt_splitcommastring (p); + const char *pet[] = { rs[Rs_preeditType], "OverTheSpot,OffTheSpot,Root,None" }; - for (i = found = 0; !found && s[i]; i++) + for (int pi = 0; pi < 2; pi++) { - if (!strcmp (s[i], "OverTheSpot")) - input_style = (XIMPreeditPosition | XIMStatusNothing); - else if (!strcmp (s[i], "OffTheSpot")) - input_style = (XIMPreeditArea | XIMStatusArea); - else if (!strcmp (s[i], "Root")) - input_style = (XIMPreeditNothing | XIMStatusNothing); - - for (j = 0; j < xim_styles->count_styles; j++) - if (input_style == xim_styles->supported_styles[j]) - { - found = 1; - break; - } + p = pet[pi]; + + if (!p) + continue; + + s = rxvt_splitcommastring (p); + + for (i = found = 0; !found && s[i]; i++) + { + if (!strcmp (s[i], "OverTheSpot")) + input_style = (XIMPreeditPosition | XIMStatusNothing); + else if (!strcmp (s[i], "OffTheSpot")) + input_style = (XIMPreeditArea | XIMStatusArea); + else if (!strcmp (s[i], "Root")) + input_style = (XIMPreeditNothing | XIMStatusNothing); + else if (!strcmp (s[i], "None")) + input_style = (XIMPreeditNone | XIMStatusNone); + + for (j = 0; j < xim_styles->count_styles; j++) + if (input_style == xim_styles->supported_styles[j]) + { + rxvt_freecommastring (s); + + found = 1; + goto foundpet; + } + + } + + rxvt_freecommastring (s); } - for (i = 0; s[i]; i++) - free (s[i]); +foundpet: - free (s); XFree (xim_styles); if (!found) @@ -1485,6 +1474,7 @@ bool found = false; s = rxvt_splitcommastring (p); + for (i = 0; s[i]; i++) { if (*s[i]) @@ -1498,9 +1488,8 @@ } } } - for (i = 0; s[i]; i++) - free (s[i]); - free (s); + + rxvt_freecommastring (s); if (found) goto done;