comparison gtk3/dw.c @ 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 37f2938ecd72
children 32830f1683c9
comparison
equal deleted inserted replaced
970:b00943f21392 971:2a21915684d1
106 ".ico", 106 ".ico",
107 ".jpg", 107 ".jpg",
108 ".bmp", 108 ".bmp",
109 }; 109 };
110 110
111 #define DW_THREAD_LIMIT 50
112
113 #ifndef max 111 #ifndef max
114 # define max(a,b) (((a) > (b)) ? (a) : (b)) 112 # define max(a,b) (((a) > (b)) ? (a) : (b))
115 #endif 113 #endif
116 114
117 #ifndef min 115 #ifndef min
118 # define min(a,b) (((a) < (b)) ? (a) : (b)) 116 # define min(a,b) (((a) < (b)) ? (a) : (b))
119 #endif 117 #endif
120 118
121 FILE *dbgfp = NULL; 119 FILE *dbgfp = NULL;
122 120
123 DWTID _dw_thread_list[DW_THREAD_LIMIT]; 121 pthread_key_t _dw_fg_color_key;
124 GdkColor _foreground[DW_THREAD_LIMIT]; 122 pthread_key_t _dw_bg_color_key;
125 GdkColor _background[DW_THREAD_LIMIT]; 123 pthread_key_t _dw_mutex_key;
126 int _transparent[DW_THREAD_LIMIT];
127 GtkClipboard *_clipboard_object[DW_THREAD_LIMIT];
128 gchar *_clipboard_contents[DW_THREAD_LIMIT];
129 124
130 GtkWidget *last_window = NULL, *popup = NULL; 125 GtkWidget *last_window = NULL, *popup = NULL;
131 126
132 static int _dw_ignore_click = 0, _dw_ignore_expand = 0, _dw_color_active = 0; 127 static int _dw_ignore_click = 0, _dw_ignore_expand = 0, _dw_color_active = 0;
133 static pthread_t _dw_thread = (pthread_t)-1; 128 static pthread_t _dw_thread = (pthread_t)-1;
134 static int _dw_mutex_locked[DW_THREAD_LIMIT];
135 /* Use default border size for the default enlightenment theme */ 129 /* Use default border size for the default enlightenment theme */
136 static int _dw_border_width = 12, _dw_border_height = 28; 130 static int _dw_border_width = 12, _dw_border_height = 28;
137 131
138 #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; } } 132 #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; } }
139 #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; } } 133 #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; } }
140 134
141 #define DEFAULT_SIZE_WIDTH 12 135 #define DEFAULT_SIZE_WIDTH 12
142 #define DEFAULT_SIZE_HEIGHT 6 136 #define DEFAULT_SIZE_HEIGHT 6
143 #define DEFAULT_TITLEBAR_HEIGHT 22 137 #define DEFAULT_TITLEBAR_HEIGHT 22
144 138
1834 return icon_pixbuf; 1828 return icon_pixbuf;
1835 } 1829 }
1836 return NULL; 1830 return NULL;
1837 } 1831 }
1838 1832
1839 /* Find the index of a given thread */ 1833 void _init_thread(void)
1840 static int _find_thread_index(DWTID tid) 1834 {
1841 { 1835 GdkColor *foreground = malloc(sizeof(GdkColor));
1842 int z; 1836
1843 1837 foreground->pixel = foreground->red = foreground->green = foreground->blue = 0;
1844 for(z=0;z<DW_THREAD_LIMIT;z++) 1838 pthread_setspecific(_dw_fg_color_key, foreground);
1845 { 1839 pthread_setspecific(_dw_bg_color_key, NULL);
1846 if(_dw_thread_list[z] == tid)
1847 return z;
1848 }
1849 return 0;
1850 }
1851
1852 /* Add a thread id to the thread list */
1853 static void _dw_thread_add(DWTID tid)
1854 {
1855 int z;
1856
1857 for(z=0;z<DW_THREAD_LIMIT;z++)
1858 {
1859 if(_dw_thread_list[z] == tid)
1860 return;
1861
1862 if(_dw_thread_list[z] == (DWTID)-1)
1863 {
1864 _dw_thread_list[z] = tid;
1865 _foreground[z].pixel = _foreground[z].red =_foreground[z].green = _foreground[z].blue = 0;
1866 _background[z].pixel = 1;
1867 _background[z].red = _background[z].green = _background[z].blue = 0;
1868 _transparent[z] = 1;
1869 _clipboard_contents[z] = NULL;
1870 _clipboard_object[z] = NULL;
1871 return;
1872 }
1873 }
1874 }
1875
1876 /* Remove a thread id to the thread list */
1877 static void _dw_thread_remove(DWTID tid)
1878 {
1879 int z;
1880
1881 for(z=0;z<DW_THREAD_LIMIT;z++)
1882 {
1883 if(_dw_thread_list[z] == (DWTID)tid)
1884 {
1885 _dw_thread_list[z] = (DWTID)-1;
1886 if ( _clipboard_contents[z] != NULL )
1887 {
1888 g_free( _clipboard_contents[z] );
1889 _clipboard_contents[z] = NULL;;
1890 }
1891 _clipboard_object[z] = NULL;;
1892 }
1893 }
1894 } 1840 }
1895 1841
1896 /* Try to load the mozilla embed shared libary */ 1842 /* Try to load the mozilla embed shared libary */
1897 #ifdef USE_GTKMOZEMBED 1843 #ifdef USE_GTKMOZEMBED
1898 #include <ctype.h> 1844 #include <ctype.h>
1991 * newthread: True if this is the only thread. 1937 * newthread: True if this is the only thread.
1992 * False if there is already a message loop running. 1938 * False if there is already a message loop running.
1993 */ 1939 */
1994 int dw_int_init(DWResources *res, int newthread, int *argc, char **argv[]) 1940 int dw_int_init(DWResources *res, int newthread, int *argc, char **argv[])
1995 { 1941 {
1996 int z;
1997 char *tmp; 1942 char *tmp;
1998 char *fname; 1943 char *fname;
1999 1944
2000 if(res) 1945 if(res)
2001 { 1946 {
2013 _dw_border_width = atoi(tmp); 1958 _dw_border_width = atoi(tmp);
2014 tmp = getenv("DW_BORDER_HEIGHT"); 1959 tmp = getenv("DW_BORDER_HEIGHT");
2015 if(tmp) 1960 if(tmp)
2016 _dw_border_height = atoi(tmp); 1961 _dw_border_height = atoi(tmp);
2017 1962
2018 for(z=0;z<DW_THREAD_LIMIT;z++) 1963 pthread_key_create(&_dw_fg_color_key, NULL);
2019 _dw_thread_list[z] = (DWTID)-1; 1964 pthread_key_create(&_dw_bg_color_key, NULL);
1965 pthread_key_create(&_dw_mutex_key, NULL);
1966
1967 _init_thread();
2020 1968
2021 /* Create a global object for glib activities */ 1969 /* Create a global object for glib activities */
2022 _DWObject = g_object_new(G_TYPE_OBJECT, NULL); 1970 _DWObject = g_object_new(G_TYPE_OBJECT, NULL);
2023 1971
2024 gtk_rc_parse_string("style \"gtk-tooltips-style\" { bg[NORMAL] = \"#eeee00\" } widget \"gtk-tooltips\" style \"gtk-tooltips-style\""); 1972 gtk_rc_parse_string("style \"gtk-tooltips-style\" { bg[NORMAL] = \"#eeee00\" } widget \"gtk-tooltips\" style \"gtk-tooltips-style\"");
2050 */ 1998 */
2051 void dw_main(void) 1999 void dw_main(void)
2052 { 2000 {
2053 gdk_threads_enter(); 2001 gdk_threads_enter();
2054 _dw_thread = pthread_self(); 2002 _dw_thread = pthread_self();
2055 _dw_thread_add(_dw_thread);
2056 gtk_main(); 2003 gtk_main();
2057 _dw_thread = (pthread_t)-1; 2004 _dw_thread = (pthread_t)-1;
2058 gdk_threads_leave(); 2005 gdk_threads_leave();
2059 } 2006 }
2060 2007
2104 */ 2051 */
2105 void dw_main_iteration(void) 2052 void dw_main_iteration(void)
2106 { 2053 {
2107 gdk_threads_enter(); 2054 gdk_threads_enter();
2108 _dw_thread = pthread_self(); 2055 _dw_thread = pthread_self();
2109 _dw_thread_add(_dw_thread);
2110 gtk_main_iteration(); 2056 gtk_main_iteration();
2111 _dw_thread = (pthread_t)-1; 2057 _dw_thread = (pthread_t)-1;
2112 gdk_threads_leave(); 2058 gdk_threads_leave();
2113 } 2059 }
2114 2060
6520 * green: green value. 6466 * green: green value.
6521 * blue: blue value. 6467 * blue: blue value.
6522 */ 6468 */
6523 void dw_color_foreground_set(unsigned long value) 6469 void dw_color_foreground_set(unsigned long value)
6524 { 6470 {
6525 int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id());
6526 GdkColor color = _internal_color(value); 6471 GdkColor color = _internal_color(value);
6527 6472 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
6528 DW_MUTEX_LOCK; 6473
6529 _foreground[index] = color; 6474 *foreground = color;
6530 DW_MUTEX_UNLOCK;
6531 } 6475 }
6532 6476
6533 /* Sets the current background drawing color. 6477 /* Sets the current background drawing color.
6534 * Parameters: 6478 * Parameters:
6535 * red: red value. 6479 * red: red value.
6536 * green: green value. 6480 * green: green value.
6537 * blue: blue value. 6481 * blue: blue value.
6538 */ 6482 */
6539 void dw_color_background_set(unsigned long value) 6483 void dw_color_background_set(unsigned long value)
6540 { 6484 {
6541 int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id()); 6485 GdkColor *background = pthread_getspecific(_dw_bg_color_key);
6542 GdkColor color = _internal_color(value); 6486
6543
6544 DW_MUTEX_LOCK;
6545 if(value == DW_CLR_DEFAULT) 6487 if(value == DW_CLR_DEFAULT)
6546 _transparent[index] = 1; 6488 {
6489 if(background)
6490 {
6491 pthread_setspecific(_dw_bg_color_key, NULL);
6492 free(background);
6493 }
6494 }
6547 else 6495 else
6548 _transparent[index] = 0; 6496 {
6549 6497 GdkColor color = _internal_color(value);
6550 _background[index] = color; 6498
6551 DW_MUTEX_UNLOCK; 6499 if(!background)
6500 {
6501 background = malloc(sizeof(GdkColor));
6502 }
6503 *background = color;
6504 }
6552 } 6505 }
6553 6506
6554 /* Internal function to handle the color OK press */ 6507 /* Internal function to handle the color OK press */
6555 static gint _gtk_color_ok(GtkWidget *widget, DWDialog *dwwait) 6508 static gint _gtk_color_ok(GtkWidget *widget, DWDialog *dwwait)
6556 { 6509 {
6662 } 6615 }
6663 else if(pixmap) 6616 else if(pixmap)
6664 cr = cairo_create(pixmap->image); 6617 cr = cairo_create(pixmap->image);
6665 if(cr) 6618 if(cr)
6666 { 6619 {
6667 int index = _find_thread_index(dw_thread_id()); 6620 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
6668 6621
6669 gdk_cairo_set_source_color (cr, &_foreground[index]); 6622 gdk_cairo_set_source_color (cr, foreground);
6670 cairo_set_line_width(cr, 1); 6623 cairo_set_line_width(cr, 1);
6671 cairo_move_to(cr, x, y); 6624 cairo_move_to(cr, x, y);
6672 cairo_stroke(cr); 6625 cairo_stroke(cr);
6673 cairo_destroy(cr); 6626 cairo_destroy(cr);
6674 } 6627 }
6703 } 6656 }
6704 else if(pixmap) 6657 else if(pixmap)
6705 cr = cairo_create(pixmap->image); 6658 cr = cairo_create(pixmap->image);
6706 if(cr) 6659 if(cr)
6707 { 6660 {
6708 int index = _find_thread_index(dw_thread_id()); 6661 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
6709 6662
6710 gdk_cairo_set_source_color (cr, &_foreground[index]); 6663 gdk_cairo_set_source_color (cr, foreground);
6711 cairo_set_line_width(cr, 1); 6664 cairo_set_line_width(cr, 1);
6712 cairo_move_to(cr, x1, y1); 6665 cairo_move_to(cr, x1, y1);
6713 cairo_line_to(cr, x2, y2); 6666 cairo_line_to(cr, x2, y2);
6714 cairo_stroke(cr); 6667 cairo_stroke(cr);
6715 cairo_destroy(cr); 6668 cairo_destroy(cr);
6746 } 6699 }
6747 else if(pixmap) 6700 else if(pixmap)
6748 cr = cairo_create(pixmap->image); 6701 cr = cairo_create(pixmap->image);
6749 if(cr) 6702 if(cr)
6750 { 6703 {
6751 int index = _find_thread_index(dw_thread_id()); 6704 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
6752 6705
6753 gdk_cairo_set_source_color (cr, &_foreground[index]); 6706 gdk_cairo_set_source_color (cr, foreground);
6754 cairo_set_line_width(cr, 1); 6707 cairo_set_line_width(cr, 1);
6755 cairo_move_to(cr, x[0], y[0]); 6708 cairo_move_to(cr, x[0], y[0]);
6756 for(z=1;z<npoints;z++) 6709 for(z=1;z<npoints;z++)
6757 { 6710 {
6758 cairo_line_to(cr, x[z], y[z]); 6711 cairo_line_to(cr, x[z], y[z]);
6794 } 6747 }
6795 else if(pixmap) 6748 else if(pixmap)
6796 cr = cairo_create(pixmap->image); 6749 cr = cairo_create(pixmap->image);
6797 if(cr) 6750 if(cr)
6798 { 6751 {
6799 int index = _find_thread_index(dw_thread_id()); 6752 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
6800 6753
6801 gdk_cairo_set_source_color (cr, &_foreground[index]); 6754 gdk_cairo_set_source_color (cr, foreground);
6802 cairo_set_line_width(cr, 1); 6755 cairo_set_line_width(cr, 1);
6803 cairo_move_to(cr, x, y); 6756 cairo_move_to(cr, x, y);
6804 cairo_line_to(cr, x, y + height); 6757 cairo_line_to(cr, x, y + height);
6805 cairo_line_to(cr, x + width, y + height); 6758 cairo_line_to(cr, x + width, y + height);
6806 cairo_line_to(cr, x + width, y); 6759 cairo_line_to(cr, x + width, y);
6859 { 6812 {
6860 PangoLayout *layout = pango_layout_new(context); 6813 PangoLayout *layout = pango_layout_new(context);
6861 6814
6862 if(layout) 6815 if(layout)
6863 { 6816 {
6864 int index = _find_thread_index(dw_thread_id()); 6817 GdkColor *foreground = pthread_getspecific(_dw_fg_color_key);
6818 GdkColor *background = pthread_getspecific(_dw_bg_color_key);
6865 6819
6866 pango_layout_set_font_description(layout, font); 6820 pango_layout_set_font_description(layout, font);
6867 pango_layout_set_text(layout, text, strlen(text)); 6821 pango_layout_set_text(layout, text, strlen(text));
6868 6822
6869 gdk_cairo_set_source_color (cr, &_foreground[index]); 6823 gdk_cairo_set_source_color (cr, foreground);
6870 /* Create a background color attribute if required */ 6824 /* Create a background color attribute if required */
6871 if(!_transparent[index]) 6825 if(background)
6872 { 6826 {
6873 PangoAttrList *list = pango_layout_get_attributes(layout); 6827 PangoAttrList *list = pango_layout_get_attributes(layout);
6874 PangoAttribute *attr = pango_attr_background_new(_background[index].red, 6828 PangoAttribute *attr = pango_attr_background_new(background->red,
6875 _background[index].green, 6829 background->green,
6876 _background[index].blue); 6830 background->blue);
6877 if(!list) 6831 if(!list)
6878 { 6832 {
6879 list = pango_attr_list_new(); 6833 list = pango_attr_list_new();
6880 } 6834 }
6881 pango_attr_list_change(list, attr); 6835 pango_attr_list_change(list, attr);
7108 * Note: This does nothing on GTK+ as transparency 7062 * Note: This does nothing on GTK+ as transparency
7109 * is handled automatically 7063 * is handled automatically
7110 */ 7064 */
7111 void dw_pixmap_set_transparent_color(HPIXMAP pixmap, unsigned long color) 7065 void dw_pixmap_set_transparent_color(HPIXMAP pixmap, unsigned long color)
7112 { 7066 {
7113 int _locked_by_me = FALSE;
7114
7115 DW_MUTEX_LOCK;
7116 pixmap = pixmap; 7067 pixmap = pixmap;
7117 color = color; 7068 color = color;
7118 DW_MUTEX_UNLOCK;
7119 } 7069 }
7120 7070
7121 /* 7071 /*
7122 * Creates a pixmap from internal resource graphic specified by id. 7072 * Creates a pixmap from internal resource graphic specified by id.
7123 * Parameters: 7073 * Parameters:
7824 */ 7774 */
7825 void _dwthreadstart(void *data) 7775 void _dwthreadstart(void *data)
7826 { 7776 {
7827 void (*threadfunc)(void *) = NULL; 7777 void (*threadfunc)(void *) = NULL;
7828 void **tmp = (void **)data; 7778 void **tmp = (void **)data;
7779 GdkColor *foreground, *background;
7829 7780
7830 threadfunc = (void (*)(void *))tmp[0]; 7781 threadfunc = (void (*)(void *))tmp[0];
7831 7782
7832 _dw_thread_add(dw_thread_id()); 7783 /* Initialize colors */
7784 _init_thread();
7785
7833 threadfunc(tmp[1]); 7786 threadfunc(tmp[1]);
7834 _dw_thread_remove(dw_thread_id());
7835 free(tmp); 7787 free(tmp);
7788
7789 /* Free colors */
7790 if((foreground = pthread_getspecific(_dw_fg_color_key)))
7791 free(foreground);
7792 if((background = pthread_getspecific(_dw_bg_color_key)))
7793 free(background);
7836 } 7794 }
7837 7795
7838 /* 7796 /*
7839 * Allocates a shared memory region with a name. 7797 * Allocates a shared memory region with a name.
7840 * Parameters: 7798 * Parameters:
10200 * Pointer to an allocated string of text or NULL if clipboard empty or contents could not 10158 * Pointer to an allocated string of text or NULL if clipboard empty or contents could not
10201 * be converted to text. 10159 * be converted to text.
10202 */ 10160 */
10203 char *dw_clipboard_get_text() 10161 char *dw_clipboard_get_text()
10204 { 10162 {
10205 int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id()); 10163 int _locked_by_me = FALSE;
10206 10164 GtkClipboard *clipboard_object;
10207 DW_MUTEX_LOCK; 10165 char *ret = NULL;
10208 if ( _clipboard_object[index] == NULL ) 10166
10209 { 10167 DW_MUTEX_LOCK;
10210 _clipboard_object[index] = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); 10168 if((clipboard_object = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD )))
10211 } 10169 {
10212 if ( _clipboard_contents[index] != NULL ) 10170 gchar *clipboard_contents;
10213 { 10171
10214 g_free( _clipboard_contents[index] ); 10172 if((clipboard_contents = gtk_clipboard_wait_for_text( clipboard_object )))
10215 } 10173 {
10216 _clipboard_contents[index] = gtk_clipboard_wait_for_text( _clipboard_object[index] ); 10174 ret = strdup((char *)clipboard_contents);
10217 DW_MUTEX_UNLOCK; 10175 g_free(clipboard_contents);
10218 return (char *)_clipboard_contents[index]; 10176 }
10177 }
10178 DW_MUTEX_UNLOCK;
10179 return ret;
10219 } 10180 }
10220 10181
10221 /* 10182 /*
10222 * Sets the contents of the default clipboard to the supplied text. 10183 * Sets the contents of the default clipboard to the supplied text.
10223 * Parameters: 10184 * Parameters:
10224 * Text. 10185 * Text.
10225 */ 10186 */
10226 void dw_clipboard_set_text( char *str, int len ) 10187 void dw_clipboard_set_text( char *str, int len )
10227 { 10188 {
10228 int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id()); 10189 int _locked_by_me = FALSE;
10229 10190 GtkClipboard *clipboard_object;
10230 DW_MUTEX_LOCK; 10191
10231 if ( _clipboard_object[index] == NULL ) 10192 DW_MUTEX_LOCK;
10232 { 10193 if((clipboard_object = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD )))
10233 _clipboard_object[index] = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); 10194 {
10234 } 10195 gtk_clipboard_set_text( clipboard_object, str, len );
10235 gtk_clipboard_set_text( _clipboard_object[index], str, len ); 10196 }
10236 DW_MUTEX_UNLOCK; 10197 DW_MUTEX_UNLOCK;
10237 } 10198 }
10238 10199
10239 /* 10200 /*
10240 * Returns a pointer to a static buffer which containes the 10201 * Returns a pointer to a static buffer which containes the