📄 xtext.c
字号:
return shaded_pix;}#endif /* !USE_MMX */#ifdef USE_GDK_PIXBUFstatic GdkPixmap *shade_pixmap_gdk (GtkXText * xtext, Pixmap p, int x, int y, int w, int h){ GdkPixmap *pp, *tmp, *shaded_pixmap; GdkPixbuf *pixbuf; GdkColormap *cmap; GdkGC *tgc; unsigned char *buf; unsigned char *pbuf; int width, height, depth; int rowstride; int pbwidth; int pbheight; int i, j; int offset; int r, g, b, a; pp = gdk_pixmap_foreign_new (p); cmap = gtk_widget_get_colormap (GTK_WIDGET (xtext)); gdk_window_get_geometry (pp, NULL, NULL, &width, &height, &depth); if (width < x + w || height < y + h || x < 0 || y < 0) { tgc = gdk_gc_new (pp); tmp = gdk_pixmap_new (pp, w, h, depth); gdk_gc_set_tile (tgc, pp); gdk_gc_set_fill (tgc, GDK_TILED); gdk_gc_set_ts_origin (tgc, -x, -y); gdk_draw_rectangle (tmp, tgc, TRUE, 0, 0, w, h); gdk_gc_destroy (tgc); pixbuf = gdk_pixbuf_get_from_drawable (NULL, tmp, cmap, 0, 0, 0, 0, w, h); gdk_pixmap_unref (tmp); } else { pixbuf = gdk_pixbuf_get_from_drawable (NULL, pp, cmap, x, y, 0, 0, w, h); } gdk_xid_table_remove (GDK_WINDOW_XWINDOW (pp)); g_dataset_destroy (pp); g_free (pp); if (!pixbuf) return NULL; buf = gdk_pixbuf_get_pixels (pixbuf); rowstride = gdk_pixbuf_get_rowstride (pixbuf); pbwidth = gdk_pixbuf_get_width (pixbuf); pbheight = gdk_pixbuf_get_height (pixbuf); a = 128; /* alpha */ r = xtext->tint_red; g = xtext->tint_green; b = xtext->tint_blue; if (gdk_pixbuf_get_has_alpha (pixbuf)) offset = 4; else offset = 3; for (i=0;i<pbheight;i++) { pbuf = buf; for (j=0;j<pbwidth;j++) { pbuf[0] = ((pbuf[0] * r) >> 8); pbuf[1] = ((pbuf[1] * g) >> 8); pbuf[2] = ((pbuf[2] * b) >> 8); pbuf+=offset; } buf+=rowstride; } /* reuse the same pixmap to save a few cycles */ if (xtext->recycle) { shaded_pixmap = xtext->pixmap; gdk_pixbuf_render_to_drawable (pixbuf, shaded_pixmap, xtext->fgc, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NORMAL, 0, 0); } else { gdk_pixbuf_render_pixmap_and_mask (pixbuf, &shaded_pixmap, NULL, 0); } gdk_pixbuf_unref (pixbuf); return shaded_pixmap;}#endif /* !USE_GDK_PIXBUF */#if defined(USE_GDK_PIXBUF) || defined(USE_MMX)static GdkPixmap *shade_pixmap (GtkXText * xtext, Pixmap p, int x, int y, int w, int h){#ifdef USE_MMX if (have_mmx () && xtext->depth != 8) return shade_pixmap_mmx (xtext, p, x, y, w, h);#ifdef USE_GDK_PIXBUF return shade_pixmap_gdk (xtext, p, x, y, w, h);#else return NULL;#endif#else return shade_pixmap_gdk (xtext, p, x, y, w, h);#endif /* !USE_MMX */}#endif /* !USE_TINT *//* free transparency xtext->pixmap */static voidgtk_xtext_free_trans (GtkXText * xtext){ if (xtext->pixmap) { if (xtext->shaded) { gdk_pixmap_unref (xtext->pixmap); } else { gdk_xid_table_remove (GDK_WINDOW_XWINDOW (xtext->pixmap)); g_dataset_destroy (xtext->pixmap); g_free (xtext->pixmap); } xtext->pixmap = NULL; }}/* grab pixmap from root window and set xtext->pixmap */static voidgtk_xtext_load_trans (GtkXText * xtext){ Pixmap rootpix; GtkWidget *widget = GTK_WIDGET (xtext); int x, y; rootpix = get_pixmap_prop (GDK_WINDOW_XWINDOW (widget->window)); if (rootpix == None) { if (xtext->error_function) xtext->error_function ("Unable to get root window pixmap!\n\n" "You may need to use Esetroot or Gnome\n" "control-center to set your background.\n"); xtext->transparent = FALSE; return; } gdk_window_get_origin (widget->window, &x, &y);#if defined(USE_GDK_PIXBUF) || defined(USE_MMX) if (xtext->shaded) { int width, height; gdk_window_get_size (GTK_WIDGET (xtext)->window, &width, &height); xtext->pixmap = shade_pixmap (xtext, rootpix, x, y, width, height); if (xtext->pixmap == NULL) { xtext->shaded = 0; goto noshade; } gdk_gc_set_tile (xtext->bgc, xtext->pixmap); gdk_gc_set_ts_origin (xtext->bgc, 0, 0); } else {#endifnoshade: xtext->pixmap = gdk_pixmap_foreign_new (rootpix); gdk_gc_set_tile (xtext->bgc, xtext->pixmap); gdk_gc_set_ts_origin (xtext->bgc, -x, -y);#if defined(USE_GDK_PIXBUF) || defined(USE_MMX) }#endif gdk_gc_set_fill (xtext->bgc, GDK_TILED);}#endif/* walk through str until this line doesn't fit anymore */static intfind_next_wrap (GtkXText * xtext, textentry * ent, unsigned char *str, int win_width, int indent){ unsigned char *last_space = str; unsigned char *orig_str = str; int str_width = indent; int col = FALSE; int nc = 0; int mbl; int ret; int limit_offset = 0; /* single liners */ if (win_width >= ent->str_width + ent->indent) return ent->str_len; /* it does happen! */ if (win_width < 1) { ret = ent->str_len - (str - ent->str); goto done; } while (1) { if ((col && isdigit (*str) && nc < 2) || (col && *str == ',' && isdigit (*(str+1)) && nc < 3)) { nc++; if (*str == ',') nc = 0; limit_offset++; str++; } else { col = FALSE; switch (*str) { case ATTR_COLOR: col = TRUE; nc = 0; case ATTR_BEEP: case ATTR_RESET: case ATTR_REVERSE: case ATTR_BOLD: case ATTR_UNDERLINE: limit_offset++; str++; break; default: str_width += get_char_width (xtext, str, &mbl, ent->mb); if (str_width > win_width) { if (xtext->wordwrap) { if (str - last_space > WORDWRAP_LIMIT + limit_offset) ret = str - orig_str; /* fall back to character wrap */ else { if (*last_space == ' ') last_space++; ret = last_space - orig_str; if (ret == 0) /* fall back to character wrap */ ret = str - orig_str; } goto done; } ret = str - orig_str; goto done; } /* keep a record of the last space, for wordwrapping */ if (is_del (*str)) { last_space = str; limit_offset = 0; } /* progress to the next char */ str += mbl; } } if (str >= ent->str + ent->str_len) { ret = str - orig_str; goto done; } }done: /* must make progress */ if (ret < 1) ret = 1; return ret;}/* render a single line, which may wrap to more lines */static intgtk_xtext_render_line (GtkXText * xtext, textentry * ent, int line, int lines_max, int subline, int win_width){ unsigned char *str; int indent, taken, len, y; taken = 0; str = ent->str; indent = ent->indent;#ifdef XCHAT /* draw the timestamp */ if (xtext->time_stamp && !xtext->skip_stamp) { char time_str[64]; int stamp_size = get_stamp_str (ent->stamp, time_str, sizeof (time_str)); y = (xtext->fontsize * line) + xtext->font->ascent - xtext->pixel_offset; gtk_xtext_render_str (xtext, y, ent, time_str, stamp_size, win_width, 2, line); }#endif /* draw each line one by one */ do { len = find_next_wrap (xtext, ent, str, win_width, indent); y = (xtext->fontsize * line) + xtext->font->ascent - xtext->pixel_offset; if (!subline) { if (!gtk_xtext_render_str (xtext, y, ent, str, len, win_width, indent, line)) { /* small optimization */ return ent->lines_taken - subline; } } else { xtext->dont_render = TRUE; gtk_xtext_render_str (xtext, y, ent, str, len, win_width, indent, line); xtext->dont_render = FALSE; subline--; line--; taken--; } indent = xtext->indent; line++; taken++; str += len; if (line >= lines_max) break; } while (str < ent->str + ent->str_len); return taken;}voidgtk_xtext_set_palette (GtkXText * xtext, GdkColor palette[]){ int i; for (i = 0; i < 20; i++) xtext->palette[i] = palette[i].pixel; if (GTK_WIDGET_REALIZED (xtext)) { xtext_set_fg (xtext->fgc, xtext->palette[18]); xtext_set_bg (xtext->fgc, xtext->palette[19]); xtext_set_fg (xtext->bgc, xtext->palette[19]); } xtext->col_fore = 18; xtext->col_back = 19;}static voidgtk_xtext_fix_indent (GtkXText * xtext){ int j; /* make indent a multiple of the space width */ if (xtext->indent && xtext->space_width) { j = 0; while (j < xtext->indent) { j += xtext->space_width; } xtext->indent = j; }}static voidgtk_xtext_recalc_widths (GtkXText * xtext, int do_str_width){ textentry *ent; /* since we have a new font, we have to recalc the text widths */ ent = xtext->text_first; while (ent) { if (do_str_width) { ent->str_width = gtk_xtext_text_width (xtext, ent->str, ent->str_len, NULL); } if (ent->left_len != -1) { ent->indent = (xtext->indent - gtk_xtext_text_width (xtext, ent->str, ent->left_len, NULL)) - xtext->space_width; if (ent->indent < MARGIN) ent->indent = MARGIN; } ent = ent->next; } gtk_xtext_calc_lines (xtext, FALSE);}voidgtk_xtext_set_font (GtkXText * xtext, GdkFont * font, char *name){ int i;#ifdef WIN32 GdkWChar c;#else unsigned char c;#endif#ifdef USE_XLIB XFontStruct *xfont;#endif if (xtext->font) gdk_font_unref (xtext->font); if (font) { xtext->font = font; gdk_font_ref (font); } else font = xtext->font = gdk_font_load (name); if (!font) font = xtext->font = gdk_font_load ("fixed"); switch (font->type) { case GDK_FONT_FONT: xtext->fontsize = font->ascent + font->descent;#ifdef USE_XLIB xfont = GDK_FONT_XFONT (font); if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) xtext->fonttype = FONT_1BYTE; else xtext->fonttype = FONT_2BYTE;#else /* without X11 we don't support 16bit fonts */ xtext->fonttype = FONT_1BYTE;#endif break; case GDK_FONT_FONTSET:#ifdef WIN32 xtext->fontsize = font->ascent + font->descent;#else xtext->fontsize = gdk_text_height (font, " ", 1);#endif xtext->fonttype = FONT_SET; break; } /* measure the width of every char */ for (i = 0; i < 256; i++) { c = i;#ifdef WIN32 xtext->fontwidth[i] = gdk_text_width_wc (font, &c, 1);#else xtext->fontwidth[i] = gdk_text_width (font, &c, 1);#endif } xtext->space_width = xtext->fontwidth[' '];#ifdef XCHAT { char time_str[64]; int stamp_size = get_stamp_str (time(0), time_str, sizeof (time_str)); xtext->stamp_width = gtk_xtext_text_width (xtext, time_str, stamp_size, NULL) + MARGIN; }#endif gtk_xtext_fix_indent (xtext); if (GTK_WIDGET_REALIZED (xtext)) { if (xtext->fonttype != FONT_SET) gdk_gc_set_font (xtext->fgc, xtext->font); gtk_xtext_recalc_widths (xtext, TRUE); }}voidgtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap, int trans, int shaded){ GdkGCValues val;#if !defined(USE_GDK_PIXBUF) && !defined(USE_MMX) shaded = FALSE;#endif#ifndef USE_XLIB shaded = FALSE; trans = FALSE;#endif if (xtext->pixmap) {#ifdef USE_XLIB if (xtext->transparent) gtk_xtext_free_trans (xtext); else#endif gdk_pixmap_unref (xtext->pixmap); xtext->pixmap = NULL; } xtext->transparent = trans;#ifdef USE_XLIB if (trans) { xtext->shaded = shaded; if (GTK_WIDGET_REALIZED (xtext)) gtk_xtext_load_trans (xtext); return; }#endif xtext->pixmap = pixmap; if (pixmap != 0) { gdk_pixmap_ref (pixmap); if (GTK_WIDGET_REALIZED (xtext)) { gdk_gc_set_tile (xtext->bgc, pixmap); gdk_gc_set_ts_origin (xtext->bgc, 0, 0); gdk_gc_set_fill (xtext->bgc, GDK_TILED); } } else { if (GTK_WIDGET_REALIZED (xtext)) { gdk_gc_destroy (xtext->bgc); val.subwindow_mode = GDK_INCLUDE_INFERIORS; val.graphics_exposures = 0; xtext->bgc = gdk_gc_new_with_values (GTK_WIDGET (xtext)->window, &val, GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW); xtext_set_fg (xtext->bgc, xtext->palette[19]); } }}#ifndef XCHATgchar *gtk_xtext_get_chars (GtkXText * xtext){ int lenght = 0; gchar *chars; textentry *tentry = xtext
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -