tWin32 now supports the "foreground" attribute of GtkTextTags when using Rich Edit controls (there are, however, some problems when using Unicode which remain to be fixed). - vaccinewars - be a doctor and try to vaccinate the world
git clone git://src.adamsgaard.dk/vaccinewars
Log
Files
Refs
README
LICENSE
---
commit c383b81213580add66d8116f660768060253e32d
parent 20317b21645411bd9e3a83c822d2a59499631cb7
Author: Ben Webb 
Date:   Sat, 31 Aug 2002 18:12:41 +0000

Win32 now supports the "foreground" attribute of GtkTextTags when using
Rich Edit controls (there are, however, some problems when using Unicode
which remain to be fixed).


Diffstat:
  M src/gtkport/gtkport.c               |     128 +++++++++++++++++++++++++++----
  M src/gtkport/gtkport.h               |       8 ++++++++
  M src/gui_client/gtk_client.c         |      17 +++++++++++------

3 files changed, 134 insertions(+), 19 deletions(-)
---
diff --git a/src/gtkport/gtkport.c b/src/gtkport/gtkport.c
t@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "gtkport.h"
t@@ -65,6 +66,7 @@ const gchar *GTK_STOCK_HELP = N_("_Help");
 HICON mainIcon = NULL;
 static WNDPROC customWndProc = NULL;
 static gboolean HaveRichEdit = FALSE;
+static gchar *RichEditClass = NULL;
 
 static guint RecurseLevel = 0;
 
t@@ -82,6 +84,7 @@ static void gtk_entry_set_size(GtkWidget *widget,
                                GtkAllocation *allocation);
 static void gtk_text_size_request(GtkWidget *widget,
                                   GtkRequisition *requisition);
+static void gtk_text_destroy(GtkWidget *widget);
 static void gtk_button_destroy(GtkWidget *widget);
 static void gtk_check_button_size_request(GtkWidget *widget,
                                           GtkRequisition *requisition);
