grim/purple-plugin-pack
Remove xchat-chats as it's hacky and carrying a super old version of the xchat widgets
--- a/meson.build Mon Mar 02 00:54:56 2020 +0000
+++ b/meson.build Sun Mar 01 19:59:18 2020 -0600
@@ -211,7 +211,6 @@
#######################################################################
--- a/xchat-chats/.todo Mon Mar 02 00:54:56 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
- - Remember the width of the nick-list on the right
- - Colorize the nicks and highlight messages etc.
- - Get rid of the font-stuff from the GtkXText widget and use the gtk-theme instead.
--- a/xchat-chats/README.md Mon Mar 02 00:54:56 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-authors: Sadrul Habib Chowdhury
-You can chat in Pidgin using XChat's indented view.
--- a/xchat-chats/meson.build Mon Mar 02 00:54:56 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-if TYPES.contains('default') and PIDGIN.found() and IS_PURPLE_TWO
- xchat_chats = shared_module('xchat-chats',
- dependencies : [PIDGIN, GTK],
- install_dir : PIDGIN_LIBDIR)
- PP_PIDGIN_BUILD += 'xchat-chats'
--- a/xchat-chats/xchat-chats.c Mon Mar 02 00:54:56 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,498 +0,0 @@
- * Purple-XChat - Use XChat-like chats
- * Copyright (C) 2005-2008
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-/* If you can't figure out what this line is for, DON'T TOUCH IT. */
-#include "../common/pp_internal.h"
-#define PLUGIN_ID "gtk-plugin_pack-xchat-chats"
-#define PLUGIN_NAME "xchat-chats"
-#define PLUGIN_AUTHOR "Sadrul Habib Chowdhury <sadrul@users.sourceforge.net>"
-#define PREFS_PREFIX "/plugins/gtk/" PLUGIN_ID
-#define PREFS_DATE_FORMAT PREFS_PREFIX "/date_format"
-#include <conversation.h>
-static PurpleConversationUiOps *uiops = NULL;
-static void (*default_write_conv)(PurpleConversation *conv, const char *name, const char *alias,
- const char *message, PurpleMessageFlags flags, time_t mtime);
-static void (*default_create_conversation)(PurpleConversation *conv);
-static void (*default_destroy_conversation)(PurpleConversation *conv);
-static GtkWidget* hack_and_get_widget(PidginConversation *gtkconv);
-void palette_alloc (GtkWidget * widget);
-typedef struct _PurpleXChat PurpleXChat;
-static GHashTable *xchats = NULL; /* Hashtable of xchats */
-static GdkColor colors[][2] = {
- { {0, 0x4c4c, 0x4c4c, 0x4c4c}, {0, 0x4c4c, 0x4c4c, 0x4c4c} }, /* Message sent */
- { {0, 0x35c2, 0x35c2, 0xb332}, {0, 0, 0, 0} }, /* Message received */
- { {0, 0xd9d9, 0xa6a6, 0x4141}, {0, 0xd9d9, 0xa6a6, 0x4141} }, /* System message */
- { {0, 0xc7c7, 0x3232, 0x3232}, {0, 0xc7c7, 0x3232, 0x3232} }, /* Highlight message */
- { {0, 0xc7c7, 0x3232, 0x3232}, {0, 0x4c4c, 0x4c4c, 0x4c4c} }, /* Error message */
- {0, 0xcccc, 0xcccc, 0xcccc}, /* 16 white */
- {0, 0x0000, 0x0000, 0x0000}, /* 17 black */
- {0, 0x35c2, 0x35c2, 0xb332}, /* 18 blue */
- {0, 0x2a3d, 0x8ccc, 0x2a3d}, /* 19 green */
- {0, 0xc7c7, 0x3232, 0x3232}, /* 21 light red */
- {0, 0x8000, 0x2666, 0x7fff}, /* 22 purple */
- {0, 0xd999, 0xa6d3, 0x4147}, /* 24 yellow */
- {0, 0x3d70, 0xcccc, 0x3d70}, /* 25 green */
- {0, 0x199a, 0x5555, 0x5555}, /* 26 aqua */
- {0, 0x2eef, 0x8ccc, 0x74df}, /* 27 light aqua */
- {0, 0x451e, 0x451e, 0xe666}, /* 28 blue */
- {0, 0x4c4c, 0x4c4c, 0x4c4c}, /* 30 grey */
- {0, 0x9595, 0x9595, 0x9595}, /* 31 light grey */
- {0, 0xcccc, 0xcccc, 0xcccc}, /* 16 white */
- {0, 0x0000, 0x0000, 0x0000}, /* 17 black */
- {0, 0x35c2, 0x35c2, 0xb332}, /* 18 blue */
- {0, 0x2a3d, 0x8ccc, 0x2a3d}, /* 19 green */
- {0, 0xc7c7, 0x3232, 0x3232}, /* 21 light red */
- {0, 0x8000, 0x2666, 0x7fff}, /* 22 purple */
- {0, 0xd999, 0xa6d3, 0x4147}, /* 24 yellow */
- {0, 0x3d70, 0xcccc, 0x3d70}, /* 25 green */
- {0, 0x199a, 0x5555, 0x5555}, /* 26 aqua */
- {0, 0x2eef, 0x8ccc, 0x74df}, /* 27 light aqua */
- {0, 0x451e, 0x451e, 0xe666}, /* 28 blue */
- {0, 0x4c4c, 0x4c4c, 0x4c4c}, /* 30 grey */
- {0, 0x9595, 0x9595, 0x9595}, /* 31 light grey */
- {0, 0xffff, 0xffff, 0xffff}, /* 32 marktext Fore (white) */
- {0, 0x3535, 0x6e6e, 0xc1c1}, /* 33 marktext Back (blue) */
- {0, 0x0000, 0x0000, 0x0000}, /* 34 foreground (black) */
- {0, 0xf0f0, 0xf0f0, 0xf0f0}, /* 35 background (white) */
- {0, 0xcccc, 0x1010, 0x1010}, /* 36 marker line (red) */
- {0, 0x9999, 0x0000, 0x0000}, /* 37 tab New Data (dark red) */
- {0, 0x0000, 0x0000, 0xffff}, /* 38 tab Nick Mentioned (blue) */
- {0, 0xffff, 0x0000, 0x0000}, /* 39 tab New Message (red) */
- {0, 0x9595, 0x9595, 0x9595}, /* 40 away user (grey) */
-/* check if a word is clickable */
-mg_word_check (GtkWidget * xtext, char *word, int len)
- session *sess = current_sess;
- ret = url_check_word (word, len); /* common/url.c */
- if (( (word[0]=='@' || word[0]=='+') && userlist_find (sess, word+1)) || userlist_find (sess, word))
- if (sess->type == SESS_DIALOG)
- return (purple_version_check(2, 4, 0) == NULL);
-static GtkWidget *get_xtext(PurpleConversation *conv)
- if ((gx = g_hash_table_lookup(xchats, conv)) == NULL)
- PidginConversation *gtkconv;
- GtkWidget *imhtml = NULL;
- gtkconv = PIDGIN_CONVERSATION(conv);
- imhtml = gtkconv->imhtml;
- style = gtk_widget_get_style(imhtml);
- palette_alloc(pidgin_conv_get_window(gtkconv)->window);
- gx = g_new0(PurpleXChat, 1);
- xtext = gtk_xtext_new(colors, TRUE);
- /* TODO: Figure out a way to set the colors correctly */
- gtk_xtext_set_foreground_color(GTK_XTEXT(xtext), &style->text[0]);
- gtk_xtext_set_background_color(GTK_XTEXT(xtext), &style->base[0]);
- gtk_xtext_set_indent(GTK_XTEXT(xtext), TRUE);
- gtk_xtext_set_max_indent(GTK_XTEXT(xtext), 200);
- gx->imhtml = hack_and_get_widget(gtkconv);
- if (!gtk_xtext_set_font(GTK_XTEXT(xtext),
- pango_font_description_to_string(style->font_desc)))
- g_hash_table_insert(xchats, conv, gx);
-palette_alloc (GtkWidget * widget)
- static int done_alloc = FALSE;
- if (!done_alloc) /* don't do it again */
- cmap = gtk_widget_get_colormap (widget);
- for (i = G_N_ELEMENTS(colors)-1; i >= 0; i--)
- gdk_colormap_alloc_color (cmap, &colors[i][0], FALSE, TRUE);
- gdk_colormap_alloc_color (cmap, &colors[i][1], FALSE, TRUE);
-static void purple_xchat_write_conv(PurpleConversation *conv, const char *name, const char *alias,
- const char *message, PurpleMessageFlags flags, time_t mtime)
- PurpleConversationType type;
- PurpleXChatMessage col = 0;
- /* Do the usual stuff first. */
- default_write_conv(conv, name, alias, message, flags, mtime);
- type = purple_conversation_get_type(conv);
- if (type != PURPLE_CONV_TYPE_CHAT)
- /* If it's IM, we have nothing to do. */
- /* So it's a chat. Let's play. */
- xtext = get_xtext(conv);
- if (name == NULL || !strcmp(name, purple_conversation_get_name(conv)))
- msg = purple_markup_strip_html(message);
- if (msg && msg[0] == '/' && msg[1] == 'm' && msg[2] == 'e' && msg[3] == ' ')
- msg = g_strdup_printf("%s%s", name, tmp+3);
- if (flags & PURPLE_MESSAGE_SEND)
- else if (flags & PURPLE_MESSAGE_RECV)
- if (flags & PURPLE_MESSAGE_NICK)
- else if (flags & PURPLE_MESSAGE_ERROR)
- else if ((flags & PURPLE_MESSAGE_SYSTEM) || (flags & PURPLE_MESSAGE_NO_LOG))
- gtk_xtext_append_indent(GTK_XTEXT(xtext)->buffer, (guchar*)name, strlen(name), colors[col][0].pixel,
- (guchar*)msg, strlen(msg), colors[col][1].pixel);
- name = G_OBJECT_TYPE_NAME(x); \
-hack_and_get_widget(PidginConversation *gtkconv)
- GtkWidget *tab_cont, *vbox, *hpaned, *frame;
- /* If you think this is ugly, you are right. */
- tab_cont = gtkconv->tab_cont;
- list = gtk_container_get_children(GTK_CONTAINER(tab_cont));
- if (!is_2_4_0_or_above()) {
- GtkWidget *pane = list->data;
- vbox = GTK_PANED(pane)->child1;
- list = GTK_BOX(vbox)->children;
- if (GTK_IS_PANED(((GtkBoxChild*)list->data)->widget))
- hpaned = ((GtkBoxChild*)list->data)->widget;
- frame = GTK_PANED(hpaned)->child1;
-purple_conversation_use_xtext(PurpleConversation *conv)
- PidginConversation *gtkconv;
- GtkWidget *parent, *box, *wid, *frame, *xtext;
- if (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT)
- gtkconv = PIDGIN_CONVERSATION(conv);
- frame = hack_and_get_widget(gtkconv);
- parent = frame->parent;
- gtk_widget_hide_all(frame);
- box = gtk_hbox_new(FALSE, 0);
- xtext = get_xtext(conv);
- GTK_PANED(parent)->child1 = NULL;
- gtk_paned_pack1(GTK_PANED(parent), box, TRUE, TRUE);
- gtk_box_pack_start(GTK_BOX(box), xtext, TRUE, TRUE, 0);
- wid = gtk_vscrollbar_new(GTK_XTEXT(xtext)->adj);
- gtk_box_pack_start(GTK_BOX(box), wid, FALSE, FALSE, 0);
- GTK_WIDGET_UNSET_FLAGS(wid, GTK_CAN_FOCUS);
- gtk_widget_show_all(box);
- gtk_widget_realize(xtext);
-purple_xchat_create_conv(PurpleConversation *conv)
- default_create_conversation(conv);
- purple_conversation_use_xtext(conv);
-purple_xchat_destroy_conv(PurpleConversation *conv)
- default_destroy_conversation(conv);
- gx = g_hash_table_lookup(xchats, conv);
- g_hash_table_remove(xchats, conv);
-workaround_for_hidden_convs(PidginConversation *gtkconv)
- PurpleConversation *conv = gtkconv->active_conv;
- if (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT ||
- g_hash_table_lookup(xchats, conv))
- purple_conversation_use_xtext(conv);
-plugin_load(PurplePlugin *plugin)
- uiops = pidgin_conversations_get_conv_ui_ops();
- /* Use the oh-so-useful uiops. Signals? bleh. */
- default_write_conv = uiops->write_conv;
- uiops->write_conv = purple_xchat_write_conv;
- default_create_conversation = uiops->create_conversation;
- uiops->create_conversation = purple_xchat_create_conv;
- default_destroy_conversation = uiops->destroy_conversation;
- uiops->destroy_conversation = purple_xchat_destroy_conv;
- xchats = g_hash_table_new(g_direct_hash, g_direct_equal);
- list = purple_get_chats();
- /* TODO: We can get the message history of the conversation and populate
- * the next xtext with that data.
- * Note: purple_conversation_get_message_history
- purple_conversation_use_xtext(list->data);
- purple_signal_connect(pidgin_conversations_get_handle(), "conversation-displayed",
- plugin, G_CALLBACK(workaround_for_hidden_convs), NULL);
-static void remove_xtext(PurpleConversation *conv, PurpleXChat *gx, gpointer null)
- GtkWidget *frame, *parent;
- frame = gx->xtext->parent;
- parent = frame->parent;
- GTK_PANED(parent)->child1 = NULL;
- gx->imhtml->parent = NULL;
- gtk_paned_add1(GTK_PANED(parent), gx->imhtml);
- g_object_unref(gx->imhtml);
- gtk_widget_destroy(frame);
- gtk_widget_show_all(gx->imhtml);
-plugin_unload(PurplePlugin *plugin)
- /* Restore the default ui-ops */
- uiops->write_conv = default_write_conv;
- uiops->create_conversation = default_create_conversation;
- uiops->destroy_conversation = default_destroy_conversation;
- /* Clear up everything */
- g_hash_table_foreach(xchats, (GHFunc)remove_xtext, NULL);
- g_hash_table_destroy(xchats);
-static PurplePluginInfo info =
- PURPLE_PLUGIN_MAGIC, /* Magic */
- PURPLE_MAJOR_VERSION, /* Purple Major Version */
- PURPLE_MINOR_VERSION, /* Purple Minor Version */
- PURPLE_PLUGIN_STANDARD, /* plugin type */
- PIDGIN_PLUGIN_TYPE, /* ui requirement */
- NULL, /* dependencies */
- PURPLE_PRIORITY_DEFAULT, /* priority */
- PLUGIN_ID, /* plugin id */
- PP_VERSION, /* version */
- NULL, /* description */
- PLUGIN_AUTHOR, /* author */
- PP_WEBSITE, /* website */
- plugin_load, /* load */
- plugin_unload, /* unload */
-init_plugin(PurplePlugin *plugin) {
- bindtextdomain(GETTEXT_PACKAGE, PP_LOCALEDIR);
- bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
- info.name = _("XChat Chats");
- info.summary = _("XChat-like chats with Pidgin");
- info.description = _("You can chat in Pidgin using XChat's indented view.");
- purple_prefs_add_none(PREFS_PREFIX);
- purple_prefs_add_string(PREFS_DATE_FORMAT, "[%H:%M]");
-PURPLE_INIT_PLUGIN(PLUGIN_STATIC_NAME, init_plugin, info)
--- a/xchat-chats/xtext.c Mon Mar 02 00:54:56 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5074 +0,0 @@
- * Copyright (C) 1998 Peter Zelezny.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA
- * =========================================================================
- * xtext, the text widget used by X-Chat.
- * By Peter Zelezny <zed@xchat.org>.
-#define TINT_VALUE 195 /* 195/255 of the brightness. */
-#define MOTION_MONITOR /* URL hilights. */
-#define SMOOTH_SCROLL /* line-by-line or pixel scroll? */
-#define SCROLL_HACK /* use XCopyArea scroll, or full redraw? */
-#undef COLOR_HILIGHT /* Color instead of underline? */
-/* Italic is buggy because it assumes drawing an italic string will have
- identical extents to the normal font. This is only true some of the
- time, so we can't use this hack yet. */
-#undef ITALIC /* support Italic? */
-#define GDK_MULTIHEAD_SAFE
-#define USE_DB /* double buffer */
-#define MARGIN 2 /* dont touch. */
-#define REFRESH_TIMEOUT 20
-#define WORDWRAP_LIMIT 24
-#include <gtk/gtkmain.h>
-#include <gtk/gtksignal.h>
-#include <gtk/gtkselection.h>
-#include <gtk/gtkclipboard.h>
-#include <gtk/gtkversion.h>
-#include <gtk/gtkwindow.h>
-#include "../../config.h" /* can define USE_XLIB here */
-#define charlen(str) g_utf8_skip[*(guchar *)(str)]
-#include <gdk/gdkwin32.h>
- (c == ' ' || c == '\n' || c == ')' || c == '(' || \
- c == '>' || c == '<' || c == ATTR_RESET || c == ATTR_BOLD || c == 0)
-/* force scrolling off */
-#define dontscroll(buf) (buf)->last_pixel_pos = 0x7fffffff
-static GtkWidgetClass *parent_class = NULL;
- struct textentry *next;
- struct textentry *prev;
- guint16 wrap_offset[RECORD_WRAPS];
- unsigned int mb:1; /* is multibyte? */
-/* values for selection info */
-static guint xtext_signals[LAST_SIGNAL];
-int xtext_get_stamp_str (time_t, char **);
-static void gtk_xtext_render_page (GtkXText * xtext);
-static void gtk_xtext_calc_lines (xtext_buffer *buf, int);
-#if defined(USE_XLIB) || defined(WIN32)
-static void gtk_xtext_load_trans (GtkXText * xtext);
-static void gtk_xtext_free_trans (GtkXText * xtext);
-static char *gtk_xtext_selection_get_text (GtkXText *xtext, int *len_ret);
-static textentry *gtk_xtext_nth (GtkXText *xtext, int line, int *subline);
-static void gtk_xtext_adjustment_changed (GtkAdjustment * adj,
-static int gtk_xtext_render_ents (GtkXText * xtext, textentry *, textentry *);
-static void gtk_xtext_recalc_widths (xtext_buffer *buf, int);
-static void gtk_xtext_fix_indent (xtext_buffer *buf);
-static int gtk_xtext_find_subline (GtkXText *xtext, textentry *ent, int line);
-gtk_xtext_strip_color (unsigned char *text, int len, unsigned char *outbuf,
- int *newlen, int *mb_ret);
-/* gives width of a 8bit string - with no mIRC codes in it */
-gtk_xtext_text_width_8bit (GtkXText *xtext, unsigned char *str, int len)
- width += xtext->fontwidth[*str];
-win32_draw_bg (GtkXText *xtext, int x, int y, int width, int height)
- /* xtext->pixmap is really a GdkImage, created in win32_tint() */
- gdk_draw_image (xtext->draw_buf, xtext->bgc, (GdkImage*)xtext->pixmap,
- x, y, x, y, width, height);
- hwnd = GDK_WINDOW_HWND (xtext->draw_buf);
- rgn = CreateRectRgn (x, y, x + width, y + height);
- SelectClipRgn (hdc, rgn);
-xtext_draw_bg (GtkXText *xtext, int x, int y, int width, int height)
- if (xtext->transparent)
- win32_draw_bg (xtext, x, y, width, height);
- gdk_draw_rectangle (xtext->draw_buf, xtext->bgc, 1, x, y, width, height);
-#define xtext_draw_bg(xt,x,y,w,h) gdk_draw_rectangle(xt->draw_buf, xt->bgc, \
-/* ========================================= */
-/* ========== XFT 1 and 2 BACKEND ========== */
-/* ========================================= */
-backend_font_close (GtkXText *xtext)
- XftFontClose (GDK_WINDOW_XDISPLAY (xtext->draw_buf), xtext->font);
- XftFontClose (GDK_WINDOW_XDISPLAY (xtext->draw_buf), xtext->ifont);
-backend_init (GtkXText *xtext)
- if (xtext->xftdraw == NULL)
- xtext->xftdraw = XftDrawCreate (
- GDK_WINDOW_XDISPLAY (xtext->draw_buf),
- GDK_WINDOW_XWINDOW (xtext->draw_buf),
- GDK_VISUAL_XVISUAL (gdk_drawable_get_visual (xtext->draw_buf)),
- GDK_COLORMAP_XCOLORMAP (gdk_drawable_get_colormap (xtext->draw_buf)));
- XftDrawSetSubwindowMode (xtext->xftdraw, IncludeInferiors);
-backend_deinit (GtkXText *xtext)
- XftDrawDestroy (xtext->xftdraw);
-backend_font_open_real (Display *xdisplay, char *name, gboolean italics)
- PangoFontDescription *fontd;
- int weight, slant, screen = DefaultScreen (xdisplay);
- fontd = pango_font_description_from_string (name);
- if (pango_font_description_get_size (fontd) != 0)
- weight = pango_font_description_get_weight (fontd);
- /* from pangoft2-fontmap.c */
- if (weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_LIGHT) / 2)
- weight = XFT_WEIGHT_LIGHT;
- else if (weight < (PANGO_WEIGHT_NORMAL + 600) / 2)
- weight = XFT_WEIGHT_MEDIUM;
- else if (weight < (600 + PANGO_WEIGHT_BOLD) / 2)
- weight = XFT_WEIGHT_DEMIBOLD;
- else if (weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2)
- weight = XFT_WEIGHT_BOLD;
- weight = XFT_WEIGHT_BLACK;
- slant = pango_font_description_get_style (fontd);
- if (slant == PANGO_STYLE_ITALIC)
- slant = XFT_SLANT_ITALIC;
- else if (slant == PANGO_STYLE_OBLIQUE)
- slant = XFT_SLANT_OBLIQUE;
- slant = XFT_SLANT_ROMAN;
- font = XftFontOpen (xdisplay, screen,
- XFT_FAMILY, XftTypeString, pango_font_description_get_family (fontd),
- XFT_CORE, XftTypeBool, False,
- XFT_SIZE, XftTypeDouble, (double)pango_font_description_get_size (fontd)/PANGO_SCALE,
- XFT_WEIGHT, XftTypeInteger, weight,
- XFT_SLANT, XftTypeInteger, italics ? XFT_SLANT_ITALIC : slant,
- pango_font_description_free (fontd);
- font = XftFontOpenName (xdisplay, screen, name);
- font = XftFontOpenName (xdisplay, screen, "sans-11");
-backend_font_open (GtkXText *xtext, char *name)
- Display *dis = GDK_WINDOW_XDISPLAY (xtext->draw_buf);
- xtext->font = backend_font_open_real (dis, name, FALSE);
- xtext->ifont = backend_font_open_real (dis, name, TRUE);
-backend_get_char_width (GtkXText *xtext, unsigned char *str, int *mbl_ret)
- return xtext->fontwidth[*str];
- *mbl_ret = charlen (str);
- XftTextExtentsUtf8 (GDK_WINDOW_XDISPLAY (xtext->draw_buf), xtext->font, str, *mbl_ret, &ext);
-backend_get_text_width (GtkXText *xtext, guchar *str, int len, int is_mb)
- return gtk_xtext_text_width_8bit (xtext, str, len);
- XftTextExtentsUtf8 (GDK_WINDOW_XDISPLAY (xtext->draw_buf), xtext->font, str, len, &ext);
-backend_draw_text (GtkXText *xtext, int dofill, GdkGC *gc, int x, int y,
- char *str, int len, int str_width, int is_mb)
- /*Display *xdisplay = GDK_WINDOW_XDISPLAY (xtext->draw_buf);*/
- void (*draw_func) (XftDraw *, XftColor *, XftFont *, int, int, XftChar8 *, int) = (void *)XftDrawString8;
- /* if all ascii, use String8 to avoid the conversion penalty */
- draw_func = (void *)XftDrawStringUtf8;
-/* register GC xgc = GDK_GC_XGC (gc);
- XSetForeground (xdisplay, xgc, xtext->xft_bg->pixel);
- XFillRectangle (xdisplay, GDK_WINDOW_XWINDOW (xtext->draw_buf), xgc, x,
- y - xtext->font->ascent, str_width, xtext->fontsize);*/
- XftDrawRect (xtext->xftdraw, xtext->xft_bg, x,
- y - xtext->font->ascent, str_width, xtext->fontsize);
- draw_func (xtext->xftdraw, xtext->xft_fg, font, x, y, str, len);
- draw_func (xtext->xftdraw, xtext->xft_fg, font, x, y, str, len);
- draw_func (xtext->xftdraw, xtext->xft_fg, font, x + 1, y, str, len);
-backend_set_clip (GtkXText *xtext, GdkRectangle *area)
- gdk_gc_set_clip_rectangle (xtext->fgc, area);
- gdk_gc_set_clip_rectangle (xtext->bgc, area);
-backend_clear_clip (GtkXText *xtext)
- gdk_gc_set_clip_rectangle (xtext->fgc, NULL);
- gdk_gc_set_clip_rectangle (xtext->bgc, NULL);
-backend_set_clip (GtkXText *xtext, GdkRectangle *area)
- rect.width = area->width;
- rect.height = area->height;
- reg = XCreateRegion ();
- XUnionRectWithRegion (&rect, reg, reg);
- XftDrawSetClip (xtext->xftdraw, reg);
- gdk_gc_set_clip_rectangle (xtext->fgc, area);
-backend_clear_clip (GtkXText *xtext)
- XftDrawSetClip (xtext->xftdraw, NULL);
- gdk_gc_set_clip_rectangle (xtext->fgc, NULL);
-/* ======================================= */
-/* ============ PANGO BACKEND ============ */
-/* ======================================= */
-backend_font_close (GtkXText *xtext)
- pango_font_description_free (xtext->font->font);
- pango_font_description_free (xtext->font->ifont);
-backend_init (GtkXText *xtext)
- if (xtext->layout == NULL)
- xtext->layout = gtk_widget_create_pango_layout (GTK_WIDGET (xtext), 0);
- pango_layout_set_font_description (xtext->layout, xtext->font->font);
-backend_deinit (GtkXText *xtext)
- g_object_unref (xtext->layout);
-static PangoFontDescription *
-backend_font_open_real (char *name)
- PangoFontDescription *font;
- font = pango_font_description_from_string (name);
- if (font && pango_font_description_get_size (font) == 0)
- pango_font_description_free (font);
- font = pango_font_description_from_string ("sans 11");
- font = pango_font_description_from_string ("sans 11");
-backend_font_open (GtkXText *xtext, char *name)
- PangoFontMetrics *metrics;
- xtext->font = &xtext->pango_font;
- xtext->font->font = backend_font_open_real (name);
- if (!xtext->font->font)
- xtext->font->ifont = backend_font_open_real (name);
- pango_font_description_set_style (xtext->font->ifont, PANGO_STYLE_ITALIC);
- pango_layout_set_font_description (xtext->layout, xtext->font->font);
- /* vte does it this way */
- context = gtk_widget_get_pango_context (GTK_WIDGET (xtext));
- lang = pango_context_get_language (context);
- metrics = pango_context_get_metrics (context, xtext->font->font, lang);
- xtext->font->ascent = pango_font_metrics_get_ascent (metrics) / PANGO_SCALE;
- xtext->font->descent = pango_font_metrics_get_descent (metrics) / PANGO_SCALE;
- pango_font_metrics_unref (metrics);
-backend_get_text_width (GtkXText *xtext, guchar *str, int len, int is_mb)
- return gtk_xtext_text_width_8bit (xtext, str, len);
- pango_layout_set_text (xtext->layout, (gchar *)str, len);
- pango_layout_get_pixel_size (xtext->layout, &width, NULL);
-backend_get_char_width (GtkXText *xtext, unsigned char *str, int *mbl_ret)
- return xtext->fontwidth[*str];
- *mbl_ret = charlen (str);
- pango_layout_set_text (xtext->layout, (char *)str, *mbl_ret);
- pango_layout_get_pixel_size (xtext->layout, &width, NULL);
-/* simplified version of gdk_draw_layout_line_with_colors() */
-xtext_draw_layout_line (GdkDrawable *drawable,
- GSList *tmp_list = line->runs;
- PangoRectangle logical_rect;
- PangoLayoutRun *run = tmp_list->data;
- pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
- gdk_draw_glyphs (drawable, gc, run->item->analysis.font,
- x + x_off / PANGO_SCALE, y, run->glyphs);
- x_off += logical_rect.width;
- tmp_list = tmp_list->next;
-backend_draw_text (GtkXText *xtext, int dofill, GdkGC *gc, int x, int y,
- char *str, int len, int str_width, int is_mb)
- pango_layout_set_font_description (xtext->layout, xtext->font->ifont);
- pango_layout_set_text (xtext->layout, str, len);
- if (xtext->transparent && !xtext->backcolor)
- win32_draw_bg (xtext, x, y - xtext->font->ascent, str_width,
- gdk_gc_get_values (gc, &val);
- col.pixel = val.background.pixel;
- gdk_gc_set_foreground (gc, &col);
- gdk_draw_rectangle (xtext->draw_buf, gc, 1, x, y -
- xtext->font->ascent, str_width, xtext->fontsize);
- col.pixel = val.foreground.pixel;
- gdk_gc_set_foreground (gc, &col);
- line = pango_layout_get_lines (xtext->layout)->data;
- xtext_draw_layout_line (xtext->draw_buf, gc, x, y, line);
- xtext_draw_layout_line (xtext->draw_buf, gc, x, y, line);
- xtext_draw_layout_line (xtext->draw_buf, gc, x + 1, y, line);
- pango_layout_set_font_description (xtext->layout, xtext->font->font);
-backend_set_clip (GtkXText *xtext, GdkRectangle *area)
- gdk_gc_set_clip_rectangle (xtext->fgc, area);
- gdk_gc_set_clip_rectangle (xtext->bgc, area);
-backend_clear_clip (GtkXText *xtext)
- gdk_gc_set_clip_rectangle (xtext->fgc, NULL);
- gdk_gc_set_clip_rectangle (xtext->bgc, NULL);
-xtext_set_fg (GtkXText *xtext, GdkGC *gc, int index)
- col.pixel = xtext->palette[index];
- gdk_gc_set_foreground (gc, &col);
- xtext->xft_fg = &xtext->color[index];
- xtext->xft_bg = &xtext->color[index];
-void gtk_xtext_set_foreground_color (GtkXText *xtext, GdkColor *color)
- xtext->palette[XTEXT_FG] = color->pixel;
-void gtk_xtext_set_background_color (GtkXText *xtext, GdkColor *color)
- xtext->palette[XTEXT_BG] = color->pixel;
-#define xtext_set_bg(xt,gc,index) xt->xft_bg = &xt->color[index]
-xtext_set_bg (GtkXText *xtext, GdkGC *gc, int index)
- col.pixel = xtext->palette[index];
- gdk_gc_set_background (gc, &col);
-gtk_xtext_init (GtkXText * xtext)
- xtext->col_back = XTEXT_BG;
- xtext->col_fore = XTEXT_FG;
- xtext->pixel_offset = 0;
- xtext->underline = FALSE;
- xtext->italics = FALSE;
- xtext->jump_out_offset = 0;
- xtext->jump_in_offset = 0;
- xtext->clip_x2 = 1000000;
- xtext->clip_y2 = 1000000;
- xtext->error_function = NULL;
- xtext->urlcheck_function = NULL;
- xtext->color_paste = FALSE;
- xtext->skip_border_fills = FALSE;
- xtext->skip_stamp = FALSE;
- xtext->render_hilights_only = FALSE;
- xtext->un_hilight = FALSE;
- xtext->recycle = FALSE;
- xtext->dont_render = FALSE;
- xtext->dont_render2 = FALSE;
- xtext->overdraw = FALSE;
- xtext->tint_red = xtext->tint_green = xtext->tint_blue = TINT_VALUE;
- xtext->adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 1, 1, 1, 1);
- g_object_ref (G_OBJECT (xtext->adj));
- gtk_object_sink ((GtkObject *) xtext->adj);
- xtext->vc_signal_tag = g_signal_connect (G_OBJECT (xtext->adj),
- "value_changed", G_CALLBACK (gtk_xtext_adjustment_changed), xtext);
- static const GtkTargetEntry targets[] = {
- { "UTF8_STRING", 0, TARGET_UTF8_STRING },
- { "STRING", 0, TARGET_STRING },
- { "TEXT", 0, TARGET_TEXT },
- { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT }
- static const gint n_targets = sizeof (targets) / sizeof (targets[0]);
- gtk_selection_add_targets (GTK_WIDGET (xtext), GDK_SELECTION_PRIMARY,
- if (getenv ("XCHAT_OVERDRAW"))
- xtext->overdraw = TRUE;
-gtk_xtext_adjustment_set (xtext_buffer *buf, int fire_signal)
- GtkAdjustment *adj = buf->xtext->adj;
- if (buf->xtext->buffer == buf)
- adj->upper = buf->num_lines;
- (GTK_WIDGET (buf->xtext)->allocation.height -
- buf->xtext->font->descent) / buf->xtext->fontsize;
- adj->page_increment = adj->page_size;
- if (adj->value > adj->upper - adj->page_size)
- adj->value = adj->upper - adj->page_size;
- gtk_adjustment_changed (adj);
-gtk_xtext_adjustment_timeout (GtkXText * xtext)
- gtk_xtext_render_page (xtext);
-gtk_xtext_adjustment_changed (GtkAdjustment * adj, GtkXText * xtext)
- if (xtext->buffer->old_value != xtext->adj->value)
- if ((int) xtext->buffer->old_value != (int) xtext->adj->value)
- if (xtext->adj->value >= xtext->adj->upper - xtext->adj->page_size)
- xtext->buffer->scrollbar_down = TRUE;
- xtext->buffer->scrollbar_down = FALSE;
- if (xtext->adj->value + 1 == xtext->buffer->old_value ||
- xtext->adj->value - 1 == xtext->buffer->old_value) /* clicked an arrow? */
- g_source_remove (xtext->io_tag);
- gtk_xtext_render_page (xtext);
- xtext->io_tag = g_timeout_add (REFRESH_TIMEOUT,
- gtk_xtext_adjustment_timeout,
- xtext->buffer->old_value = adj->value;
-gtk_xtext_new (GdkColor palette[], int separator)
- xtext = g_object_new (gtk_xtext_get_type (), NULL);
- xtext->separator = separator;
- xtext->wordwrap = TRUE;
- xtext->buffer = gtk_xtext_buffer_new (xtext);
- xtext->orig_buffer = xtext->buffer;
- gtk_widget_set_double_buffered (GTK_WIDGET (xtext), FALSE);
- gtk_xtext_set_palette (xtext, palette);
- return GTK_WIDGET (xtext);
-gtk_xtext_destroy (GtkObject * object)
- GtkXText *xtext = GTK_XTEXT (object);
- g_source_remove (xtext->add_io_tag);
- g_source_remove (xtext->scroll_tag);
- g_source_remove (xtext->io_tag);
-#if defined(USE_XLIB) || defined(WIN32)
- if (xtext->transparent)
- gtk_xtext_free_trans (xtext);
- g_object_unref (xtext->pixmap);
- backend_font_close (xtext);
- g_signal_handlers_disconnect_matched (G_OBJECT (xtext->adj),
- G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, xtext);
- /* gtk_signal_disconnect_by_data (GTK_OBJECT (xtext->adj), xtext);*/
- g_object_unref (G_OBJECT (xtext->adj));
- g_object_unref (xtext->bgc);
- g_object_unref (xtext->fgc);
- g_object_unref (xtext->light_gc);
- xtext->light_gc = NULL;
- g_object_unref (xtext->dark_gc);
- g_object_unref (xtext->thin_gc);
- g_object_unref (xtext->marker_gc);
- xtext->marker_gc = NULL;
- if (xtext->hand_cursor)
- gdk_cursor_unref (xtext->hand_cursor);
- xtext->hand_cursor = NULL;
- if (xtext->resize_cursor)
- gdk_cursor_unref (xtext->resize_cursor);
- xtext->resize_cursor = NULL;
- if (xtext->orig_buffer)
- gtk_xtext_buffer_free (xtext->orig_buffer);
- xtext->orig_buffer = NULL;
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-gtk_xtext_unrealize (GtkWidget * widget)
- backend_deinit (GTK_XTEXT (widget));
- /* if there are still events in the queue, this'll avoid segfault */
- gdk_window_set_user_data (widget->window, NULL);
- if (parent_class->unrealize)
- (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
-gtk_xtext_realize (GtkWidget * widget)
- GdkWindowAttr attributes;
- GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
- xtext = GTK_XTEXT (widget);
- attributes.x = widget->allocation.x;
- attributes.y = widget->allocation.y;
- attributes.width = widget->allocation.width;
- attributes.height = widget->allocation.height;
- attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.event_mask = gtk_widget_get_events (widget) |
- GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- | GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK;
- | GDK_POINTER_MOTION_MASK;
- cmap = gtk_widget_get_colormap (widget);
- attributes.colormap = cmap;
- attributes.visual = gtk_widget_get_visual (widget);
- widget->window = gdk_window_new (widget->parent->window, &attributes,
- GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL |
- gdk_window_set_user_data (widget->window, widget);
- xtext->depth = gdk_drawable_get_visual (widget->window)->depth;
- val.subwindow_mode = GDK_INCLUDE_INFERIORS;
- val.graphics_exposures = 0;
- xtext->bgc = gdk_gc_new_with_values (widget->window, &val,
- GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);
- xtext->fgc = gdk_gc_new_with_values (widget->window, &val,
- GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);
- xtext->light_gc = gdk_gc_new_with_values (widget->window, &val,
- GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);
- xtext->dark_gc = gdk_gc_new_with_values (widget->window, &val,
- GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);
- xtext->thin_gc = gdk_gc_new_with_values (widget->window, &val,
- GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);
- xtext->marker_gc = gdk_gc_new_with_values (widget->window, &val,
- GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);
- /* for the separator bar (light) */
- col.red = 0xffff; col.green = 0xffff; col.blue = 0xffff;
- gdk_colormap_alloc_color (cmap, &col, FALSE, TRUE);
- gdk_gc_set_foreground (xtext->light_gc, &col);
- /* for the separator bar (dark) */
- col.red = 0x1111; col.green = 0x1111; col.blue = 0x1111;
- gdk_colormap_alloc_color (cmap, &col, FALSE, TRUE);
- gdk_gc_set_foreground (xtext->dark_gc, &col);
- /* for the separator bar (thinline) */
- col.red = 0x8e38; col.green = 0x8e38; col.blue = 0x9f38;
- gdk_colormap_alloc_color (cmap, &col, FALSE, TRUE);
- gdk_gc_set_foreground (xtext->thin_gc, &col);
- /* for the marker bar (marker) */
- col.pixel = xtext->palette[XTEXT_MARKER];
- gdk_gc_set_foreground (xtext->marker_gc, &col);
- xtext_set_fg (xtext, xtext->fgc, XTEXT_FG);
- xtext_set_bg (xtext, xtext->fgc, XTEXT_BG);
- xtext_set_fg (xtext, xtext->bgc, XTEXT_BG);
- /* draw directly to window */
- xtext->draw_buf = widget->window;
-#if defined(USE_XLIB) || defined(WIN32)
- if (xtext->transparent)
- gtk_xtext_load_trans (xtext);
- gdk_gc_set_tile (xtext->bgc, xtext->pixmap);
- gdk_gc_set_ts_origin (xtext->bgc, 0, 0);
- xtext->ts_x = xtext->ts_y = 0;
- gdk_gc_set_fill (xtext->bgc, GDK_TILED);
-#if (GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION == 0)
- xtext->hand_cursor = gdk_cursor_new (GDK_HAND1);
- xtext->resize_cursor = gdk_cursor_new (GDK_LEFT_SIDE);
- xtext->hand_cursor = gdk_cursor_new_for_display (gdk_drawable_get_display (widget->window), GDK_HAND1);
- xtext->resize_cursor = gdk_cursor_new_for_display (gdk_drawable_get_display (widget->window), GDK_LEFT_SIDE);
- gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
- widget->style = gtk_style_attach (widget->style, widget->window);
-gtk_xtext_size_request (GtkWidget * widget, GtkRequisition * requisition)
- requisition->width = 200;
- requisition->height = 90;
-gtk_xtext_size_allocate (GtkWidget * widget, GtkAllocation * allocation)
- GtkXText *xtext = GTK_XTEXT (widget);
- int height_only = FALSE;
- if (allocation->width == xtext->buffer->window_width)
- if (allocation->x == widget->allocation.x &&
- allocation->y == widget->allocation.y && xtext->avoid_trans)
- xtext->avoid_trans = FALSE;
- widget->allocation = *allocation;
- if (GTK_WIDGET_REALIZED (widget))
- xtext->buffer->window_width = allocation->width;
- xtext->buffer->window_height = allocation->height;
- gdk_window_move_resize (widget->window, allocation->x, allocation->y,
- allocation->width, allocation->height);
- dontscroll (xtext->buffer); /* force scrolling off */
- gtk_xtext_calc_lines (xtext->buffer, FALSE);
- xtext->buffer->pagetop_ent = NULL;
- gtk_xtext_adjustment_set (xtext->buffer, FALSE);
-#if defined(USE_XLIB) || defined(WIN32)
- if (do_trans && xtext->transparent && xtext->shaded)
- gtk_xtext_free_trans (xtext);
- gtk_xtext_load_trans (xtext);
- if (xtext->buffer->scrollbar_down)
- gtk_adjustment_set_value (xtext->adj, xtext->adj->upper -
- xtext->adj->page_size);
-gtk_xtext_selection_clear_full (xtext_buffer *buf)
- textentry *ent = buf->text_first;
-gtk_xtext_selection_clear (xtext_buffer *buf)
- ent = buf->last_ent_start;
- if (ent->mark_start != -1)
- if (ent == buf->last_ent_end)
-find_x (GtkXText *xtext, textentry *ent, unsigned char *text, int x, int indent)
- unsigned char *orig = text;
- if ((col && isdigit (*text) && nc < 2) ||
- (col && *text == ',' && isdigit (*(text+1)) && nc < 3))
- xx += backend_get_char_width (xtext, text, &mbl);
- return i + (orig - ent->str);
- if (text - orig >= ent->str_len)
-gtk_xtext_find_x (GtkXText * xtext, int x, textentry * ent, int subline,
- int line, int *out_of_bounds)
- indent = xtext->buffer->indent;
- if (line > xtext->adj->page_size || line < 0)
- if (xtext->buffer->grid_dirty || line > 255)
- str = ent->str + gtk_xtext_find_subline (xtext, ent, subline);
- if (str >= ent->str + ent->str_len)
- if (xtext->buffer->grid_offset[line] > ent->str_len)
- str = ent->str + xtext->buffer->grid_offset[line];
- return (str - ent->str);
- return find_x (xtext, ent, str, x, indent);
-gtk_xtext_find_char (GtkXText * xtext, int x, int y, int *off,
- line = (y + xtext->pixel_offset) / xtext->fontsize;
- ent = gtk_xtext_nth (xtext, line + (int)xtext->adj->value, &subline);
- *off = gtk_xtext_find_x (xtext, x, ent, subline, line, out_of_bounds);
-gtk_xtext_draw_sep (GtkXText * xtext, int y)
- height = GTK_WIDGET (xtext)->allocation.height;
- height = xtext->fontsize;
- /* draw the separator line */
- if (xtext->separator && xtext->buffer->indent)
- light = xtext->light_gc;
- x = xtext->buffer->indent - ((xtext->space_width + 1) / 2);
- if (xtext->moving_separator)
- gdk_draw_line (xtext->draw_buf, light, x, y, x, y + height);
- gdk_draw_line (xtext->draw_buf, xtext->thin_gc, x, y, x, y + height);
- if (xtext->moving_separator)
- gdk_draw_line (xtext->draw_buf, light, x - 1, y, x - 1, y + height);
- gdk_draw_line (xtext->draw_buf, dark, x, y, x, y + height);
- gdk_draw_line (xtext->draw_buf, dark, x - 1, y, x - 1, y + height);
- gdk_draw_line (xtext->draw_buf, light, x, y, x, y + height);
-gtk_xtext_draw_marker (GtkXText * xtext, textentry * ent, int y)
- int x, width, render_y;
- if (!xtext->marker) return;
- if (xtext->buffer->marker_pos == ent)
- render_y = y + xtext->font->descent;
- else if (xtext->buffer->marker_pos == ent->next && ent->next != NULL)
- render_y = y + xtext->font->descent + xtext->fontsize * ent->lines_taken;
- width = GTK_WIDGET (xtext)->allocation.width;
- gdk_draw_line (xtext->draw_buf, xtext->marker_gc, x, render_y, x + width, render_y);
-#if GTK_CHECK_VERSION(2,4,0)
- if (gtk_window_has_toplevel_focus (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (xtext)))))
- if (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (xtext)))->has_focus)
- xtext->buffer->marker_seen = TRUE;
-gtk_xtext_paint (GtkWidget *widget, GdkRectangle *area)
- GtkXText *xtext = GTK_XTEXT (widget);
- textentry *ent_start, *ent_end;
-#if defined(USE_XLIB) || defined(WIN32)
- if (xtext->transparent)
- gdk_window_get_origin (widget->window, &x, &y);
- /* update transparency only if it moved */
- if (xtext->last_win_x != x || xtext->last_win_y != y)
-#if !defined(USE_SHM) && !defined(WIN32)
- gtk_xtext_load_trans (xtext);
- xtext->recycle = FALSE;
- gtk_xtext_free_trans (xtext);
- gtk_xtext_load_trans (xtext);
- if (area->x == 0 && area->y == 0 &&
- area->height == widget->allocation.height &&
- area->width == widget->allocation.width)
- dontscroll (xtext->buffer); /* force scrolling off */
- gtk_xtext_render_page (xtext);
- ent_start = gtk_xtext_find_char (xtext, area->x, area->y, NULL, NULL);
- xtext_draw_bg (xtext, area->x, area->y, area->width, area->height);
- ent_end = gtk_xtext_find_char (xtext, area->x + area->width,
- area->y + area->height, NULL, NULL);
- ent_end = xtext->buffer->text_last;
- /* can't set a clip here, because fgc/bgc are used to draw the DB too */
-/* backend_set_clip (xtext, area);*/
- xtext->clip_x = area->x;
- xtext->clip_x2 = area->x + area->width;
- xtext->clip_y = area->y;
- xtext->clip_y2 = area->y + area->height;
- /* y is the last pixel y location it rendered text at */
- y = gtk_xtext_render_ents (xtext, ent_start, ent_end);
- if (y && y < widget->allocation.height && !ent_end->next)
- rect.width = widget->allocation.width;
- rect.height = widget->allocation.height - y;
- /* fill any space below the last line that also intersects with
- the exposure rectangle */
- if (gdk_rectangle_intersect (area, &rect, &rect))
- xtext_draw_bg (xtext, rect.x, rect.y, rect.width, rect.height);
- /*backend_clear_clip (xtext);*/
- xtext->clip_x2 = 1000000;
- xtext->clip_y2 = 1000000;
- x = xtext->buffer->indent - ((xtext->space_width + 1) / 2);
- gtk_xtext_draw_sep (xtext, -1);
-gtk_xtext_expose (GtkWidget * widget, GdkEventExpose * event)
- gtk_xtext_paint (widget, &event->area);
-/* render a selection that has extended or contracted upward */
-gtk_xtext_selection_up (GtkXText *xtext, textentry *start, textentry *end,
- /* render all the complete lines */
- if (start->next == end)
- gtk_xtext_render_ents (xtext, end, NULL);
- gtk_xtext_render_ents (xtext, start->next, end);
- /* now the incomplete upper line */
- if (start == xtext->buffer->last_ent_start)
- xtext->jump_in_offset = xtext->buffer->last_offset_start;
- xtext->jump_in_offset = start_offset;
- gtk_xtext_render_ents (xtext, start, NULL);
- xtext->jump_in_offset = 0;
-/* render a selection that has extended or contracted downward */
-gtk_xtext_selection_down (GtkXText *xtext, textentry *start, textentry *end,
- /* render all the complete lines */
- if (end->prev == start)
- gtk_xtext_render_ents (xtext, start, NULL);
- gtk_xtext_render_ents (xtext, start, end->prev);
- /* now the incomplete bottom line */
- if (end == xtext->buffer->last_ent_end)
- xtext->jump_out_offset = xtext->buffer->last_offset_end;
- xtext->jump_out_offset = end_offset;
- gtk_xtext_render_ents (xtext, end, NULL);
- xtext->jump_out_offset = 0;
-gtk_xtext_selection_render (GtkXText *xtext,
- textentry *start_ent, int start_offset,
- textentry *end_ent, int end_offset)
- xtext->skip_border_fills = TRUE;
- xtext->skip_stamp = TRUE;
- /* force an optimized render if there was no previous selection */
- if (xtext->buffer->last_ent_start == NULL && start_ent == end_ent)
- xtext->buffer->last_offset_start = start_offset;
- xtext->buffer->last_offset_end = end_offset;
- /* mark changed within 1 ent only? */
- if (xtext->buffer->last_ent_start == start_ent &&
- xtext->buffer->last_ent_end == end_ent)
- /* when only 1 end of the selection is changed, we can really
- if (xtext->buffer->last_offset_start == start_offset ||
- xtext->buffer->last_offset_end == end_offset)
- /* figure out where to start and end the rendering */
- if (end_offset > xtext->buffer->last_offset_end)
- start = xtext->buffer->last_offset_end;
- } else if (end_offset < xtext->buffer->last_offset_end)
- end = xtext->buffer->last_offset_end;
- } else if (start_offset < xtext->buffer->last_offset_start)
- end = xtext->buffer->last_offset_start;
- } else if (start_offset > xtext->buffer->last_offset_start)
- start = xtext->buffer->last_offset_start;
- { /* WORD selects end up here */
- /* LINE selects end up here */
- /* so which ent actually changed? */
- if (xtext->buffer->last_offset_start == start_offset)
- end = MAX (xtext->buffer->last_offset_end, end_offset);
- start = MIN (xtext->buffer->last_offset_start, start_offset);
- xtext->jump_out_offset = end;
- xtext->jump_in_offset = start;
- gtk_xtext_render_ents (xtext, ent, NULL);
- xtext->jump_out_offset = 0;
- xtext->jump_in_offset = 0;
- /* marking downward? */
- else if (xtext->buffer->last_ent_start == start_ent &&
- xtext->buffer->last_offset_start == start_offset)
- /* find the range that covers both old and new selection */
- if (ent == xtext->buffer->last_ent_end)
- gtk_xtext_selection_down (xtext, ent, end_ent, end_offset);
- /*gtk_xtext_render_ents (xtext, ent, end_ent);*/
- gtk_xtext_selection_down (xtext, ent, xtext->buffer->last_ent_end, end_offset);
- /*gtk_xtext_render_ents (xtext, ent, xtext->buffer->last_ent_end);*/
- else if (xtext->buffer->last_ent_end == end_ent &&
- xtext->buffer->last_offset_end == end_offset)
- gtk_xtext_selection_up (xtext, xtext->buffer->last_ent_start, ent, start_offset);
- /*gtk_xtext_render_ents (xtext, xtext->buffer->last_ent_start, ent);*/
- if (ent == xtext->buffer->last_ent_start)
- gtk_xtext_selection_up (xtext, start_ent, ent, start_offset);
- /*gtk_xtext_render_ents (xtext, start_ent, ent);*/
- else /* cross-over mark (stretched or shrunk at both ends) */
- /* unrender the old mark */
- gtk_xtext_render_ents (xtext, xtext->buffer->last_ent_start, xtext->buffer->last_ent_end);
- /* now render the new mark, but skip overlaps */
- if (start_ent == xtext->buffer->last_ent_start)
- /* if the new mark is a sub-set of the old, do nothing */
- if (start_ent != end_ent)
- gtk_xtext_render_ents (xtext, start_ent->next, end_ent);
- } else if (end_ent == xtext->buffer->last_ent_end)
- /* if the new mark is a sub-set of the old, do nothing */
- if (start_ent != end_ent)
- gtk_xtext_render_ents (xtext, start_ent, end_ent->prev);
- gtk_xtext_render_ents (xtext, start_ent, end_ent);
- xtext->buffer->last_ent_start = start_ent;
- xtext->buffer->last_ent_end = end_ent;
- xtext->buffer->last_offset_start = start_offset;
- xtext->buffer->last_offset_end = end_offset;
- xtext->skip_border_fills = FALSE;
- xtext->skip_stamp = FALSE;
-gtk_xtext_selection_draw (GtkXText * xtext, GdkEventMotion * event)
- if (xtext->select_start_y > xtext->select_end_y)
- low_x = xtext->select_end_x;
- low_y = xtext->select_end_y;
- high_x = xtext->select_start_x;
- high_y = xtext->select_start_y;
- low_x = xtext->select_start_x;
- low_y = xtext->select_start_y;
- high_x = xtext->select_end_x;
- high_y = xtext->select_end_y;
- ent_start = gtk_xtext_find_char (xtext, low_x, low_y, &offset_start, &tmp);
- if (xtext->adj->value != xtext->buffer->old_value)
- gtk_xtext_render_page (xtext);
- ent_end = gtk_xtext_find_char (xtext, high_x, high_y, &offset_end, &tmp);
- ent_end = xtext->buffer->text_last;
- if (xtext->adj->value != xtext->buffer->old_value)
- gtk_xtext_render_page (xtext);
- offset_end = ent_end->str_len;
- /* marking less than a complete line? */
- /* make sure "start" is smaller than "end" (swap them if need be) */
- if (ent_start == ent_end && offset_start > offset_end)
- offset_start = offset_end;
- /* has the selection changed? Dont render unless necessary */
- if (xtext->buffer->last_ent_start == ent_start &&
- xtext->buffer->last_ent_end == ent_end &&
- xtext->buffer->last_offset_start == offset_start &&
- xtext->buffer->last_offset_end == offset_end)
- /* set all the old mark_ fields to -1 */
- gtk_xtext_selection_clear (xtext->buffer);
- ent_start->mark_start = offset_start;
- ent_start->mark_end = offset_end;
- if (ent_start != ent_end)
- ent_start->mark_end = ent_start->str_len;
- ent_end->mark_start = 0;
- ent_end->mark_end = offset_end;
- /* set all the mark_ fields of the ents within the selection */
- while (ent && ent != ent_end)
- ent->mark_end = ent->str_len;
- gtk_xtext_selection_render (xtext, ent_start, offset_start, ent_end, offset_end);
-gtk_xtext_scrolldown_timeout (GtkXText * xtext)
- gdk_window_get_pointer (GTK_WIDGET (xtext)->window, 0, &p_y, 0);
- gdk_drawable_get_size (GTK_WIDGET (xtext)->window, 0, &win_height);
- if (p_y > win_height &&
- xtext->adj->value < (xtext->adj->upper - xtext->adj->page_size))
- gtk_adjustment_changed (xtext->adj);
- gtk_xtext_render_page (xtext);
-gtk_xtext_scrollup_timeout (GtkXText * xtext)
- gdk_window_get_pointer (GTK_WIDGET (xtext)->window, 0, &p_y, 0);
- if (p_y < 0 && xtext->adj->value > 0.0)
- gtk_adjustment_changed (xtext->adj);
- gtk_xtext_render_page (xtext);
-gtk_xtext_selection_update (GtkXText * xtext, GdkEventMotion * event, int p_y)
- gdk_drawable_get_size (GTK_WIDGET (xtext)->window, 0, &win_height);
- /* selecting past top of window, scroll up! */
- if (p_y < 0 && xtext->adj->value >= 0)
- if (!xtext->scroll_tag)
- xtext->scroll_tag = g_timeout_add (100,
- gtk_xtext_scrollup_timeout,
- /* selecting past bottom of window, scroll down! */
- if (p_y > win_height &&
- xtext->adj->value < (xtext->adj->upper - xtext->adj->page_size))
- if (!xtext->scroll_tag)
- xtext->scroll_tag = g_timeout_add (100,
- gtk_xtext_scrolldown_timeout,
- moved = (int)xtext->adj->value - xtext->select_start_adj;
- xtext->select_start_y -= (moved * xtext->fontsize);
- xtext->select_start_adj = xtext->adj->value;
- gtk_xtext_selection_draw (xtext, event);
-gtk_xtext_get_word (GtkXText * xtext, int x, int y, textentry ** ret_ent,
- int *ret_off, int *ret_len)
- ent = gtk_xtext_find_char (xtext, x, y, &offset, &out_of_bounds);
- if (offset == ent->str_len)
- /*offset--;*/ /* FIXME: not all chars are 1 byte */
- str = ent->str + offset;
- while (!is_del (*str) && str != ent->str)
- while (!is_del (*str) && len != ent->str_len)
- if (len > 0 && word[len-1]=='.')
- *ret_off = word - ent->str;
- return gtk_xtext_strip_color (word, len, xtext->scratch_buffer, NULL, NULL);
-gtk_xtext_unrender_hilight (GtkXText *xtext)
- xtext->render_hilights_only = TRUE;
- xtext->skip_border_fills = TRUE;
- xtext->skip_stamp = TRUE;
- xtext->un_hilight = TRUE;
- gtk_xtext_render_ents (xtext, xtext->hilight_ent, NULL);
- xtext->render_hilights_only = FALSE;
- xtext->skip_border_fills = FALSE;
- xtext->skip_stamp = FALSE;
- xtext->un_hilight = FALSE;
-gtk_xtext_leave_notify (GtkWidget * widget, GdkEventCrossing * event)
- GtkXText *xtext = GTK_XTEXT (widget);
- if (xtext->cursor_hand)
- gtk_xtext_unrender_hilight (xtext);
- xtext->hilight_start = -1;
- xtext->hilight_end = -1;
- xtext->cursor_hand = FALSE;
- gdk_window_set_cursor (widget->window, 0);
- xtext->hilight_ent = NULL;
- if (xtext->cursor_resize)
- gtk_xtext_unrender_hilight (xtext);
- xtext->hilight_start = -1;
- xtext->hilight_end = -1;
- xtext->cursor_resize = FALSE;
- gdk_window_set_cursor (widget->window, 0);
- xtext->hilight_ent = NULL;
-gtk_xtext_motion_notify (GtkWidget * widget, GdkEventMotion * event)
- GtkXText *xtext = GTK_XTEXT (widget);
- int tmp, x, y, offset, len, line_x;
- gdk_window_get_pointer (widget->window, &x, &y, 0);
- if (xtext->moving_separator)
- if (x < (3 * widget->allocation.width) / 5 && x > 15)
- tmp = xtext->buffer->indent;
- xtext->buffer->indent = x;
- gtk_xtext_fix_indent (xtext->buffer);
- if (tmp != xtext->buffer->indent)
- gtk_xtext_recalc_widths (xtext->buffer, FALSE);
- if (xtext->buffer->scrollbar_down)
- gtk_adjustment_set_value (xtext->adj, xtext->adj->upper -
- xtext->adj->page_size);
- xtext->io_tag = g_timeout_add (REFRESH_TIMEOUT,
- gtk_xtext_adjustment_timeout,
- if (xtext->button_down)
- /*gdk_pointer_grab (widget->window, TRUE,
- GDK_BUTTON_RELEASE_MASK |
- GDK_BUTTON_MOTION_MASK, NULL, NULL, 0);*/
- xtext->select_end_x = x;
- xtext->select_end_y = y;
- gtk_xtext_selection_update (xtext, event, y);
- xtext->hilighting = TRUE;
- if (xtext->separator && xtext->buffer->indent)
- line_x = xtext->buffer->indent - ((xtext->space_width + 1) / 2);
- if (line_x == x || line_x == x + 1 || line_x == x - 1)
- if (!xtext->cursor_resize)
- gdk_window_set_cursor (GTK_WIDGET (xtext)->window,
- xtext->cursor_resize = TRUE;
- if (xtext->urlcheck_function == NULL)
- word = gtk_xtext_get_word (xtext, x, y, &word_ent, &offset, &len);
- if (xtext->urlcheck_function (GTK_WIDGET (xtext), word, len) > 0)
- if (!xtext->cursor_hand ||
- xtext->hilight_ent != word_ent ||
- xtext->hilight_start != offset ||
- xtext->hilight_end != offset + len)
- if (!xtext->cursor_hand)
- gdk_window_set_cursor (GTK_WIDGET (xtext)->window,
- xtext->cursor_hand = TRUE;
- /* un-render the old hilight */
- if (xtext->hilight_ent)
- gtk_xtext_unrender_hilight (xtext);
- xtext->hilight_ent = word_ent;
- xtext->hilight_start = offset;
- xtext->hilight_end = offset + len;
- xtext->skip_border_fills = TRUE;
- xtext->render_hilights_only = TRUE;
- xtext->skip_stamp = TRUE;
- gtk_xtext_render_ents (xtext, word_ent, NULL);
- xtext->skip_border_fills = FALSE;
- xtext->render_hilights_only = FALSE;
- xtext->skip_stamp = FALSE;
- gtk_xtext_leave_notify (widget, NULL);
-gtk_xtext_set_clip_owner (GtkWidget * xtext, GdkEventButton * event)
- if (GTK_XTEXT (xtext)->selection_buffer &&
- GTK_XTEXT (xtext)->selection_buffer != GTK_XTEXT (xtext)->buffer)
- gtk_xtext_selection_clear (GTK_XTEXT (xtext)->selection_buffer);
- GTK_XTEXT (xtext)->selection_buffer = GTK_XTEXT (xtext)->buffer;
- str = gtk_xtext_selection_get_text (GTK_XTEXT (xtext), &len);
-#if (GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION == 0)
- gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
- gtk_clipboard_set_text (gtk_widget_get_clipboard (xtext, GDK_SELECTION_CLIPBOARD),
- gtk_selection_owner_set (xtext, GDK_SELECTION_PRIMARY, event->time);
-gtk_xtext_unselect (GtkXText *xtext)
- xtext_buffer *buf = xtext->buffer;
- xtext->skip_border_fills = TRUE;
- xtext->skip_stamp = TRUE;
- xtext->jump_in_offset = buf->last_ent_start->mark_start;
- /* just a single ent was marked? */
- if (buf->last_ent_start == buf->last_ent_end)
- xtext->jump_out_offset = buf->last_ent_start->mark_end;
- buf->last_ent_end = NULL;
- gtk_xtext_selection_clear (xtext->buffer);
- /* FIXME: use jump_out on multi-line selects too! */
- gtk_xtext_render_ents (xtext, buf->last_ent_start, buf->last_ent_end);
- xtext->jump_in_offset = 0;
- xtext->jump_out_offset = 0;
- xtext->skip_border_fills = FALSE;
- xtext->skip_stamp = FALSE;
- xtext->buffer->last_ent_start = NULL;
- xtext->buffer->last_ent_end = NULL;
-gtk_xtext_button_release (GtkWidget * widget, GdkEventButton * event)
- GtkXText *xtext = GTK_XTEXT (widget);
- if (xtext->moving_separator)
- xtext->moving_separator = FALSE;
- old = xtext->buffer->indent;
- if (event->x < (4 * widget->allocation.width) / 5 && event->x > 15)
- xtext->buffer->indent = event->x;
- gtk_xtext_fix_indent (xtext->buffer);
- if (xtext->buffer->indent != old)
- gtk_xtext_recalc_widths (xtext->buffer, FALSE);
- gtk_xtext_adjustment_set (xtext->buffer, TRUE);
- gtk_xtext_render_page (xtext);
- gtk_xtext_draw_sep (xtext, -1);
- if (xtext->word_or_line_select)
- xtext->word_or_line_select = FALSE;
- xtext->button_down = FALSE;
- if (event->button == 1)
- xtext->button_down = FALSE;
- gtk_grab_remove (widget);
- /*gdk_pointer_ungrab (0);*/
- if (xtext->buffer->last_ent_start)
- gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event);
- if (xtext->select_start_x == event->x &&
- xtext->select_start_y == event->y &&
- xtext->buffer->last_ent_start)
- gtk_xtext_unselect (xtext);
- if (!xtext->hilighting)
- word = gtk_xtext_get_word (xtext, event->x, event->y, 0, 0, 0);
- g_signal_emit (G_OBJECT (xtext), xtext_signals[WORD_CLICK], 0, word ? word : NULL, event);
- xtext->hilighting = FALSE;
-gtk_xtext_button_press (GtkWidget * widget, GdkEventButton * event)
- GtkXText *xtext = GTK_XTEXT (widget);
- int line_x, x, y, offset, len;
- gdk_window_get_pointer (widget->window, &x, &y, 0);
- if (event->button == 3 || event->button == 2) /* right/middle click */
- word = gtk_xtext_get_word (xtext, x, y, 0, 0, 0);
- g_signal_emit (G_OBJECT (xtext), xtext_signals[WORD_CLICK], 0,
- g_signal_emit (G_OBJECT (xtext), xtext_signals[WORD_CLICK], 0,
- if (event->button != 1) /* we only want left button */
- if (event->type == GDK_2BUTTON_PRESS) /* WORD select */
- if (gtk_xtext_get_word (xtext, x, y, &ent, &offset, &len))
- gtk_xtext_selection_clear (xtext->buffer);
- ent->mark_start = offset;
- ent->mark_end = offset + len;
- gtk_xtext_selection_render (xtext, ent, offset, ent, offset + len);
- xtext->word_or_line_select = TRUE;
- gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event);
- if (event->type == GDK_3BUTTON_PRESS) /* LINE select */
- if (gtk_xtext_get_word (xtext, x, y, &ent, 0, 0))
- gtk_xtext_selection_clear (xtext->buffer);
- ent->mark_end = ent->str_len;
- gtk_xtext_selection_render (xtext, ent, 0, ent, ent->str_len);
- xtext->word_or_line_select = TRUE;
- gtk_xtext_set_clip_owner (GTK_WIDGET (xtext), event);
- /* check if it was a separator-bar click */
- if (xtext->separator && xtext->buffer->indent)
- line_x = xtext->buffer->indent - ((xtext->space_width + 1) / 2);
- if (line_x == x || line_x == x + 1 || line_x == x - 1)
- xtext->moving_separator = TRUE;
- /* draw the separator line */
- gtk_xtext_draw_sep (xtext, -1);
- xtext->button_down = TRUE;
- xtext->select_start_x = x;
- xtext->select_start_y = y;
- xtext->select_start_adj = xtext->adj->value;
-/* another program has claimed the selection */
-gtk_xtext_selection_kill (GtkXText *xtext, GdkEventSelection *event)
- if (xtext->buffer->last_ent_start)
- gtk_xtext_unselect (xtext);
-gtk_xtext_selection_get_text (GtkXText *xtext, int *len_ret)
- buf = xtext->selection_buffer;
- /* first find out how much we need to malloc ... */
- ent = buf->last_ent_start;
- if (ent->mark_start != -1)
- if (ent->mark_end - ent->mark_start > 0)
- len += (ent->mark_end - ent->mark_start) + 1;
- if (ent == buf->last_ent_end)
- /* now allocate mem and copy buffer */
- pos = txt = malloc (len);
- ent = buf->last_ent_start;
- if (ent->mark_start != -1)
- if (ent->mark_end - ent->mark_start > 0)
- memcpy (pos, ent->str + ent->mark_start,
- ent->mark_end - ent->mark_start);
- pos += ent->mark_end - ent->mark_start;
- if (ent == buf->last_ent_end)
- if (xtext->color_paste)
- stripped = gtk_xtext_strip_color ((unsigned char *)txt, strlen (txt), NULL, &len, 0);
-/* another program is asking for our selection */
-gtk_xtext_selection_get (GtkWidget * widget,
- GtkSelectionData * selection_data_ptr,
- guint info, guint time)
- GtkXText *xtext = GTK_XTEXT (widget);
- stripped = gtk_xtext_selection_get_text (xtext, &len);
- case TARGET_UTF8_STRING:
- /* it's already in utf8 */
- gtk_selection_data_set_text (selection_data_ptr, stripped, len);
- case TARGET_COMPOUND_TEXT:
-#if (GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION == 0)
- gdk_string_to_compound_text (
- gdk_string_to_compound_text_for_display (
- gdk_drawable_get_display (widget->window),
- stripped, &encoding, &format, &new_text,
- gtk_selection_data_set (selection_data_ptr, encoding, format,
- gdk_free_compound_text (new_text);
- new_text =(guchar *) g_locale_from_utf8 (stripped, len, NULL, &glen, NULL);
- gtk_selection_data_set (selection_data_ptr, GDK_SELECTION_TYPE_STRING,
-gtk_xtext_scroll (GtkWidget *widget, GdkEventScroll *event)
- GtkXText *xtext = GTK_XTEXT (widget);
- if (event->direction == GDK_SCROLL_UP) /* mouse wheel pageUp */
- new_value = xtext->adj->value - (xtext->adj->page_increment / 10);
- if (new_value < xtext->adj->lower)
- new_value = xtext->adj->lower;
- gtk_adjustment_set_value (xtext->adj, new_value);
- else if (event->direction == GDK_SCROLL_DOWN) /* mouse wheel pageDn */
- new_value = xtext->adj->value + (xtext->adj->page_increment / 10);
- if (new_value > (xtext->adj->upper - xtext->adj->page_size))
- new_value = xtext->adj->upper - xtext->adj->page_size;
- gtk_adjustment_set_value (xtext->adj, new_value);
-gtk_xtext_class_init (GtkXTextClass * class)
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
- GtkXTextClass *xtext_class;
- object_class = (GtkObjectClass *) class;
- widget_class = (GtkWidgetClass *) class;
- xtext_class = (GtkXTextClass *) class;
- parent_class = gtk_type_class (gtk_widget_get_type ());
- xtext_signals[WORD_CLICK] =
- g_signal_new ("word_click",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (GtkXTextClass, word_click),
- gtk_marshal_VOID__POINTER_POINTER,
- 2, G_TYPE_POINTER, G_TYPE_POINTER);
- object_class->destroy = gtk_xtext_destroy;
- widget_class->realize = gtk_xtext_realize;
- widget_class->unrealize = gtk_xtext_unrealize;
- widget_class->size_request = gtk_xtext_size_request;
- widget_class->size_allocate = gtk_xtext_size_allocate;
- widget_class->button_press_event = gtk_xtext_button_press;
- widget_class->button_release_event = gtk_xtext_button_release;
- widget_class->motion_notify_event = gtk_xtext_motion_notify;
- widget_class->selection_clear_event = (void *)gtk_xtext_selection_kill;
- widget_class->selection_get = gtk_xtext_selection_get;
- widget_class->expose_event = gtk_xtext_expose;
- widget_class->scroll_event = gtk_xtext_scroll;
- widget_class->leave_notify_event = gtk_xtext_leave_notify;
- xtext_class->word_click = NULL;
-gtk_xtext_get_type (void)
- static GtkType xtext_type = 0;
- static const GTypeInfo xtext_info =
- sizeof (GtkXTextClass),
- NULL, /* base_finalize */
- (GClassInitFunc) gtk_xtext_class_init,
- NULL, /* class_finalize */
- (GInstanceInitFunc) gtk_xtext_init,
- xtext_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkXText",
-/* strip MIRC colors and other attribs. */
-gtk_xtext_strip_color (unsigned char *text, int len, unsigned char *outbuf,
- int *newlen, int *mb_ret)
- unsigned char *new_str;
- new_str = malloc (len + 2);
- if ((col && isdigit (*text) && nc < 2) ||
- (col && *text == ',' && isdigit (*(text+1)) && nc < 3))
- return (char *)new_str;
-/* gives width of a string, excluding the mIRC codes */
-gtk_xtext_text_width (GtkXText *xtext, unsigned char *text, int len,
- unsigned char *new_buf;
- new_buf = (unsigned char *)gtk_xtext_strip_color (text, len, xtext->scratch_buffer,
- return backend_get_text_width (xtext, new_buf, new_len, mb);
-/* actually draw text to screen (one run with the same color/attribs) */
-gtk_xtext_render_flush (GtkXText * xtext, int x, int y, unsigned char *str,
- int len, GdkGC *gc, int is_mb)
- GdkDrawable *pix = NULL;
- int dest_x = 0, dest_y = 0;
- if (xtext->dont_render || len < 1)
- str_width = backend_get_text_width (xtext, str, len, is_mb);
- if (xtext->dont_render2)
- /* roll-your-own clipping (avoiding XftDrawString is always good!) */
- if (x > xtext->clip_x2 || x + str_width < xtext->clip_x)
- if (y - xtext->font->ascent > xtext->clip_y2 || (y - xtext->font->ascent) + xtext->fontsize < xtext->clip_y)
- if (xtext->render_hilights_only)
- if (!xtext->in_hilight) /* is it a hilight prefix? */
- if (!xtext->un_hilight) /* doing a hilight? no need to draw the text */
- if (!xtext->transparent)
- pix = gdk_pixmap_new (xtext->draw_buf, str_width, xtext->fontsize, xtext->depth);
- XftDrawChange (xtext->xftdraw, GDK_WINDOW_XWINDOW (pix));
- dest_y = y - xtext->font->ascent;
- gdk_gc_set_ts_origin (xtext->bgc, xtext->ts_x - x, xtext->ts_y - dest_y);
- y = xtext->font->ascent;
- /* backcolor is always handled by XDrawImageString */
- if (!xtext->backcolor && xtext->pixmap)
- /* draw the background pixmap behind the text - CAUSES FLICKER HERE!! */
- xtext_draw_bg (xtext, x, y - xtext->font->ascent, str_width,
- dofill = FALSE; /* already drawn the background */
- backend_draw_text (xtext, dofill, gc, x, y, (char *)str, len, str_width, is_mb);
- gdk_gc_set_ts_origin (xtext->bgc, xtext->ts_x, xtext->ts_y);
- xtext->draw_buf = GTK_WIDGET (xtext)->window;
- XftDrawChange (xtext->xftdraw, GDK_WINDOW_XWINDOW (xtext->draw_buf));
- gdk_draw_drawable (xtext->draw_buf, xtext->bgc, pix, 0, 0, dest_x,
- dest_y, str_width, xtext->fontsize);
- clip.x = xtext->clip_x;
- clip.y = xtext->clip_y;
- clip.width = xtext->clip_x2 - xtext->clip_x;
- clip.height = xtext->clip_y2 - xtext->clip_y;
- dest.width = str_width;
- dest.height = xtext->fontsize;
- if (gdk_rectangle_intersect (&clip, &dest, &dest))
- /* dump the DB to window, but only within the clip_x/x2/y/y2 */
- gdk_draw_drawable (xtext->draw_buf, xtext->bgc, pix,
- dest.x - dest_x, dest.y - dest_y,
- dest.x, dest.y, dest.width, dest.height);
- col.pixel = xtext->xft_fg->pixel;
- gdk_gc_set_foreground (gc, &col);
- y = dest_y + xtext->font->ascent + 1;
- /* draw directly to window, it's out of the range of our DB */
- gdk_draw_line (xtext->draw_buf, gc, dest_x, y, dest_x + str_width - 1, y);
-gtk_xtext_reset (GtkXText * xtext, int mark, int attribs)
- xtext->underline = FALSE;
- xtext->italics = FALSE;
- xtext->backcolor = FALSE;
- if (xtext->col_fore != XTEXT_FG)
- xtext_set_fg (xtext, xtext->fgc, XTEXT_FG);
- if (xtext->col_back != XTEXT_BG)
- xtext_set_bg (xtext, xtext->fgc, XTEXT_BG);
- xtext->col_fore = XTEXT_FG;
- xtext->col_back = XTEXT_BG;
- xtext->parsing_color = FALSE;
- xtext->parsing_backcolor = FALSE;
-/* render a single line, which WONT wrap, and parse mIRC colors */
-gtk_xtext_render_str (GtkXText * xtext, int y, textentry * ent,
- unsigned char *str, int len, int win_width, int indent,
- int line, int left_only)
- int i = 0, x = indent, j = 0;
- unsigned char *pstr = str;
- xtext->in_hilight = FALSE;
- offset = str - ent->str;
- if (line < 255 && line >= 0)
- xtext->buffer->grid_offset[line] = offset;
- gc = xtext->fgc; /* our foreground GC */
- if (ent->mark_start != -1 &&
- ent->mark_start <= i + offset && ent->mark_end > i + offset)
- xtext_set_bg (xtext, gc, XTEXT_MARK_BG);
- xtext_set_fg (xtext, gc, XTEXT_MARK_FG);
- xtext->backcolor = TRUE;
- if (xtext->hilight_ent == ent &&
- xtext->hilight_start <= i + offset && xtext->hilight_end > i + offset)
- if (!xtext->un_hilight)
- xtext_set_bg (xtext, gc, 2);
- xtext->underline = TRUE;
- xtext->in_hilight = TRUE;
- if (!xtext->skip_border_fills && !xtext->dont_render)
- /* draw background to the left of the text */
- if (str == ent->str && indent > MARGIN && xtext->buffer->time_stamp)
- /* don't overwrite the timestamp */
- if (indent > xtext->stamp_width)
- xtext_draw_bg (xtext, xtext->stamp_width, y - xtext->font->ascent,
- indent - xtext->stamp_width, xtext->fontsize);
- /* fill the indent area with background gc */
- if (indent >= xtext->clip_x)
- xtext_draw_bg (xtext, 0, y - xtext->font->ascent,
- MIN (indent, xtext->clip_x2), xtext->fontsize);
- if (xtext->jump_in_offset > 0 && offset < xtext->jump_in_offset)
- xtext->dont_render2 = TRUE;
- if (xtext->hilight_ent == ent && xtext->hilight_start == (i + offset))
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- if (!xtext->un_hilight)
- xtext_set_bg (xtext, gc, 2);
- xtext->underline = TRUE;
- xtext->in_hilight = TRUE;
- if ((xtext->parsing_color && isdigit (str[i]) && xtext->nc < 2) ||
- (xtext->parsing_color && str[i] == ',' && isdigit (str[i+1]) && xtext->nc < 3))
- xtext->parsing_backcolor = TRUE;
- xtext->num[xtext->nc] = 0;
- col_num = atoi (xtext->num);
- if (col_num == 99) /* mIRC lameness */
- col_num = col_num % XTEXT_MIRC_COLS;
- xtext->col_fore = col_num;
- /*xtext_set_fg (xtext, gc, col_num);*/
- xtext->num[xtext->nc] = str[i];
- if (xtext->parsing_color)
- xtext->parsing_color = FALSE;
- xtext->num[xtext->nc] = 0;
- col_num = atoi (xtext->num);
- if (xtext->parsing_backcolor)
- if (col_num == 99) /* mIRC lameness */
- col_num = col_num % XTEXT_MIRC_COLS;
- if (col_num == XTEXT_BG)
- xtext->backcolor = FALSE;
- xtext->backcolor = TRUE;
- /*xtext_set_bg (xtext, gc, col_num);*/
- /*xtext->col_back = col_num;*/
- if (col_num == 99) /* mIRC lameness */
- col_num = col_num % XTEXT_MIRC_COLS;
- /*xtext_set_fg (xtext, gc, col_num);*/
- /*xtext->col_fore = col_num;*/
- xtext->parsing_backcolor = FALSE;
- /* got a \003<non-digit>... i.e. reset colors */
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- /*gtk_xtext_reset (xtext, mark, FALSE);*/
- if (offset +i < ent->left_len)
- GdkColor temp = {ent->left_color, 0, 0, 0};
- gdk_gc_set_foreground(xtext->fgc, &temp);
- GdkColor temp = {ent->right_color, 0, 0, 0};
- gdk_gc_set_foreground(xtext->fgc, &temp);
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext->col_fore = xtext->col_back;
- xtext_set_fg (xtext, gc, xtext->col_fore);
- xtext_set_bg (xtext, gc, xtext->col_back);
- if (xtext->col_back != XTEXT_BG)
- xtext->backcolor = TRUE;
- xtext->backcolor = FALSE;
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext->bold = !xtext->bold;
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext->underline = !xtext->underline;
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext->italics = !xtext->italics;
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- gtk_xtext_reset (xtext, mark, !xtext->in_hilight);
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext->parsing_color = TRUE;
- tmp = charlen (str + i);
- /* invalid utf8 safe guard */
- j += tmp; /* move to the next utf8 char */
- i += charlen (str + i); /* move to the next utf8 char */
- /* invalid utf8 safe guard */
- /* Separate the left part, the space and the right part
- into separate runs, and reset bidi state inbetween.
- Perform this only on the first line of the message.
- /* we've reached the end of the left part? */
- if (((pstr-str)+j == ent->left_len) || ((pstr-str)+j == ent->left_len+1))
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- /*xtext_set_bg(xtext, gc, XTEXT_FG);*/
- /*xtext_set_fg(xtext, gc, XTEXT_BG);*/
- /* have we been told to stop rendering at this point? */
- if (xtext->jump_out_offset > 0 && xtext->jump_out_offset <= (i + offset))
- gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- ret = 0; /* skip the rest of the lines, we're done. */
- if (xtext->jump_in_offset > 0 && xtext->jump_in_offset == (i + offset))
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext->dont_render2 = FALSE;
- if (xtext->hilight_ent == ent && xtext->hilight_end == (i + offset))
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext_set_bg (xtext, gc, XTEXT_MARK_BG);
- xtext->backcolor = TRUE;
- xtext_set_bg (xtext, gc, xtext->col_back);
- if (xtext->col_back != XTEXT_BG)
- xtext->backcolor = TRUE;
- xtext->backcolor = FALSE;
- xtext->underline = FALSE;
- xtext->in_hilight = FALSE;
- if (xtext->render_hilights_only)
- /* stop drawing this ent */
- if (!mark && ent->mark_start == (i + offset))
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext_set_bg (xtext, gc, XTEXT_MARK_BG);
- xtext_set_fg (xtext, gc, XTEXT_MARK_FG);
- xtext->backcolor = TRUE;
- if (mark && ent->mark_end == (i + offset))
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext_set_bg (xtext, gc, xtext->col_back);
- xtext_set_fg (xtext, gc, xtext->col_fore);
- if (xtext->col_back != XTEXT_BG)
- xtext->backcolor = TRUE;
- xtext->backcolor = FALSE;
- x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb);
- xtext_set_bg (xtext, gc, xtext->col_back);
- xtext_set_fg (xtext, gc, xtext->col_fore);
- if (xtext->col_back != XTEXT_BG)
- xtext->backcolor = TRUE;
- xtext->backcolor = FALSE;
- /* draw background to the right of the text */
- if (!left_only && !xtext->dont_render)
- /* draw separator now so it doesn't appear to flicker */
- gtk_xtext_draw_sep (xtext, y - xtext->font->ascent);
- if (!xtext->skip_border_fills && xtext->clip_x2 >= x)
- int xx = MAX (x, xtext->clip_x);
- y - xtext->font->ascent, /* y */
- MIN (xtext->clip_x2 - xx, (win_width + MARGIN) - xx), /* width */
- xtext->fontsize); /* height */
- xtext->dont_render2 = FALSE;
-/* get the desktop/root window */
-static Window desktop_window = None;
-get_desktop_window (Display *xdisplay, Window the_window)
- unsigned long length, after;
- unsigned int nchildren;
- Window w, root, *children, parent;
- prop = XInternAtom (xdisplay, "_XROOTPMAP_ID", True);
- prop = XInternAtom (xdisplay, "_XROOTCOLOR_PIXEL", True);
- for (w = the_window; w; w = parent)
- if ((XQueryTree (xdisplay, w, &root, &parent, &children,
- XGetWindowProperty (xdisplay, w, prop, 0L, 1L, False,
- AnyPropertyType, &type, &format, &length, &after,
- return (desktop_window = w);
- return (desktop_window = None);
-/* find the root window (backdrop) Pixmap */
-get_pixmap_prop (Display *xdisplay, Window the_window)
- unsigned long length, after;
- static Atom prop = None;
- if (desktop_window == None)
- desktop_window = get_desktop_window (xdisplay, the_window);
- if (desktop_window == None)
- desktop_window = DefaultRootWindow (xdisplay);
- prop = XInternAtom (xdisplay, "_XROOTPMAP_ID", True);
- XGetWindowProperty (xdisplay, desktop_window, prop, 0L, 1L, False,
- AnyPropertyType, &type, &format, &length, &after,
- pix = *((Pixmap *) data);
-/* slow generic routine, for the depths/bpp we don't know about */
-shade_ximage_generic (GdkVisual *visual, XImage *ximg, int bpl, int w, int h, int rm, int gm, int bm, int bg)
- int bgr = (256 - rm) * (bg & visual->red_mask);
- int bgg = (256 - gm) * (bg & visual->green_mask);
- int bgb = (256 - bm) * (bg & visual->blue_mask);
- for (x = 0; x < w; x++)
- for (y = 0; y < h; y++)
- unsigned long pixel = XGetPixel (ximg, x, y);
- r = rm * (pixel & visual->red_mask) + bgr;
- g = gm * (pixel & visual->green_mask) + bgg;
- b = bm * (pixel & visual->blue_mask) + bgb;
- ((r >> 8) & visual->red_mask) |
- ((g >> 8) & visual->green_mask) |
- ((b >> 8) & visual->blue_mask));
-/* Fast shading routine. Based on code by Willem Monsuwe <willem@stack.nl> */
-#define SHADE_IMAGE(bytes, type, rmask, gmask, bmask) \
- int bgr = (256 - rm) * (bg & rmask); \
- int bgg = (256 - gm) * (bg & gmask); \
- int bgb = (256 - bm) * (bg & bmask); \
- ptr = (unsigned char *) data + (w * bytes); \
- for (y = h; --y >= 0;) \
- for (x = -w; x < 0; x++) \
- b = ((type *) ptr)[x]; \
- r = rm * (b & rmask) + bgr; \
- g = gm * (b & gmask) + bgg; \
- b = bm * (b & bmask) + bgb; \
- ((type *) ptr)[x] = ((r >> 8) & rmask) \
- | ((b >> 8) & bmask); \
-shade_ximage_15 (void *data, int bpl, int w, int h, int rm, int gm, int bm, int bg)
- SHADE_IMAGE (2, guint16, 0x7c00, 0x3e0, 0x1f);
-shade_ximage_16 (void *data, int bpl, int w, int h, int rm, int gm, int bm, int bg)
- SHADE_IMAGE (2, guint16, 0xf800, 0x7e0, 0x1f);
-shade_ximage_24 (void *data, int bpl, int w, int h, int rm, int gm, int bm, int bg)
- /* 24 has to be a special case, there's no guint24, or 24bit MOV :) */
- int bgr = (256 - rm) * ((bg & 0xff0000) >> 16);
- int bgg = (256 - gm) * ((bg & 0xff00) >> 8);
- int bgb = (256 - bm) * (bg & 0xff);
- ptr = (unsigned char *) data + (w * 3);
- for (x = -(w * 3); x < 0; x += 3)
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
- r = (ptr[x + 0] * rm + bgr) >> 8;
- g = (ptr[x + 1] * gm + bgg) >> 8;
- b = (ptr[x + 2] * bm + bgb) >> 8;
- r = (ptr[x + 2] * rm + bgr) >> 8;
- g = (ptr[x + 1] * gm + bgg) >> 8;
- b = (ptr[x + 0] * bm + bgb) >> 8;
-shade_ximage_32 (void *data, int bpl, int w, int h, int rm, int gm, int bm, int bg)
- SHADE_IMAGE (4, guint32, 0xff0000, 0xff00, 0xff);
-shade_image (GdkVisual *visual, void *data, int bpl, int bpp, int w, int h,
- int rm, int gm, int bm, int bg, int depth)
- bg_r = bg & visual->red_mask;
- bg_g = bg & visual->green_mask;
- bg_b = bg & visual->blue_mask;
- /* the MMX routines are about 50% faster at 16-bit. */
- /* only use MMX routines with a pure black background */
- if (bg_r == 0 && bg_g == 0 && bg_b == 0 && have_mmx ()) /* do a runtime check too! */
- shade_ximage_15_mmx (data, bpl, w, h, rm, gm, bm);
- shade_ximage_16_mmx (data, bpl, w, h, rm, gm, bm);
- shade_ximage_32_mmx (data, bpl, w, h, rm, gm, bm);
- shade_ximage_15 (data, bpl, w, h, rm, gm, bm, bg);
- shade_ximage_16 (data, bpl, w, h, rm, gm, bm, bg);
- shade_ximage_24 (data, bpl, w, h, rm, gm, bm, bg);
- shade_ximage_32 (data, bpl, w, h, rm, gm, bm, bg);
-get_shm_image (Display *xdisplay, XShmSegmentInfo *shminfo, int x, int y,
- int w, int h, int depth, Pixmap pix)
- shminfo->shmaddr = (char*) -1;
- ximg = XShmCreateImage (xdisplay, 0, depth, ZPixmap, 0, shminfo, w, h);
- shminfo->shmid = shmget (IPC_PRIVATE, ximg->bytes_per_line * ximg->height,
- if (shminfo->shmid == -1)
- shminfo->readOnly = False;
- ximg->data = shminfo->shmaddr = (char *)shmat (shminfo->shmid, 0, 0);
- if (shminfo->shmaddr == ((char *)-1))
- shmctl (shminfo->shmid, IPC_RMID, 0);
- XShmAttach (xdisplay, shminfo);
- XSync (xdisplay, False);
- shmctl (shminfo->shmid, IPC_RMID, 0);
- XShmGetImage (xdisplay, pix, ximg, x, y, AllPlanes);
-get_image (GtkXText *xtext, Display *xdisplay, XShmSegmentInfo *shminfo,
- int x, int y, int w, int h, int depth, Pixmap pix)
- ximg = get_shm_image (xdisplay, shminfo, x, y, w, h, depth, pix);
- ximg = XGetImage (xdisplay, pix, x, y, w, h, -1, ZPixmap);
-shade_pixmap (GtkXText * xtext, Pixmap p, int x, int y, int w, int h)
- unsigned int width, height, depth, udummy;
- Display *xdisplay = GDK_WINDOW_XDISPLAY (xtext->draw_buf);
- XGetGeometry (xdisplay, p, &root, &dummy, &dummy, &width, &height,
- if (width < x + w || height < y + h || x < 0 || y < 0)
- gcv.subwindow_mode = IncludeInferiors;
- gcv.graphics_exposures = False;
- tgc = XCreateGC (xdisplay, p, GCGraphicsExposures|GCSubwindowMode,
- tmp = XCreatePixmap (xdisplay, p, w, h, depth);
- XSetTile (xdisplay, tgc, p);
- XSetFillStyle (xdisplay, tgc, FillTiled);
- XSetTSOrigin (xdisplay, tgc, -x, -y);
- XFillRectangle (xdisplay, tmp, tgc, 0, 0, w, h);
- XFreeGC (xdisplay, tgc);
- ximg = get_image (xtext, xdisplay, &xtext->shminfo, 0, 0, w, h, depth, tmp);
- ximg = XGetImage (xdisplay, tmp, 0, 0, w, h, -1, ZPixmap);
- XFreePixmap (xdisplay, tmp);
- ximg = get_image (xtext, xdisplay, &xtext->shminfo, x, y, w, h, depth, p);
- ximg = XGetImage (xdisplay, p, x, y, w, h, -1, ZPixmap);
- shade_ximage_generic (gdk_drawable_get_visual (GTK_WIDGET (xtext)->window),
- ximg, ximg->bytes_per_line, w, h, xtext->tint_red,
- xtext->tint_green, xtext->tint_blue,
- xtext->palette[XTEXT_BG]);
- shade_image (gdk_drawable_get_visual (GTK_WIDGET (xtext)->window),
- ximg->data, ximg->bytes_per_line, ximg->bits_per_pixel,
- w, h, xtext->tint_red, xtext->tint_green, xtext->tint_blue,
- xtext->palette[XTEXT_BG], depth);
- shaded_pix = xtext->pixmap;
-#if (GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION == 0)
- shaded_pix = gdk_pixmap_foreign_new (
- XShmCreatePixmap (xdisplay, p, ximg->data, &xtext->shminfo, w, h, depth));
- shaded_pix = gdk_pixmap_foreign_new_for_display (
- gdk_drawable_get_display (xtext->draw_buf),
- XShmCreatePixmap (xdisplay, p, ximg->data, &xtext->shminfo, w, h, depth));
- shaded_pix = gdk_pixmap_new (GTK_WIDGET (xtext)->window, w, h, depth);
- XPutImage (xdisplay, GDK_WINDOW_XWINDOW (shaded_pix),
- GDK_GC_XGC (xtext->fgc), ximg, 0, 0, 0, 0, w, h);
-/* free transparency xtext->pixmap */
-#if defined(USE_XLIB) || defined(WIN32)
-gtk_xtext_free_trans (GtkXText * xtext)
- XFreePixmap (GDK_WINDOW_XDISPLAY (xtext->pixmap),
- GDK_WINDOW_XWINDOW (xtext->pixmap));
- XShmDetach (GDK_WINDOW_XDISPLAY (xtext->draw_buf), &xtext->shminfo);
- shmdt (xtext->shminfo.shmaddr);
- g_object_unref (xtext->pixmap);
-win32_tint (GtkXText *xtext, GdkImage *img, int width, int height)
- GdkVisual *visual = gdk_drawable_get_visual (GTK_WIDGET (xtext)->window);
- /* slow generic routine */
- for (y = 0; y < height; y++)
- for (x = 0; x < width; x++)
- pixel = (((guchar *) img->mem)[y * img->bpl + (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0;
- pixelp = (guchar *) img->mem + y * img->bpl + (x >> 1);
- pixel = (*pixelp) & 0x0F;
- pixel = (*pixelp) >> 4;
- pixelp = (guchar *) img->mem + y * img->bpl + x * img->bpp;
- pixel = *pixelp; break;
- /* Windows is always LSB, no need to check img->byte_order. */
- pixel = pixelp[0] | (pixelp[1] << 8); break;
- pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16); break;
- pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16); break;
- r = (pixel & visual->red_mask) >> visual->red_shift;
- g = (pixel & visual->green_mask) >> visual->green_shift;
- b = (pixel & visual->blue_mask) >> visual->blue_shift;
- /* actual tinting is only these 3 lines */
- pixel = ((r * xtext->tint_red) >> 8) << visual->red_shift |
- ((g * xtext->tint_green) >> 8) << visual->green_shift |
- ((b * xtext->tint_blue) >> 8) << visual->blue_shift;
- ((guchar *) img->mem)[y * img->bpl + (x >> 3)] |= (1 << (7 - (x & 0x7)));
- ((guchar *) img->mem)[y * img->bpl + (x >> 3)] &= ~(1 << (7 - (x & 0x7)));
- else if (img->depth == 4)
- pixelp = (guchar *) img->mem + y * img->bpl + (x >> 1);
- *pixelp |= (pixel & 0x0F);
- *pixelp |= (pixel << 4);
- pixelp = (guchar *) img->mem + y * img->bpl + x * img->bpp;
- /* Windows is always LSB, no need to check img->byte_order. */
- pixelp[2] = ((pixel >> 16) & 0xFF);
- pixelp[1] = ((pixel >> 8) & 0xFF);
- pixelp[0] = (pixel & 0xFF);
- shade_image (visual, img->mem, img->bpl, img->bpp, width, height,
- xtext->tint_red, xtext->tint_green, xtext->tint_blue,
- xtext->palette[XTEXT_BG], visual->depth);
- /* no need to dump it to a Pixmap, it's one and the same on win32 */
- pix = (GdkPixmap *)img;
-/* grab pixmap from root window and set xtext->pixmap */
-#if defined(USE_XLIB) || defined(WIN32)
-gtk_xtext_load_trans (GtkXText * xtext)
- /* if not shaded, we paint directly with PaintDesktop() */
- hwnd = GDK_WINDOW_HWND (GTK_WIDGET (xtext)->window);
- gdk_window_get_size (GTK_WIDGET (xtext)->window, &width, &height);
- img = gdk_image_get (GTK_WIDGET (xtext)->window, 0, 0, width+128, height);
- xtext->pixmap = win32_tint (xtext, img, img->width, img->height);
- GtkWidget *widget = GTK_WIDGET (xtext);
- rootpix = get_pixmap_prop (GDK_WINDOW_XDISPLAY (widget->window), GDK_WINDOW_XWINDOW (widget->window));
- if (xtext->error_function)
- xtext->error_function (0);
- xtext->transparent = FALSE;
- gdk_window_get_origin (widget->window, &x, &y);
- gdk_drawable_get_size (GTK_WIDGET (xtext)->window, &width, &height);
- xtext->pixmap = shade_pixmap (xtext, rootpix, x, y, width+105, height);
- if (xtext->pixmap == NULL)
- gdk_gc_set_tile (xtext->bgc, xtext->pixmap);
- gdk_gc_set_ts_origin (xtext->bgc, 0, 0);
- xtext->ts_x = xtext->ts_y = 0;
-#if (GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION == 0)
- xtext->pixmap = gdk_pixmap_foreign_new (rootpix);
- xtext->pixmap = gdk_pixmap_foreign_new_for_display (gdk_drawable_get_display (GTK_WIDGET (xtext)->window), rootpix);
- gdk_gc_set_tile (xtext->bgc, xtext->pixmap);
- gdk_gc_set_ts_origin (xtext->bgc, -x, -y);
- gdk_gc_set_fill (xtext->bgc, GDK_TILED);
-#endif /* ! XLIB || WIN32 */
-/* walk through str until this line doesn't fit anymore */
-find_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;
- if (win_width >= ent->str_width + ent->indent)
- ret = ent->str_len - (str - ent->str);
- if ((col && isdigit (*str) && nc < 2) ||
- (col && *str == ',' && isdigit (*(str+1)) && nc < 3))
- str_width += backend_get_char_width (xtext, str, &mbl);
- if (str_width > win_width)
- if (str - last_space > WORDWRAP_LIMIT + limit_offset)
- ret = str - orig_str; /* fall back to character wrap */
- if (*last_space == ' ')
- ret = last_space - orig_str;
- if (ret == 0) /* fall back to character wrap */
- /* keep a record of the last space, for wordwrapping */
- /* progress to the next char */
- if (str >= ent->str + ent->str_len)
- /* must make progress */
-/* find the offset, in bytes, that wrap number 'line' starts at */
-gtk_xtext_find_subline (GtkXText *xtext, textentry *ent, int line)
- int indent, str_pos, line_pos, len;
- if (ent->lines_taken < 2 || line < 1)
- /* we record the first 4 lines' wraps, so take a shortcut */
- if (line <= RECORD_WRAPS)
- return ent->wrap_offset[line - 1];
- gdk_drawable_get_size (GTK_WIDGET (xtext)->window, &win_width, 0);
-/* indent = ent->indent;
- line_pos = str_pos = 0;*/
- /* start from the last recorded wrap, and move forward */
- indent = xtext->buffer->indent;
- str_pos = ent->wrap_offset[RECORD_WRAPS-1];
- str = str_pos + ent->str;
- line_pos = RECORD_WRAPS;
- len = find_next_wrap (xtext, ent, str, win_width, indent);
- indent = xtext->buffer->indent;
- while (str < ent->str + ent->str_len);
-/* render a single line, which may wrap to more lines */
-gtk_xtext_render_line (GtkXText * xtext, textentry * ent, int line,
- int lines_max, int subline, int win_width)
- int indent, taken, entline, len, y, start_subline;
- start_subline = subline;
- /* draw the timestamp */
- if (xtext->auto_indent && xtext->buffer->time_stamp && !xtext->skip_stamp)
- int stamp_size = xtext_get_stamp_str (ent->stamp, &time_str);
- y = (xtext->fontsize * line) + xtext->font->ascent - xtext->pixel_offset;
- /* XXX: Set up the color here first? */
- gtk_xtext_render_str (xtext, y, ent, time_str, stamp_size,
- win_width, 2, line, TRUE);
- /* draw each line one by one */
- /* if it's one of the first 4 wraps, we don't need to calculate it, it's
- recorded in ->wrap_offset. This saves us a loop. */
- if (entline < RECORD_WRAPS)
- if (ent->lines_taken < 2)
- len = ent->wrap_offset[entline] - ent->wrap_offset[entline-1];
- len = ent->wrap_offset[0];
- len = find_next_wrap (xtext, ent, str, win_width, indent);
- y = (xtext->fontsize * line) + xtext->font->ascent - xtext->pixel_offset;
- if (!gtk_xtext_render_str (xtext, y, ent, str, len, win_width,
- /* small optimization */
- gtk_xtext_draw_marker (xtext, ent, y - xtext->fontsize * (taken + start_subline + 1));
- return ent->lines_taken - subline;
- xtext->dont_render = TRUE;
- gtk_xtext_render_str (xtext, y, ent, str, len, win_width,
- xtext->dont_render = FALSE;
- indent = xtext->buffer->indent;
- while (str < ent->str + ent->str_len);
- gtk_xtext_draw_marker (xtext, ent, y - xtext->fontsize * (taken + start_subline));
-gtk_xtext_set_palette (GtkXText * xtext, GdkColor palette[])
- for (i = (XTEXT_COLS-1); i >= 0; i--)
- xtext->color[i].color.red = palette[i].red;
- xtext->color[i].color.green = palette[i].green;
- xtext->color[i].color.blue = palette[i].blue;
- xtext->color[i].color.alpha = 0xffff;
- xtext->color[i].pixel = palette[i].pixel;
- xtext->palette[i] = palette[i].pixel;
- if (GTK_WIDGET_REALIZED (xtext))
- xtext_set_fg (xtext, xtext->fgc, XTEXT_FG);
- xtext_set_bg (xtext, xtext->fgc, XTEXT_BG);
- xtext_set_fg (xtext, xtext->bgc, XTEXT_BG);
- col.pixel = xtext->palette[XTEXT_MARKER];
- gdk_gc_set_foreground (xtext->marker_gc, &col);
- xtext->col_fore = XTEXT_FG;
- xtext->col_back = XTEXT_BG;
-gtk_xtext_fix_indent (xtext_buffer *buf)
- /* make indent a multiple of the space width */
- if (buf->indent && buf->xtext->space_width)
- while (j < buf->indent)
- j += buf->xtext->space_width;
- dontscroll (buf); /* force scrolling off */
-gtk_xtext_recalc_widths (xtext_buffer *buf, int do_str_width)
- /* since we have a new font, we have to recalc the text widths */
- ent->str_width = gtk_xtext_text_width (buf->xtext, ent->str,
- if (ent->left_len != -1)
- gtk_xtext_text_width (buf->xtext, ent->str,
- ent->left_len, NULL)) - buf->xtext->space_width;
- if (ent->indent < MARGIN)
- gtk_xtext_calc_lines (buf, FALSE);
-gtk_xtext_set_font (GtkXText *xtext, char *name)
- backend_font_close (xtext);
- /* realize now, so that font_open has a XDisplay */
- gtk_widget_realize (GTK_WIDGET (xtext));
- backend_font_open (xtext, name);
- if (xtext->font == NULL)
- /* measure the width of every char; only the ASCII ones for XFT */
- for (i = 0; i < sizeof(xtext->fontwidth)/sizeof(xtext->fontwidth[0]); i++)
- xtext->fontwidth[i] = backend_get_text_width (xtext, &c, 1, TRUE);
- xtext->space_width = xtext->fontwidth[' '];
- xtext->fontsize = xtext->font->ascent + xtext->font->descent;
- int stamp_size = xtext_get_stamp_str (time(0), &time_str);
- gtk_xtext_text_width (xtext, time_str, stamp_size, NULL) + MARGIN;
- gtk_xtext_fix_indent (xtext->buffer);
- if (GTK_WIDGET_REALIZED (xtext))
- gtk_xtext_recalc_widths (xtext->buffer, TRUE);
-gtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap, gboolean trans)
- gboolean shaded = FALSE;
- if (trans && (xtext->tint_red != 255 || xtext->tint_green != 255 || xtext->tint_blue != 255))
-#if !defined(USE_XLIB) && !defined(WIN32)
-#if defined(USE_XLIB) || defined(WIN32)
- if (xtext->transparent)
- gtk_xtext_free_trans (xtext);
- g_object_unref (xtext->pixmap);
- xtext->transparent = trans;
-#if defined(USE_XLIB) || defined(WIN32)
- xtext->shaded = shaded;
- if (GTK_WIDGET_REALIZED (xtext))
- gtk_xtext_load_trans (xtext);
- dontscroll (xtext->buffer);
- xtext->pixmap = pixmap;
- if (GTK_WIDGET_REALIZED (xtext))
- gdk_gc_set_tile (xtext->bgc, pixmap);
- gdk_gc_set_ts_origin (xtext->bgc, 0, 0);
- xtext->ts_x = xtext->ts_y = 0;
- gdk_gc_set_fill (xtext->bgc, GDK_TILED);
- } else if (GTK_WIDGET_REALIZED (xtext))
- g_object_unref (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, xtext->bgc, XTEXT_BG);
-gtk_xtext_save (GtkXText * xtext, int fh)
- ent = xtext->buffer->text_first;
- buf = gtk_xtext_strip_color (ent->str, ent->str_len, NULL,
- write (fh, buf, newlen);
-/* count how many lines 'ent' will take (with wraps) */
-gtk_xtext_lines_taken (xtext_buffer *buf, textentry * ent)
- int indent, taken, len;
- win_width = buf->window_width - MARGIN;
- if (ent->str_width + ent->indent < win_width)
- len = find_next_wrap (buf->xtext, ent, str, win_width, indent);
- if (taken < RECORD_WRAPS)
- ent->wrap_offset[taken] = (str + len) - ent->str;
- while (str < ent->str + ent->str_len);
-/* Calculate number of actual lines (with wraps), to set adj->lower. *
- * This should only be called when the window resizes. */
-gtk_xtext_calc_lines (xtext_buffer *buf, int fire_signal)
- gdk_drawable_get_size (GTK_WIDGET (buf->xtext)->window, &width, &height);
- if (width < 30 || height < buf->xtext->fontsize || width < buf->indent + 30)
- ent->lines_taken = gtk_xtext_lines_taken (buf, ent);
- lines += ent->lines_taken;
- buf->pagetop_ent = NULL;
- buf->num_lines = lines;
- gtk_xtext_adjustment_set (buf, fire_signal);
-/* find the n-th line in the linked list, this includes wrap calculations */
-gtk_xtext_nth (GtkXText *xtext, int line, int *subline)
- ent = xtext->buffer->text_first;
- /* -- optimization -- try to make a short-cut using the pagetop ent */
- if (xtext->buffer->pagetop_ent)
- if (line == xtext->buffer->pagetop_line)
- *subline = xtext->buffer->pagetop_subline;
- return xtext->buffer->pagetop_ent;
- if (line > xtext->buffer->pagetop_line)
- /* lets start from the pagetop instead of the absolute beginning */
- ent = xtext->buffer->pagetop_ent;
- lines = xtext->buffer->pagetop_line - xtext->buffer->pagetop_subline;
- else if (line > xtext->buffer->pagetop_line - line)
- /* move backwards from pagetop */
- ent = xtext->buffer->pagetop_ent;
- lines = xtext->buffer->pagetop_line - xtext->buffer->pagetop_subline;
- *subline = line - lines;
- lines -= ent->lines_taken;
- /* -- end of optimization -- */
- lines += ent->lines_taken;
- *subline = ent->lines_taken - (lines - line);
-/* render enta (or an inclusive range enta->entb) */
-gtk_xtext_render_ents (GtkXText * xtext, textentry * enta, textentry * entb)
- textentry *ent, *orig_ent, *tmp_ent;
- if (xtext->buffer->indent < MARGIN)
- xtext->buffer->indent = MARGIN; /* 2 pixels is our left margin */
- gdk_drawable_get_size (GTK_WIDGET (xtext)->window, &width, &height);
- if (width < 32 || height < xtext->fontsize || width < xtext->buffer->indent + 30)
- lines_max = ((height + xtext->pixel_offset) / xtext->fontsize) + 1;
- orig_ent = xtext->buffer->pagetop_ent;
- subline = xtext->buffer->pagetop_subline;
- /* used before a complete page is in buffer */
- orig_ent = xtext->buffer->text_first;
- /* check if enta is before the start of this page */
- tmp_ent = tmp_ent->next;
- if (entb && ent == enta)
- if (drawing || ent == entb || ent == enta)
- gtk_xtext_reset (xtext, FALSE, TRUE);
- line += gtk_xtext_render_line (xtext, ent, line, lines_max,
- xtext->jump_in_offset = 0; /* jump_in_offset only for the 1st */
- line += ent->lines_taken;
- /* space below last line */
- return (xtext->fontsize * line) - xtext->pixel_offset;
-/* render a whole page/window, starting from 'startline' */
-gtk_xtext_render_page (GtkXText * xtext)
- int startline = xtext->adj->value;
- if(!GTK_WIDGET_REALIZED(xtext))
- if (xtext->buffer->indent < MARGIN)
- xtext->buffer->indent = MARGIN; /* 2 pixels is our left margin */
- gdk_drawable_get_size (GTK_WIDGET (xtext)->window, &width, &height);
- if (width < 34 || height < xtext->fontsize || width < xtext->buffer->indent + 32)
- xtext->pixel_offset = (xtext->adj->value - startline) * xtext->fontsize;
- xtext->pixel_offset = 0;
- ent = xtext->buffer->text_first;
- ent = gtk_xtext_nth (xtext, startline, &subline);
- xtext->buffer->pagetop_ent = ent;
- xtext->buffer->pagetop_subline = subline;
- xtext->buffer->pagetop_line = startline;
- if (xtext->buffer->num_lines <= xtext->adj->page_size)
- dontscroll (xtext->buffer);
- pos = xtext->adj->value * xtext->fontsize;
- pos = startline * xtext->fontsize;
- overlap = xtext->buffer->last_pixel_pos - pos;
- xtext->buffer->last_pixel_pos = pos;
- if (!xtext->transparent && !xtext->pixmap && abs (overlap) < height)
- if (!xtext->pixmap && abs (overlap) < height)
- /* dont scroll PageUp/Down without a DB, it looks ugly */
- if (!xtext->transparent && !xtext->pixmap && abs (overlap) < height - (3*xtext->fontsize))
- if (!xtext->pixmap && abs (overlap) < height - (3*xtext->fontsize))
- /* so the obscured regions are exposed */
- gdk_gc_set_exposures (xtext->fgc, TRUE);
- if (overlap < 1) /* DOWN */
- gdk_draw_drawable (xtext->draw_buf, xtext->fgc, xtext->draw_buf,
- 0, -overlap, 0, 0, width, height + overlap);
- remainder = ((height - xtext->font->descent) % xtext->fontsize) +
- area.y = (height + overlap) - remainder;
- area.height = remainder - overlap;
- gdk_draw_drawable (xtext->draw_buf, xtext->fgc, xtext->draw_buf,
- 0, 0, 0, overlap, width, height - overlap);
- gdk_gc_set_exposures (xtext->fgc, FALSE);
- gtk_xtext_paint (GTK_WIDGET (xtext), &area);
- xtext->buffer->grid_dirty = TRUE;
- xtext->buffer->grid_dirty = FALSE;
- lines_max = ((height + xtext->pixel_offset) / xtext->fontsize) + 1;
- gtk_xtext_reset (xtext, FALSE, TRUE);
- line += gtk_xtext_render_line (xtext, ent, line, lines_max,
- line = (xtext->fontsize * line) - xtext->pixel_offset;
- /* fill any space below the last line with our background GC */
- xtext_draw_bg (xtext, 0, line, width + MARGIN, height - line);
- /* draw the separator line */
- gtk_xtext_draw_sep (xtext, -1);
-gtk_xtext_refresh (GtkXText * xtext, int do_trans)
- if (GTK_WIDGET_REALIZED (GTK_WIDGET (xtext)))
-#if defined(USE_XLIB) || defined(WIN32)
- if (xtext->transparent && do_trans)
- gtk_xtext_free_trans (xtext);
- gtk_xtext_load_trans (xtext);
- gtk_xtext_render_page (xtext);
-/* remove the topline from the list */
-gtk_xtext_remove_top (xtext_buffer *buffer)
- ent = buffer->text_first;
- buffer->num_lines -= ent->lines_taken;
- buffer->pagetop_line -= ent->lines_taken;
- buffer->last_pixel_pos -= (ent->lines_taken * buffer->xtext->fontsize);
- buffer->text_first = ent->next;
- buffer->text_first->prev = NULL;
- buffer->old_value -= ent->lines_taken;
- if (buffer->xtext->buffer == buffer) /* is it the current buffer? */
- buffer->xtext->adj->value -= ent->lines_taken;
- buffer->xtext->select_start_adj -= ent->lines_taken;
- if (ent == buffer->pagetop_ent)
- buffer->pagetop_ent = NULL;
- if (ent == buffer->last_ent_start)
- buffer->last_ent_start = ent->next;
- if (ent == buffer->last_ent_end)
- buffer->last_ent_start = NULL;
- buffer->last_ent_end = NULL;
- if (buffer->marker_pos == ent) buffer->marker_pos = NULL;
-gtk_xtext_clear (xtext_buffer *buf)
- buf->scrollbar_down = TRUE;
- buf->last_ent_start = NULL;
- buf->last_ent_end = NULL;
- buf->marker_pos = NULL;
- while (buf->text_first)
- next = buf->text_first->next;
- free (buf->text_first);
- buf->text_first = next;
- if (buf->xtext->buffer == buf)
- gtk_xtext_calc_lines (buf, TRUE);
- gtk_xtext_refresh (buf->xtext, 0);
- gtk_xtext_calc_lines (buf, FALSE);
- if (buf->xtext->auto_indent)
- buf->xtext->buffer->indent = 1;
-gtk_xtext_check_ent_visibility (GtkXText * xtext, textentry *find_ent, int add)
- gdk_drawable_get_size (GTK_WIDGET (xtext)->window, &width, &height);
- lines_max = ((height + xtext->pixel_offset) / xtext->fontsize) + add;
- ent = xtext->buffer->pagetop_ent;
- while (ent && line < lines_max)
- line += ent->lines_taken;
-gtk_xtext_check_marker_visibility (GtkXText * xtext)
- if (gtk_xtext_check_ent_visibility (xtext, xtext->buffer->marker_pos, 1))
- xtext->buffer->marker_seen = TRUE;
-gtk_xtext_search (GtkXText * xtext, const gchar *text, textentry *start, gboolean case_match, gboolean backward)
- gchar *str = NULL, *nee = NULL, *hay = NULL; /* needle in haystack */
- gtk_xtext_selection_clear_full (xtext->buffer);
- xtext->buffer->last_ent_start = NULL;
- xtext->buffer->last_ent_end = NULL;
- /* set up text comparand for Case Match or Ignore */
- nee = g_utf8_casefold (text, strlen (text));
- /* Validate that start gives a currently valid ent pointer */
- ent = xtext->buffer->text_first;
- /* Choose first ent to look at */
- ent = backward? start->prev: start->next;
- ent = backward? xtext->buffer->text_last: xtext->buffer->text_first;
- /* Search from there to one end or the other until found */
- /* If Case Ignore, fold before & free after calling strstr */
- hay = g_strdup ((char *)ent->str);
- hay = g_utf8_casefold ((char *)ent->str, strlen ((char *)ent->str));
- /* Try to find the needle in this haystack */
- str = g_strstr_len (hay, strlen (hay), nee);
- ent = backward? ent->prev: ent->next;
- /* Save distance to start, end of found string */
- ent->mark_start = str - hay;
- ent->mark_end = ent->mark_start + strlen (nee);
- /* is the match visible? Might need to scroll */
- if (!gtk_xtext_check_ent_visibility (xtext, ent, 0))
- ent = xtext->buffer->text_first;
- line += ent->lines_taken;
- while (line > xtext->adj->upper - xtext->adj->page_size)
- xtext->adj->value = line;
- xtext->buffer->scrollbar_down = FALSE;
- gtk_adjustment_changed (xtext->adj);
- gtk_widget_queue_draw (GTK_WIDGET (xtext));
-gtk_xtext_render_page_timeout (GtkXText * xtext)
- GtkAdjustment *adj = xtext->adj;
- /* less than a complete page? */
- if (xtext->buffer->num_lines <= adj->page_size)
- xtext->buffer->old_value = 0;
- gtk_xtext_render_page (xtext);
- } else if (xtext->buffer->scrollbar_down)
- g_signal_handler_block (xtext->adj, xtext->vc_signal_tag);
- gtk_xtext_adjustment_set (xtext->buffer, FALSE);
- gtk_adjustment_set_value (adj, adj->upper - adj->page_size);
- g_signal_handler_unblock (xtext->adj, xtext->vc_signal_tag);
- xtext->buffer->old_value = adj->value;
- gtk_xtext_render_page (xtext);
- gtk_xtext_adjustment_set (xtext->buffer, TRUE);
- if (xtext->indent_changed)
- xtext->indent_changed = FALSE;
- gtk_xtext_render_page (xtext);
-/* append a textentry to our linked list */
-gtk_xtext_append_entry (xtext_buffer *buf, textentry * ent)
- /* we don't like tabs */
- while (i < ent->str_len)
- if (ent->str[i] == '\t')
- ent->str_width = gtk_xtext_text_width (buf->xtext, ent->str, ent->str_len, &mb);
- if (ent->indent < MARGIN)
- ent->indent = MARGIN; /* 2 pixels is the left margin */
- /* append to our linked list */
- buf->text_last->next = ent;
- ent->prev = buf->text_last;
- ent->lines_taken = gtk_xtext_lines_taken (buf, ent);
- buf->num_lines += ent->lines_taken;
- if (buf->reset_marker_pos ||
- ((buf->marker_pos == NULL || buf->marker_seen) && (buf->xtext->buffer != buf ||
-#if GTK_CHECK_VERSION(2,4,0)
- !gtk_window_has_toplevel_focus (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (buf->xtext)))))))
- !(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (buf->xtext))))->has_focus)))
- dontscroll (buf); /* force scrolling off */
- buf->marker_seen = FALSE;
- buf->reset_marker_pos = FALSE;
- if (buf->xtext->max_lines > 2 && buf->xtext->max_lines < buf->num_lines)
- gtk_xtext_remove_top (buf);
- if (buf->xtext->buffer == buf)
- /* this could be improved */
- if ((buf->num_lines - 1) <= buf->xtext->adj->page_size)
- if (!buf->xtext->add_io_tag)
- /* remove scrolling events */
- if (buf->xtext->io_tag)
- g_source_remove (buf->xtext->io_tag);
- buf->xtext->io_tag = 0;
- buf->xtext->add_io_tag = g_timeout_add (REFRESH_TIMEOUT * 2,
- gtk_xtext_render_page_timeout,
- } else if (buf->scrollbar_down)
- buf->old_value = buf->num_lines - buf->xtext->adj->page_size;
- if (buf->old_value < 0)
-/* the main two public functions */
-gtk_xtext_append_indent (xtext_buffer *buf,
- unsigned char *left_text, int left_len, int left_color,
- unsigned char *right_text, int right_len, int right_color)
- left_len = strlen ((char *)left_text);
- right_len = strlen ((char *)right_text);
- if (right_len >= sizeof (buf->xtext->scratch_buffer))
- right_len = sizeof (buf->xtext->scratch_buffer) - 1;
- if (right_text[right_len-1] == '\n')
- ent = malloc (left_len + right_len + 2 + sizeof (textentry));
- str = (unsigned char *) ent + sizeof (textentry);
- memcpy (str, left_text, left_len);
- memcpy (str + left_len + 1, right_text, right_len);
- str[left_len + 1 + right_len] = 0;
- left_width = gtk_xtext_text_width (buf->xtext, left_text, left_len, NULL);
- ent->left_len = left_len;
- ent->str_len = left_len + 1 + right_len;
- ent->indent = (buf->indent - left_width) - buf->xtext->space_width;
- ent->left_color = left_color;
- ent->right_color = right_color;
- space = buf->xtext->stamp_width;
- /* do we need to auto adjust the separator position? */
- if (buf->xtext->auto_indent && ent->indent < MARGIN + space)
- tempindent = MARGIN + space + buf->xtext->space_width + left_width;
- if (tempindent > buf->indent)
- buf->indent = tempindent;
- if (buf->indent > buf->xtext->max_auto_indent)
- buf->indent = buf->xtext->max_auto_indent;
- gtk_xtext_fix_indent (buf);
- gtk_xtext_recalc_widths (buf, FALSE);
- ent->indent = (buf->indent - left_width) - buf->xtext->space_width;
- buf->xtext->indent_changed = TRUE;
- gtk_xtext_append_entry (buf, ent);
-gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len)
- len = strlen ((char *)text);
- if (text[len-1] == '\n')
- if (len >= sizeof (buf->xtext->scratch_buffer))
- len = sizeof (buf->xtext->scratch_buffer) - 1;
- ent = malloc (len + 1 + sizeof (textentry));
- ent->str = (unsigned char *) ent + sizeof (textentry);
- memcpy (ent->str, text, len);
- gtk_xtext_append_entry (buf, ent);
-gtk_xtext_is_empty (xtext_buffer *buf)
- return buf->text_first == NULL;
-gtk_xtext_foreach (xtext_buffer *buf, GtkXTextForeach func, void *data)
- textentry *ent = buf->text_first;
- (*func) (buf->xtext, ent->str, data);
-gtk_xtext_set_error_function (GtkXText *xtext, void (*error_function) (int))
- xtext->error_function = error_function;
-gtk_xtext_set_indent (GtkXText *xtext, gboolean indent)
- xtext->auto_indent = indent;
-gtk_xtext_set_max_indent (GtkXText *xtext, int max_auto_indent)
- xtext->max_auto_indent = max_auto_indent;
-gtk_xtext_set_max_lines (GtkXText *xtext, int max_lines)
- xtext->max_lines = max_lines;
-gtk_xtext_set_show_marker (GtkXText *xtext, gboolean show_marker)
- xtext->marker = show_marker;
-gtk_xtext_set_show_separator (GtkXText *xtext, gboolean show_separator)
- xtext->separator = show_separator;
-gtk_xtext_set_thin_separator (GtkXText *xtext, gboolean thin_separator)
- xtext->thinline = thin_separator;
-gtk_xtext_set_time_stamp (xtext_buffer *buf, gboolean time_stamp)
- buf->time_stamp = time_stamp;
-gtk_xtext_set_tint (GtkXText *xtext, int tint_red, int tint_green, int tint_blue)
- xtext->tint_red = tint_red;
- xtext->tint_green = tint_green;
- xtext->tint_blue = tint_blue;
- /*if (xtext->tint_red != 255 || xtext->tint_green != 255 || xtext->tint_blue != 255)
-gtk_xtext_set_urlcheck_function (GtkXText *xtext, int (*urlcheck_function) (GtkWidget *, char *, int))
- xtext->urlcheck_function = urlcheck_function;
-gtk_xtext_set_wordwrap (GtkXText *xtext, gboolean wordwrap)
- xtext->wordwrap = wordwrap;
-gtk_xtext_reset_marker_pos (GtkXText *xtext)
- xtext->buffer->marker_pos = NULL;
- dontscroll (xtext->buffer); /* force scrolling off */
- gtk_xtext_render_page (xtext);
- xtext->buffer->reset_marker_pos = TRUE;
-gtk_xtext_buffer_show (GtkXText *xtext, xtext_buffer *buf, int render)
- if (xtext->buffer == buf)
-/*printf("text_buffer_show: xtext=%p buffer=%p\n", xtext, buf);*/
- g_source_remove (xtext->add_io_tag);
- g_source_remove (xtext->io_tag);
- if (!GTK_WIDGET_REALIZED (GTK_WIDGET (xtext)))
- gtk_widget_realize (GTK_WIDGET (xtext));
- gdk_drawable_get_size (GTK_WIDGET (xtext)->window, &w, &h);
- /* after a font change */
- buf->needs_recalc = FALSE;
- gtk_xtext_recalc_widths (buf, TRUE);
- /* now change to the new buffer */
- dontscroll (buf); /* force scrolling off */
- xtext->adj->value = buf->old_value;
- xtext->adj->upper = buf->num_lines;
- if (xtext->adj->upper == 0)
- else if (xtext->adj->value > xtext->adj->upper - xtext->adj->page_size)
- /*buf->pagetop_ent = NULL;*/
- xtext->adj->value = xtext->adj->upper - xtext->adj->page_size;
- if (xtext->adj->value < 0)
- /* did the window change size since this buffer was last shown? */
- if (buf->window_width != w)
- gtk_xtext_calc_lines (buf, FALSE);
- if (buf->scrollbar_down)
- gtk_adjustment_set_value (xtext->adj, xtext->adj->upper -
- xtext->adj->page_size);
- } else if (buf->window_height != h)
- buf->window_height = h;
- buf->pagetop_ent = NULL;
- gtk_xtext_adjustment_set (buf, FALSE);
- gtk_xtext_render_page (xtext);
- gtk_adjustment_changed (xtext->adj);
- /* avoid redoing the transparency */
- xtext->avoid_trans = TRUE;
-gtk_xtext_buffer_new (GtkXText *xtext)
- buf = malloc (sizeof (xtext_buffer));
- memset (buf, 0, sizeof (xtext_buffer));
- buf->scrollbar_down = TRUE;
- buf->indent = xtext->space_width * 2;
-gtk_xtext_buffer_free (xtext_buffer *buf)
- if (buf->xtext->buffer == buf)
- buf->xtext->buffer = buf->xtext->orig_buffer;
- if (buf->xtext->selection_buffer == buf)
- buf->xtext->selection_buffer = NULL;
--- a/xchat-chats/xtext.h Mon Mar 02 00:54:56 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,271 +0,0 @@
-#include <gtk/gtkadjustment.h>
-#include <X11/Xft/Xft.h>
-#include <X11/extensions/XShm.h>
-#define GTK_TYPE_XTEXT (gtk_xtext_get_type ())
-#define GTK_XTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_XTEXT, GtkXText))
-#define GTK_XTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_XTEXT, GtkXTextClass))
-#define GTK_IS_XTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_XTEXT))
-#define GTK_IS_XTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_XTEXT))
-#define GTK_XTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_XTEXT, GtkXTextClass))
-#define ATTR_BOLD '\002'
-#define ATTR_COLOR '\003'
-#define ATTR_BLINK '\006'
-#define ATTR_BEEP '\007'
-#define ATTR_ITALICS2 '\011'
-#define ATTR_RESET '\017'
-#define ATTR_REVERSE '\026'
-#define ATTR_ITALICS '\035'
-#define ATTR_UNDERLINE '\037'
-/* these match palette.h */
-#define XTEXT_MIRC_COLS 32
-#define XTEXT_COLS 37 /* 32 plus 5 for extra stuff below */
-#define XTEXT_MARK_FG 32 /* for marking text */
-#define XTEXT_MARK_BG 33
-#define XTEXT_MARKER 36 /* for marker line */
-typedef struct _GtkXText GtkXText;
-typedef struct _GtkXTextClass GtkXTextClass;
-typedef struct textentry textentry;
- GtkXText *xtext; /* attached to this widget */
- gfloat old_value; /* last known adj->value */
- guint16 grid_offset[256];
- textentry *last_ent_start; /* this basically describes the last rendered */
- textentry *last_ent_end; /* selection. */
- textentry *pagetop_ent; /* what's at xtext->adj->value */
- int indent; /* position of separator (pixels) from left */
- int window_width; /* window size when last rendered. */
- unsigned int time_stamp:1;
- unsigned int scrollbar_down:1;
- unsigned int needs_recalc:1;
- unsigned int grid_dirty:1;
- unsigned int marker_seen:1;
- unsigned int reset_marker_pos:1;
- xtext_buffer *orig_buffer;
- xtext_buffer *selection_buffer;
- XShmSegmentInfo shminfo;
- GdkPixmap *pixmap; /* 0 = use palette[19] */
- GdkDrawable *draw_buf; /* points to ->window */
- GdkCursor *hand_cursor;
- GdkCursor *resize_cursor;
- int pixel_offset; /* amount of pixels the top line is chopped by */
- GdkGC *bgc; /* backing pixmap */
- GdkGC *fgc; /* text foreground color */
- GdkGC *light_gc; /* sep bar */
- gulong palette[XTEXT_COLS];
- gint io_tag; /* for delayed refresh events */
- gint add_io_tag; /* "" when adding new text */
- gint scroll_tag; /* marking-scroll timeout */
- gulong vc_signal_tag; /* signal handler for "value_changed" adj */
- int select_start_adj; /* the adj->value when the selection started */
- int depth; /* gdk window depth */
- char num[8]; /* for parsing mirc color */
- int nc; /* offset into xtext->num */
- textentry *hilight_ent;
- guint16 fontwidth[128]; /* each char's width, only the ASCII ones */
- XftColor color[XTEXT_COLS];
- XftColor *xft_bg; /* both point into color[20] */
- XftFont *ifont; /* italics */
- PangoFontDescription *font;
- PangoFontDescription *ifont; /* italics */
- int space_width; /* width (pixels) of the space " " character */
- int stamp_width; /* width of "[88:88:88]" */
- unsigned char scratch_buffer[4096];
- void (*error_function) (int type);
- int (*urlcheck_function) (GtkWidget * xtext, char *word, int len);
- int jump_out_offset; /* point at which to stop rendering */
- int jump_in_offset; /* "" start rendering */
- int ts_x; /* ts origin for ->bgc GC */
- int clip_x; /* clipping (x directions) */
- int clip_x2; /* from x to x2 */
- int clip_y; /* clipping (y directions) */
- int clip_y2; /* from y to y2 */
- unsigned int auto_indent:1;
- unsigned int moving_separator:1;
- unsigned int word_or_line_select:1;
- unsigned int color_paste:1;
- unsigned int thinline:1;
- unsigned int parsing_backcolor:1;
- unsigned int parsing_color:1;
- unsigned int backcolor:1;
- unsigned int button_down:1;
- unsigned int hilighting:1;
- unsigned int underline:1;
- unsigned int italics:1;
- unsigned int transparent:1;
- unsigned int separator:1;
- unsigned int wordwrap:1;
- unsigned int dont_render:1;
- unsigned int dont_render2:1;
- unsigned int cursor_hand:1;
- unsigned int cursor_resize:1;
- unsigned int skip_border_fills:1;
- unsigned int skip_stamp:1;
- unsigned int render_hilights_only:1;
- unsigned int in_hilight:1;
- unsigned int un_hilight:1;
- unsigned int recycle:1;
- unsigned int avoid_trans:1;
- unsigned int overdraw:1;
- unsigned int indent_changed:1;
- GtkWidgetClass parent_class;
- void (*word_click) (GtkXText * xtext, char *word, GdkEventButton * event);
-GtkWidget *gtk_xtext_new (GdkColor palette[], int separator);
-void gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len);
-void gtk_xtext_append_indent (xtext_buffer *buf,
- unsigned char *left_text, int left_len, int left_color,
- unsigned char *right_text, int right_len, int right_color);
-int gtk_xtext_set_font (GtkXText *xtext, char *name);
-void gtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap, gboolean trans);
-void gtk_xtext_set_palette (GtkXText * xtext, GdkColor palette[]);
-void gtk_xtext_clear (xtext_buffer *buf);
-void gtk_xtext_save (GtkXText * xtext, int fh);
-void gtk_xtext_refresh (GtkXText * xtext, int do_trans);
-textentry *gtk_xtext_search (GtkXText * xtext, const gchar *text, textentry *start, gboolean case_match, gboolean backward);
-void gtk_xtext_reset_marker_pos (GtkXText *xtext);
-void gtk_xtext_check_marker_visibility(GtkXText *xtext);
-gboolean gtk_xtext_is_empty (xtext_buffer *buf);
-typedef void (*GtkXTextForeach) (GtkXText *xtext, unsigned char *text, void *data);
-void gtk_xtext_foreach (xtext_buffer *buf, GtkXTextForeach func, void *data);
-void gtk_xtext_set_error_function (GtkXText *xtext, void (*error_function) (int));
-void gtk_xtext_set_indent (GtkXText *xtext, gboolean indent);
-void gtk_xtext_set_max_indent (GtkXText *xtext, int max_auto_indent);
-void gtk_xtext_set_max_lines (GtkXText *xtext, int max_lines);
-void gtk_xtext_set_show_marker (GtkXText *xtext, gboolean show_marker);
-void gtk_xtext_set_show_separator (GtkXText *xtext, gboolean show_separator);
-void gtk_xtext_set_thin_separator (GtkXText *xtext, gboolean thin_separator);
-void gtk_xtext_set_time_stamp (xtext_buffer *buf, gboolean timestamp);
-void gtk_xtext_set_tint (GtkXText *xtext, int tint_red, int tint_green, int tint_blue);
-void gtk_xtext_set_urlcheck_function (GtkXText *xtext, int (*urlcheck_function) (GtkWidget *, char *, int));
-void gtk_xtext_set_wordwrap (GtkXText *xtext, gboolean word_wrap);
-xtext_buffer *gtk_xtext_buffer_new (GtkXText *xtext);
-void gtk_xtext_buffer_free (xtext_buffer *buf);
-void gtk_xtext_buffer_show (GtkXText *xtext, xtext_buffer *buf, int render);
-GtkType gtk_xtext_get_type (void);
- * Set the foreground color for the widget.
-void gtk_xtext_set_foreground_color (GtkXText *xtext, GdkColor *color);
- * Set the background color for the widget.
-void gtk_xtext_set_background_color (GtkXText *xtext, GdkColor *color);