--- rxvt-unicode/src/command.C 2003/12/05 04:27:20 1.13 +++ rxvt-unicode/src/command.C 2003/12/18 08:06:46 1.21 @@ -1,7 +1,7 @@ /*--------------------------------*-C-*---------------------------------* * File: command.c *----------------------------------------------------------------------* - * $Id: command.C,v 1.13 2003/12/05 04:27:20 pcg Exp $ + * $Id: command.C,v 1.21 2003/12/18 08:06:46 pcg Exp $ * * All portions of code are copyright by their respective author/s. * Copyright (c) 1992 John Bovey, University of Kent at Canterbury @@ -50,6 +50,8 @@ #include "version.h" #include "command.h" +#include + /*----------------------------------------------------------------------*/ /*{{{ Convert the keypress event into a string */ @@ -63,9 +65,7 @@ #ifdef DEBUG_CMD static int debug_key = 1; /* accessible by a debugger only */ #endif -#ifdef USE_XIM int valid_keysym; -#endif unsigned char *kbuf = R->kbuf; /* @@ -77,65 +77,82 @@ shft = (ev->state & ShiftMask); ctrl = (ev->state & ControlMask); meta = (ev->state & R->ModMetaMask); - if (R->numlock_state || (ev->state & R->ModNumLockMask)) { + + if (R->numlock_state || (ev->state & R->ModNumLockMask)) + { R->numlock_state = (ev->state & R->ModNumLockMask); PrivMode((!R->numlock_state), PrivMode_aplKP); - } + } + + kbuf[0] = 0; + #ifdef USE_XIM - if (R->Input_Context != NULL) { - Status status_return; + if (R->Input_Context) + { + Status status_return; - kbuf[0] = '\0'; #ifdef X_HAVE_UTF8_STRING - len = Xutf8LookupString(R->Input_Context, ev, (char *)kbuf, - KBUFSZ, &keysym, &status_return); -#else - len = XmbLookupString(R->Input_Context, ev, (char *)kbuf, - KBUFSZ, &keysym, &status_return); + if (R->enc_utf8) + len = Xutf8LookupString (R->Input_Context, ev, (char *)kbuf, + KBUFSZ, &keysym, &status_return); + else #endif - valid_keysym = ((status_return == XLookupKeySym) - || (status_return == XLookupBoth)); - } else { - len = XLookupString(ev, (char *)kbuf, KBUFSZ, &keysym, - &R->compose); - valid_keysym = 1; - } -#else /* USE_XIM */ - len = XLookupString(ev, (char *)kbuf, KBUFSZ, &keysym, - &R->compose); -/* - * map unmapped Latin[2-4]/Katakana/Arabic/Cyrillic/Greek entries -> Latin1 - * good for installations with correct fonts, but without XLOCALE - */ - if (!len) { - if ((keysym >= 0x0100) && (keysym < 0x0800)) { - kbuf[0] = (keysym & 0xFF); - kbuf[1] = '\0'; - len = 1; - } else - kbuf[0] = '\0'; - } -#endif /* USE_XIM */ + { + wchar_t wkbuf[KBUFSZ + 1]; -#ifdef USE_XIM - if (valid_keysym) + // the XOpenIM manpage lies about hardcoding the locale + // at the point of XOpenIM, so temporarily switch locales + if (R->rs[Rs_imLocale]) + SET_LOCALE (R->rs[Rs_imLocale]); + // assume wchar_t == unicode or better + len = XwcLookupString (R->Input_Context, ev, wkbuf, + KBUFSZ, &keysym, &status_return); + if (R->rs[Rs_imLocale]) + SET_LOCALE (R->locale); + + if (status_return == XLookupChars + || status_return == XLookupBoth) + { + wkbuf[len] = 0; + len = wcstombs ((char *)kbuf, wkbuf, KBUFSZ); + if (len < 0) + len = 0; + } + else + len = 0; + } + + valid_keysym = status_return == XLookupKeySym + || status_return == XLookupBoth; + } + else #endif - { + { + len = XLookupString (ev, (char *)kbuf, KBUFSZ, &keysym, &R->compose); + valid_keysym = !len; + } + + if (valid_keysym) + { /* for some backwards compatibility */ #if defined(HOTKEY_CTRL) || defined(HOTKEY_META) # ifdef HOTKEY_CTRL - if (ctrl) { + if (ctrl) # else - if (meta) { + if (meta) # endif - if (keysym == R->ks_bigfont) { + { + if (keysym == R->ks_bigfont) + { rxvt_change_font(aR_ 0, FONT_UP); return; - } else if (keysym == R->ks_smallfont) { + } + else if (keysym == R->ks_smallfont) + { rxvt_change_font(aR_ 0, FONT_DN); return; - } - } + } + } #endif if (R->TermWin.saveLines) { @@ -239,8 +256,8 @@ # ifdef META8_OPTION if (R->meta_char == C0_ESC) # endif - R->tt_write(&ch, 1); - R->tt_write(kbuf0, l); + R->tt_write (&ch, 1); + R->tt_write (kbuf0, l); return; } else #endif @@ -574,7 +591,7 @@ #endif /* nil */ ; } - } + } if (len <= 0) return; /* not mapped */ @@ -690,6 +707,7 @@ rxvt_term::check_cb (check_watcher &w) { SET_R (this); + SET_LOCALE (locale); flush (); } @@ -743,8 +761,6 @@ void rxvt_term::blink_cb (time_watcher &w) { - SET_R (this); - w.at += BLINK_INTERVAL; hidden_cursor = !hidden_cursor; want_refresh = 1; @@ -754,6 +770,7 @@ rxvt_term::x_cb (io_watcher &w, short revents) { SET_R (this); + SET_LOCALE (locale); process_x_events (); } @@ -784,6 +801,7 @@ rxvt_term::pty_cb (io_watcher &w, short revents) { SET_R (this); + SET_LOCALE (locale); if (revents & EVENT_WRITE) tt_write (0, 0); @@ -901,51 +919,23 @@ uint32_t rxvt_term::next_char () { - struct mbstate &s = mbstate; - while (cmdbuf_ptr < cmdbuf_endp) { - uint8_t ch = *cmdbuf_ptr; + if (*cmdbuf_ptr < 0x80) // assume < 0x80 to be ascii ALWAYS (all shift-states etc.) uh-oh + return *cmdbuf_ptr++; - if (s.cnt) - { - if ((ch & 0xc0) == 0x80) - { - cmdbuf_ptr++; + wchar_t wc; + int len = mbrtowc (&wc, (char *)cmdbuf_ptr, cmdbuf_endp - cmdbuf_ptr, &mbstate.mbs); - /* continuation */ - s.reg = (s.reg << 6) | (ch & 0x7f); + if (len == (size_t)-2) + return NOCHAR; - if (--s.cnt == 0 && s.reg >= 128) /* if !inrange then corruption or Racking */ - return s.reg; + if (len == (size_t)-1) + return *cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through - continue; - } - else - { - s.cnt = 0; - return s.orig; /* the _occasional_ non-utf-8 character may slip through... */ - } - } - - if ((ch & 0xc0) == 0xc0) - { - cmdbuf_ptr++; - - /* first byte */ - s.orig = ch; /* for broken encodings */ - s.reg = ch; - if ((ch & 0xe0) == 0xc0) { s.reg &= 0x1f; s.cnt = 1; } - if ((ch & 0xf0) == 0xe0) { s.reg &= 0x0f; s.cnt = 2; } - if ((ch & 0xf8) == 0xf0) { s.reg &= 0x07; s.cnt = 3; } - if ((ch & 0xfc) == 0xf8) { s.reg &= 0x03; s.cnt = 4; } - if ((ch & 0xfe) == 0xfc) { s.reg &= 0x01; s.cnt = 5; } - } - else - { - cmdbuf_ptr++; /* _occasional_ non-utf8 may slip through... */ - return ch; - } + // assume wchar == unicode + cmdbuf_ptr += len; + return wc; } return NOCHAR; @@ -1037,7 +1027,7 @@ rxvt_term::pointer_unblank () { XDefineCursor (Xdisplay, TermWin.vt, TermWin_cursor); - rxvt_recolour_cursor (this); + recolour_cursor (); #ifdef POINTER_BLANK hidden_pointer = 0; @@ -1066,6 +1056,7 @@ rxvt_term::pointer_cb (time_watcher &w) { SET_R (this); + SET_LOCALE (locale); pointer_blank (); } @@ -1157,7 +1148,6 @@ Window unused_root, unused_child; int unused_root_x, unused_root_y; unsigned int unused_mask; - struct timeval tp; #ifdef DEBUG_X const char *const eventnames[] = @@ -1198,49 +1188,16 @@ "ClientMessage", "MappingNotify" }; - struct tm *ltt; -#endif - - /* - * check if we need to get the time for any timeouts - */ - - for (i = NUM_TIMEOUTS; i--; ) - if (R->timeout[i].tv_sec) { - want_timeout = 1; - break; - } - -#ifndef DEBUG_X - if (want_timeout) #endif - (void)gettimeofday(&tp, NULL); #ifdef DEBUG_X + struct timeval tp; + struct tm *ltt; + (void)gettimeofday(&tp, NULL); ltt = localtime(&(tp.tv_sec)); D_X((stderr, "Event: %-16s %-7s %08lx (%4d-%02d-%02d %02d:%02d:%02d.%.6ld) %s %lu", eventnames[ev->type], (ev->xany.window == R->TermWin.parent[0] ? "parent" : (ev->xany.window == R->TermWin.vt ? "vt" : (ev->xany.window == R->scrollBar.win ? "scroll" : (ev->xany.window == R->menuBar.win ? "menubar" : "UNKNOWN")))), (ev->xany.window == R->TermWin.parent[0] ? R->TermWin.parent[0] : (ev->xany.window == R->TermWin.vt ? R->TermWin.vt : (ev->xany.window == R->scrollBar.win ? R->scrollBar.win : (ev->xany.window == R->menuBar.win ? R->menuBar.win : 0)))), ltt->tm_year + 1900, ltt->tm_mon + 1, ltt->tm_mday, ltt->tm_hour, ltt->tm_min, ltt->tm_sec, tp.tv_usec, ev->xany.send_event ? "S" : " ", ev->xany.serial)); #endif - /* X event timeouts */ - if (want_timeout) - for (i = NUM_TIMEOUTS; i--; ) { - if (R->timeout[i].tv_sec == 0) - continue; - if ((tp.tv_sec < R->timeout[i].tv_sec) - || (tp.tv_sec == R->timeout[i].tv_sec - && tp.tv_usec < R->timeout[i].tv_usec)) - continue; - R->timeout[i].tv_sec = 0; - switch(i) { - case TIMEOUT_INCR: - rxvt_print_error("data loss: timeout on INCR selection paste"); - R->selection_wait = Sel_none; - break; - default: - break; - } - } - switch (ev->type) { case KeyPress: rxvt_lookup_key(aR_ (XKeyEvent *)ev); @@ -1465,7 +1422,7 @@ GraphicsExpose, &unused_xevent)) ; if (isScrollbarWindow(ev->xany.window)) { - scrollbar_setIdle(); + R->scrollBar.setIdle(); rxvt_scrollbar_show(aR_ 0); } #ifdef MENUBAR @@ -1588,7 +1545,7 @@ { #if RXVT_GRAPHICS if (ev->subwindow != None) - rxvt_Gr_ButtonPress(ev->x, ev->y); + rxvt_Gr_ButtonPress (ev->x, ev->y); else #endif { @@ -1633,11 +1590,24 @@ switch (ev->button) { case Button1: - if (R->MEvent.button == Button1 && clickintime) - R->MEvent.clicks++; + /* allow shift+left click to extend selection */ + if (ev->state & ShiftMask) + { + if (R->MEvent.button == Button1 && clickintime) + rxvt_selection_rotate (aR_ ev->x, ev->y); + else + rxvt_selection_extend (aR_ ev->x, ev->y, 1); + } else - R->MEvent.clicks = 1; - rxvt_selection_click(aR_ R->MEvent.clicks, ev->x, ev->y); + { + if (R->MEvent.button == Button1 && clickintime) + R->MEvent.clicks++; + else + R->MEvent.clicks = 1; + + rxvt_selection_click (aR_ R->MEvent.clicks, ev->x, ev->y); + } + R->MEvent.button = Button1; break; @@ -1660,7 +1630,7 @@ */ if (isScrollbarWindow(ev->window)) { - scrollbar_setIdle(); + R->scrollBar.setIdle (); /* * Rxvt-style scrollbar: * move up if mouse is above slider @@ -1723,9 +1693,9 @@ #endif if (rxvt_scr_page(aR_ upordown < 0 ? UP : DN, 1)) { if (upordown < 0) - scrollbar_setUp(); + R->scrollBar.setUp (); else - scrollbar_setDn(); + R->scrollBar.setDn (); } } else switch (ev->button) { @@ -1747,7 +1717,7 @@ rxvt_scr_move_to(aR_ scrollbar_position(ev->y) - R->csrO, scrollbar_size()); - scrollbar_setMotion(); + R->scrollBar.setMotion (); break; case Button1: @@ -1770,7 +1740,7 @@ rxvt_scr_page(aR_ DN, R->TermWin.nrow / 4); # endif else - scrollbar_setMotion(); + R->scrollBar.setMotion (); } else { rxvt_scr_page(aR_ (ev->button == Button1 ? DN : UP), (R->TermWin.nrow @@ -1802,7 +1772,7 @@ reportmode = !!(R->PrivateModes & PrivMode_mouse_report); if (scrollbar_isUpDn()) { - scrollbar_setIdle(); + R->scrollBar.setIdle (); rxvt_scrollbar_show(aR_ 0); #ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING R->refresh_type &= ~SMOOTH_REFRESH; @@ -1863,7 +1833,8 @@ case Button4: case Button5: { - int i, v; + int i; + page_dirn v; v = (ev->button == Button4) ? UP : DN; if (ev->state & ShiftMask) @@ -2048,7 +2019,7 @@ for (; n < (unsigned int)i; n++) { XGetWindowAttributes(R->Xdisplay, R->TermWin.parent[n], &wattr); D_X((stderr, "InheritPixmap Checking Parent[%d]: %s", n, (wattr.depth == rootdepth && wattr.class != InputOnly) ? "OK" : "FAIL")); - if (wattr.depth != rootdepth || wattr.class == InputOnly) { + if (wattr.depth != rootdepth || wattr.c_class == InputOnly) { n = (int)(sizeof(R->TermWin.parent) / sizeof(Window)) + 1; break; } @@ -2627,7 +2598,7 @@ arg[0] = -arg[0]; /* FALLTHROUGH */ case CSI_SU: /* 8.3.148: (1) SCROLL UP */ - rxvt_scroll_text(aR_ R->screen.tscroll, R->screen.bscroll, arg[0], 0); + R->scr_scroll_text (R->screen.tscroll, R->screen.bscroll, arg[0], 0); break; case CSI_DA: /* 8.3.24: (0) DEVICE ATTRIBUTES */ @@ -3406,7 +3377,7 @@ if ((cmd == 'T') && (nargs >= 5)) { int i, len = args[4]; - text = rxvt_malloc((len + 1) * sizeof(char)); + text = (unsigned char *)rxvt_malloc((len + 1) * sizeof(char)); if (text != NULL) { for (i = 0; i < len; i++)