t@@ -393,6 +396,7 @@ static GtkClass GtkSpinButtonClass = {
 static GtkSignalType GtkTextSignals[] = {
   {"size_request", gtk_marshal_VOID__GPOIN, gtk_text_size_request},
   {"realize", gtk_marshal_VOID__VOID, gtk_text_realize},
+  {"destroy", gtk_marshal_VOID__VOID, gtk_text_destroy},
   {"", NULL, NULL}
 };
 
t@@ -1148,7 +1152,16 @@ void win32_init(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 
   InitCommonControls();
   LoadLibrary("RICHED32.DLL");
-  HaveRichEdit = GetClassInfo(hInstance, "RichEdit", &wc);
+
+  /* Rich Edit controls have two different class names, depending on whether
+   * we want ANSI or Unicode - argh! */
+  if (HaveUnicodeSupport()) {
+    RichEditClass = "RichEdit20W";
+  } else {
+    RichEditClass = "RichEdit20A";
+  }
+  RichEditClass = "RichEdit";
+  HaveRichEdit = GetClassInfo(hInstance, RichEditClass, &wc);
 
   if (!hPrevInstance) {
     wc.style = 0;
t@@ -1861,7 +1874,12 @@ GtkWidget *gtk_frame_new(const gchar *text)
 
 GtkWidget *gtk_text_new(GtkAdjustment *hadj, GtkAdjustment *vadj)
 {
-  return GTK_WIDGET(GtkNewObject(&GtkTextClass));
+  GtkText *text;
+
+  text = GTK_TEXT(GtkNewObject(&GtkTextClass));
+  text->buffer = g_new(GtkTextBuffer, 1);
+  g_datalist_init(&text->buffer->tags);
+  return GTK_WIDGET(text);
 }
 
 GtkWidget *gtk_scrolled_text_view_new(GtkWidget **pack_widg)
t@@ -1937,8 +1955,9 @@ static void gtk_text_view_set_format(GtkTextView *textview,
                                      const gchar *tagname, guint len,
                                      gint endpos)
 {
-  CHARFORMAT cf;
+  CHARFORMAT *cf, cfdef;
   GtkWidget *widget = GTK_WIDGET(textview);
+  GtkTextBuffer *buffer;
 
   if (!GTK_WIDGET_REALIZED(widget)) {
     return;
t@@ -1946,15 +1965,15 @@ static void gtk_text_view_set_format(GtkTextView *textview,
 
   mySendMessage(widget->hWnd, EM_SETSEL, (WPARAM)(endpos - len),
                 (LPARAM)endpos);
-  cf.cbSize = sizeof(CHARFORMAT);
-  cf.dwMask = CFM_COLOR;
-  if (tagname) {
-    cf.crTextColor = RGB(0, 0, 255);
-    cf.dwEffects = 0;
-  } else {
-    cf.dwEffects = CFE_AUTOCOLOR;
+
+  if (!tagname || !(buffer = gtk_text_view_get_buffer(textview))
+      || !(cf = g_datalist_get_data(&buffer->tags, tagname))) {
+    cfdef.cbSize = sizeof(CHARFORMAT);
+    cfdef.dwMask = CFM_COLOR;
+    cfdef.dwEffects = CFE_AUTOCOLOR;
+    cf = &cfdef;
   }
-  mySendMessage(widget->hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+  mySendMessage(widget->hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)cf);
 }
 
 void gtk_editable_delete_text(GtkEditable *editable,
t@@ -2092,6 +2111,17 @@ void gtk_box_destroy(GtkWidget *widget)
   g_list_free(GTK_BOX(widget)->children);
 }
 
+static void gtk_text_destroy(GtkWidget *widget)
+{
+  GtkText *text = GTK_TEXT(widget);
+  GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
+
+  if (buffer) {
+    g_datalist_clear(&buffer->tags);
+    g_free(buffer);
+  }
+}
+
 static void EnableParent(GtkWindow *window)
 {
   GtkWidget *parent;
t@@ -2457,7 +2487,7 @@ void gtk_text_realize(GtkWidget *widget)
   editable = GTK_EDITABLE(widget)->is_editable;
   GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS);
   widget->hWnd = myCreateWindowEx(WS_EX_CLIENTEDGE,
-                                  HaveRichEdit ? "RichEdit" : "EDIT", "",
+                                  HaveRichEdit ? RichEditClass : "EDIT", "",
                                   WS_CHILD | (editable ? WS_TABSTOP : 0) |
                                   ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL |
                                   (GTK_TEXT(widget)->word_wrap ?
t@@ -4677,6 +4707,78 @@ void gtk_text_thaw(GtkText *text)
 {
 }
 
+GtkTextBuffer *gtk_text_view_get_buffer(GtkText *text)
+{
+  return text->buffer;
+}
+
+static int parse_colcomp(const gchar *hexval)
+{
+  int col = 0, i, ch;
+
+  for (i = 0; i < 4; ++i) {
+    col <<= 4;
+    ch = toupper(hexval[i]);
+    if (ch >= '0' && ch <= '9') {
+      col |= (ch - '0');
+    } else if (ch >= 'A' && ch <= 'F') {
+      col |= (ch - 'A' + 10);
+    }
+  }
+  return col / 257; /* Scale from 0-65535 to 0-255 */
+}
+
+static gboolean parse_color(const gchar *name, COLORREF *color)
+{
+  int red, green, blue, i, ch;
+
+  if (!name || strlen(name) != 13 || name[0] != '#') {
+    return FALSE;
+  }
+  for (i = strlen(name) - 1; i >= 1; --i) {
+    ch = toupper(name[i]);
+    if (!((ch >= '0' && ch <= '9')
+          || (ch >= 'A' && ch <= 'F'))) {
+      return FALSE;
+    }
+  }
+  red = parse_colcomp(&name[1]);
+  green = parse_colcomp(&name[5]);
+  blue = parse_colcomp(&name[9]);
+  if (color) {
+    *color = RGB(red, green, blue);
+  }
+  return TRUE;
+}
+
+void gtk_text_buffer_create_tag(GtkTextBuffer *buffer, const gchar *name, ...)
+{
+  va_list ap;
+  gchar *attr, *data;
+  CHARFORMAT *cf;
+
+  va_start(ap, name);
+  cf = g_new(CHARFORMAT, 1);
+  cf->cbSize = sizeof(CHARFORMAT);
+  cf->dwMask = 0;
+  do {
+    attr = va_arg(ap, gchar *);
+    if (attr) {
+      if (strcmp(attr, "foreground") == 0) {
+        data = va_arg(ap, gchar *);
+        cf->dwMask |= CFM_COLOR;
+        cf->dwEffects = 0;
+        if (!parse_color(data, &cf->crTextColor)) {
+          cf->dwEffects = CFE_AUTOCOLOR;
+        }
+      }
+    }
+  } while (attr);
+
+  g_datalist_set_data_full(&buffer->tags, name, cf, g_free);
+  va_end(ap);
+}
+
 GtkWidget *gtk_option_menu_new()
 {
   GtkOptionMenu *option_menu;
t@@ -5507,7 +5609,7 @@ void TextViewAppend(GtkTextView *textview, const gchar *text,
   gtk_editable_insert_text(GTK_EDITABLE(textview), text, strlen(text),
                            &editpos);
 #ifdef CYGWIN
-  gtk_text_view_set_format(textview, tagname, strlen(text), editpos);
+  gtk_text_view_set_format(textview, tagname, myw32strlen(text), editpos);
 #endif
   if (scroll) {
     gtk_editable_set_position(GTK_EDITABLE(textview), editpos);
diff --git a/src/gtkport/gtkport.h b/src/gtkport/gtkport.h
t@@ -225,6 +225,7 @@ struct _GtkMenuBar {
 typedef struct _GtkEditable GtkEditable;
 typedef struct _GtkEntry GtkEntry;
 typedef struct _GtkText GtkText;
+typedef struct _GtkTextBuffer GtkTextBuffer;
 typedef struct _GtkSpinButton GtkSpinButton;
 
 struct _GtkEditable {
t@@ -244,9 +245,14 @@ struct _GtkSpinButton {
   HWND updown;
 };
 
+struct _GtkTextBuffer {
+  GData *tags;
+};
+
 struct _GtkText {
   GtkEditable editable;
   gint word_wrap:1;
+  GtkTextBuffer *buffer;
 };
 
 typedef struct _GtkLabel GtkLabel;
t@@ -547,6 +553,8 @@ void gtk_text_set_editable(GtkText *text, gboolean is_editable);
 void gtk_text_set_word_wrap(GtkText *text, gboolean word_wrap);
 void gtk_text_freeze(GtkText *text);
 void gtk_text_thaw(GtkText *text);
+GtkTextBuffer *gtk_text_view_get_buffer(GtkText *text);
+void gtk_text_buffer_create_tag(GtkTextBuffer *buffer, const gchar *name, ...);
 void gtk_table_attach(GtkTable *table, GtkWidget *widget,
                       guint left_attach, guint right_attach,
                       guint top_attach, guint bottom_attach,
diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c
t@@ -2142,14 +2142,19 @@ static void SetIcon(GtkWidget *window, gchar **xpmdata)
 
 static void make_tags(GtkTextView *textview)
 {
-#if HAVE_GLIB2 && !CYGWIN
+#if HAVE_GLIB2
   GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview);
 
-  gtk_text_buffer_create_tag(buffer, "jet", "foreground", "blue", NULL);
-  gtk_text_buffer_create_tag(buffer, "talk", "foreground", "red", NULL);
-  gtk_text_buffer_create_tag(buffer, "page", "foreground", "magenta", NULL);
-  gtk_text_buffer_create_tag(buffer, "join", "foreground", "darkblue", NULL);
-  gtk_text_buffer_create_tag(buffer, "leave", "foreground", "darkred", NULL);
+  gtk_text_buffer_create_tag(buffer, "jet", "foreground",
+                             "#00000000FFFF", NULL);
+  gtk_text_buffer_create_tag(buffer, "talk", "foreground",
+                             "#FFFF00000000", NULL);
+  gtk_text_buffer_create_tag(buffer, "page", "foreground",
+                             "#FFFF0000FFFF", NULL);
+  gtk_text_buffer_create_tag(buffer, "join", "foreground",
+                             "#000000008B8B", NULL);
+  gtk_text_buffer_create_tag(buffer, "leave", "foreground",
+                             "#8B8B00000000", NULL);
 #endif
 }