--- rxvt-unicode/src/main.C 2004/03/03 04:07:52 1.48 +++ rxvt-unicode/src/main.C 2004/03/28 02:07:08 1.60 @@ -58,6 +58,70 @@ } } +#if ENABLE_COMBINING +class rxvt_composite_vec rxvt_composite; + +text_t rxvt_composite_vec::compose (unicode_t c1, unicode_t c2) +{ + compose_char *cc; + + // break compose chains, as stupid readline really likes to duplicate + // composing characters for some reason near the end of a line. + cc = (*this)[c1]; + while (cc) + { + if (cc->c2 == c2) return c1; + cc = (*this)[cc->c1]; + } + + // check to see wether this combination already exists otherwise + for (cc = v.end (); cc-- > v.begin (); ) + { + if (cc->c1 == c1 && cc->c2 == c2) + return COMPOSE_LO + (cc - v.begin ()); + } + + // allocate a new combination + if (v.size () == COMPOSE_HI - COMPOSE_LO + 1) + { + static int seen; + + if (!seen++) + fprintf (stderr, "too many unrepresentable composite characters, try --enable-unicode3\n"); + + return REPLACEMENT_CHAR; + } + + v.push_back (compose_char (c1, c2)); + + return v.size () - 1 + COMPOSE_LO; +} + +int rxvt_composite_vec::expand (unicode_t c, wchar_t *r) +{ + compose_char *cc = (*this)[c]; + + if (!cc) + { + if (r) *r = c; + return 1; + } + + int len = expand (cc->c1, r); + + if (r) r += len; + + if (cc->c2 != NOCHAR) + { + len++; + if (r) *r++ = cc->c2; + } + + return len; + +} +#endif + void * rxvt_term::operator new (size_t s) { @@ -120,6 +184,37 @@ if (display) { + selection_clear (); + +#ifdef MENUBAR + if (menubarGC) XFreeGC (display->display, menubarGC); +#endif +#ifdef XTERM_SCROLLBAR + if (xscrollbarGC) XFreeGC (display->display, xscrollbarGC); + if (ShadowGC) XFreeGC (display->display, ShadowGC); +#endif +#ifdef PLAIN_SCROLLBAR + if (pscrollbarGC) XFreeGC (display->display, pscrollbarGC); +#endif +#ifdef NEXT_SCROLLBAR + if (blackGC) XFreeGC (display->display, blackGC); + if (whiteGC) XFreeGC (display->display, whiteGC); + if (grayGC) XFreeGC (display->display, grayGC); + if (darkGC) XFreeGC (display->display, darkGC); + if (stippleGC) XFreeGC (display->display, stippleGC); + if (dimple) XFreePixmap (display->display, dimple); + if (upArrow) XFreePixmap (display->display, upArrow); + if (downArrow) XFreePixmap (display->display, downArrow); + if (upArrowHi) XFreePixmap (display->display, upArrowHi); + if (downArrowHi) XFreePixmap (display->display, downArrowHi); +#endif +#if defined(MENUBAR) || defined(RXVT_SCROLLBAR) + if (topShadowGC) XFreeGC (display->display, topShadowGC); + if (botShadowGC) XFreeGC (display->display, botShadowGC); + if (scrollbarGC) XFreeGC (display->display, scrollbarGC); +#endif + if (TermWin.gc) XFreeGC (display->display, TermWin.gc); + #if defined(MENUBAR) && (MENUBAR_MAX > 1) delete menuBar.drawable; //if (menuBar.win) @@ -139,12 +234,20 @@ scr_release (); + /* clear all resources */ + for (int i = 0; i < allocated.size (); i++) + free (allocated[i]); + + free (selection.text); + // TODO: manage env vars in child only(!) free (env_windowid); free (env_display); free (env_term); free (env_colorfgbg); free (locale); +#if 0 free (codeset); +#endif delete envv; delete argv; @@ -195,55 +298,14 @@ /*----------------------------------------------------------------------*/ /* rxvt_init () */ -/* LIBPROTO */ -rxvt_t -rxvt_init (int argc, const char *const *argv) -{ - SET_R (new rxvt_term); - - if (!GET_R->init_vars () || !GET_R->init (argc, argv)) - { - delete GET_R; - SET_R (0); - } - - return GET_R; -} - -static int (*old_xerror_handler) (Display *dpy, XErrorEvent *event); - -void -rxvt_init_signals () -{ - /* install exit handler for cleanup */ -#if 0 -#ifdef HAVE_ATEXIT - atexit (rxvt_clean_exit); -#else -#endif -#endif - - 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); - - /* need to trap SIGURG for SVR4 (Unixware) rlogin */ - /* signal (SIGURG, SIG_DFL); */ - - old_xerror_handler = XSetErrorHandler ((XErrorHandler) rxvt_xerror_handler); - //XSetIOErrorHandler ((XErrorHandler) rxvt_xioerror_handler); -} - bool rxvt_term::init (int argc, const char *const *argv) { + SET_R (this); + + if (!init_vars ()) + return false; + /* * Save and then give up any super-user privileges * If we need privileges in any area then we must specifically request it. @@ -308,6 +370,37 @@ return true; } +static int (*old_xerror_handler) (Display *dpy, XErrorEvent *event); + +void +rxvt_init_signals () +{ + /* install exit handler for cleanup */ +#if 0 +#ifdef HAVE_ATEXIT + atexit (rxvt_clean_exit); +#else +#endif +#endif + + 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); + + /* need to trap SIGURG for SVR4 (Unixware) rlogin */ + /* signal (SIGURG, SIG_DFL); */ + + old_xerror_handler = XSetErrorHandler ((XErrorHandler) rxvt_xerror_handler); + //XSetIOErrorHandler ((XErrorHandler) rxvt_xioerror_handler); +} + /* ------------------------------------------------------------------------- * * SIGNAL HANDLING & EXIT HANDLER * * ------------------------------------------------------------------------- */ @@ -339,7 +432,7 @@ { signal (sig, SIG_DFL); #ifdef DEBUG_CMD - rxvt_print_error ("signal %d", sig); + rxvt_warn ("caught signal %d, exiting.\n", sig); #endif rxvt_clean_exit (); kill (getpid (), sig); @@ -624,6 +717,7 @@ } } } + /* TODO: BOUNDS */ TermWin.width = TermWin.ncol * TermWin.fwidth; TermWin.height = TermWin.nrow * TermWin.fheight; @@ -780,27 +874,31 @@ #else char *name; - if (XFetchName (display->display, TermWin.parent[0], &name) == 0) + if (!XFetchName (display->display, TermWin.parent[0], &name)) name = NULL; + if (name == NULL || STRCMP (name, str)) XStoreName (display->display, TermWin.parent[0], str); + if (name) XFree (name); #endif } void -rxvt_term::set_iconName (const char *str) +rxvt_term::set_icon_name (const char *str) { #ifndef SMART_WINDOW_TITLE XSetIconName (display->display, TermWin.parent[0], str); #else char *name; - if (XGetIconName (display->display, TermWin.parent[0], &name)) + if (!XGetIconName (display->display, TermWin.parent[0], &name)) name = NULL; + if (name == NULL || STRCMP (name, str)) XSetIconName (display->display, TermWin.parent[0], str); + if (name) XFree (name); #endif @@ -948,7 +1046,7 @@ { if (!screen_in_out->set (display, colour)) { - rxvt_print_error ("can't allocate colour: %s", colour); + rxvt_warn ("can't get colour '%s', continuing without.\n", colour); return false; } @@ -1325,7 +1423,7 @@ if (Input_Context == NULL) { - rxvt_print_error ("failed to create input context"); + rxvt_warn ("failed to create input context, continuing without XIM.\n"); display->put_xim (input_method); return false; }