--- rxvt-unicode/src/screen.C 2004/01/16 16:34:56 1.15 +++ rxvt-unicode/src/screen.C 2004/01/29 23:26:01 1.19 @@ -1,7 +1,6 @@ /*--------------------------------*-C-*--------------------------------------* * File: screen.c *---------------------------------------------------------------------------* - * $Id: screen.C,v 1.15 2004/01/16 16:34:56 pcg Exp $ * * Copyright (c) 1997-2001 Geoff Wing * @@ -904,27 +903,32 @@ // rely on wcwidth to tell us the character width, at least for non-ascii int width = c <= 128 ? 1 : wcwidth (c); - // width 0 characters (e.g. combining chars) are ignored. your problem, really - while (width-- > 0) - { - stp[R->screen.cur.col] = c; - srp[R->screen.cur.col] = rend; + // width -1 characters (e.g. combining chars) are ignored currently. + if (width > 0) + do + { + stp[R->screen.cur.col] = c; + srp[R->screen.cur.col] = rend; - if (R->screen.cur.col < last_col - 1) - R->screen.cur.col++; - else - { - R->screen.tlen[row] = last_col; - if (R->screen.flags & Screen_Autowrap) - R->screen.flags |= Screen_WrapNext; - break; - } + if (R->screen.cur.col < last_col - 1) + R->screen.cur.col++; + else + { + R->screen.tlen[row] = last_col; + if (R->screen.flags & Screen_Autowrap) + R->screen.flags |= Screen_WrapNext; + break; + } - c = NOCHAR; - } + c = NOCHAR; + } + while (--width > 0); + else + 1; /* handle combining character etc. here. */ } + if (R->screen.tlen[row] != -1) /* XXX: think about this */ - MAX_IT(R->screen.tlen[row], R->screen.cur.col); + MAX_IT(R->screen.tlen[row], R->screen.cur.col); /* * If we wrote anywhere in the selected area, kill the selection @@ -1643,29 +1647,32 @@ /* ------------------------------------------------------------------------- * - * GRAPHICS COLOURS * + * MAJOR SCREEN MANIPULATION * * ------------------------------------------------------------------------- */ -#ifdef RXVT_GRAPHICS -/* EXTPROTO */ -int -rxvt_scr_get_fgcolor(pR) +/* + * refresh matching text. + */ +bool +rxvt_term::scr_refresh_rend (rend_t mask, rend_t value) { - return GET_FGCOLOR(R->rstyle); -} + bool found = false; -/* ------------------------------------------------------------------------- */ -/* EXTPROTO */ -int -rxvt_scr_get_bgcolor(pR) -{ - return GET_BGCOLOR(R->rstyle); + for (int i = 0; i < TermWin.nrow; i++) + { + int col = 0; + rend_t *drp = drawn_rend [i]; + + for (; col < TermWin.ncol; col++, drp++) + if ((*drp & mask) == value) + { + found = true; + *drp = ~value; + } + } + + return found; } -#endif - -/* ------------------------------------------------------------------------- * - * MAJOR SCREEN MANIPULATION * - * ------------------------------------------------------------------------- */ /* * Refresh an area @@ -1852,15 +1859,6 @@ * R->screen.text/R->screen.rend contain what the screen will change to. */ -#if defined (NO_BRIGHTCOLOR) || defined (VERYBOLD) -# define MONO_BOLD(x) ((x) & (RS_Bold|RS_Blink)) -# define MONO_BOLD_FG(x, fg) MONO_BOLD(x) -#else -# define MONO_BOLD(x) \ - (((x) & (RS_Bold | RS_fgMask)) == (RS_Bold | Color_fg)) -# define MONO_BOLD_FG(x, fg) (((x) & RS_Bold) && (fg) == Color_fg) -#endif - #define FONT_WIDTH(X, Y) \ (X)->per_char[(Y) - (X)->min_char_or_byte2].width #define FONT_RBEAR(X, Y) \ @@ -1876,13 +1874,8 @@ unsigned char clearfirst, /* first character writes before cell */ clearlast, /* last character writes beyond cell */ must_clear, /* use draw_string not draw_image_string */ -#ifndef NO_BOLDFONT - bfont, /* we've changed font to bold font */ -#endif rvid, /* reverse video this position */ - wbyte, /* we're in multibyte */ showcursor; /* show the cursor */ - int fore, back; /* desired foreground/background */ int16_t col, row, /* column/row we're processing */ ocrow; /* old cursor row */ int cursorwidth; @@ -1901,10 +1894,7 @@ /* * A: set up vars */ - clearfirst = clearlast = must_clear = wbyte = 0; -#ifndef NO_BOLDFONT - bfont = 0; -#endif + clearfirst = clearlast = must_clear = 0; if (currmaxcol < TermWin.ncol) { @@ -1985,9 +1975,6 @@ *srp = SET_BGCOLOR(*srp, ccol2); #endif } - - while (IS_WIDE (*srp)) - cursorwidth++, srp++; } /* make sure no outline cursor is left around */ @@ -2140,7 +2127,7 @@ continue; } - if (((rend ^ srp[col]) & ~RS_wide) != 0) + if (rend != srp[col]) break; count++; @@ -2165,13 +2152,25 @@ /* * Determine the attributes for the string */ - int fid = GET_FONT(rend); - fore = GET_FGCOLOR(rend); - back = GET_BGCOLOR(rend); - rend = GET_ATTR(rend); - - rvid = (rend & RS_RVid) ? 1 : 0; -#ifdef OPTION_HC + int fid = GET_FONT (rend); + int fore = GET_FGCOLOR (rend); // desired foreground + int back = GET_BGCOLOR (rend); // desired background + + rend = GET_ATTR (rend); + + rvid = !!(rend & RS_RVid); +#ifdef TEXT_BLINK + if (rend & RS_Blink) + { + if (!text_blink_ev.active) + { + text_blink_ev.start (NOW + TEXT_BLINK_INTERVAL); + hidden_text = 0; + } + else if (hidden_text) + fore = back; + } +#elif OPTION_HC if (!rvid && (rend & RS_Blink)) { if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_HC)) @@ -2196,21 +2195,16 @@ #ifndef NO_BOLD_UNDERLINE_REVERSE else if (rend & RS_Bold) { - if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_BD)) - { + if (Xdepth > 2) + if (ISSET_PIXCOLOR (this, Color_BD)) fore = Color_BD; -# ifndef VERYBOLD - rend &= ~RS_Bold; /* we've taken care of it */ -# endif - } + else + fore = Color_White; } else if (rend & RS_Uline) { if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_UL)) - { - fore = Color_UL; - rend &= ~RS_Uline; /* we've taken care of it */ - } + fore = Color_UL; } #endif @@ -2481,8 +2475,6 @@ long nread = 0; unsigned long bytes_after; XTextProperty ct; - int dummy_count; - char **cl; D_SELECT((stderr, "rxvt_selection_paste(%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, R->selection_wait)); @@ -2497,6 +2489,17 @@ rxvt_selection_request_other(aR_ XA_STRING, selnum); } + if ((R->selection_type & Sel_UTF8String)) + { + int selnum = R->selection_type & Sel_whereMask; + + R->selection_type = Sel_CompoundText; + if (selnum != Sel_direct) + rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], selnum); + else + R->selection_type = 0; + } + return 0; } @@ -2539,10 +2542,15 @@ } nread += ct.nitems; + + char **cl; + int cr; if (XmbTextPropertyToTextList (R->Xdisplay, &ct, &cl, - &dummy_count) == Success && cl) + &cr) >= 0 && cl) { - R->paste ((unsigned char *)cl[0], STRLEN (cl[0])); + for (int i = 0; i < cr; i++) + R->paste ((unsigned char *)cl[i], STRLEN (cl[i])); + XFreeStringList (cl); } else @@ -2567,10 +2575,9 @@ void rxvt_term::incr_cb (time_watcher &w) { - w.stop (); selection_wait = Sel_none; - rxvt_print_error("data loss: timeout on INCR selection paste"); + rxvt_print_error ("data loss: timeout on INCR selection paste"); } /* @@ -2646,9 +2653,15 @@ R->selection_request_time = tm; R->selection_wait = Sel_normal; for (i = Sel_Primary; i <= Sel_Clipboard; i++) { +#if X_HAVE_UTF8_STRING + R->selection_type = Sel_UTF8String; + if (rxvt_selection_request_other(aR_ R->xa[XA_UTF8_STRING], i)) + return; +#else R->selection_type = Sel_CompoundText; if (rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], i)) return; +#endif } } R->selection_wait = Sel_none; /* don't loop in rxvt_selection_paste() */ @@ -2790,11 +2803,12 @@ return; } - // due to MB_MAX_CUR, selection wastage is usually high + // due to MB_MAX_CUR, selection wastage is usually high, so realloc if (str - (char *)new_selection_text > 1024) new_selection_text = (unsigned char *)rxvt_realloc (new_selection_text, i + 1); R->selection.len = i; + if (R->selection.text) free (R->selection.text); @@ -2803,8 +2817,23 @@ XSetSelectionOwner(R->Xdisplay, XA_PRIMARY, R->TermWin.vt, tm); if (XGetSelectionOwner(R->Xdisplay, XA_PRIMARY) != R->TermWin.vt) rxvt_print_error("can't get primary selection"); - XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, - PropModeReplace, R->selection.text, (int)R->selection.len); + + + { + XTextProperty ct; + char *cl = (char *)R->selection.text; + + if (XmbTextListToTextProperty(R->Xdisplay, &cl, 1, XStringStyle, &ct) >= 0) + { + XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, + PropModeReplace, ct.value, ct.nitems); + XFree (ct.value); + } + else + XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, + PropModeReplace, R->selection.text, (int)R->selection.len); + } + R->selection_time = tm; D_SELECT((stderr, "rxvt_selection_make(): R->selection.len=%d", R->selection.len)); } @@ -3266,7 +3295,7 @@ * that is exactly 32 bits wide, because a format of 64 is not allowed by * the X11 protocol. */ -typedef CARD32 Atom32; +typedef CARD32 Atom32; /* ------------------------------------------------------------------------- */ /* @@ -3278,15 +3307,9 @@ rxvt_selection_send(pR_ const XSelectionRequestEvent *rq) { XSelectionEvent ev; -#ifdef USE_XIM - Atom32 target_list[4]; -#else - Atom32 target_list[3]; -#endif - Atom target; - XTextProperty ct; + XTextProperty ct; XICCEncodingStyle style; - char *cl[2], dummy[1]; + Atom target; ev.type = SelectionNotify; ev.property = None; @@ -3297,16 +3320,20 @@ ev.time = rq->time; if (rq->target == R->xa[XA_TARGETS]) { - target_list[0] = (Atom32) R->xa[XA_TARGETS]; - target_list[1] = (Atom32) XA_STRING; - target_list[2] = (Atom32) R->xa[XA_TEXT]; -#ifdef USE_XIM - target_list[3] = (Atom32) R->xa[XA_COMPOUND_TEXT]; + Atom32 target_list[5]; + Atom32 *target = target_list; + + *target++ = (Atom32) R->xa[XA_TARGETS]; + *target++ = (Atom32) XA_STRING; + *target++ = (Atom32) R->xa[XA_TEXT]; + *target++ = (Atom32) R->xa[XA_COMPOUND_TEXT]; +#if X_HAVE_UTF8_STRING + *target++ = (Atom32) R->xa[XA_UTF8_STRING]; #endif XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_ATOM, (8 * sizeof(target_list[0])), PropModeReplace, (unsigned char *)target_list, - (sizeof(target_list) / sizeof(target_list[0]))); + target - target_list); ev.property = rq->property; } else if (rq->target == R->xa[XA_MULTIPLE]) { /* TODO: Handle MULTIPLE */ @@ -3316,50 +3343,58 @@ (unsigned char *)&R->selection_time, 1); ev.property = rq->property; } else if (rq->target == XA_STRING + || rq->target == R->xa[XA_TEXT] || rq->target == R->xa[XA_COMPOUND_TEXT] - || rq->target == R->xa[XA_TEXT]) { -#ifdef USE_XIM - short freect = 0; + || rq->target == R->xa[XA_UTF8_STRING] + ) { + short freect = 0; + int selectlen; + char *cl; + + target = rq->target; + + if (target == XA_STRING) + // we actually don't do XA_STRING, but who cares, as i18n clients + // will ask for another format anyways. + style = XStringStyle; + else if (target == R->xa[XA_TEXT]) + style = XTextStyle; + else if (target == R->xa[XA_COMPOUND_TEXT]) + style = XCompoundTextStyle; +#if X_HAVE_UTF8_STRING + else if (target == R->xa[XA_UTF8_STRING]) + style = XUTF8StringStyle; #endif - int selectlen; - -#ifdef USE_XIM - if (rq->target != XA_STRING) { + else + { target = R->xa[XA_COMPOUND_TEXT]; - style = (rq->target == R->xa[XA_COMPOUND_TEXT]) - ? XCompoundTextStyle : XStdICCTextStyle; - } else -#endif - { - target = XA_STRING; - style = XStringStyle; - } + style = XCompoundTextStyle; + } + if (R->selection.text) { - cl[0] = (char *)R->selection.text; + cl = (char *)R->selection.text; selectlen = R->selection.len; } else { - cl[0] = dummy; - *dummy = '\0'; + cl = ""; selectlen = 0; } -#ifdef USE_XIM - if (XmbTextListToTextProperty(R->Xdisplay, cl, 1, style, &ct) - == Success) /* if we failed to convert then send it raw */ + + if (XmbTextListToTextProperty(R->Xdisplay, &cl, 1, style, &ct) >= 0) freect = 1; else -#endif - { - ct.value = (unsigned char *)cl[0]; + { + /* if we failed to convert then send it raw */ + ct.value = (unsigned char *)cl; ct.nitems = selectlen; - } + } + XChangeProperty(R->Xdisplay, rq->requestor, rq->property, target, 8, PropModeReplace, ct.value, (int)ct.nitems); ev.property = rq->property; -#ifdef USE_XIM + if (freect) - XFree(ct.value); -#endif + XFree (ct.value); } XSendEvent(R->Xdisplay, rq->requestor, False, 0L, (XEvent *)&ev); }