changeset 971:2a21915684d1

Step 1 in modernizing the GTK3 module. Removed all the thread arrays, switching to using pthread_setspecific() to use TLS. Also simplified the clipboard functions. The dw_clipboard_get() function returns a malloc()ed buffer which needs to be dw_free()ed.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 05 May 2011 22:05:06 +0000
parents b00943f21392
children 32830f1683c9
files gtk3/dw.c
diffstat 1 files changed, 89 insertions(+), 128 deletions(-) [+]
line wrap: on
line diff
--- a/gtk3/dw.c	Thu May 05 17:14:24 2011 +0000
+++ b/gtk3/dw.c	Thu May 05 22:05:06 2011 +0000
@@ -108,8 +108,6 @@
    ".bmp",
 };
 
-#define DW_THREAD_LIMIT 50
-
 #ifndef max
 # define max(a,b)        (((a) > (b)) ? (a) : (b))
 #endif
@@ -120,23 +118,19 @@
 
 FILE *dbgfp = NULL;
 
-DWTID _dw_thread_list[DW_THREAD_LIMIT];
-GdkColor _foreground[DW_THREAD_LIMIT];
-GdkColor _background[DW_THREAD_LIMIT];
-int _transparent[DW_THREAD_LIMIT];
-GtkClipboard *_clipboard_object[DW_THREAD_LIMIT];
-gchar *_clipboard_contents[DW_THREAD_LIMIT];
+pthread_key_t _dw_fg_color_key;
+pthread_key_t _dw_bg_color_key;
+pthread_key_t _dw_mutex_key;
 
 GtkWidget *last_window = NULL, *popup = NULL;
 
 static int _dw_ignore_click = 0, _dw_ignore_expand = 0, _dw_color_active = 0;
 static pthread_t _dw_thread = (pthread_t)-1;
-static int _dw_mutex_locked[DW_THREAD_LIMIT];
 /* Use default border size for the default enlightenment theme */
 static int _dw_border_width = 12, _dw_border_height = 28;
 
-#define  DW_MUTEX_LOCK { int index = _find_thread_index(dw_thread_id()); if(pthread_self() != _dw_thread && _dw_mutex_locked[index] == FALSE) { gdk_threads_enter(); _dw_mutex_locked[index] = TRUE; _locked_by_me = TRUE; } }
-#define  DW_MUTEX_UNLOCK { if(pthread_self() != _dw_thread && _locked_by_me == TRUE) { gdk_threads_leave(); _dw_mutex_locked[_find_thread_index(dw_thread_id())] = FALSE; _locked_by_me = FALSE; } }
+#define  DW_MUTEX_LOCK { if(pthread_self() != _dw_thread && !pthread_getspecific(_dw_mutex_key)) { gdk_threads_enter(); pthread_setspecific(_dw_mutex_key, (void *)1); _locked_by_me = TRUE; } }
+#define  DW_MUTEX_UNLOCK { if(pthread_self() != _dw_thread && _locked_by_me == TRUE) { gdk_threads_leave(); pthread_setspecific(_dw_mutex_key, NULL); _locked_by_me = FALSE; } }
 
 #define DEFAULT_SIZE_WIDTH 12
 #define DEFAULT_SIZE_HEIGHT 6
@@ -1836,61 +1830,13 @@
    return NULL;
 }
 
