--- rxvt-unicode/src/command.C 2003/11/27 16:49:45 1.10 +++ rxvt-unicode/src/command.C 2003/12/18 02:07:12 1.18 @@ -1,7 +1,7 @@ /*--------------------------------*-C-*---------------------------------* * File: command.c *----------------------------------------------------------------------* - * $Id: command.C,v 1.10 2003/11/27 16:49:45 pcg Exp $ + * $Id: command.C,v 1.18 2003/12/18 02:07:12 pcg Exp $ * * All portions of code are copyright by their respective author/s. * Copyright (c) 1992 John Bovey, University of Kent at Canterbury @@ -63,9 +63,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 +75,70 @@ 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); + 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); + wchar_t wkbuf[KBUFSZ + 1]; + + // assume wchar_t == unicode or better + len = XwcLookupString (R->Input_Context, ev, wkbuf, + KBUFSZ, &keysym, &status_return); + + if (status_return == XLookupChars + || status_return == XLookupBoth) + { + wkbuf[len] = 0; + len = wcstombs ((char *)kbuf, wkbuf, KBUFSZ); + } + else + len = 0; #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 */ + valid_keysym = status_return == XLookupKeySym + || status_return == XLookupBoth; + } + else +#endif + { + len = XLookupString (ev, (char *)kbuf, KBUFSZ, &keysym, &R->compose); + valid_keysym = !len; + } -#ifdef USE_XIM if (valid_keysym) -#endif - { + { /* 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 +242,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 +577,7 @@ #endif /* nil */ ; } - } + } if (len <= 0) return; /* not mapped */ @@ -658,6 +661,43 @@ #endif /* MENUBAR_MAX */ void +rxvt_term::flush () +{ +#ifdef TRANSPARENT + if (want_full_refresh) + { + want_full_refresh = 0; + rxvt_scr_clear (this); + rxvt_scr_touch (this, False); + want_refresh = 1; + } +#endif + + if (want_refresh) + { + rxvt_scr_refresh (this, refresh_type); + rxvt_scrollbar_show (this, 1); +#ifdef USE_XIM + rxvt_IMSendSpot (this); +#endif + } + + XFlush (Xdisplay); +#if 0 + if (XPending (Xdisplay)) process_x_events (); + if (XPending (Xdisplay)) process_x_events (); +#endif +} + +void +rxvt_term::check_cb (check_watcher &w) +{ + SET_R (this); + + flush (); +} + +void rxvt_term::process_x_events () { do @@ -711,7 +751,6 @@ w.at += BLINK_INTERVAL; hidden_cursor = !hidden_cursor; want_refresh = 1; - flush (); } void @@ -720,8 +759,144 @@ SET_R (this); process_x_events (); +} - flush (); +bool +rxvt_term::pty_fill () +{ + ssize_t n = cmdbuf_endp - cmdbuf_ptr; + + memmove (cmdbuf_base, cmdbuf_ptr, n); + cmdbuf_ptr = cmdbuf_base; + cmdbuf_endp = cmdbuf_ptr + n; + + n = read (cmd_fd, cmdbuf_endp, BUFSIZ - n); + + if (n > 0) + { + cmdbuf_endp += n; + return true; + } + else if (n < 0 && errno != EAGAIN) + destroy (); + + return false; +} + +void +rxvt_term::pty_cb (io_watcher &w, short revents) +{ + SET_R (this); + + if (revents & EVENT_WRITE) + tt_write (0, 0); + else if (revents & EVENT_READ) + { + bool flag = true; + + // loop, but don't allow a single term to monopolize us + // the number of loops is fully arbitrary, and thus wrong + while (flag && pty_fill ()) + { + if (!seen_input) + { + seen_input = 1; + /* once we know the shell is running, send the screen size. Again! */ + tt_winch (); + } + + uint32_t ch = NOCHAR; + + for (;;) + { + if (ch == NOCHAR) + ch = next_char (); + + if (ch == NOCHAR) // TODO: improve + break; + + if (ch >= ' ' || ch == '\t' || ch == '\n' || ch == '\r') + { + /* Read a text string from the input buffer */ + uint32_t buf[BUFSIZ]; + bool refreshnow = false; + int nlines = 0; + uint32_t *str = buf; + + *str++ = ch; + + for (;;) + { + ch = next_char (); + + if (ch == NOCHAR || (ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r')) + break; + else + { + *str++ = ch; + + if (ch == '\n') + { + nlines++; + refresh_count++; + + if (!(Options & Opt_jumpScroll) + || (refresh_count >= (refresh_limit * (TermWin.nrow - 1)))) + { + refreshnow = true; + flag = false; + ch = NOCHAR; + break; + } + } + + if (str >= buf + BUFSIZ) + { + ch = NOCHAR; + break; + } + } + } + + rxvt_scr_add_lines (this, buf, nlines, str - buf); + + /* + * If there have been a lot of new lines, then update the screen + * What the heck I'll cheat and only refresh less than every page-full. + * the number of pages between refreshes is refresh_limit, which + * is incremented here because we must be doing flat-out scrolling. + * + * refreshing should be correct for small scrolls, because of the + * time-out + */ + if (refreshnow) + { + if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD) + refresh_limit++; + + rxvt_scr_refresh (this, refresh_type); + } + + } + else + { + switch (ch) + { + default: + rxvt_process_nonprinting (this, ch); + break; + case C0_ESC: /* escape char */ + rxvt_process_escape_seq (this); + break; + /*case 0x9b: */ /* CSI */ + /* rxvt_process_csi_seq (this); */ + } + + ch = NOCHAR; + } + } + } + } } // read the next character, currently handles UTF-8 @@ -779,166 +954,6 @@ return NOCHAR; } -bool -rxvt_term::pty_fill () -{ - ssize_t n = cmdbuf_endp - cmdbuf_ptr; - - memmove (cmdbuf_base, cmdbuf_ptr, n); - cmdbuf_ptr = cmdbuf_base; - cmdbuf_endp = cmdbuf_ptr + n; - - n = read (cmd_fd, cmdbuf_endp, BUFSIZ - n); - - if (n > 0) - { - cmdbuf_endp += n; - return true; - } - else if (n < 0 && errno == EAGAIN) - return false; - - destroy (); -} - -void -rxvt_term::pty_cb (io_watcher &w, short revents) -{ - SET_R (this); - - if (revents & EVENT_WRITE) - tt_write (0, 0); - else if (revents & EVENT_READ) - // loop, but don't allow a single term to monopolize us - // the number of loops is fully arbitrary, and thus wrong - for (int i = 7; i-- && pty_fill (); ) - { - //TODO: - /* once we know the shell is running, send the screen size. Again! */ - //ch = rxvt_cmd_getc(aR); /* wait for something */ - //rxvt_tt_winsize(cmd_fd, TermWin.ncol, TermWin.nrow, cmd_pid); - - uint32_t ch = NOCHAR; - - for (;;) - { - if (ch == NOCHAR) - ch = next_char (); - - if (ch == NOCHAR) // TODO: improve - break; - - if (ch >= ' ' || ch == '\t' || ch == '\n' || ch == '\r') - { - /* Read a text string from the input buffer */ - uint32_t buf[BUFSIZ]; - bool refreshnow = false; - int nlines = 0; - uint32_t *str = buf; - - *str++ = ch; - - for (;;) - { - ch = next_char (); - - if (ch == NOCHAR || (ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r')) - break; - else - { - *str++ = ch; - - if (ch == '\n') - { - nlines++; - refresh_count++; - - if (!(Options & Opt_jumpScroll) - || (refresh_count >= (refresh_limit * (TermWin.nrow - 1)))) - { - refreshnow = true; - ch = NOCHAR; - break; - } - } - - if (str >= buf + BUFSIZ) - { - ch = NOCHAR; - break; - } - } - } - - rxvt_scr_add_lines (this, buf, nlines, str - buf); - - /* - * If there have been a lot of new lines, then update the screen - * What the heck I'll cheat and only refresh less than every page-full. - * the number of pages between refreshes is refresh_limit, which - * is incremented here because we must be doing flat-out scrolling. - * - * refreshing should be correct for small scrolls, because of the - * time-out - */ - if (refreshnow) - { - if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD) - refresh_limit++; - - rxvt_scr_refresh (this, refresh_type); - } - - } - else - { - switch (ch) - { - default: - rxvt_process_nonprinting (this, ch); - break; - case C0_ESC: /* escape char */ - rxvt_process_escape_seq (this); - break; - /*case 0x9b: */ /* CSI */ - /* rxvt_process_csi_seq (this); */ - } - - ch = NOCHAR; - } - } - } - - flush (); -} - -void -rxvt_term::flush () -{ -#ifdef TRANSPARENT - if (want_full_refresh) - { - want_full_refresh = 0; - rxvt_scr_clear (this); - rxvt_scr_touch (this, False); - want_refresh = 1; - } -#endif - - if (want_refresh) - { - rxvt_scr_refresh (this, refresh_type); - rxvt_scrollbar_show (this, 1); -#ifdef USE_XIM - rxvt_IMSendSpot (this); -#endif - } - - if (XPending (Xdisplay)) process_x_events (); - XFlush (Xdisplay); - if (XPending (Xdisplay)) process_x_events (); -} - /* rxvt_cmd_getc() - Return next input character */ /* * Return the next input character after first passing any keyboard input @@ -1145,7 +1160,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[] = @@ -1186,49 +1200,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); @@ -1576,7 +1557,7 @@ { #if RXVT_GRAPHICS if (ev->subwindow != None) - rxvt_Gr_ButtonPress(ev->x, ev->y); + rxvt_Gr_ButtonPress (ev->x, ev->y); else #endif { @@ -1851,7 +1832,8 @@ case Button4: case Button5: { - int i, v; + int i; + page_dirn v; v = (ev->button == Button4) ? UP : DN; if (ev->state & ShiftMask) @@ -2036,7 +2018,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; } @@ -2096,15 +2078,15 @@ /* EXTPROTO */ int -rxvt_pclose_printer(FILE *stream) +rxvt_pclose_printer (FILE *stream) { - fflush(stream); + fflush (stream); /* pclose() reported not to work on SunOS 4.1.3 */ # if defined (__sun__) /* TODO: RESOLVE THIS */ /* pclose works provided SIGCHLD handler uses waitpid */ - return pclose(stream); /* return fclose (stream); */ + return pclose (stream); /* return fclose (stream); */ # else - return pclose(stream); + return pclose (stream); # endif } @@ -2615,7 +2597,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 */ @@ -3394,7 +3376,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++)