--- ./zvt/zvtterm.c.jp2 Tue Oct 24 08:12:43 2000 +++ ./zvt/zvtterm.c Sun Oct 29 18:32:20 2000 @@ -49,12 +49,15 @@ #include #include - /* define to 'x' to enable copious debug output */ #define d(x) /* default font */ +#ifndef ZVT_MB #define DEFAULT_FONT "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1" +#else +#define DEFAULT_FONT "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-1" +#endif #define PADDING 2 @@ -115,6 +118,12 @@ /* load the "current" background, from file or from system */ static void load_background (ZvtTerm *term); +#ifdef ZVT_IM_ON_THE_SPOT +static void zvt_im_preedit_set_spot(ZvtTerm *term, int col, int row, int offx, int offy); +static void zvt_im_preedit_set_foreground(ZvtTerm *term, GdkColor *color); +static void zvt_im_preedit_set_background(ZvtTerm *term, GdkColor *color); +static void zvt_im_preedit_set_font(ZvtTerm *term, GdkFont *font); +#endif /* static data */ @@ -146,6 +155,13 @@ }; static guint term_signals[LAST_SIGNAL] = { 0 }; +/* values for selection info */ +enum { + TARGET_STRING, + TARGET_UTF8, + TARGET_TEXT, + TARGET_COMPOUND_TEXT +}; /* GTK parent class */ static GtkWidgetClass *parent_class = NULL; @@ -237,6 +253,17 @@ zvt_term_init (ZvtTerm *term) { struct _zvtprivate *zp; + static const GtkTargetEntry targets[] = { + { "STRING", 0, TARGET_STRING }, +#ifdef ZVT_UTF + { "UTF-8", 0, TARGET_UTF8 }, +#endif +#ifdef ZVT_MB + { "TEXT", 0, TARGET_TEXT }, + { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT } +#endif + }; + static const gint n_targets = sizeof(targets) / sizeof(targets[0]); GTK_WIDGET_SET_FLAGS (term, GTK_CAN_FOCUS); @@ -329,19 +356,9 @@ term); /* selection received */ - gtk_selection_add_target ( - GTK_WIDGET (term), - GDK_SELECTION_PRIMARY, - GDK_SELECTION_TYPE_STRING, - 0); -#ifdef ZVT_UTF - gtk_selection_add_target ( - GTK_WIDGET (term), - GDK_SELECTION_PRIMARY, - gdk_atom_intern ("UTF-8", FALSE), - 1); -#endif - + gtk_selection_add_targets (GTK_WIDGET (term), + GDK_SELECTION_PRIMARY, + targets, n_targets); } /** @@ -666,6 +683,11 @@ clone_col(&zp->queue_red, 0); clone_col(&zp->queue_green, 0); clone_col(&zp->queue_blue, 0); +#ifdef ZVT_IM_ON_THE_SPOT + zvt_im_preedit_set_background(term, &c); + c.pixel = term->colors [16]; + zvt_im_preedit_set_foreground(term, &c); +#endif /* ZVT_IM_ON_THE_SPOT */ } /** @@ -801,6 +823,9 @@ term_force_size(term); /* input context */ +#ifdef ZVT_IM_ON_THE_SPOT + zvt_term_set_open_im (term, True); +#else if (gdk_im_ready () && !term->ic) { GdkICAttr attr; @@ -813,6 +838,7 @@ g_warning("Can't create input context."); } } +#endif } static void @@ -1280,7 +1306,11 @@ case GDK_FONT_FONTSET: { XFontSet fontset = (XFontSet) ((GdkFontPrivate *)font)->xfont; XFontSetExtents *extents = XExtentsOfFontSet(fontset); +#ifdef ZVT_MB /* This is look bug..., isn't it? */ + term->charwidth = gdk_string_width (font, "M"); +#else term->charwidth = extents->max_logical_extent.width; +#endif term->charheight = extents->max_logical_extent.height; zp->fonttype = ZVT_FONT_FONTSET; } @@ -1295,6 +1325,9 @@ if (term->font) gdk_font_unref (term->font); term->font = font; +#ifdef ZVT_IM_ON_THE_SPOT + zvt_im_preedit_set_font(term, font); +#endif if (term->font_bold) gdk_font_unref (term->font_bold); @@ -1395,16 +1428,28 @@ if (rest) { g_string_sprintf (outname, "%s-medium-r%s", newname->str, rest); +#ifndef ZVT_MB font = gdk_font_load (outname->str); +#else + font = gdk_fontset_load (outname->str); +#endif d( printf("loading normal font %s\n", outname->str) ); g_string_sprintf (outname, "%s-bold-r%s", newname->str, rest); +#ifndef ZVT_MB font_bold = gdk_font_load (outname->str); +#else + font_bold = gdk_fontset_load (outname->str); +#endif d( printf("loading bold font %s\n", outname->str) ); zvt_term_set_fonts_internal (term, font, font_bold); } else { +#ifndef ZVT_MB font = gdk_font_load (name); +#else + font = gdk_fontset_load (name); +#endif zvt_term_set_fonts_internal (term, font, 0); } @@ -1444,7 +1489,11 @@ { GdkAtom string_atom; #ifdef ZVT_UTF +#ifdef ZVT_MB + char *types[] = {"UTF-8", "COMPOUND_TEXT"}; +#else char *types[] = {"UTF-8", "STRING"}; +#endif /* ZVT_MB */ int index; struct _zvtprivate *zp = _ZVT_PRIVATE(widget); @@ -1464,7 +1513,11 @@ d(printf(" %s atom = %d\n", types[index], (int)string_atom)); #else /* Get the atom corresonding to the target "STRING" */ +#ifdef ZVT_MB + string_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE); +#else string_atom = gdk_atom_intern ("STRING", FALSE); +#endif /* ZVT_MB */ #endif if (string_atom == GDK_NONE) { @@ -1890,10 +1943,15 @@ switch (type) { default: - case 0: { /* this is ascii/isolatin1 */ + +#ifdef ZVT_MB + case TARGET_COMPOUND_TEXT: + case TARGET_TEXT: +#endif + case TARGET_STRING: { /* this is ascii/isolatin1 */ unsigned char *o; d(printf("converting selection to ISOLATIN1\n")); - out = g_malloc(term->vx->selection_size); + out = g_malloc(term->vx->selection_size+1); o = out; for(i=0;ivx->selection_size;i++) { c = term->vx->selection_data[i]; @@ -1902,7 +1960,7 @@ *outlen = term->vx->selection_size; break; } - case 1: { /* this is utf-8, basically a local implementation of wcstombs() */ + case TARGET_UTF8: { /* this is utf-8, basically a local implementation of wcstombs() */ unsigned char *o; unsigned int len=0; d(printf("converting selection to UTF-8\n")); @@ -1991,10 +2049,34 @@ term = ZVT_TERM (widget); vx = term->vx; +#ifdef ZVT_MB + if (info == TARGET_COMPOUND_TEXT||info == TARGET_TEXT) { + GdkAtom encoding; + gint format; + guchar *str, *new_str; + gint new_len; +#ifdef ZVT_UTF + str = zvt_term_convert_selection(term, info, &len); +#else + int len = vx->selection_size; + str = (guchar*)vx->selection_data; +#endif + str[len] = '\0'; + gdk_string_to_compound_text (str, &encoding, &format, &new_str, &new_len); + gtk_selection_data_set (selection_data_ptr, encoding, format, + new_str, new_len); + gdk_free_compound_text (new_str); +#if ZVT_UTF + g_free(str); +#endif + return; + } +#endif /* ZVT_MB */ + #ifdef ZVT_UTF /* convert selection based on info */ /* the selection is actually stored in 32 bit chars */ - if (info==1) + if (info==TARGET_UTF8) atom = gdk_atom_intern ("UTF-8", FALSE); else atom = GDK_SELECTION_TYPE_STRING; @@ -2045,6 +2127,7 @@ /* Make sure we got the data in the expected form */ if (selection_data->type != GDK_SELECTION_TYPE_STRING + && selection_data->type != gdk_atom_intern("COMPOUND_TEXT", FALSE) && selection_data->type != gdk_atom_intern("UTF-8", FALSE)) { g_print ("Selection \"STRING\" was not returned as strings!\n"); return; @@ -2055,13 +2138,40 @@ { int i; char *ctmp = selection_data->data; + gint length = selection_data->length; - for(i = 0; i < selection_data->length; i++) - if(ctmp[i] == '\n') ctmp[i] = '\r'; - - if (term->scroll_on_keystroke) - zvt_term_scroll (term, 0); - zvt_term_writechild(term, selection_data->data, selection_data->length); + if (selection_data->type == gdk_atom_intern("COMPOUND_TEXT",FALSE)) { + gchar **list; + gint count; + + count = gdk_text_property_to_text_list (selection_data->type, + selection_data->format, + selection_data->data, + selection_data->length, + &list); + if (count > 0) { + gint n; + length = 0; + for (n=0; nscroll_on_keystroke) + zvt_term_scroll (term, 0); + vt_writechild(&vx->vt, ctmp, length); + } + gdk_free_text_list (list); + } + } else { + for (i = 0; i < length; i++) + if(ctmp[i] == '\n') ctmp[i] = '\r'; + + if (term->scroll_on_keystroke) + zvt_term_scroll (term, 0); + vt_writechild(&vx->vt, ctmp, length); + } } } @@ -2113,6 +2223,141 @@ return length; } +#ifdef ZVT_IM_ON_THE_SPOT +/** + * zvt_term_set_open_im: + * @term: A &ZvtTerm widget. + * @state: if True, open IM, else close. + **/ +void +zvt_term_set_open_im (ZvtTerm *term, int state) +{ + if(!state) + { + if (term->ic) + { + gdk_ic_destroy(term->ic); + term->ic = NULL; + } + return; + } + + if (gdk_im_ready () && !term->ic) + { + gint width, height; + GdkICAttr attr; + GdkColormap *colormap; + GdkICAttributesType attrmask = GDK_IC_ALL_REQ; + GdkIMStyle style; + GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE | + GDK_IM_PREEDIT_NOTHING | + GDK_IM_PREEDIT_POSITION | + GDK_IM_STATUS_NONE | + GDK_IM_STATUS_NOTHING; + + if (GTK_WIDGET (term)->style && + GTK_WIDGET (term)->style->font->type != GDK_FONT_FONTSET) + supported_style &= ~GDK_IM_PREEDIT_POSITION; + + attr.style = style = gdk_im_decide_style (supported_style); + attr.client_window = attr.focus_window = term->term_window; + + if ((colormap = gtk_widget_get_colormap (GTK_WIDGET (term))) + != gtk_widget_get_default_colormap ()) + { + attrmask |= GDK_IC_PREEDIT_COLORMAP; + attr.preedit_colormap = colormap; + } + + switch (style & GDK_IM_PREEDIT_MASK) + { + case GDK_IM_PREEDIT_POSITION: + if (term->font && term->font->type != GDK_FONT_FONTSET) + { + g_warning ("over-the-spot style requires fontset"); + break; + } +#if 0 + gdk_window_get_size (term->term_window, &width, &height); +#else + width = term->vx->vt.width* term->charwidth; + height = term->vx->vt.height* term->charheight; +#endif + attrmask |= GDK_IC_PREEDIT_POSITION_REQ|GDK_IC_PREEDIT_FONTSET; + attr.spot_location.x = 0; + attr.spot_location.y = 0; + attr.preedit_area.x = 0; + attr.preedit_area.y = 0; + attr.preedit_area.width = width; + attr.preedit_area.height = height; + attr.preedit_fontset = term->font; + break; + } + + term->ic = gdk_ic_new(&attr, attrmask); + + if (!term->ic) + { + g_warning("Can't create input context."); + } + } +} + + +static void +zvt_im_preedit_set_spot(ZvtTerm *term, int col, int row, int offx, int offy) +{ + if (term->ic && + (gdk_ic_get_style (term->ic) & GDK_IM_PREEDIT_POSITION)) + { + GdkICAttr attr; + attr.spot_location.x = col * term->charwidth + offx; + attr.spot_location.y = row * term->charheight + + term->font->ascent + offy; + gdk_ic_set_attr (term->ic, &attr, GDK_IC_SPOT_LOCATION); + } +} + +static void +zvt_im_preedit_set_foreground(ZvtTerm *term, GdkColor *color) +{ + if (term->ic && + (gdk_ic_get_style (term->ic) & GDK_IM_PREEDIT_POSITION)) + { + GdkICAttr attr; + attr.preedit_foreground = *color; + gdk_ic_set_attr (term->ic, &attr, GDK_IC_PREEDIT_FOREGROUND); + } +} + +static void +zvt_im_preedit_set_background(ZvtTerm *term, GdkColor *color) +{ + if (term->ic && + (gdk_ic_get_style (term->ic) & GDK_IM_PREEDIT_POSITION)) + { + GdkICAttr attr; + attr.preedit_background = *color; + gdk_ic_set_attr (term->ic, &attr, GDK_IC_PREEDIT_BACKGROUND); + } +} + + +static void +zvt_im_preedit_set_font(ZvtTerm *term, GdkFont *font) +{ + if (term->ic && + (gdk_ic_get_style (term->ic) & GDK_IM_PREEDIT_POSITION)) + { + GdkICAttr attr; + if (font && font->type != GDK_FONT_FONTSET) + g_warning ("over-the-spot style requires fontset"); + attr.preedit_fontset = font; + gdk_ic_set_attr (term->ic, &attr, GDK_IC_PREEDIT_FONTSET); + } +} +#endif /* ZVT_IM_ON_THE_SPOT */ + static void zvt_term_writemore (gpointer data, gint fd, GdkInputCondition condition) { @@ -2343,7 +2588,7 @@ static gint zvt_term_key_press (GtkWidget *widget, GdkEventKey *event) { - char buffer[64]; + char buffer[128]; char *p=buffer; struct _vtx *vx; ZvtTerm *term; @@ -2547,11 +2792,12 @@ break; default: if (event->length > 0){ + gint length = MIN(((buffer+ sizeof(buffer)) - p)/sizeof(char), event->length); if (event->state & GDK_MOD1_MASK){ *p++ = '\033'; } - memcpy(p, event->string, event->length*sizeof(char)); - p += event->length; + memcpy(p, event->string, length); + p += length; } else { handled = FALSE; } @@ -3161,24 +3407,24 @@ break; /* this is limited to 65535 characters! */ case ZVT_FONT_FONTSET: { - wchar_t *expandwc = zp->text_expand; + char *expand = zp->text_expand; XFontSet fontset = (XFontSet) font_private->xfont; for (i=0;idata[i+col]); + expand[i] = VT_ASCII(line->data[i+col]) & 0xff; } /* render wide characters, with fill if we can */ if (dofill) { - XwcDrawImageString(drawable_private->xdisplay, drawable_private->xwindow, - fontset, gc_private->xgc, offx + x, offy + y, expandwc, len); + XmbDrawImageString(drawable_private->xdisplay, drawable_private->xwindow, + fontset, gc_private->xgc, offx + x, offy + y, expand, len); } else { - XwcDrawString(drawable_private->xdisplay, drawable_private->xwindow, - fontset, gc_private->xgc, offx + x, offy + y, expandwc, len); + XmbDrawString(drawable_private->xdisplay, drawable_private->xwindow, + fontset, gc_private->xgc, offx + x, offy + y, expand, len); } if (overstrike) - XwcDrawString(drawable_private->xdisplay, drawable_private->xwindow, - fontset, gc_private->xgc, offx + x + 1, offy + y, expandwc, len); + XmbDrawString(drawable_private->xdisplay, drawable_private->xwindow, + fontset, gc_private->xgc, offx + x + 1, offy + y, expand, len); } } @@ -3199,6 +3445,10 @@ x + offx + len*term->charwidth, offy + row*term->charheight, 1, term->charheight); } +#ifdef ZVT_IM_ON_THE_SPOT + if (len <= MB_CUR_MAX) + zvt_im_preedit_set_spot(term, col, row, offx, offy); +#endif } @@ -3833,6 +4083,7 @@ } else { d(printf("background hasn't moved, leaving\n")); } + } static gint