-/* Find the index of a given thread */
-static int _find_thread_index(DWTID tid)
-{
-   int z;
-
-   for(z=0;z<DW_THREAD_LIMIT;z++)
-   {
-      if(_dw_thread_list[z] == tid)
-         return z;
-   }
-   return 0;
-}
-
-/* Add a thread id to the thread list */
-static void _dw_thread_add(DWTID tid)
-{
-   int z;
-
-   for(z=0;z<DW_THREAD_LIMIT;z++)
-   {
-      if(_dw_thread_list[z] == tid)
-         return;
-
-      if(_dw_thread_list[z] == (DWTID)-1)
-      {
-         _dw_thread_list[z] = tid;
-         _foreground[z].pixel = _foreground[z].red =_foreground[z].green = _foreground[z].blue = 0;
-         _background[z].pixel = 1;
-         _background[z].red = _background[z].green = _background[z].blue = 0;
-         _transparent[z] = 1;
-         _clipboard_contents[z] = NULL;
-         _clipboard_object[z] = NULL;
-         return;
-      }
-   }
-}
-
-/* Remove a thread id to the thread list */
-static void _dw_thread_remove(DWTID tid)
-{
-   int z;
-
-   for(z=0;z<DW_THREAD_LIMIT;z++)
-   {
-      if(_dw_thread_list[z] == (DWTID)tid)
-      {
-         _dw_thread_list[z] = (DWTID)-1;
-         if ( _clipboard_contents[z] != NULL )
-         {
-            g_free( _clipboard_contents[z] );
-            _clipboard_contents[z] = NULL;;
-         }
-         _clipboard_object[z] = NULL;;
-      }
-   }
+void _init_thread(void)
+{
+   GdkColor *foreground = malloc(sizeof(GdkColor));
+   
+   foreground->pixel = foreground->red = foreground->green = foreground->blue = 0;
+   pthread_setspecific(_dw_fg_color_key, foreground);
+   pthread_setspecific(_dw_bg_color_key, NULL);
 }
 
 /* Try to load the mozilla embed shared libary */
@@ -1993,7 +1939,6 @@
  */
 int dw_int_init(DWResources *res, int newthread, int *argc, char **argv[])
 {
-   int z;
    char *tmp;
    char *fname;
 
@@ -2015,8 +1960,11 @@
    if(tmp)
       _dw_border_height = atoi(tmp);
 
-   for(z=0;z<DW_THREAD_LIMIT;z++)
-      _dw_thread_list[z] = (DWTID)-1;
+   pthread_key_create(&_dw_fg_color_key, NULL);
+   pthread_key_create(&_dw_bg_color_key, NULL);
+   pthread_key_create(&_dw_mutex_key, NULL);
+   
+   _init_thread();
     
    /* Create a global object for glib activities */
    _DWObject = g_object_new(G_TYPE_OBJECT, NULL);
@@ -2052,7 +2000,6 @@
 {
    gdk_threads_enter();
    _dw_thread = pthread_self();
-   _dw_thread_add(_dw_thread);
    gtk_main();
    _dw_thread = (pthread_t)-1;
    gdk_threads_leave();
@@ -2106,7 +2053,6 @@
 {
    gdk_threads_enter();
    _dw_thread = pthread_self();
-   _dw_thread_add(_dw_thread);
    gtk_main_iteration();
    _dw_thread = (pthread_t)-1;
    gdk_threads_leave();
@@ -6522,12 +6468,10 @@
  */
 void dw_color_foreground_set(unsigned long value)
 {
-   int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id());
    GdkColor color = _internal_color(value);
-
-   DW_MUTEX_LOCK;
-   _foreground[index] = color;
-   DW_MUTEX_UNLOCK;
+   GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
+
+   *foreground = color;
 }
 
 /* Sets the current background drawing color.
@@ -6538,17 +6482,26 @@
  */
 void dw_color_background_set(unsigned long value)
 {
-   int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id());
-   GdkColor color = _internal_color(value);
-
-   DW_MUTEX_LOCK;
+   GdkColor *background = pthread_getspecific(_dw_bg_color_key);
+   
    if(value == DW_CLR_DEFAULT)
-      _transparent[index] = 1;
+   {
+      if(background)
+      {
+         pthread_setspecific(_dw_bg_color_key, NULL);
+         free(background);
+      }
+   }
    else
-      _transparent[index] = 0;
-
-   _background[index] = color;
-   DW_MUTEX_UNLOCK;
+   {
+      GdkColor color = _internal_color(value);
+
+      if(!background)
+      {
+         background = malloc(sizeof(GdkColor));
+      }
+      *background = color;
+   }
 }
 
 /* Internal function to handle the color OK press */
@@ -6664,9 +6617,9 @@
       cr = cairo_create(pixmap->image);
    if(cr)
    {
-      int index = _find_thread_index(dw_thread_id());
+      GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
       
-      gdk_cairo_set_source_color (cr, &_foreground[index]);
+      gdk_cairo_set_source_color (cr, foreground);
       cairo_set_line_width(cr, 1);
       cairo_move_to(cr, x, y);
       cairo_stroke(cr);
@@ -6705,9 +6658,9 @@
       cr = cairo_create(pixmap->image);
    if(cr)
    {
-      int index = _find_thread_index(dw_thread_id());
+      GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
       
-      gdk_cairo_set_source_color (cr, &_foreground[index]);
+      gdk_cairo_set_source_color (cr, foreground);
       cairo_set_line_width(cr, 1);
       cairo_move_to(cr, x1, y1);
       cairo_line_to(cr, x2, y2);
@@ -6748,9 +6701,9 @@
       cr = cairo_create(pixmap->image);
    if(cr)
    {
-      int index = _find_thread_index(dw_thread_id());
+       GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
       
-      gdk_cairo_set_source_color (cr, &_foreground[index]);
+      gdk_cairo_set_source_color (cr, foreground);
       cairo_set_line_width(cr, 1);
       cairo_move_to(cr, x[0], y[0]);
       for(z=1;z<npoints;z++)
@@ -6796,9 +6749,9 @@
       cr = cairo_create(pixmap->image);
    if(cr)
    {
-      int index = _find_thread_index(dw_thread_id());
+      GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
       
-      gdk_cairo_set_source_color (cr, &_foreground[index]);
+      gdk_cairo_set_source_color (cr, foreground);
       cairo_set_line_width(cr, 1);
       cairo_move_to(cr, x, y);
       cairo_line_to(cr, x, y + height);
@@ -6861,19 +6814,20 @@
 
             if(layout)
             {
-               int index = _find_thread_index(dw_thread_id());
+               GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
+               GdkColor *background = pthread_getspecific(_dw_bg_color_key);
 
                pango_layout_set_font_description(layout, font);
                pango_layout_set_text(layout, text, strlen(text));
 
-               gdk_cairo_set_source_color (cr, &_foreground[index]);
+               gdk_cairo_set_source_color (cr, foreground);
                /* Create a background color attribute if required */
-               if(!_transparent[index])
+               if(background)
                {
                   PangoAttrList *list = pango_layout_get_attributes(layout);
-                  PangoAttribute *attr = pango_attr_background_new(_background[index].red,
-                                                                   _background[index].green,
-                                                                   _background[index].blue);
+                  PangoAttribute *attr = pango_attr_background_new(background->red,
+                                                                   background->green,
+                                                                   background->blue);
                   if(!list)
                   {
                      list = pango_attr_list_new();
@@ -7110,12 +7064,8 @@
  */
 void dw_pixmap_set_transparent_color(HPIXMAP pixmap, unsigned long color)
 {
-   int _locked_by_me = FALSE;
-
-   DW_MUTEX_LOCK;
    pixmap = pixmap;
    color = color;
-   DW_MUTEX_UNLOCK;
 }
 
 /*
@@ -7826,13 +7776,21 @@
 {
    void (*threadfunc)(void *) = NULL;
    void **tmp = (void **)data;
+   GdkColor *foreground, *background;
 
    threadfunc = (void (*)(void *))tmp[0];
-
-   _dw_thread_add(dw_thread_id());
+   
+   /* Initialize colors */
+   _init_thread();
+   
    threadfunc(tmp[1]);
-   _dw_thread_remove(dw_thread_id());
    free(tmp);
+   
+   /* Free colors */
+   if((foreground = pthread_getspecific(_dw_fg_color_key)))
+      free(foreground);
+   if((background = pthread_getspecific(_dw_bg_color_key)))
+      free(background);
 }
 
 /*
@@ -10202,20 +10160,23 @@
  */
 char *dw_clipboard_get_text()
 {
-   int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id());
-
-   DW_MUTEX_LOCK;
-   if ( _clipboard_object[index] == NULL )
-   {
-      _clipboard_object[index] = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD );
-   }
-   if ( _clipboard_contents[index] != NULL )
-   {
-      g_free( _clipboard_contents[index] );
-   }
-   _clipboard_contents[index] = gtk_clipboard_wait_for_text( _clipboard_object[index] );
-   DW_MUTEX_UNLOCK;
-   return (char *)_clipboard_contents[index];
+   int _locked_by_me = FALSE;
+   GtkClipboard *clipboard_object;
+   char *ret = NULL;
+   
+   DW_MUTEX_LOCK;
+   if((clipboard_object = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD )))
+   {
+      gchar *clipboard_contents;
+      
+      if((clipboard_contents = gtk_clipboard_wait_for_text( clipboard_object )))
+      {
+         ret = strdup((char *)clipboard_contents);
+         g_free(clipboard_contents);
+      }
+   }
+   DW_MUTEX_UNLOCK;
+   return ret;
 }
 
 /*
@@ -10225,14 +10186,14 @@
  */
 void  dw_clipboard_set_text( char *str, int len )
 {
-   int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id());
-
-   DW_MUTEX_LOCK;
-   if ( _clipboard_object[index] == NULL )
-   {
-      _clipboard_object[index] = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD );
-   }
-   gtk_clipboard_set_text( _clipboard_object[index], str, len );
+   int _locked_by_me = FALSE;
+   GtkClipboard *clipboard_object;
+
+   DW_MUTEX_LOCK;
+   if((clipboard_object = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD )))
+   {
+      gtk_clipboard_set_text( clipboard_object, str, len );
+   }
    DW_MUTEX_UNLOCK;
 }