Mercurial > dwindows
comparison gtk3/dw.c @ 775:5ec50e403a8a
Added initial support for GTK 3.0. Split it off into its own directory.
Lots of stuff is broken but it builds and sort of works.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sun, 20 Mar 2011 05:12:40 +0000 |
parents | |
children | c0e7200dad31 |
comparison
equal
deleted
inserted
replaced
774:bf3e9892146f | 775:5ec50e403a8a |
---|---|
1 /* | |
2 * Dynamic Windows: | |
3 * A GTK like implementation of the PM GUI | |
4 * GTK3 forwarder module for portabilty. | |
5 * | |
6 * (C) 2000-2011 Brian Smith <brian@dbsoft.org> | |
7 * (C) 2003-2004 Mark Hessling <m.hessling@qut.edu.au> | |
8 * (C) 2002 Nickolay V. Shmyrev <shmyrev@yandex.ru> | |
9 */ | |
10 #include "config.h" | |
11 #include "dw.h" | |
12 #include <string.h> | |
13 #include <stdlib.h> | |
14 #if !defined(GDK_WINDOWING_WIN32) | |
15 # include <sys/utsname.h> | |
16 # include <sys/socket.h> | |
17 # include <sys/un.h> | |
18 # include <sys/mman.h> | |
19 #endif | |
20 #include <stdarg.h> | |
21 #include <stdio.h> | |
22 #include <unistd.h> | |
23 #include <errno.h> | |
24 #include <sys/time.h> | |
25 #include <dirent.h> | |
26 #include <sys/stat.h> | |
27 #include <signal.h> | |
28 #include <fcntl.h> | |
29 #include <unistd.h> | |
30 #include <gdk/gdkkeysyms.h> | |
31 #ifdef USE_IMLIB | |
32 #include <gdk_imlib.h> | |
33 #endif | |
34 | |
35 #ifdef USE_GTKMOZEMBED | |
36 # include <gtkmozembed.h> | |
37 # undef GTK_TYPE_MOZ_EMBED | |
38 # define GTK_TYPE_MOZ_EMBED (_dw_moz_embed_get_type()) | |
39 #endif | |
40 | |
41 #ifdef USE_LIBGTKHTML2 | |
42 # include <libgtkhtml/gtkhtml.h> | |
43 #endif | |
44 | |
45 #ifdef USE_WEBKIT | |
46 # if defined(USE_WEBKIT10) || defined(USE_WEBKIT11) | |
47 # include <webkit/webkit.h> | |
48 # else | |
49 # include <webkit.h> | |
50 # endif | |
51 #endif | |
52 | |
53 #include <gdk-pixbuf/gdk-pixbuf.h> | |
54 | |
55 #if __STDC_VERSION__ < 199901L | |
56 # if __GNUC__ >= 2 | |
57 # define __func__ __FUNCTION__ | |
58 # else | |
59 # define __func__ "<unknown>" | |
60 # endif | |
61 #endif | |
62 | |
63 #include "gtk/messagebox_error.xpm" | |
64 #include "gtk/messagebox_warning.xpm" | |
65 #include "gtk/messagebox_information.xpm" | |
66 #include "gtk/messagebox_question.xpm" | |
67 | |
68 #ifdef USE_GTKMOZEMBED | |
69 extern gint mozilla_get_mouse_event_button(gpointer event); | |
70 extern gint mozilla_get_mouse_location( gpointer event, glong *x, glong *y); | |
71 #endif | |
72 | |
73 /* These are used for resource management */ | |
74 #if defined(DW_RESOURCES) && !defined(BUILD_DLL) | |
75 extern DWResources _resources; | |
76 #endif | |
77 | |
78 GdkColor _colors[] = | |
79 { | |
80 { 0, 0x0000, 0x0000, 0x0000 }, /* 0 black */ | |
81 { 0, 0xbbbb, 0x0000, 0x0000 }, /* 1 red */ | |
82 { 0, 0x0000, 0xbbbb, 0x0000 }, /* 2 green */ | |
83 { 0, 0xaaaa, 0xaaaa, 0x0000 }, /* 3 yellow */ | |
84 { 0, 0x0000, 0x0000, 0xcccc }, /* 4 blue */ | |
85 { 0, 0xbbbb, 0x0000, 0xbbbb }, /* 5 magenta */ | |
86 { 0, 0x0000, 0xbbbb, 0xbbbb }, /* 6 cyan */ | |
87 { 0, 0xbbbb, 0xbbbb, 0xbbbb }, /* 7 white */ | |
88 { 0, 0x7777, 0x7777, 0x7777 }, /* 8 grey */ | |
89 { 0, 0xffff, 0x0000, 0x0000 }, /* 9 bright red */ | |
90 { 0, 0x0000, 0xffff, 0x0000 }, /* 10 bright green */ | |
91 { 0, 0xeeee, 0xeeee, 0x0000 }, /* 11 bright yellow */ | |
92 { 0, 0x0000, 0x0000, 0xffff }, /* 12 bright blue */ | |
93 { 0, 0xffff, 0x0000, 0xffff }, /* 13 bright magenta */ | |
94 { 0, 0x0000, 0xeeee, 0xeeee }, /* 14 bright cyan */ | |
95 { 0, 0xffff, 0xffff, 0xffff }, /* 15 bright white */ | |
96 }; | |
97 | |
98 /* | |
99 * List those icons that have transparency first | |
100 */ | |
101 #define NUM_EXTS 5 | |
102 char *image_exts[NUM_EXTS] = | |
103 { | |
104 ".xpm", | |
105 ".png", | |
106 ".ico", | |
107 ".jpg", | |
108 ".bmp", | |
109 }; | |
110 | |
111 #define DW_THREAD_LIMIT 50 | |
112 | |
113 #ifndef max | |
114 # define max(a,b) (((a) > (b)) ? (a) : (b)) | |
115 #endif | |
116 | |
117 #ifndef min | |
118 # define min(a,b) (((a) < (b)) ? (a) : (b)) | |
119 #endif | |
120 | |
121 FILE *dbgfp = NULL; | |
122 | |
123 DWTID _dw_thread_list[DW_THREAD_LIMIT]; | |
124 GdkColor _foreground[DW_THREAD_LIMIT]; | |
125 GdkColor _background[DW_THREAD_LIMIT]; | |
126 int _transparent[DW_THREAD_LIMIT]; | |
127 GtkClipboard *_clipboard_object[DW_THREAD_LIMIT]; | |
128 gchar *_clipboard_contents[DW_THREAD_LIMIT]; | |
129 | |
130 GtkWidget *last_window = NULL, *popup = NULL; | |
131 | |
132 static int _dw_ignore_click = 0, _dw_ignore_expand = 0, _dw_color_active = 0; | |
133 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 */ | |
136 static int _dw_border_width = 12, _dw_border_height = 28; | |
137 | |
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; } } | |
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; } } | |
140 | |
141 #define DEFAULT_SIZE_WIDTH 12 | |
142 #define DEFAULT_SIZE_HEIGHT 6 | |
143 #define DEFAULT_TITLEBAR_HEIGHT 22 | |
144 | |
145 static GdkVisual *_dw_cmap = NULL; | |
146 | |
147 /* Signal forwarder prototypes */ | |
148 static gint _button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data); | |
149 static gint _button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data); | |
150 static gint _motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data); | |
151 static gint _delete_event(GtkWidget *widget, GdkEvent *event, gpointer data); | |
152 static gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data); | |
153 static gint _generic_event(GtkWidget *widget, gpointer data); | |
154 static gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data); | |
155 static gint _activate_event(GtkWidget *widget, gpointer data); | |
156 static gint _container_select_event(GtkWidget *widget, GdkEventButton *event, gpointer data); | |
157 static gint _container_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data); | |
158 static gint _item_select_event(GtkWidget *widget, GtkWidget *child, gpointer data); | |
159 static gint _expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data); | |
160 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data); | |
161 static gint _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data); | |
162 static gint _value_changed_event(GtkAdjustment *adjustment, gpointer user_data); | |
163 static gint _tree_select_event(GtkTreeSelection *sel, gpointer data); | |
164 static gint _tree_expand_event(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer data); | |
165 static gint _switch_page_event(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data); | |
166 static gint _column_click_event(GtkWidget *widget, gint column_num, gpointer data); | |
167 | |
168 /* Embedable Mozilla functions*/ | |
169 #ifdef USE_GTKMOZEMBED | |
170 void (*_gtk_moz_embed_go_back)(GtkMozEmbed *) = NULL; | |
171 void (*_gtk_moz_embed_go_forward)(GtkMozEmbed *) = NULL; | |
172 void (*_gtk_moz_embed_load_url)(GtkMozEmbed *, const char *) = NULL; | |
173 void (*_gtk_moz_embed_reload)(GtkMozEmbed *, guint32) = NULL; | |
174 void (*_gtk_moz_embed_stop_load)(GtkMozEmbed *) = NULL; | |
175 void (*_gtk_moz_embed_render_data)(GtkMozEmbed *, const char *, guint32, const char *, const char *) = NULL; | |
176 GtkWidget *(*_gtk_moz_embed_new)(void) = NULL; | |
177 GtkType (*_dw_moz_embed_get_type)(void) = NULL; | |
178 gboolean (*_gtk_moz_embed_can_go_back)(GtkMozEmbed *) = NULL; | |
179 gboolean (*_gtk_moz_embed_can_go_forward)(GtkMozEmbed *) = NULL; | |
180 void (*_gtk_moz_embed_set_comp_path)(const char *) = NULL; | |
181 void (*_gtk_moz_embed_set_profile_path)(const char *, const char *) = NULL; | |
182 void (*_gtk_moz_embed_push_startup)(void) = NULL; | |
183 #endif | |
184 | |
185 #ifdef USE_LIBGTKHTML2 | |
186 GtkHtmlContext *(*_gtk_html_context_get)(void) = NULL; | |
187 HtmlDocument *(*_html_document_new)(void) = NULL; | |
188 GtkWidget *(*_html_view_new)(void) = NULL; | |
189 #endif | |
190 | |
191 #ifdef USE_WEBKIT | |
192 /* | |
193 * we need to add these equivalents from webkitwebview.h so we can refer to | |
194 * our own pointers to functions (we don't link with the webkit libraries | |
195 */ | |
196 # define DW_WEBKIT_TYPE_WEB_VIEW (_webkit_web_view_get_type()) | |
197 # define DW_WEBKIT_WEB_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), DW_WEBKIT_TYPE_WEB_VIEW, WebKitWebView)) | |
198 WEBKIT_API GType (*_webkit_web_view_get_type)(void) = NULL; | |
199 WEBKIT_API void (*_webkit_web_view_load_html_string)(WebKitWebView *, const gchar *, const gchar *) = NULL; | |
200 WEBKIT_API void (*_webkit_web_view_open)(WebKitWebView *, const gchar *) = NULL; | |
201 WEBKIT_API GtkWidget *(*_webkit_web_view_new)(void) = NULL; | |
202 WEBKIT_API void (*_webkit_web_view_go_back)(WebKitWebView *) = NULL; | |
203 WEBKIT_API void (*_webkit_web_view_go_forward)(WebKitWebView *) = NULL; | |
204 WEBKIT_API void (*_webkit_web_view_reload)(WebKitWebView *) = NULL; | |
205 WEBKIT_API void (*_webkit_web_view_stop_loading)(WebKitWebView *) = NULL; | |
206 # ifdef WEBKIT_CHECK_VERSION | |
207 # if WEBKIT_CHECK_VERSION(1,1,5) | |
208 WEBKIT_API void (*_webkit_web_frame_print)(WebKitWebFrame *) = NULL; | |
209 WEBKIT_API WebKitWebFrame *(*_webkit_web_view_get_focused_frame)(WebKitWebView *) = NULL; | |
210 # endif | |
211 # endif | |
212 #endif | |
213 | |
214 typedef struct | |
215 { | |
216 GdkPixbuf *pixbuf; | |
217 int used; | |
218 unsigned long width, height; | |
219 } DWPrivatePixmap; | |
220 | |
221 static DWPrivatePixmap *_PixmapArray = NULL; | |
222 static int _PixmapCount = 0; | |
223 | |
224 typedef struct | |
225 { | |
226 void *func; | |
227 char name[30]; | |
228 | |
229 } SignalList; | |
230 | |
231 typedef struct | |
232 { | |
233 HWND window; | |
234 void *func; | |
235 gpointer data; | |
236 gint cid; | |
237 void *intfunc; | |
238 | |
239 } SignalHandler; | |
240 | |
241 #define SIGNALMAX 19 | |
242 | |
243 /* A list of signal forwarders, to account for paramater differences. */ | |
244 static SignalList SignalTranslate[SIGNALMAX] = { | |
245 { _configure_event, DW_SIGNAL_CONFIGURE }, | |
246 { _key_press_event, DW_SIGNAL_KEY_PRESS }, | |
247 { _button_press_event, DW_SIGNAL_BUTTON_PRESS }, | |
248 { _button_release_event, DW_SIGNAL_BUTTON_RELEASE }, | |
249 { _motion_notify_event, DW_SIGNAL_MOTION_NOTIFY }, | |
250 { _delete_event, DW_SIGNAL_DELETE }, | |
251 { _expose_event, DW_SIGNAL_EXPOSE }, | |
252 { _activate_event, "activate" }, | |
253 { _generic_event, DW_SIGNAL_CLICKED }, | |
254 { _container_select_event, DW_SIGNAL_ITEM_ENTER }, | |
255 { _container_context_event, DW_SIGNAL_ITEM_CONTEXT }, | |
256 { _tree_context_event, "tree-context" }, | |
257 { _item_select_event, DW_SIGNAL_LIST_SELECT }, | |
258 { _tree_select_event, DW_SIGNAL_ITEM_SELECT }, | |
259 { _set_focus_event, DW_SIGNAL_SET_FOCUS }, | |
260 { _value_changed_event, DW_SIGNAL_VALUE_CHANGED }, | |
261 { _switch_page_event, DW_SIGNAL_SWITCH_PAGE }, | |
262 { _column_click_event, DW_SIGNAL_COLUMN_CLICK }, | |
263 { _tree_expand_event, DW_SIGNAL_TREE_EXPAND } | |
264 }; | |
265 | |
266 /* Alignment flags */ | |
267 #define DW_CENTER 0.5f | |
268 #define DW_LEFT 0.0f | |
269 #define DW_RIGHT 1.0f | |
270 #define DW_TOP 0.0f | |
271 #define DW_BOTTOM 1.0f | |
272 | |
273 /* MDI Support Code */ | |
274 #define GTK_MDI(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, gtk_mdi_get_type (), GtkMdi) | |
275 #define GTK_MDI_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, gtk_mdi_get_type (), GtkMdiClass) | |
276 #define GTK_IS_MDI(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gtk_mdi_get_type ()) | |
277 | |
278 typedef struct _GtkMdi GtkMdi; | |
279 typedef struct _GtkMdiClass GtkMdiClass; | |
280 typedef struct _GtkMdiDragInfo GtkMdiDragInfo; | |
281 typedef enum _GtkMdiChildState GtkMdiChildState; | |
282 | |
283 enum _GtkMdiChildState | |
284 { | |
285 CHILD_NORMAL, | |
286 CHILD_MAXIMIZED, | |
287 CHILD_ICONIFIED | |
288 }; | |
289 | |
290 struct _GtkMdi | |
291 { | |
292 GtkContainer container; | |
293 GList *children; | |
294 | |
295 GdkPoint drag_start; | |
296 gint drag_button; | |
297 }; | |
298 | |
299 struct _GtkMdiClass | |
300 { | |
301 GtkContainerClass parent_class; | |
302 | |
303 void (*mdi) (GtkMdi * mdi); | |
304 }; | |
305 | |
306 #include "gtk/maximize.xpm" | |
307 #include "gtk/minimize.xpm" | |
308 #include "gtk/kill.xpm" | |
309 | |
310 #define GTK_MDI_BACKGROUND "Grey70" | |
311 #define GTK_MDI_LABEL_BACKGROUND "RoyalBlue4" | |
312 #define GTK_MDI_LABEL_FOREGROUND "white" | |
313 #define GTK_MDI_DEFAULT_WIDTH 0 | |
314 #define GTK_MDI_DEFAULT_HEIGHT 0 | |
315 #define GTK_MDI_MIN_HEIGHT 22 | |
316 #define GTK_MDI_MIN_WIDTH 55 | |
317 | |
318 typedef struct _GtkMdiChild GtkMdiChild; | |
319 | |
320 struct _GtkMdiChild | |
321 { | |
322 GtkWidget *widget; | |
323 | |
324 GtkWidget *child; | |
325 GtkMdi *mdi; | |
326 | |
327 gint x; | |
328 gint y; | |
329 gint width; | |
330 gint height; | |
331 | |
332 GtkMdiChildState state; | |
333 }; | |
334 | |
335 static void gtk_mdi_class_init(GtkMdiClass *klass); | |
336 static void gtk_mdi_init(GtkMdi *mdi); | |
337 | |
338 static void gtk_mdi_realize(GtkWidget *widget); | |
339 static void gtk_mdi_size_request(GtkWidget *widget, GtkRequisition *requisition); | |
340 static void gtk_mdi_size_allocate(GtkWidget *widget, GtkAllocation *allocation); | |
341 static gint gtk_mdi_expose(GtkWidget *widget, GdkEventExpose *event); | |
342 | |
343 /* Callbacks */ | |
344 static gboolean move_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
345 static gboolean resize_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
346 static gboolean iconify_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
347 static gboolean maximize_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
348 static gboolean kill_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data); | |
349 | |
350 static void gtk_mdi_add(GtkContainer *container, GtkWidget *widget); | |
351 static void gtk_mdi_remove_true(GtkContainer *container, GtkWidget *widget); | |
352 static void gtk_mdi_forall(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); | |
353 | |
354 static GtkMdiChild *get_child(GtkMdi *mdi, GtkWidget * widget); | |
355 | |
356 static void _dw_log( char *format, ... ) | |
357 { | |
358 va_list args; | |
359 va_start(args, format); | |
360 if ( dbgfp != NULL ) | |
361 { | |
362 vfprintf( dbgfp, format, args ); | |
363 fflush( dbgfp ); | |
364 } | |
365 va_end(args); | |
366 } | |
367 | |
368 static GType gtk_mdi_get_type(void) | |
369 { | |
370 static GType mdi_type = 0; | |
371 | |
372 if (!mdi_type) | |
373 { | |
374 | |
375 static const GTypeInfo mdi_info = | |
376 { | |
377 sizeof (GtkMdiClass), | |
378 NULL, | |
379 NULL, | |
380 (GClassInitFunc) gtk_mdi_class_init, | |
381 NULL, | |
382 NULL, | |
383 sizeof (GtkMdi), | |
384 0, | |
385 (GInstanceInitFunc) gtk_mdi_init, | |
386 }; | |
387 | |
388 mdi_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkMdi", &mdi_info, 0); | |
389 } | |
390 | |
391 return mdi_type; | |
392 } | |
393 | |
394 /* Local data */ | |
395 static GtkWidgetClass *parent_class = NULL; | |
396 | |
397 static void gtk_mdi_class_init(GtkMdiClass *class) | |
398 { | |
399 GObjectClass *object_class; | |
400 GtkWidgetClass *widget_class; | |
401 GtkContainerClass *container_class; | |
402 | |
403 object_class = (GObjectClass *) class; | |
404 widget_class = (GtkWidgetClass *) class; | |
405 container_class = (GtkContainerClass *) class; | |
406 | |
407 parent_class = g_type_class_ref (GTK_TYPE_CONTAINER); | |
408 | |
409 widget_class->realize = gtk_mdi_realize; | |
410 #if 0 /* TODO */ | |
411 widget_class->expose_event = gtk_mdi_expose; | |
412 widget_class->size_request = gtk_mdi_size_request; | |
413 #endif | |
414 widget_class->size_allocate = gtk_mdi_size_allocate; | |
415 | |
416 container_class->add = gtk_mdi_add; | |
417 container_class->remove = gtk_mdi_remove_true; | |
418 container_class->forall = gtk_mdi_forall; | |
419 class->mdi = NULL; | |
420 } | |
421 | |
422 static void gtk_mdi_init(GtkMdi *mdi) | |
423 { | |
424 mdi->drag_button = -1; | |
425 mdi->children = NULL; | |
426 } | |
427 | |
428 static GtkWidget *gtk_mdi_new(void) | |
429 { | |
430 GtkWidget *mdi; | |
431 GdkColor background; | |
432 | |
433 mdi = GTK_WIDGET (g_object_new (gtk_mdi_get_type (), NULL)); | |
434 gdk_color_parse (GTK_MDI_BACKGROUND, &background); | |
435 gtk_widget_modify_bg (mdi, GTK_STATE_NORMAL, &background); | |
436 | |
437 return mdi; | |
438 } | |
439 | |
440 static void gtk_mdi_put(GtkMdi *mdi, GtkWidget *child_widget, gint x, gint y, GtkWidget *label) | |
441 { | |
442 GtkMdiChild *child; | |
443 | |
444 GtkWidget *table; | |
445 GtkWidget *button[3]; | |
446 | |
447 GtkWidget *child_box; | |
448 GtkWidget *top_event_box; | |
449 GtkWidget *bottom_event_box; | |
450 GtkWidget *child_widget_box; | |
451 GtkWidget *image; | |
452 | |
453 GdkColor color; | |
454 gint i, j; | |
455 GdkCursor *cursor; | |
456 GdkPixbuf *pixbuf; | |
457 GtkStyle *style; | |
458 | |
459 child_box = gtk_event_box_new (); | |
460 child_widget_box = gtk_event_box_new (); | |
461 top_event_box = gtk_event_box_new (); | |
462 bottom_event_box = gtk_event_box_new (); | |
463 table = gtk_table_new (4, 7, FALSE); | |
464 gtk_table_set_row_spacings (GTK_TABLE (table), 1); | |
465 gtk_table_set_col_spacings (GTK_TABLE (table), 1); | |
466 gtk_table_set_row_spacing (GTK_TABLE (table), 3, 0); | |
467 gtk_table_set_col_spacing (GTK_TABLE (table), 6, 0); | |
468 gtk_table_set_row_spacing (GTK_TABLE (table), 2, 0); | |
469 gtk_table_set_col_spacing (GTK_TABLE (table), 5, 0); | |
470 | |
471 for (i = 0; i < 3; i++) | |
472 { | |
473 button[i] = gtk_event_box_new (); | |
474 gtk_widget_set_events (button[0], GDK_BUTTON_PRESS_MASK); | |
475 } | |
476 | |
477 gdk_color_parse (GTK_MDI_LABEL_BACKGROUND, &color); | |
478 | |
479 gtk_widget_modify_bg (top_event_box, GTK_STATE_NORMAL, &color); | |
480 gtk_widget_modify_bg (bottom_event_box, GTK_STATE_NORMAL, &color); | |
481 gtk_widget_modify_bg (child_box, GTK_STATE_NORMAL, &color); | |
482 for (i = GTK_STATE_NORMAL; i < GTK_STATE_ACTIVE; i++) | |
483 { | |
484 for (j = 0; j < 3; j++) | |
485 { | |
486 gtk_widget_modify_bg (button[j], i, &color); | |
487 } | |
488 } | |
489 gdk_color_parse (GTK_MDI_LABEL_FOREGROUND, &color); | |
490 gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &color); | |
491 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); | |
492 | |
493 gtk_container_add (GTK_CONTAINER (top_event_box), label); | |
494 gtk_container_add (GTK_CONTAINER (child_widget_box), child_widget); | |
495 gtk_widget_set_size_request (bottom_event_box, 2, 2); | |
496 | |
497 | |
498 style = gtk_widget_get_default_style (); | |
499 pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)minimize_xpm); | |
500 image = gtk_image_new_from_pixbuf(pixbuf); | |
501 gtk_widget_show(image); | |
502 gtk_container_add (GTK_CONTAINER (button[0]), image); | |
503 pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **) maximize_xpm); | |
504 image = gtk_image_new_from_pixbuf(pixbuf); | |
505 gtk_widget_show(image); | |
506 gtk_container_add (GTK_CONTAINER (button[1]), image); | |
507 pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **) kill_xpm); | |
508 image = gtk_image_new_from_pixbuf(pixbuf); | |
509 gtk_widget_show(image); | |
510 gtk_container_add (GTK_CONTAINER (button[2]), image); | |
511 | |
512 gtk_table_attach (GTK_TABLE (table), child_widget_box, 1, 6, 2, 3, | |
513 GTK_EXPAND | GTK_SHRINK | GTK_FILL, | |
514 GTK_EXPAND | GTK_SHRINK | GTK_FILL, | |
515 0, 0); | |
516 gtk_table_attach (GTK_TABLE (table), top_event_box, 1, 2, 1, 2, | |
517 GTK_FILL | GTK_EXPAND | GTK_SHRINK, | |
518 0, | |
519 0, 0); | |
520 gtk_table_attach (GTK_TABLE (table), bottom_event_box, 6, 7, 3, 4, | |
521 0, | |
522 0, | |
523 0, 0); | |
524 gtk_table_attach (GTK_TABLE (table), button[0], 2, 3, 1, 2, | |
525 0, | |
526 0, | |
527 0, 0); | |
528 gtk_table_attach (GTK_TABLE (table), button[1], 3, 4, 1, 2, | |
529 0, | |
530 0, | |
531 0, 0); | |
532 gtk_table_attach (GTK_TABLE (table), button[2], 4, 5, 1, 2, | |
533 0, | |
534 0, | |
535 0, 0); | |
536 | |
537 gtk_container_add (GTK_CONTAINER (child_box), table); | |
538 | |
539 child = g_new (GtkMdiChild, 1); | |
540 child->widget = child_box; | |
541 child->x = x; | |
542 child->y = y; | |
543 child->width = -1; | |
544 child->height = -1; | |
545 child->child = child_widget; | |
546 child->mdi = mdi; | |
547 child->state = CHILD_NORMAL; | |
548 | |
549 gtk_widget_set_parent (child_box, GTK_WIDGET (mdi)); | |
550 mdi->children = g_list_append (mdi->children, child); | |
551 | |
552 gtk_widget_show (child_box); | |
553 gtk_widget_show (table); | |
554 gtk_widget_show (top_event_box); | |
555 gtk_widget_show (bottom_event_box); | |
556 gtk_widget_show (child_widget_box); | |
557 for (i = 0; i < 3; i++) | |
558 { | |
559 gtk_widget_show (button[i]); | |
560 } | |
561 | |
562 cursor = gdk_cursor_new (GDK_HAND1); | |
563 gtk_widget_realize (top_event_box); | |
564 gdk_window_set_cursor (gtk_widget_get_window(top_event_box), cursor); | |
565 cursor = gdk_cursor_new (GDK_BOTTOM_RIGHT_CORNER); | |
566 gtk_widget_realize (bottom_event_box); | |
567 gdk_window_set_cursor (gtk_widget_get_window(bottom_event_box), cursor); | |
568 | |
569 g_signal_connect (G_OBJECT (top_event_box), "event", | |
570 G_CALLBACK (move_child_callback), | |
571 child); | |
572 g_signal_connect (G_OBJECT (bottom_event_box), "event", | |
573 G_CALLBACK (resize_child_callback), | |
574 child); | |
575 g_signal_connect (G_OBJECT (button[0]), "button_press_event", | |
576 G_CALLBACK (iconify_child_callback), | |
577 child); | |
578 g_signal_connect (G_OBJECT (button[1]), "button_press_event", | |
579 G_CALLBACK (maximize_child_callback), | |
580 child); | |
581 g_signal_connect (G_OBJECT (button[2]), "button_press_event", | |
582 G_CALLBACK (kill_child_callback), | |
583 child); | |
584 } | |
585 | |
586 static void gtk_mdi_move(GtkMdi *mdi, GtkWidget *widget, gint x, gint y) | |
587 { | |
588 GtkMdiChild *child; | |
589 | |
590 g_return_if_fail(GTK_IS_MDI(mdi)); | |
591 g_return_if_fail(GTK_IS_WIDGET(widget)); | |
592 | |
593 child = get_child(mdi, widget); | |
594 g_return_if_fail(child); | |
595 | |
596 child->x = x; | |
597 child->y = y; | |
598 if (gtk_widget_get_visible(widget) && gtk_widget_get_visible(GTK_WIDGET(mdi))) | |
599 gtk_widget_queue_resize(GTK_WIDGET(widget)); | |
600 } | |
601 | |
602 static void gtk_mdi_get_pos(GtkMdi *mdi, GtkWidget *widget, gint *x, gint *y) | |
603 { | |
604 GtkMdiChild *child; | |
605 | |
606 g_return_if_fail(GTK_IS_MDI (mdi)); | |
607 g_return_if_fail(GTK_IS_WIDGET (widget)); | |
608 | |
609 child = get_child(mdi, widget); | |
610 g_return_if_fail(child); | |
611 | |
612 *x = child->x; | |
613 *y = child->y; | |
614 } | |
615 | |
616 static void gtk_mdi_tile(GtkMdi *mdi) | |
617 { | |
618 int i, n; | |
619 int width, height; | |
620 GList *children; | |
621 GtkMdiChild *child; | |
622 | |
623 g_return_if_fail(GTK_IS_MDI(mdi)); | |
624 | |
625 children = mdi->children; | |
626 n = g_list_length (children); | |
627 width = gtk_widget_get_allocated_width(GTK_WIDGET (mdi)); | |
628 height = gtk_widget_get_allocated_height(GTK_WIDGET (mdi)) / n; | |
629 for(i=0;i<n;i++) | |
630 { | |
631 child = (GtkMdiChild *) children->data; | |
632 children = children->next; | |
633 child->x = 0; | |
634 child->y = i * height; | |
635 gtk_widget_set_size_request (child->widget, width, height); | |
636 child->state = CHILD_NORMAL; | |
637 child->width = -1; | |
638 child->height = -1; | |
639 } | |
640 if (gtk_widget_get_visible(GTK_WIDGET (mdi))) | |
641 gtk_widget_queue_resize (GTK_WIDGET (mdi)); | |
642 return; | |
643 } | |
644 static void gtk_mdi_cascade(GtkMdi *mdi) | |
645 { | |
646 int i, n; | |
647 int width, height; | |
648 GList *children; | |
649 GtkMdiChild *child; | |
650 | |
651 g_return_if_fail(GTK_IS_MDI(mdi)); | |
652 if(!gtk_widget_get_visible(GTK_WIDGET(mdi))) | |
653 return; | |
654 | |
655 children = mdi->children; | |
656 n = g_list_length (children); | |
657 width = gtk_widget_get_allocated_width(GTK_WIDGET (mdi)) / (2 * n - 1); | |
658 height = gtk_widget_get_allocated_height(GTK_WIDGET (mdi)) / (2 * n - 1); | |
659 for (i = 0; i < n; i++) | |
660 { | |
661 child = (GtkMdiChild *) children->data; | |
662 children = children->next; | |
663 child->x = i * width; | |
664 child->y = i * height; | |
665 gtk_widget_set_size_request (child->widget, width * n, height * n); | |
666 child->state = CHILD_NORMAL; | |
667 child->width = -1; | |
668 child->height = -1; | |
669 } | |
670 if (gtk_widget_get_visible(GTK_WIDGET(mdi))) | |
671 gtk_widget_queue_resize(GTK_WIDGET(mdi)); | |
672 return; | |
673 } | |
674 | |
675 static GtkMdiChildState gtk_mdi_get_state(GtkMdi *mdi, GtkWidget *widget) | |
676 { | |
677 GtkMdiChild *child; | |
678 | |
679 g_return_val_if_fail (GTK_IS_MDI (mdi), CHILD_NORMAL); | |
680 g_return_val_if_fail (GTK_IS_WIDGET (widget), CHILD_NORMAL); | |
681 | |
682 child = get_child (mdi, widget); | |
683 g_return_val_if_fail (child, CHILD_NORMAL); | |
684 | |
685 return child->state; | |
686 } | |
687 | |
688 static void gtk_mdi_set_state(GtkMdi *mdi, GtkWidget *widget, GtkMdiChildState state) | |
689 { | |
690 GtkMdiChild *child; | |
691 | |
692 g_return_if_fail (GTK_IS_MDI (mdi)); | |
693 g_return_if_fail (GTK_IS_WIDGET (widget)); | |
694 | |
695 child = get_child (mdi, widget); | |
696 g_return_if_fail (child); | |
697 | |
698 child->state = state; | |
699 if (gtk_widget_get_visible(child->widget) && gtk_widget_get_visible(GTK_WIDGET(mdi))) | |
700 gtk_widget_queue_resize(GTK_WIDGET(child->widget)); | |
701 } | |
702 | |
703 static void gtk_mdi_remove(GtkMdi *mdi, GtkWidget *widget) | |
704 { | |
705 GtkMdiChild *child; | |
706 | |
707 g_return_if_fail (GTK_IS_MDI (mdi)); | |
708 child = get_child (mdi, widget); | |
709 g_return_if_fail (child); | |
710 gtk_mdi_remove_true (GTK_CONTAINER (mdi), child->widget); | |
711 } | |
712 | |
713 static void gtk_mdi_realize(GtkWidget *widget) | |
714 { | |
715 GtkMdi *mdi; | |
716 GdkWindowAttr attributes; | |
717 gint attributes_mask; | |
718 | |
719 mdi = GTK_MDI (widget); | |
720 | |
721 g_return_if_fail (widget != NULL); | |
722 g_return_if_fail (GTK_IS_MDI (mdi)); | |
723 | |
724 gtk_widget_set_realized(widget, TRUE); | |
725 | |
726 GtkAllocation allocation; | |
727 gtk_widget_get_allocation(widget, &allocation); | |
728 attributes.x = allocation.x; | |
729 attributes.y = allocation.y; | |
730 attributes.width = allocation.width; | |
731 attributes.height = allocation.height; | |
732 attributes.wclass = GDK_INPUT_OUTPUT; | |
733 attributes.window_type = GDK_WINDOW_CHILD; | |
734 attributes.event_mask = gtk_widget_get_events (widget) | | |
735 GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | | |
736 GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | | |
737 GDK_POINTER_MOTION_HINT_MASK; | |
738 attributes.visual = gtk_widget_get_visual (widget); | |
739 | |
740 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; | |
741 gtk_widget_set_parent_window(widget, gdk_window_new (gtk_widget_get_parent_window(widget), &attributes, attributes_mask)); | |
742 | |
743 gtk_widget_set_style(widget, gtk_style_attach (gtk_widget_get_style(widget), gtk_widget_get_window(widget))); | |
744 | |
745 gdk_window_set_user_data (gtk_widget_get_window(widget), widget); | |
746 | |
747 gtk_style_set_background (gtk_widget_get_style(widget), gtk_widget_get_window(widget), GTK_STATE_NORMAL); | |
748 } | |
749 | |
750 static void gtk_mdi_size_request (GtkWidget *widget, GtkRequisition *requisition) | |
751 { | |
752 GtkMdi *mdi; | |
753 GtkMdiChild *child; | |
754 GList *children; | |
755 GtkRequisition child_requisition; | |
756 | |
757 mdi = GTK_MDI (widget); | |
758 requisition->width = GTK_MDI_DEFAULT_WIDTH; | |
759 requisition->height = GTK_MDI_DEFAULT_HEIGHT; | |
760 | |
761 children = mdi->children; | |
762 while(children) | |
763 { | |
764 child = children->data; | |
765 children = children->next; | |
766 | |
767 if(gtk_widget_get_visible(child->widget)) | |
768 { | |
769 gtk_widget_size_request(child->widget, &child_requisition); | |
770 } | |
771 } | |
772 } | |
773 | |
774 static void gtk_mdi_size_allocate(GtkWidget *widget, GtkAllocation *allocation) | |
775 { | |
776 GtkMdi *mdi; | |
777 GtkMdiChild *child; | |
778 GtkAllocation child_allocation; | |
779 GtkRequisition child_requisition; | |
780 GList *children; | |
781 | |
782 mdi = GTK_MDI (widget); | |
783 | |
784 gtk_widget_set_allocation(widget, allocation); | |
785 | |
786 if(gtk_widget_get_realized(widget)) | |
787 gdk_window_move_resize (gtk_widget_get_window(widget), | |
788 allocation->x, | |
789 allocation->y, | |
790 allocation->width, | |
791 allocation->height); | |
792 | |
793 | |
794 children = mdi->children; | |
795 while(children) | |
796 { | |
797 child = children->data; | |
798 children = children->next; | |
799 | |
800 if(gtk_widget_get_visible(child->widget)) | |
801 { | |
802 gtk_widget_get_child_requisition (child->widget, &child_requisition); | |
803 child_allocation.x = 0; | |
804 child_allocation.y = 0; | |
805 switch (child->state) | |
806 { | |
807 case CHILD_NORMAL: | |
808 { | |
809 if ((child->width < 0) && (child->height < 0)) | |
810 { | |
811 child_allocation.width = child_requisition.width; | |
812 child_allocation.height = child_requisition.height; | |
813 } | |
814 else | |
815 { | |
816 child_allocation.width = child->width; | |
817 child_allocation.height = child->height; | |
818 child->width = -1; | |
819 child->height = -1; | |
820 } | |
821 child_allocation.x += child->x; | |
822 child_allocation.y += child->y; | |
823 break; | |
824 } | |
825 case CHILD_MAXIMIZED: | |
826 { | |
827 if ((child->width < 0) && (child->height < 0)) | |
828 { | |
829 child->width = child_requisition.width; | |
830 child->height = child_requisition.height; | |
831 } | |
832 child_allocation.width = allocation->width; | |
833 child_allocation.height = allocation->height; | |
834 } | |
835 break; | |
836 case CHILD_ICONIFIED: | |
837 { | |
838 if ((child->width < 0) && (child->height < 0)) | |
839 { | |
840 child->width = child_requisition.width; | |
841 child->height = child_requisition.height; | |
842 } | |
843 child_allocation.x += child->x; | |
844 child_allocation.y += child->y; | |
845 child_allocation.width = child_requisition.width; | |
846 child_allocation.height = GTK_MDI_MIN_HEIGHT; | |
847 break; | |
848 } | |
849 } | |
850 gtk_widget_size_allocate (child->widget, &child_allocation); | |
851 } | |
852 } | |
853 } | |
854 | |
855 static gint gtk_mdi_expose(GtkWidget *widget, GdkEventExpose *event) | |
856 { | |
857 #if 0 /* TODO: Is this needed... propogate expose is no longer supported */ | |
858 GtkMdiChild *child; | |
859 GList *children; | |
860 GtkMdi *mdi; | |
861 | |
862 g_return_val_if_fail (widget != NULL, FALSE); | |
863 g_return_val_if_fail (GTK_IS_MDI (widget), FALSE); | |
864 g_return_val_if_fail (event != NULL, FALSE); | |
865 | |
866 mdi = GTK_MDI (widget); | |
867 for (children = mdi->children; children; children = children->next) | |
868 { | |
869 child = (GtkMdiChild *) children->data; | |
870 gtk_container_propagate_expose (GTK_CONTAINER (mdi), | |
871 child->widget, | |
872 event); | |
873 } | |
874 #endif | |
875 return FALSE; | |
876 } | |
877 | |
878 static void gtk_mdi_add(GtkContainer *container, GtkWidget *widget) | |
879 { | |
880 GtkWidget *label; | |
881 label = gtk_label_new (""); | |
882 gtk_mdi_put (GTK_MDI (container), widget, 0, 0, label); | |
883 } | |
884 | |
885 static void gtk_mdi_remove_true(GtkContainer *container, GtkWidget *widget) | |
886 { | |
887 GtkMdi *mdi; | |
888 GtkMdiChild *child = NULL; | |
889 GList *children; | |
890 | |
891 mdi = GTK_MDI (container); | |
892 | |
893 children = mdi->children; | |
894 while (children) | |
895 { | |
896 child = children->data; | |
897 if (child->widget == widget) | |
898 break; | |
899 | |
900 children = children->next; | |
901 } | |
902 | |
903 if(child) | |
904 { | |
905 gtk_widget_unparent (child->widget); | |
906 g_free (child); | |
907 } | |
908 mdi->children = g_list_remove_link (mdi->children, children); | |
909 g_list_free (children); | |
910 } | |
911 | |
912 static void gtk_mdi_forall(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) | |
913 { | |
914 GtkMdi *mdi; | |
915 GtkMdiChild *child; | |
916 GList *children; | |
917 | |
918 g_return_if_fail (callback != NULL); | |
919 | |
920 mdi = GTK_MDI (container); | |
921 | |
922 children = mdi->children; | |
923 while (children) | |
924 { | |
925 child = children->data; | |
926 children = children->next; | |
927 | |
928 (*callback) (child->widget, callback_data); | |
929 } | |
930 } | |
931 | |
932 static gboolean move_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data) | |
933 { | |
934 GtkMdi *mdi; | |
935 GtkMdiChild *child; | |
936 | |
937 child = (GtkMdiChild *) data; | |
938 mdi = child->mdi; | |
939 | |
940 g_return_val_if_fail (GTK_IS_MDI (mdi), FALSE); | |
941 g_return_val_if_fail (GTK_IS_EVENT_BOX (widget), FALSE); | |
942 | |
943 | |
944 switch (event->type) | |
945 { | |
946 case GDK_2BUTTON_PRESS: | |
947 { | |
948 gdk_window_raise (gtk_widget_get_window(child->widget)); | |
949 } | |
950 case GDK_BUTTON_PRESS: | |
951 if (child->state == CHILD_MAXIMIZED) | |
952 return FALSE; | |
953 if (mdi->drag_button < 0) | |
954 { | |
955 if (gdk_pointer_grab (event->button.window, | |
956 FALSE, | |
957 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | | |
958 GDK_BUTTON_RELEASE_MASK, | |
959 NULL, | |
960 NULL, | |
961 event->button.time) != GDK_GRAB_SUCCESS) | |
962 return FALSE; | |
963 | |
964 mdi->drag_button = event->button.button; | |
965 | |
966 mdi->drag_start.x = event->button.x; | |
967 mdi->drag_start.y = event->button.y; | |
968 } | |
969 break; | |
970 | |
971 case GDK_BUTTON_RELEASE: | |
972 if (mdi->drag_button < 0) | |
973 return FALSE; | |
974 | |
975 if (mdi->drag_button == event->button.button) | |
976 { | |
977 int x, y; | |
978 | |
979 gdk_pointer_ungrab (event->button.time); | |
980 mdi->drag_button = -1; | |
981 | |
982 x = event->button.x + child->x - mdi->drag_start.x; | |
983 y = event->button.y + child->y - mdi->drag_start.y; | |
984 | |
985 gtk_mdi_move (mdi, child->child, x, y); | |
986 } | |
987 break; | |
988 | |
989 case GDK_MOTION_NOTIFY: | |
990 { | |
991 int x, y; | |
992 | |
993 if (mdi->drag_button < 0) | |
994 return FALSE; | |
995 | |
996 gdk_window_get_pointer (gtk_widget_get_window(widget), &x, &y, NULL); | |
997 | |
998 | |
999 x = x - mdi->drag_start.x + child->x; | |
1000 y = y - mdi->drag_start.y + child->y; | |
1001 | |
1002 | |
1003 gtk_mdi_move (mdi, child->child, x, y); | |
1004 } | |
1005 break; | |
1006 | |
1007 default: | |
1008 break; | |
1009 } | |
1010 | |
1011 return FALSE; | |
1012 } | |
1013 | |
1014 static gboolean resize_child_callback(GtkWidget *widget, GdkEvent *event, gpointer data) | |
1015 { | |
1016 GtkMdi *mdi; | |
1017 GtkMdiChild *child; | |
1018 | |
1019 child = (GtkMdiChild *) data; | |
1020 mdi = child->mdi; | |
1021 | |
1022 g_return_val_if_fail (GTK_IS_MDI (mdi), FALSE); | |
1023 g_return_val_if_fail (GTK_IS_EVENT_BOX (widget), FALSE); | |
1024 | |
1025 switch (event->type) | |
1026 { | |
1027 case GDK_BUTTON_PRESS: | |
1028 if (mdi->drag_button < 0) | |
1029 { | |
1030 if (gdk_pointer_grab (event->button.window, | |
1031 FALSE, | |
1032 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | | |
1033 GDK_BUTTON_RELEASE_MASK, | |
1034 NULL, | |
1035 NULL, | |
1036 event->button.time) != GDK_GRAB_SUCCESS) | |
1037 return FALSE; | |
1038 | |
1039 mdi->drag_button = event->button.button; | |
1040 if ((child->state == CHILD_MAXIMIZED) || (child->state == CHILD_ICONIFIED)) | |
1041 { | |
1042 GtkAllocation allocation; | |
1043 | |
1044 child->state = CHILD_NORMAL; | |
1045 gtk_widget_get_allocation(child->widget, &allocation); | |
1046 child->x = allocation.x; | |
1047 child->y = allocation.y; | |
1048 child->width = allocation.width; | |
1049 child->height = allocation.height; | |
1050 } | |
1051 | |
1052 } | |
1053 break; | |
1054 | |
1055 case GDK_BUTTON_RELEASE: | |
1056 if (mdi->drag_button < 0) | |
1057 return FALSE; | |
1058 | |
1059 if (mdi->drag_button == event->button.button) | |
1060 { | |
1061 int width, height; | |
1062 GtkAllocation allocation; | |
1063 | |
1064 gdk_pointer_ungrab (event->button.time); | |
1065 mdi->drag_button = -1; | |
1066 | |
1067 gtk_widget_get_allocation(widget, &allocation); | |
1068 width = event->button.x + allocation.x; | |
1069 height = event->button.y + allocation.y; | |
1070 | |
1071 width = MAX (width, GTK_MDI_MIN_WIDTH); | |
1072 height = MAX (height, GTK_MDI_MIN_HEIGHT); | |
1073 | |
1074 gtk_widget_set_size_request (child->widget, width, height); | |
1075 gtk_widget_queue_resize (child->widget); | |
1076 } | |
1077 break; | |
1078 | |
1079 case GDK_MOTION_NOTIFY: | |
1080 { | |
1081 int x, y; | |
1082 int width, height; | |
1083 GtkAllocation allocation; | |
1084 | |
1085 if (mdi->drag_button < 0) | |
1086 return FALSE; | |
1087 | |
1088 gdk_window_get_pointer (gtk_widget_get_window(widget), &x, &y, NULL); | |
1089 | |
1090 gtk_widget_get_allocation(widget, &allocation); | |
1091 width = x + allocation.x; | |
1092 height = y + allocation.y; | |
1093 | |
1094 width = MAX (width, GTK_MDI_MIN_WIDTH); | |
1095 height = MAX (height, GTK_MDI_MIN_HEIGHT); | |
1096 | |
1097 gtk_widget_set_size_request (child->widget, width, height); | |
1098 gtk_widget_queue_resize (child->widget); | |
1099 } | |
1100 break; | |
1101 | |
1102 default: | |
1103 break; | |
1104 } | |
1105 | |
1106 return FALSE; | |
1107 } | |
1108 | |
1109 static gboolean iconify_child_callback (GtkWidget *widget, GdkEvent *event, gpointer data) | |
1110 { | |
1111 GtkMdiChild *child; | |
1112 child = (GtkMdiChild *) data; | |
1113 if(child->state == CHILD_ICONIFIED) | |
1114 { | |
1115 child->state = CHILD_NORMAL; | |
1116 } | |
1117 else | |
1118 { | |
1119 child->state = CHILD_ICONIFIED; | |
1120 } | |
1121 if(gtk_widget_get_visible(child->widget)) | |
1122 gtk_widget_queue_resize(GTK_WIDGET (child->widget)); | |
1123 return FALSE; | |
1124 } | |
1125 | |
1126 static gboolean maximize_child_callback (GtkWidget *widget, GdkEvent * event, gpointer data) | |
1127 { | |
1128 GtkMdiChild *child; | |
1129 child = (GtkMdiChild *) data; | |
1130 if (child->state == CHILD_MAXIMIZED) | |
1131 { | |
1132 child->state = CHILD_NORMAL; | |
1133 } | |
1134 else | |
1135 { | |
1136 child->state = CHILD_MAXIMIZED; | |
1137 } | |
1138 if(gtk_widget_get_visible(child->widget)) | |
1139 gtk_widget_queue_resize(GTK_WIDGET (child->widget)); | |
1140 return FALSE; | |
1141 } | |
1142 | |
1143 static gboolean kill_child_callback (GtkWidget *widget, GdkEvent *event, gpointer data) | |
1144 { | |
1145 GtkMdiChild *child; | |
1146 GtkMdi *mdi; | |
1147 | |
1148 child = (GtkMdiChild *) data; | |
1149 mdi = child->mdi; | |
1150 | |
1151 g_return_val_if_fail (GTK_IS_MDI (mdi), FALSE); | |
1152 | |
1153 gtk_mdi_remove_true (GTK_CONTAINER (mdi), child->widget); | |
1154 return FALSE; | |
1155 } | |
1156 | |
1157 static GtkMdiChild *get_child (GtkMdi *mdi, GtkWidget *widget) | |
1158 { | |
1159 GList *children; | |
1160 | |
1161 children = mdi->children; | |
1162 while (children) | |
1163 { | |
1164 GtkMdiChild *child; | |
1165 | |
1166 child = children->data; | |
1167 children = children->next; | |
1168 | |
1169 if (child->child == widget) | |
1170 return child; | |
1171 } | |
1172 | |
1173 return NULL; | |
1174 } | |
1175 | |
1176 static void _dw_msleep(long period) | |
1177 { | |
1178 #ifdef __sun__ | |
1179 /* usleep() isn't threadsafe on Solaris */ | |
1180 struct timespec req; | |
1181 | |
1182 req.tv_sec = 0; | |
1183 req.tv_nsec = period * 10000000; | |
1184 | |
1185 nanosleep(&req, NULL); | |
1186 #else | |
1187 usleep(period * 1000); | |
1188 #endif | |
1189 } | |
1190 | |
1191 /* Finds the translation function for a given signal name */ | |
1192 static void *_findsigfunc(char *signame) | |
1193 { | |
1194 int z; | |
1195 | |
1196 for(z=0;z<SIGNALMAX;z++) | |
1197 { | |
1198 if(strcasecmp(signame, SignalTranslate[z].name) == 0) | |
1199 return SignalTranslate[z].func; | |
1200 } | |
1201 return NULL; | |
1202 } | |
1203 | |
1204 static SignalHandler _get_signal_handler(GtkWidget *widget, gpointer data) | |
1205 { | |
1206 int counter = (int)data; | |
1207 SignalHandler sh; | |
1208 char text[100]; | |
1209 | |
1210 sprintf(text, "_dw_sigwindow%d", counter); | |
1211 sh.window = (HWND)g_object_get_data(G_OBJECT(widget), text); | |
1212 sprintf(text, "_dw_sigfunc%d", counter); | |
1213 sh.func = (void *)g_object_get_data(G_OBJECT(widget), text); | |
1214 sprintf(text, "_dw_intfunc%d", counter); | |
1215 sh.intfunc = (void *)g_object_get_data(G_OBJECT(widget), text); | |
1216 sprintf(text, "_dw_sigdata%d", counter); | |
1217 sh.data = g_object_get_data(G_OBJECT(widget), text); | |
1218 sprintf(text, "_dw_sigcid%d", counter); | |
1219 sh.cid = (gint)g_object_get_data(G_OBJECT(widget), text); | |
1220 | |
1221 return sh; | |
1222 } | |
1223 | |
1224 static void _remove_signal_handler(GtkWidget *widget, int counter) | |
1225 { | |
1226 char text[100]; | |
1227 gint cid; | |
1228 | |
1229 sprintf(text, "_dw_sigcid%d", counter); | |
1230 cid = (gint)g_object_get_data(G_OBJECT(widget), text); | |
1231 g_signal_handler_disconnect(G_OBJECT(widget), cid); | |
1232 g_object_set_data(G_OBJECT(widget), text, NULL); | |
1233 sprintf(text, "_dw_sigwindow%d", counter); | |
1234 g_object_set_data(G_OBJECT(widget), text, NULL); | |
1235 sprintf(text, "_dw_sigfunc%d", counter); | |
1236 g_object_set_data(G_OBJECT(widget), text, NULL); | |
1237 sprintf(text, "_dw_intfunc%d", counter); | |
1238 g_object_set_data(G_OBJECT(widget), text, NULL); | |
1239 sprintf(text, "_dw_sigdata%d", counter); | |
1240 g_object_set_data(G_OBJECT(widget), text, NULL); | |
1241 } | |
1242 | |
1243 static int _set_signal_handler(GtkWidget *widget, HWND window, void *func, gpointer data, void *intfunc) | |
1244 { | |
1245 int counter = (int)g_object_get_data(G_OBJECT(widget), "_dw_sigcounter"); | |
1246 char text[100]; | |
1247 | |
1248 sprintf(text, "_dw_sigwindow%d", counter); | |
1249 g_object_set_data(G_OBJECT(widget), text, (gpointer)window); | |
1250 sprintf(text, "_dw_sigfunc%d", counter); | |
1251 g_object_set_data(G_OBJECT(widget), text, (gpointer)func); | |
1252 sprintf(text, "_dw_intfunc%d", counter); | |
1253 g_object_set_data(G_OBJECT(widget), text, (gpointer)intfunc); | |
1254 sprintf(text, "_dw_sigdata%d", counter); | |
1255 g_object_set_data(G_OBJECT(widget), text, (gpointer)data); | |
1256 | |
1257 counter++; | |
1258 g_object_set_data(G_OBJECT(widget), "_dw_sigcounter", GINT_TO_POINTER(counter)); | |
1259 | |
1260 return counter - 1; | |
1261 } | |
1262 | |
1263 static void _set_signal_handler_id(GtkWidget *widget, int counter, gint cid) | |
1264 { | |
1265 char text[100]; | |
1266 | |
1267 sprintf(text, "_dw_sigcid%d", counter); | |
1268 g_object_set_data(G_OBJECT(widget), text, GINT_TO_POINTER(cid)); | |
1269 } | |
1270 | |
1271 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data) | |
1272 { | |
1273 SignalHandler work = _get_signal_handler((GtkWidget *)window, data); | |
1274 int retval = FALSE; | |
1275 | |
1276 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1277 if(work.window) | |
1278 { | |
1279 int (*setfocusfunc)(HWND, void *) = work.func; | |
1280 | |
1281 retval = setfocusfunc(work.window, work.data); | |
1282 } | |
1283 return retval; | |
1284 } | |
1285 | |
1286 static gint _button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) | |
1287 { | |
1288 SignalHandler work = _get_signal_handler(widget, data); | |
1289 int retval = FALSE; | |
1290 | |
1291 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1292 if(work.window) | |
1293 { | |
1294 int (*buttonfunc)(HWND, int, int, int, void *) = work.func; | |
1295 int mybutton = event->button; | |
1296 | |
1297 if(event->button == 3) | |
1298 mybutton = 2; | |
1299 else if(event->button == 2) | |
1300 mybutton = 3; | |
1301 | |
1302 retval = buttonfunc(work.window, event->x, event->y, mybutton, work.data); | |
1303 } | |
1304 return retval; | |
1305 } | |
1306 | |
1307 static gint _button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) | |
1308 { | |
1309 SignalHandler work = _get_signal_handler(widget, data); | |
1310 int retval = FALSE; | |
1311 | |
1312 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1313 if(work.window) | |
1314 { | |
1315 int (*buttonfunc)(HWND, int, int, int, void *) = work.func; | |
1316 int mybutton = event->button; | |
1317 | |
1318 if(event->button == 3) | |
1319 mybutton = 2; | |
1320 else if(event->button == 2) | |
1321 mybutton = 3; | |
1322 | |
1323 retval = buttonfunc(work.window, event->x, event->y, mybutton, work.data); | |
1324 } | |
1325 return retval; | |
1326 } | |
1327 | |
1328 static gint _motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) | |
1329 { | |
1330 SignalHandler work = _get_signal_handler(widget, data); | |
1331 int retval = FALSE; | |
1332 | |
1333 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1334 if(work.window) | |
1335 { | |
1336 int (*motionfunc)(HWND, int, int, int, void *) = work.func; | |
1337 int keys = 0, x, y; | |
1338 GdkModifierType state; | |
1339 | |
1340 if (event->is_hint) | |
1341 gdk_window_get_pointer (event->window, &x, &y, &state); | |
1342 else | |
1343 { | |
1344 x = event->x; | |
1345 y = event->y; | |
1346 state = event->state; | |
1347 } | |
1348 | |
1349 if (state & GDK_BUTTON1_MASK) | |
1350 keys = DW_BUTTON1_MASK; | |
1351 if (state & GDK_BUTTON3_MASK) | |
1352 keys |= DW_BUTTON2_MASK; | |
1353 if (state & GDK_BUTTON2_MASK) | |
1354 keys |= DW_BUTTON3_MASK; | |
1355 | |
1356 retval = motionfunc(work.window, x, y, keys, work.data); | |
1357 } | |
1358 return retval; | |
1359 } | |
1360 | |
1361 static gint _delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) | |
1362 { | |
1363 SignalHandler work = _get_signal_handler(widget, data); | |
1364 int retval = FALSE; | |
1365 | |
1366 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1367 if(work.window) | |
1368 { | |
1369 int (*closefunc)(HWND, void *) = work.func; | |
1370 | |
1371 retval = closefunc(work.window, work.data); | |
1372 } | |
1373 return retval; | |
1374 } | |
1375 | |
1376 static gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) | |
1377 { | |
1378 SignalHandler work = _get_signal_handler(widget, data); | |
1379 int retval = FALSE; | |
1380 | |
1381 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1382 if(work.window) | |
1383 { | |
1384 int (*keypressfunc)(HWND, char, int, int, void *) = work.func; | |
1385 | |
1386 retval = keypressfunc(work.window, *event->string, event->keyval, | |
1387 event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK), work.data); | |
1388 } | |
1389 return retval; | |
1390 } | |
1391 | |
1392 static gint _generic_event(GtkWidget *widget, gpointer data) | |
1393 { | |
1394 SignalHandler work = _get_signal_handler(widget, data); | |
1395 int retval = FALSE; | |
1396 | |
1397 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1398 if(work.window) | |
1399 { | |
1400 int (*genericfunc)(HWND, void *) = work.func; | |
1401 | |
1402 retval = genericfunc(work.window, work.data); | |
1403 } | |
1404 return retval; | |
1405 } | |
1406 | |
1407 static gint _activate_event(GtkWidget *widget, gpointer data) | |
1408 { | |
1409 SignalHandler work = _get_signal_handler(widget, data); | |
1410 int retval = FALSE; | |
1411 | |
1412 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1413 if(work.window && !_dw_ignore_click) | |
1414 { | |
1415 int (*activatefunc)(HWND, void *) = work.func; | |
1416 | |
1417 retval = activatefunc(popup ? popup : work.window, work.data); | |
1418 popup = NULL; | |
1419 } | |
1420 return retval; | |
1421 } | |
1422 | |
1423 static gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data) | |
1424 { | |
1425 SignalHandler work = _get_signal_handler(widget, data); | |
1426 int retval = FALSE; | |
1427 | |
1428 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1429 if(work.window) | |
1430 { | |
1431 int (*sizefunc)(HWND, int, int, void *) = work.func; | |
1432 | |
1433 retval = sizefunc(work.window, event->width, event->height, work.data); | |
1434 } | |
1435 return retval; | |
1436 } | |
1437 | |
1438 static gint _expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) | |
1439 { | |
1440 SignalHandler work = _get_signal_handler(widget, data); | |
1441 int retval = FALSE; | |
1442 | |
1443 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1444 if(work.window) | |
1445 { | |
1446 DWExpose exp; | |
1447 int (*exposefunc)(HWND, DWExpose *, void *) = work.func; | |
1448 | |
1449 exp.x = event->area.x; | |
1450 exp.y = event->area.y; | |
1451 exp.width = event->area.width; | |
1452 exp.height = event->area.height; | |
1453 retval = exposefunc(work.window, &exp, work.data); | |
1454 } | |
1455 return retval; | |
1456 } | |
1457 | |
1458 static gint _item_select_event(GtkWidget *widget, GtkWidget *child, gpointer data) | |
1459 { | |
1460 SignalHandler work = _get_signal_handler(widget, data); | |
1461 static int _dw_recursing = 0; | |
1462 int retval = FALSE; | |
1463 | |
1464 #if 0 | |
1465 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1466 if(_dw_recursing) | |
1467 return FALSE; | |
1468 | |
1469 if(work.window) | |
1470 { | |
1471 int (*selectfunc)(HWND, int, void *) = work.func; | |
1472 GList *list; | |
1473 int item = 0; | |
1474 | |
1475 _dw_recursing = 1; | |
1476 | |
1477 if(GTK_IS_COMBO_BOX(work.window)) | |
1478 list = GTK_LIST(GTK_COMBO_BOX(work.window)->list)->children; | |
1479 else if(GTK_IS_LIST(widget)) | |
1480 list = GTK_LIST(widget)->children; | |
1481 else | |
1482 return FALSE; | |
1483 | |
1484 while(list) | |
1485 { | |
1486 if(list->data == (gpointer)child) | |
1487 { | |
1488 if(!g_object_get_data(G_OBJECT(work.window), "_dw_appending")) | |
1489 { | |
1490 g_object_set_data(G_OBJECT(work.window), "_dw_item", GINT_TO_POINTER(item)); | |
1491 if(selectfunc) | |
1492 retval = selectfunc(work.window, item, work.data); | |
1493 } | |
1494 break; | |
1495 } | |
1496 item++; | |
1497 list = list->next; | |
1498 } | |
1499 _dw_recursing = 0; | |
1500 } | |
1501 #endif | |
1502 return retval; | |
1503 } | |
1504 | |
1505 static gint _container_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data) | |
1506 { | |
1507 SignalHandler work = _get_signal_handler(widget, data); | |
1508 int retval = FALSE; | |
1509 | |
1510 #if 0 | |
1511 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1512 if(work.window) | |
1513 { | |
1514 if(event->button == 3) | |
1515 { | |
1516 int (*contextfunc)(HWND, char *, int, int, void *, void *) = work.func; | |
1517 char *text; | |
1518 int row, col; | |
1519 | |
1520 gtk_clist_get_selection_info(GTK_CLIST(widget), event->x, event->y, &row, &col); | |
1521 | |
1522 text = (char *)gtk_clist_get_row_data(GTK_CLIST(widget), row); | |
1523 retval = contextfunc(work.window, text, event->x, event->y, work.data, NULL); | |
1524 } | |
1525 } | |
1526 #endif | |
1527 return retval; | |
1528 } | |
1529 | |
1530 static gint _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data) | |
1531 { | |
1532 SignalHandler work = _get_signal_handler(widget, data); | |
1533 int retval = FALSE; | |
1534 | |
1535 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1536 if(work.window) | |
1537 { | |
1538 if(event->button == 3) | |
1539 { | |
1540 int (*contextfunc)(HWND, char *, int, int, void *, void *) = work.func; | |
1541 char *text = NULL; | |
1542 void *itemdata = NULL; | |
1543 | |
1544 if(widget && GTK_IS_TREE_VIEW(widget)) | |
1545 { | |
1546 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); | |
1547 GtkTreeIter iter; | |
1548 | |
1549 if(sel && gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
1550 { | |
1551 GtkTreeModel *store = (GtkTreeModel *)gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
1552 gtk_tree_model_get(store, &iter, 0, &text, 2, &itemdata, -1); | |
1553 } | |
1554 } | |
1555 | |
1556 retval = contextfunc(work.window, text, event->x, event->y, work.data, itemdata); | |
1557 } | |
1558 } | |
1559 return retval; | |
1560 } | |
1561 | |
1562 static gint _tree_select_event(GtkTreeSelection *sel, gpointer data) | |
1563 { | |
1564 GtkWidget *item, *widget = (GtkWidget *)gtk_tree_selection_get_tree_view(sel); | |
1565 int retval = FALSE; | |
1566 | |
1567 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1568 if(widget) | |
1569 { | |
1570 SignalHandler work = _get_signal_handler(widget, data); | |
1571 | |
1572 if(work.window) | |
1573 { | |
1574 int (*treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = work.func; | |
1575 GtkTreeIter iter; | |
1576 char *text = NULL; | |
1577 void *itemdata = NULL; | |
1578 | |
1579 if(gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
1580 { | |
1581 GtkTreeModel *store = (GtkTreeModel *)gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
1582 gtk_tree_model_get(store, &iter, 0, &text, 2, &itemdata, 3, &item, -1); | |
1583 retval = treeselectfunc(work.window, (HTREEITEM)item, text, work.data, itemdata); | |
1584 } | |
1585 } | |
1586 } | |
1587 return retval; | |
1588 } | |
1589 | |
1590 static gint _tree_expand_event(GtkTreeView *widget, GtkTreeIter *iter, GtkTreePath *path, gpointer data) | |
1591 { | |
1592 SignalHandler work = _get_signal_handler((GtkWidget *)widget, data); | |
1593 int retval = FALSE; | |
1594 | |
1595 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1596 if(!_dw_ignore_expand && work.window) | |
1597 { | |
1598 int (*treeexpandfunc)(HWND, HTREEITEM, void *) = work.func; | |
1599 retval = treeexpandfunc(work.window, (HTREEITEM)iter, work.data); | |
1600 } | |
1601 return retval; | |
1602 } | |
1603 | |
1604 static gint _container_select_event(GtkWidget *widget, GdkEventButton *event, gpointer data) | |
1605 { | |
1606 SignalHandler work = _get_signal_handler(widget, data); | |
1607 int retval = FALSE; | |
1608 | |
1609 #if 0 | |
1610 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1611 if(work.window) | |
1612 { | |
1613 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS) | |
1614 { | |
1615 int (*contextfunc)(HWND, char *, void *) = work.func; | |
1616 char *text; | |
1617 int row, col; | |
1618 | |
1619 gtk_clist_get_selection_info(GTK_CLIST(widget), event->x, event->y, &row, &col); | |
1620 | |
1621 text = (char *)gtk_clist_get_row_data(GTK_CLIST(widget), row); | |
1622 retval = contextfunc(work.window, text, work.data); | |
1623 g_object_set_data(G_OBJECT(widget), "_dw_double_click", GINT_TO_POINTER(1)); | |
1624 } | |
1625 } | |
1626 #endif | |
1627 return retval; | |
1628 } | |
1629 | |
1630 static gint _container_enter_event(GtkWidget *widget, GdkEventKey *event, gpointer data) | |
1631 { | |
1632 SignalHandler work = _get_signal_handler(widget, data); | |
1633 int retval = FALSE; | |
1634 | |
1635 #if 0 | |
1636 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1637 if(work.window && event->keyval == VK_RETURN) | |
1638 { | |
1639 int (*contextfunc)(HWND, char *, void *) = work.func; | |
1640 char *text; | |
1641 | |
1642 text = (char *)gtk_clist_get_row_data(GTK_CLIST(widget), GTK_CLIST(widget)->focus_row); | |
1643 retval = contextfunc(work.window, text, work.data); | |
1644 } | |
1645 #endif | |
1646 return retval; | |
1647 } | |
1648 | |
1649 /* Return the logical page id from the physical page id */ | |
1650 int _get_logical_page(HWND handle, unsigned long pageid) | |
1651 { | |
1652 int z; | |
1653 GtkWidget **pagearray = g_object_get_data(G_OBJECT(handle), "_dw_pagearray"); | |
1654 GtkWidget *thispage = gtk_notebook_get_nth_page(GTK_NOTEBOOK(handle), pageid); | |
1655 | |
1656 if(pagearray && thispage) | |
1657 { | |
1658 for(z=0;z<256;z++) | |
1659 { | |
1660 if(thispage == pagearray[z]) | |
1661 return z; | |
1662 } | |
1663 } | |
1664 return 256; | |
1665 } | |
1666 | |
1667 | |
1668 static gint _switch_page_event(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data) | |
1669 { | |
1670 SignalHandler work = _get_signal_handler((GtkWidget *)notebook, data); | |
1671 int retval = FALSE; | |
1672 | |
1673 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1674 if(work.window) | |
1675 { | |
1676 int (*switchpagefunc)(HWND, unsigned long, void *) = work.func; | |
1677 retval = switchpagefunc(work.window, _get_logical_page(GTK_WIDGET(notebook), page_num), work.data); | |
1678 } | |
1679 return retval; | |
1680 } | |
1681 | |
1682 static gint _column_click_event(GtkWidget *widget, gint column_num, gpointer data) | |
1683 { | |
1684 SignalHandler work = _get_signal_handler(widget, data); | |
1685 int retval = FALSE; | |
1686 | |
1687 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1688 if(work.window) | |
1689 { | |
1690 int (*clickcolumnfunc)(HWND, int, void *) = work.func; | |
1691 retval = clickcolumnfunc(work.window, column_num, work.data); | |
1692 } | |
1693 return retval; | |
1694 } | |
1695 | |
1696 static gint _container_select_row(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) | |
1697 { | |
1698 #if 0 | |
1699 SignalHandler work = _get_signal_handler(widget, data); | |
1700 char *rowdata = gtk_clist_get_row_data(GTK_CLIST(widget), row); | |
1701 int (*contextfunc)(HWND, HWND, char *, void *, void *) = work.func; | |
1702 | |
1703 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1704 if(!work.window) | |
1705 return TRUE; | |
1706 | |
1707 if(g_object_get_data(G_OBJECT(widget), "_dw_double_click")) | |
1708 { | |
1709 g_object_set_data(G_OBJECT(widget), "_dw_double_click", GINT_TO_POINTER(0)); | |
1710 return TRUE; | |
1711 } | |
1712 return contextfunc(work.window, 0, rowdata, work.data, 0);; | |
1713 #endif | |
1714 return TRUE; | |
1715 } | |
1716 | |
1717 static int _round_value(gfloat val) | |
1718 { | |
1719 int newval = (int)val; | |
1720 | |
1721 if(val >= 0.5 + (gfloat)newval) | |
1722 newval++; | |
1723 | |
1724 return newval; | |
1725 } | |
1726 | |
1727 static gint _value_changed_event(GtkAdjustment *adjustment, gpointer data) | |
1728 { | |
1729 int max = _round_value(gtk_adjustment_get_upper(adjustment)); | |
1730 int val = _round_value(gtk_adjustment_get_value(adjustment)); | |
1731 GtkWidget *slider = (GtkWidget *)g_object_get_data(G_OBJECT(adjustment), "_dw_slider"); | |
1732 GtkWidget *spinbutton = (GtkWidget *)g_object_get_data(G_OBJECT(adjustment), "_dw_spinbutton"); | |
1733 GtkWidget *scrollbar = (GtkWidget *)g_object_get_data(G_OBJECT(adjustment), "_dw_scrollbar"); | |
1734 | |
1735 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1736 if (slider) | |
1737 { | |
1738 SignalHandler work = _get_signal_handler((GtkWidget *)adjustment, data); | |
1739 | |
1740 if (work.window) | |
1741 { | |
1742 int (*valuechangedfunc)(HWND, int, void *) = work.func; | |
1743 | |
1744 if(GTK_IS_VSCALE(slider)) | |
1745 valuechangedfunc(work.window, (max - val) - 1, work.data); | |
1746 else | |
1747 valuechangedfunc(work.window, val, work.data); | |
1748 } | |
1749 } | |
1750 else if (scrollbar || spinbutton) | |
1751 { | |
1752 SignalHandler work = _get_signal_handler((GtkWidget *)adjustment, data); | |
1753 | |
1754 if (work.window) | |
1755 { | |
1756 int (*valuechangedfunc)(HWND, int, void *) = work.func; | |
1757 | |
1758 valuechangedfunc(work.window, val, work.data); | |
1759 } | |
1760 } | |
1761 return FALSE; | |
1762 } | |
1763 | |
1764 static gint _default_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) | |
1765 { | |
1766 GtkWidget *next = (GtkWidget *)data; | |
1767 | |
1768 if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); | |
1769 if(next) | |
1770 { | |
1771 if(event->keyval == GDK_KEY_Return) | |
1772 { | |
1773 if(GTK_IS_BUTTON(next)) | |
1774 g_signal_emit_by_name(G_OBJECT(next), "clicked"); | |
1775 else | |
1776 gtk_widget_grab_focus(next); | |
1777 } | |
1778 } | |
1779 return FALSE; | |
1780 } | |
1781 | |
1782 static GdkPixbuf *_find_private_pixbuf(long id, unsigned long *userwidth, unsigned long *userheight) | |
1783 { | |
1784 if(id < _PixmapCount && _PixmapArray[id].used) | |
1785 { | |
1786 if(userwidth) | |
1787 *userwidth = _PixmapArray[id].width; | |
1788 if(userheight) | |
1789 *userheight = _PixmapArray[id].height; | |
1790 return _PixmapArray[id].pixbuf; | |
1791 } | |
1792 return NULL; | |
1793 } | |
1794 | |
1795 static GdkPixbuf *_find_pixbuf(long id, unsigned long *userwidth, unsigned long *userheight) | |
1796 { | |
1797 char *data = NULL; | |
1798 int z; | |
1799 | |
1800 if(id & (1 << 31)) | |
1801 return _find_private_pixbuf((id & 0xFFFFFF), userwidth, userheight); | |
1802 | |
1803 for(z=0;z<_resources.resource_max;z++) | |
1804 { | |
1805 if(_resources.resource_id[z] == id) | |
1806 { | |
1807 data = _resources.resource_data[z]; | |
1808 break; | |
1809 } | |
1810 } | |
1811 | |
1812 if(data) | |
1813 { | |
1814 GdkPixbuf *icon_pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)data); | |
1815 | |
1816 if(userwidth) | |
1817 *userwidth = gdk_pixbuf_get_width(icon_pixbuf); | |
1818 if(userheight) | |
1819 *userheight = gdk_pixbuf_get_height(icon_pixbuf); | |
1820 | |
1821 return icon_pixbuf; | |
1822 } | |
1823 return NULL; | |
1824 } | |
1825 | |
1826 /* Find the index of a given thread */ | |
1827 static int _find_thread_index(DWTID tid) | |
1828 { | |
1829 int z; | |
1830 | |
1831 for(z=0;z<DW_THREAD_LIMIT;z++) | |
1832 { | |
1833 if(_dw_thread_list[z] == tid) | |
1834 return z; | |
1835 } | |
1836 return 0; | |
1837 } | |
1838 | |
1839 /* Add a thread id to the thread list */ | |
1840 static void _dw_thread_add(DWTID tid) | |
1841 { | |
1842 int z; | |
1843 | |
1844 for(z=0;z<DW_THREAD_LIMIT;z++) | |
1845 { | |
1846 if(_dw_thread_list[z] == tid) | |
1847 return; | |
1848 | |
1849 if(_dw_thread_list[z] == (DWTID)-1) | |
1850 { | |
1851 _dw_thread_list[z] = tid; | |
1852 _foreground[z].pixel = _foreground[z].red =_foreground[z].green = _foreground[z].blue = 0; | |
1853 _background[z].pixel = 1; | |
1854 _background[z].red = _background[z].green = _background[z].blue = 0; | |
1855 _transparent[z] = 1; | |
1856 _clipboard_contents[z] = NULL; | |
1857 _clipboard_object[z] = NULL; | |
1858 return; | |
1859 } | |
1860 } | |
1861 } | |
1862 | |
1863 /* Remove a thread id to the thread list */ | |
1864 static void _dw_thread_remove(DWTID tid) | |
1865 { | |
1866 int z; | |
1867 | |
1868 for(z=0;z<DW_THREAD_LIMIT;z++) | |
1869 { | |
1870 if(_dw_thread_list[z] == (DWTID)tid) | |
1871 { | |
1872 _dw_thread_list[z] = (DWTID)-1; | |
1873 if ( _clipboard_contents[z] != NULL ) | |
1874 { | |
1875 g_free( _clipboard_contents[z] ); | |
1876 _clipboard_contents[z] = NULL;; | |
1877 } | |
1878 _clipboard_object[z] = NULL;; | |
1879 } | |
1880 } | |
1881 } | |
1882 | |
1883 /* Try to load the mozilla embed shared libary */ | |
1884 #ifdef USE_GTKMOZEMBED | |
1885 #include <ctype.h> | |
1886 | |
1887 void init_mozembed(void) | |
1888 { | |
1889 void *handle = NULL; | |
1890 gchar *profile; | |
1891 handle = dlopen( "libgtkembedmoz.so", RTLD_LAZY ); | |
1892 | |
1893 /* If we loaded it, grab the symbols we want */ | |
1894 if ( handle ) | |
1895 { | |
1896 _gtk_moz_embed_go_back = dlsym(handle, "gtk_moz_embed_go_back"); | |
1897 _gtk_moz_embed_go_forward = dlsym(handle, "gtk_moz_embed_go_forward"); | |
1898 _gtk_moz_embed_load_url = dlsym(handle, "gtk_moz_embed_load_url"); | |
1899 _gtk_moz_embed_reload = dlsym(handle, "gtk_moz_embed_reload"); | |
1900 _gtk_moz_embed_stop_load = dlsym(handle, "gtk_moz_embed_stop_load"); | |
1901 _gtk_moz_embed_render_data = dlsym(handle, "gtk_moz_embed_render_data"); | |
1902 _dw_moz_embed_get_type = dlsym(handle, "gtk_moz_embed_get_type"); | |
1903 _gtk_moz_embed_new = dlsym(handle, "gtk_moz_embed_new"); | |
1904 _gtk_moz_embed_can_go_back = dlsym(handle, "gtk_moz_embed_can_go_back"); | |
1905 _gtk_moz_embed_can_go_forward = dlsym(handle, "gtk_moz_embed_can_go_forward"); | |
1906 _gtk_moz_embed_set_comp_path = dlsym(handle, "gtk_moz_embed_set_comp_path"); | |
1907 _gtk_moz_embed_set_profile_path = dlsym(handle, "gtk_moz_embed_set_profile_path"); | |
1908 _gtk_moz_embed_push_startup = dlsym(handle, "gtk_moz_embed_push_startup"); | |
1909 _gtk_moz_embed_set_comp_path( "/usr/lib/mozilla"); | |
1910 _gtk_moz_embed_set_comp_path( "/usr/lib/firefox"); | |
1911 profile = g_build_filename(g_get_home_dir(), ".dwindows/mozilla", NULL); | |
1912 | |
1913 /* initialize profile */ | |
1914 _gtk_moz_embed_set_profile_path(profile, "dwindows"); | |
1915 g_free(profile); | |
1916 | |
1917 /* startup done */ | |
1918 _gtk_moz_embed_push_startup(); | |
1919 } | |
1920 } | |
1921 #endif | |
1922 | |
1923 /* Try to load the libgtkhtml2 shared libary */ | |
1924 #ifdef USE_LIBGTKHTML2 | |
1925 #include <ctype.h> | |
1926 | |
1927 void init_libgtkhtml2 (void) | |
1928 { | |
1929 void *handle = NULL; | |
1930 handle = dlopen( "libgtkhtml-2.so", RTLD_LAZY ); | |
1931 | |
1932 /* If we loaded it, grab the symbols we want */ | |
1933 if ( handle ) | |
1934 { | |
1935 _html_document_new = dlsym(handle, "html_document_new"); | |
1936 _html_view_new = dlsym(handle, "html_view_new"); | |
1937 //... | |
1938 _gtk_html_context_get = dlsym(handle, "gtk_html_context_get" ); | |
1939 g_object_set( G_OBJECT(_gtk_html_context_get()), "debug_painting", FALSE, NULL ); | |
1940 } | |
1941 } | |
1942 #endif | |
1943 | |
1944 /* Try to load the WebKitGtk shared libary */ | |
1945 #ifdef USE_WEBKIT | |
1946 void init_webkit(void) | |
1947 { | |
1948 char libname[100]; | |
1949 void *handle = NULL; | |
1950 | |
1951 sprintf( libname, "lib%s.so", WEBKIT_LIB); | |
1952 handle = dlopen( libname, RTLD_LAZY ); | |
1953 | |
1954 /* If we loaded it, grab the symbols we want */ | |
1955 if ( handle ) | |
1956 { | |
1957 _webkit_web_view_get_type = dlsym( handle, "webkit_web_view_get_type" ); | |
1958 _webkit_web_view_load_html_string = dlsym( handle, "webkit_web_view_load_html_string" ); | |
1959 _webkit_web_view_open = dlsym( handle, "webkit_web_view_open" ); | |
1960 _webkit_web_view_new = dlsym( handle, "webkit_web_view_new" ); | |
1961 _webkit_web_view_go_back = dlsym( handle, "webkit_web_view_go_back" ); | |
1962 _webkit_web_view_go_forward = dlsym( handle, "webkit_web_view_go_forward" ); | |
1963 _webkit_web_view_reload = dlsym( handle, "webkit_web_view_reload" ); | |
1964 _webkit_web_view_stop_loading = dlsym( handle, "webkit_web_view_stop_loading" ); | |
1965 # ifdef WEBKIT_CHECK_VERSION | |
1966 # if WEBKIT_CHECK_VERSION(1,1,5) | |
1967 _webkit_web_frame_print = dlsym( handle, "webkit_web_frame_print" ); | |
1968 _webkit_web_view_get_focused_frame = dlsym( handle, "webkit_web_view_get_focused_frame" ); | |
1969 # endif | |
1970 # endif | |
1971 } | |
1972 } | |
1973 #endif | |
1974 | |
1975 /* | |
1976 * Initializes the Dynamic Windows engine. | |
1977 * Parameters: | |
1978 * newthread: True if this is the only thread. | |
1979 * False if there is already a message loop running. | |
1980 */ | |
1981 int dw_int_init(DWResources *res, int newthread, int *argc, char **argv[]) | |
1982 { | |
1983 int z; | |
1984 char *tmp; | |
1985 char *fname; | |
1986 | |
1987 if(res) | |
1988 { | |
1989 _resources.resource_max = res->resource_max; | |
1990 _resources.resource_id = res->resource_id; | |
1991 _resources.resource_data = res->resource_data; | |
1992 } | |
1993 g_thread_init(NULL); | |
1994 gdk_threads_init(); | |
1995 | |
1996 gtk_init(argc, argv); | |
1997 | |
1998 tmp = getenv("DW_BORDER_WIDTH"); | |
1999 if(tmp) | |
2000 _dw_border_width = atoi(tmp); | |
2001 tmp = getenv("DW_BORDER_HEIGHT"); | |
2002 if(tmp) | |
2003 _dw_border_height = atoi(tmp); | |
2004 | |
2005 for(z=0;z<DW_THREAD_LIMIT;z++) | |
2006 _dw_thread_list[z] = (DWTID)-1; | |
2007 | |
2008 gtk_rc_parse_string("style \"gtk-tooltips-style\" { bg[NORMAL] = \"#eeee00\" } widget \"gtk-tooltips\" style \"gtk-tooltips-style\""); | |
2009 | |
2010 #ifdef USE_GTKMOZEMBED | |
2011 init_mozembed(); | |
2012 #endif | |
2013 | |
2014 #ifdef USE_LIBGTKHTML2 | |
2015 init_libgtkhtml2(); | |
2016 #endif | |
2017 | |
2018 #ifdef USE_WEBKIT | |
2019 init_webkit(); | |
2020 #endif | |
2021 /* | |
2022 * Setup logging/debugging | |
2023 */ | |
2024 if ( (fname = getenv( "DWINDOWS_DEBUGFILE" ) ) != NULL ) | |
2025 { | |
2026 dbgfp = fopen( fname, "w" ); | |
2027 } | |
2028 | |
2029 return TRUE; | |
2030 } | |
2031 | |
2032 /* | |
2033 * Runs a message loop for Dynamic Windows. | |
2034 */ | |
2035 void dw_main(void) | |
2036 { | |
2037 gdk_threads_enter(); | |
2038 _dw_thread = pthread_self(); | |
2039 _dw_thread_add(_dw_thread); | |
2040 gtk_main(); | |
2041 _dw_thread = (pthread_t)-1; | |
2042 gdk_threads_leave(); | |
2043 } | |
2044 | |
2045 /* | |
2046 * Runs a message loop for Dynamic Windows, for a period of milliseconds. | |
2047 * Parameters: | |
2048 * milliseconds: Number of milliseconds to run the loop for. | |
2049 */ | |
2050 void dw_main_sleep(int milliseconds) | |
2051 { | |
2052 struct timeval tv, start; | |
2053 pthread_t curr = pthread_self(); | |
2054 | |
2055 gettimeofday(&start, NULL); | |
2056 | |
2057 if(_dw_thread == (pthread_t)-1 || _dw_thread == curr) | |
2058 { | |
2059 pthread_t orig = _dw_thread; | |
2060 | |
2061 gettimeofday(&tv, NULL); | |
2062 | |
2063 while(((tv.tv_sec - start.tv_sec)*1000) + ((tv.tv_usec - start.tv_usec)/1000) <= milliseconds) | |
2064 { | |
2065 if(orig == (pthread_t)-1) | |
2066 { | |
2067 gdk_threads_enter(); | |
2068 _dw_thread = curr; | |
2069 } | |
2070 if(gtk_events_pending()) | |
2071 gtk_main_iteration(); | |
2072 else | |
2073 _dw_msleep(1); | |
2074 if(orig == (pthread_t)-1) | |
2075 { | |
2076 _dw_thread = orig; | |
2077 gdk_threads_leave(); | |
2078 } | |
2079 gettimeofday(&tv, NULL); | |
2080 } | |
2081 } | |
2082 else | |
2083 _dw_msleep(milliseconds); | |
2084 } | |
2085 | |
2086 /* | |
2087 * Processes a single message iteration and returns. | |
2088 */ | |
2089 void dw_main_iteration(void) | |
2090 { | |
2091 gdk_threads_enter(); | |
2092 _dw_thread = pthread_self(); | |
2093 _dw_thread_add(_dw_thread); | |
2094 gtk_main_iteration(); | |
2095 _dw_thread = (pthread_t)-1; | |
2096 gdk_threads_leave(); | |
2097 } | |
2098 | |
2099 /* | |
2100 * Free's memory allocated by dynamic windows. | |
2101 * Parameters: | |
2102 * ptr: Pointer to dynamic windows allocated | |
2103 * memory to be free()'d. | |
2104 */ | |
2105 void dw_free(void *ptr) | |
2106 { | |
2107 free(ptr); | |
2108 } | |
2109 | |
2110 /* | |
2111 * Allocates and initializes a dialog struct. | |
2112 * Parameters: | |
2113 * data: User defined data to be passed to functions. | |
2114 */ | |
2115 DWDialog *dw_dialog_new(void *data) | |
2116 { | |
2117 DWDialog *tmp = malloc(sizeof(DWDialog)); | |
2118 | |
2119 if ( tmp ) | |
2120 { | |
2121 tmp->eve = dw_event_new(); | |
2122 dw_event_reset(tmp->eve); | |
2123 tmp->data = data; | |
2124 tmp->done = FALSE; | |
2125 tmp->method = FALSE; | |
2126 tmp->result = NULL; | |
2127 } | |
2128 return tmp; | |
2129 } | |
2130 | |
2131 /* | |
2132 * Accepts a dialog struct and returns the given data to the | |
2133 * initial called of dw_dialog_wait(). | |
2134 * Parameters: | |
2135 * dialog: Pointer to a dialog struct aquired by dw_dialog_new). | |
2136 * result: Data to be returned by dw_dialog_wait(). | |
2137 */ | |
2138 int dw_dialog_dismiss(DWDialog *dialog, void *result) | |
2139 { | |
2140 dialog->result = result; | |
2141 if(dialog->method) | |
2142 gtk_main_quit(); | |
2143 else | |
2144 dw_event_post(dialog->eve); | |
2145 dialog->done = TRUE; | |
2146 return 0; | |
2147 } | |
2148 | |
2149 /* | |
2150 * Accepts a dialog struct waits for dw_dialog_dismiss() to be | |
2151 * called by a signal handler with the given dialog struct. | |
2152 * Parameters: | |
2153 * dialog: Pointer to a dialog struct aquired by dw_dialog_new). | |
2154 */ | |
2155 void *dw_dialog_wait(DWDialog *dialog) | |
2156 { | |
2157 void *tmp; | |
2158 int newprocess = 0; | |
2159 | |
2160 /* _dw_thread will be -1 if dw_main hasn't been run yet. */ | |
2161 if(_dw_thread == (pthread_t)-1) | |
2162 { | |
2163 _dw_thread = pthread_self(); | |
2164 newprocess = 1; | |
2165 gdk_threads_enter(); | |
2166 } | |
2167 | |
2168 if(pthread_self() == _dw_thread) | |
2169 { | |
2170 dialog->method = TRUE; | |
2171 gtk_main(); | |
2172 } | |
2173 else | |
2174 { | |
2175 dialog->method = FALSE; | |
2176 dw_event_wait(dialog->eve, -1); | |
2177 } | |
2178 | |
2179 if(newprocess) | |
2180 { | |
2181 _dw_thread = (pthread_t)-1; | |
2182 gdk_threads_leave(); | |
2183 } | |
2184 | |
2185 dw_event_close(&dialog->eve); | |
2186 tmp = dialog->result; | |
2187 free(dialog); | |
2188 return tmp; | |
2189 } | |
2190 | |
2191 static int _dw_ok_func(HWND window, void *data) | |
2192 { | |
2193 DWDialog *dwwait = (DWDialog *)data; | |
2194 | |
2195 if(!dwwait) | |
2196 return FALSE; | |
2197 | |
2198 dw_window_destroy((HWND)dwwait->data); | |
2199 dw_dialog_dismiss((DWDialog *)data, (void *)DW_MB_RETURN_OK); | |
2200 return FALSE; | |
2201 } | |
2202 | |
2203 int _dw_yes_func(HWND window, void *data) | |
2204 { | |
2205 DWDialog *dwwait = (DWDialog *)data; | |
2206 | |
2207 if(!dwwait) | |
2208 return FALSE; | |
2209 | |
2210 dw_window_destroy((HWND)dwwait->data); | |
2211 dw_dialog_dismiss((DWDialog *)data, (void *)DW_MB_RETURN_YES); | |
2212 return FALSE; | |
2213 } | |
2214 | |
2215 int _dw_no_func(HWND window, void *data) | |
2216 { | |
2217 DWDialog *dwwait = (DWDialog *)data; | |
2218 | |
2219 if(!dwwait) | |
2220 return FALSE; | |
2221 | |
2222 dw_window_destroy((HWND)dwwait->data); | |
2223 dw_dialog_dismiss((DWDialog *)data, (void *)DW_MB_RETURN_NO); | |
2224 return FALSE; | |
2225 } | |
2226 | |
2227 int _dw_cancel_func(HWND window, void *data) | |
2228 { | |
2229 DWDialog *dwwait = (DWDialog *)data; | |
2230 | |
2231 if(!dwwait) | |
2232 return FALSE; | |
2233 | |
2234 dw_window_destroy((HWND)dwwait->data); | |
2235 dw_dialog_dismiss((DWDialog *)data, (void *)DW_MB_RETURN_CANCEL); | |
2236 return FALSE; | |
2237 } | |
2238 | |
2239 /* | |
2240 * Displays a Message Box with given text and title.. | |
2241 * Parameters: | |
2242 * title: The title of the message box. | |
2243 * flags: Defines buttons and icons to display | |
2244 * format: printf style format string. | |
2245 * ...: Additional variables for use in the format. | |
2246 */ | |
2247 int dw_messagebox(char *title, int flags, char *format, ...) | |
2248 { | |
2249 HWND entrywindow, texttargetbox, imagetextbox, mainbox, okbutton, nobutton, yesbutton, cancelbutton, buttonbox, stext; | |
2250 ULONG flStyle = DW_FCF_TITLEBAR | DW_FCF_SHELLPOSITION | DW_FCF_SIZEBORDER; | |
2251 DWDialog *dwwait; | |
2252 va_list args; | |
2253 char outbuf[1000]; | |
2254 char **xpm_data = NULL; | |
2255 int x, y, extra_width=0,text_width,text_height; | |
2256 int width,height; | |
2257 | |
2258 va_start(args, format); | |
2259 vsnprintf(outbuf, 999, format, args); | |
2260 va_end(args); | |
2261 | |
2262 entrywindow = dw_window_new(HWND_DESKTOP, title, flStyle); | |
2263 mainbox = dw_box_new(DW_VERT, 10); | |
2264 dw_box_pack_start(entrywindow, mainbox, 0, 0, TRUE, TRUE, 0); | |
2265 | |
2266 /* determine if an icon is to be used - if so we need another HORZ box */ | |
2267 if((flags & DW_MB_ERROR) | (flags & DW_MB_WARNING) | (flags & DW_MB_INFORMATION) | (flags & DW_MB_QUESTION)) | |
2268 { | |
2269 imagetextbox = dw_box_new(DW_HORZ, 0); | |
2270 dw_box_pack_start(mainbox, imagetextbox, 0, 0, TRUE, TRUE, 2); | |
2271 texttargetbox = imagetextbox; | |
2272 } | |
2273 else | |
2274 { | |
2275 imagetextbox = NULL; | |
2276 texttargetbox = mainbox; | |
2277 } | |
2278 | |
2279 if(flags & DW_MB_ERROR) | |
2280 xpm_data = (char **)_dw_messagebox_error; | |
2281 else if(flags & DW_MB_WARNING) | |
2282 xpm_data = (char **)_dw_messagebox_warning; | |
2283 else if(flags & DW_MB_INFORMATION) | |
2284 xpm_data = (char **)_dw_messagebox_information; | |
2285 else if(flags & DW_MB_QUESTION) | |
2286 xpm_data = (char **)_dw_messagebox_question; | |
2287 | |
2288 if(xpm_data) | |
2289 extra_width = 32; | |
2290 | |
2291 if(texttargetbox == imagetextbox) | |
2292 { | |
2293 HWND handle = dw_bitmap_new( 100 ); | |
2294 GdkPixbuf *icon_pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm_data); | |
2295 | |
2296 gtk_image_set_from_pixbuf(GTK_IMAGE(handle), icon_pixbuf); | |
2297 | |
2298 dw_box_pack_start( texttargetbox, handle, 32, 32, FALSE, FALSE, 2); | |
2299 } | |
2300 | |
2301 /* Create text */ | |
2302 text_width = 240; | |
2303 text_height = 0; | |
2304 stext = dw_text_new(outbuf, 0); | |
2305 dw_window_set_style(stext, DW_DT_WORDBREAK, DW_DT_WORDBREAK); | |
2306 dw_font_text_extents_get(stext, NULL, outbuf, &width, &height); | |
2307 #if 0 | |
2308 height = height+3; | |
2309 if(width < text_width) | |
2310 text_height = height*2; | |
2311 else if(width < text_width*2) | |
2312 text_height = height*3; | |
2313 else if(width < text_width*3) | |
2314 text_height = height*4; | |
2315 else /* width > (3*text_width) */ | |
2316 { | |
2317 text_width = (width / 3) + 60; | |
2318 text_height = height*4; | |
2319 } | |
2320 #else | |
2321 text_width = min( width, dw_screen_width() - extra_width - 100 ); | |
2322 text_height = min( height, dw_screen_height() ); | |
2323 #endif | |
2324 dw_box_pack_start(texttargetbox, stext, text_width, text_height, TRUE, TRUE, 2); | |
2325 | |
2326 /* Buttons */ | |
2327 buttonbox = dw_box_new(DW_HORZ, 10); | |
2328 | |
2329 dw_box_pack_start(mainbox, buttonbox, 0, 0, TRUE, FALSE, 0); | |
2330 | |
2331 dwwait = dw_dialog_new((void *)entrywindow); | |
2332 | |
2333 /* which buttons ? */ | |
2334 if(flags & DW_MB_OK) | |
2335 { | |
2336 okbutton = dw_button_new("Ok", 1001L); | |
2337 dw_box_pack_start(buttonbox, okbutton, 50, 30, TRUE, FALSE, 2); | |
2338 dw_signal_connect(okbutton, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_ok_func), (void *)dwwait); | |
2339 } | |
2340 else if(flags & DW_MB_OKCANCEL) | |
2341 { | |
2342 okbutton = dw_button_new("Ok", 1001L); | |
2343 dw_box_pack_start(buttonbox, okbutton, 50, 30, TRUE, FALSE, 2); | |
2344 dw_signal_connect(okbutton, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_ok_func), (void *)dwwait); | |
2345 cancelbutton = dw_button_new("Cancel", 1002L); | |
2346 dw_box_pack_start(buttonbox, cancelbutton, 50, 30, TRUE, FALSE, 2); | |
2347 dw_signal_connect(cancelbutton, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait); | |
2348 } | |
2349 else if(flags & DW_MB_YESNO) | |
2350 { | |
2351 yesbutton = dw_button_new("Yes", 1001L); | |
2352 dw_box_pack_start(buttonbox, yesbutton, 50, 30, TRUE, FALSE, 2); | |
2353 dw_signal_connect(yesbutton, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_yes_func), (void *)dwwait); | |
2354 nobutton = dw_button_new("No", 1002L); | |
2355 dw_box_pack_start(buttonbox, nobutton, 50, 30, TRUE, FALSE, 2); | |
2356 dw_signal_connect(nobutton, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_no_func), (void *)dwwait); | |
2357 } | |
2358 else if(flags & DW_MB_YESNOCANCEL) | |
2359 { | |
2360 yesbutton = dw_button_new("Yes", 1001L); | |
2361 dw_box_pack_start(buttonbox, yesbutton, 50, 30, TRUE, FALSE, 2); | |
2362 dw_signal_connect(yesbutton, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_yes_func), (void *)dwwait); | |
2363 nobutton = dw_button_new("No", 1002L); | |
2364 dw_box_pack_start(buttonbox, nobutton, 50, 30, TRUE, FALSE, 2); | |
2365 dw_signal_connect(nobutton, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_no_func), (void *)dwwait); | |
2366 cancelbutton = dw_button_new("Cancel", 1003L); | |
2367 dw_box_pack_start(buttonbox, cancelbutton, 50, 30, TRUE, FALSE, 2); | |
2368 dw_signal_connect(cancelbutton, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait); | |
2369 } | |
2370 | |
2371 height = max(50,text_height)+100; | |
2372 x = ( - (text_width+60+extra_width))/2; | |
2373 y = (dw_screen_height() - height)/2; | |
2374 | |
2375 dw_window_set_pos_size(entrywindow, x, y, (text_width+60+extra_width), height); | |
2376 | |
2377 dw_window_show(entrywindow); | |
2378 | |
2379 return (int)dw_dialog_wait(dwwait); | |
2380 } | |
2381 | |
2382 /* | |
2383 * Minimizes or Iconifies a top-level window. | |
2384 * Parameters: | |
2385 * handle: The window handle to minimize. | |
2386 */ | |
2387 int dw_window_minimize(HWND handle) | |
2388 { | |
2389 int _locked_by_me = FALSE; | |
2390 GtkWidget *mdi = NULL; | |
2391 | |
2392 if(!handle) | |
2393 return 0; | |
2394 | |
2395 DW_MUTEX_LOCK; | |
2396 if((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi)) | |
2397 { | |
2398 gtk_mdi_set_state(GTK_MDI(mdi), handle, CHILD_ICONIFIED); | |
2399 } | |
2400 else | |
2401 { | |
2402 #if 0 | |
2403 XIconifyWindow(GDK_WINDOW_XDISPLAY(GTK_WIDGET(handle)->window), | |
2404 GDK_WINDOW_XWINDOW(GTK_WIDGET(handle)->window), | |
2405 DefaultScreen (GDK_DISPLAY ())); | |
2406 #else | |
2407 gtk_window_iconify( GTK_WINDOW(handle) ); | |
2408 #endif | |
2409 } | |
2410 DW_MUTEX_UNLOCK; | |
2411 return 0; | |
2412 } | |
2413 | |
2414 /* | |
2415 * Makes the window topmost. | |
2416 * Parameters: | |
2417 * handle: The window handle to make topmost. | |
2418 */ | |
2419 int dw_window_raise(HWND handle) | |
2420 { | |
2421 int _locked_by_me = FALSE; | |
2422 | |
2423 if(!handle) | |
2424 return 0; | |
2425 | |
2426 DW_MUTEX_LOCK; | |
2427 gdk_window_raise(gtk_widget_get_window(GTK_WIDGET(handle))); | |
2428 DW_MUTEX_UNLOCK; | |
2429 return 0; | |
2430 } | |
2431 | |
2432 /* | |
2433 * Makes the window bottommost. | |
2434 * Parameters: | |
2435 * handle: The window handle to make bottommost. | |
2436 */ | |
2437 int dw_window_lower(HWND handle) | |
2438 { | |
2439 int _locked_by_me = FALSE; | |
2440 | |
2441 if(!handle) | |
2442 return 0; | |
2443 | |
2444 DW_MUTEX_LOCK; | |
2445 gdk_window_lower(gtk_widget_get_window(GTK_WIDGET(handle))); | |
2446 DW_MUTEX_UNLOCK; | |
2447 return 0; | |
2448 } | |
2449 | |
2450 /* | |
2451 * Makes the window visible. | |
2452 * Parameters: | |
2453 * handle: The window handle to make visible. | |
2454 */ | |
2455 int dw_window_show(HWND handle) | |
2456 { | |
2457 int _locked_by_me = FALSE; | |
2458 GtkWidget *defaultitem; | |
2459 GtkWidget *mdi; | |
2460 | |
2461 if (!handle) | |
2462 return 0; | |
2463 | |
2464 DW_MUTEX_LOCK; | |
2465 gtk_widget_show(handle); | |
2466 if ((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi)) | |
2467 { | |
2468 gtk_mdi_set_state(GTK_MDI(mdi), handle, CHILD_NORMAL); | |
2469 } | |
2470 else | |
2471 { | |
2472 if (gtk_widget_get_window(GTK_WIDGET(handle))) | |
2473 { | |
2474 int width = (int)g_object_get_data(G_OBJECT(handle), "_dw_width"); | |
2475 int height = (int)g_object_get_data(G_OBJECT(handle), "_dw_height"); | |
2476 | |
2477 if (width && height) | |
2478 { | |
2479 gtk_widget_set_size_request(handle, width, height); | |
2480 g_object_set_data(G_OBJECT(handle), "_dw_width", GINT_TO_POINTER(0)); | |
2481 g_object_set_data(G_OBJECT(handle), "_dw_height", GINT_TO_POINTER(0)); | |
2482 } | |
2483 | |
2484 gdk_window_raise(gtk_widget_get_window(GTK_WIDGET(handle))); | |
2485 gdk_flush(); | |
2486 gdk_window_show(gtk_widget_get_window(GTK_WIDGET(handle))); | |
2487 gdk_flush(); | |
2488 } | |
2489 defaultitem = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_defaultitem"); | |
2490 if (defaultitem) | |
2491 gtk_widget_grab_focus(defaultitem); | |
2492 } | |
2493 DW_MUTEX_UNLOCK; | |
2494 return 0; | |
2495 } | |
2496 | |
2497 /* | |
2498 * Makes the window invisible. | |
2499 * Parameters: | |
2500 * handle: The window handle to make visible. | |
2501 */ | |
2502 int dw_window_hide(HWND handle) | |
2503 { | |
2504 int _locked_by_me = FALSE; | |
2505 GtkWidget *mdi = NULL; | |
2506 | |
2507 if(!handle) | |
2508 return 0; | |
2509 | |
2510 DW_MUTEX_LOCK; | |
2511 if((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi)) | |
2512 { | |
2513 gtk_mdi_set_state(GTK_MDI(mdi), handle, CHILD_ICONIFIED); | |
2514 } | |
2515 else | |
2516 gtk_widget_hide(handle); | |
2517 DW_MUTEX_UNLOCK; | |
2518 return 0; | |
2519 } | |
2520 | |
2521 /* | |
2522 * Destroys a window and all of it's children. | |
2523 * Parameters: | |
2524 * handle: The window handle to destroy. | |
2525 */ | |
2526 int dw_window_destroy(HWND handle) | |
2527 { | |
2528 int _locked_by_me = FALSE; | |
2529 GtkWidget *mdi = NULL; | |
2530 | |
2531 if(!handle) | |
2532 return 0; | |
2533 | |
2534 DW_MUTEX_LOCK; | |
2535 if((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi)) | |
2536 { | |
2537 gtk_mdi_remove(GTK_MDI(mdi), handle); | |
2538 } | |
2539 if(GTK_IS_WIDGET(handle)) | |
2540 { | |
2541 GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_eventbox"); | |
2542 | |
2543 if(eventbox && GTK_IS_WIDGET(eventbox)) | |
2544 gtk_widget_destroy(eventbox); | |
2545 else | |
2546 gtk_widget_destroy(handle); | |
2547 } | |
2548 DW_MUTEX_UNLOCK; | |
2549 return 0; | |
2550 } | |
2551 | |
2552 /* Causes entire window to be invalidated and redrawn. | |
2553 * Parameters: | |
2554 * handle: Toplevel window handle to be redrawn. | |
2555 */ | |
2556 void dw_window_redraw(HWND handle) | |
2557 { | |
2558 } | |
2559 | |
2560 /* | |
2561 * Changes a window's parent to newparent. | |
2562 * Parameters: | |
2563 * handle: The window handle to destroy. | |
2564 * newparent: The window's new parent window. | |
2565 */ | |
2566 void dw_window_reparent(HWND handle, HWND newparent) | |
2567 { | |
2568 int _locked_by_me = FALSE; | |
2569 | |
2570 DW_MUTEX_LOCK; | |
2571 gdk_window_reparent(gtk_widget_get_window(GTK_WIDGET(handle)), newparent ? gtk_widget_get_window(GTK_WIDGET(newparent)) : GDK_ROOT_WINDOW(), 0, 0); | |
2572 DW_MUTEX_UNLOCK; | |
2573 } | |
2574 | |
2575 static int _set_font(HWND handle, char *fontname) | |
2576 { | |
2577 int retval = FALSE; | |
2578 PangoFontDescription *font = pango_font_description_from_string(fontname); | |
2579 | |
2580 if(font) | |
2581 { | |
2582 gtk_widget_modify_font(handle, font); | |
2583 pango_font_description_free(font); | |
2584 } | |
2585 return retval; | |
2586 } | |
2587 | |
2588 /* | |
2589 * Sets the font used by a specified window (widget) handle. | |
2590 * Parameters: | |
2591 * handle: The window (widget) handle. | |
2592 * fontname: Name and size of the font in the form "size.fontname" | |
2593 */ | |
2594 int dw_window_set_font(HWND handle, char *fontname) | |
2595 { | |
2596 PangoFontDescription *pfont; | |
2597 GtkWidget *handle2 = handle; | |
2598 char *font; | |
2599 int _locked_by_me = FALSE; | |
2600 gpointer data; | |
2601 | |
2602 DW_MUTEX_LOCK; | |
2603 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
2604 { | |
2605 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
2606 if(tmp) | |
2607 handle2 = tmp; | |
2608 } | |
2609 font = strdup(fontname); | |
2610 | |
2611 /* Free old font name if one is allocated */ | |
2612 data = g_object_get_data(G_OBJECT(handle2), "_dw_fontname"); | |
2613 if(data) | |
2614 free(data); | |
2615 | |
2616 g_object_set_data(G_OBJECT(handle2), "_dw_fontname", (gpointer)font); | |
2617 pfont = pango_font_description_from_string(fontname); | |
2618 | |
2619 if(pfont) | |
2620 { | |
2621 gtk_widget_modify_font(handle2, pfont); | |
2622 pango_font_description_free(pfont); | |
2623 } | |
2624 DW_MUTEX_UNLOCK; | |
2625 return TRUE; | |
2626 } | |
2627 | |
2628 /* | |
2629 * Gets the font used by a specified window (widget) handle. | |
2630 * Parameters: | |
2631 * handle: The window (widget) handle. | |
2632 */ | |
2633 char *dw_window_get_font(HWND handle) | |
2634 { | |
2635 PangoFontDescription *pfont; | |
2636 PangoContext *pcontext; | |
2637 GtkWidget *handle2 = handle; | |
2638 char *font; | |
2639 char *retfont=NULL; | |
2640 int _locked_by_me = FALSE; | |
2641 gpointer data; | |
2642 | |
2643 DW_MUTEX_LOCK; | |
2644 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
2645 { | |
2646 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
2647 if(tmp) | |
2648 handle2 = tmp; | |
2649 } | |
2650 | |
2651 #if 0 | |
2652 /* Free old font name if one is allocated */ | |
2653 data = g_object_get_data(G_OBJECT(handle2), "_dw_fontname"); | |
2654 if(data) | |
2655 free(data); | |
2656 | |
2657 g_object_set_data(G_OBJECT(handle2), "_dw_fontname", (gpointer)font); | |
2658 #endif | |
2659 | |
2660 pcontext = gtk_widget_get_pango_context( handle2 ); | |
2661 if ( pcontext ) | |
2662 { | |
2663 pfont = pango_context_get_font_description( pcontext ); | |
2664 if ( pfont ) | |
2665 { | |
2666 font = pango_font_description_to_string( pfont ); | |
2667 retfont = strdup(font); | |
2668 g_free( font ); | |
2669 } | |
2670 } | |
2671 DW_MUTEX_UNLOCK; | |
2672 return retfont; | |
2673 } | |
2674 | |
2675 void _free_gdk_colors(HWND handle) | |
2676 { | |
2677 GdkColor *old = (GdkColor *)g_object_get_data(G_OBJECT(handle), "_dw_foregdk"); | |
2678 | |
2679 if(old) | |
2680 free(old); | |
2681 | |
2682 old = (GdkColor *)g_object_get_data(G_OBJECT(handle), "_dw_backgdk"); | |
2683 | |
2684 if(old) | |
2685 free(old); | |
2686 } | |
2687 | |
2688 /* Free old color pointers and allocate new ones */ | |
2689 static void _save_gdk_colors(HWND handle, GdkColor fore, GdkColor back) | |
2690 { | |
2691 GdkColor *foregdk = malloc(sizeof(GdkColor)); | |
2692 GdkColor *backgdk = malloc(sizeof(GdkColor)); | |
2693 | |
2694 _free_gdk_colors(handle); | |
2695 | |
2696 *foregdk = fore; | |
2697 *backgdk = back; | |
2698 | |
2699 g_object_set_data(G_OBJECT(handle), "_dw_foregdk", (gpointer)foregdk); | |
2700 g_object_set_data(G_OBJECT(handle), "_dw_backgdk", (gpointer)backgdk); | |
2701 } | |
2702 | |
2703 static int _set_color(HWND handle, unsigned long fore, unsigned long back) | |
2704 { | |
2705 /* Remember that each color component in X11 use 16 bit no matter | |
2706 * what the destination display supports. (and thus GDK) | |
2707 */ | |
2708 GdkColor forecolor, backcolor; | |
2709 | |
2710 if(fore & DW_RGB_COLOR) | |
2711 { | |
2712 forecolor.pixel = 0; | |
2713 forecolor.red = DW_RED_VALUE(fore) << 8; | |
2714 forecolor.green = DW_GREEN_VALUE(fore) << 8; | |
2715 forecolor.blue = DW_BLUE_VALUE(fore) << 8; | |
2716 | |
2717 gtk_widget_modify_text(handle, 0, &forecolor); | |
2718 gtk_widget_modify_text(handle, 1, &forecolor); | |
2719 gtk_widget_modify_fg(handle, 0, &forecolor); | |
2720 gtk_widget_modify_fg(handle, 1, &forecolor); | |
2721 } | |
2722 else if(fore != DW_CLR_DEFAULT) | |
2723 { | |
2724 forecolor = _colors[fore]; | |
2725 | |
2726 gtk_widget_modify_text(handle, 0, &_colors[fore]); | |
2727 gtk_widget_modify_text(handle, 1, &_colors[fore]); | |
2728 gtk_widget_modify_fg(handle, 0, &_colors[fore]); | |
2729 gtk_widget_modify_fg(handle, 1, &_colors[fore]); | |
2730 } | |
2731 if(back & DW_RGB_COLOR) | |
2732 { | |
2733 backcolor.pixel = 0; | |
2734 backcolor.red = DW_RED_VALUE(back) << 8; | |
2735 backcolor.green = DW_GREEN_VALUE(back) << 8; | |
2736 backcolor.blue = DW_BLUE_VALUE(back) << 8; | |
2737 | |
2738 gtk_widget_modify_base(handle, 0, &backcolor); | |
2739 gtk_widget_modify_base(handle, 1, &backcolor); | |
2740 gtk_widget_modify_bg(handle, 0, &backcolor); | |
2741 gtk_widget_modify_bg(handle, 1, &backcolor); | |
2742 } | |
2743 else if(back != DW_CLR_DEFAULT) | |
2744 { | |
2745 backcolor = _colors[back]; | |
2746 | |
2747 gtk_widget_modify_base(handle, 0, &_colors[back]); | |
2748 gtk_widget_modify_base(handle, 1, &_colors[back]); | |
2749 gtk_widget_modify_bg(handle, 0, &_colors[back]); | |
2750 gtk_widget_modify_bg(handle, 1, &_colors[back]); | |
2751 } | |
2752 | |
2753 _save_gdk_colors(handle, forecolor, backcolor); | |
2754 | |
2755 return TRUE; | |
2756 } | |
2757 /* | |
2758 * Sets the colors used by a specified window (widget) handle. | |
2759 * Parameters: | |
2760 * handle: The window (widget) handle. | |
2761 * fore: Foreground color in RGB format. | |
2762 * back: Background color in RGB format. | |
2763 */ | |
2764 int dw_window_set_color(HWND handle, unsigned long fore, unsigned long back) | |
2765 { | |
2766 GtkWidget *handle2 = handle; | |
2767 int _locked_by_me = FALSE; | |
2768 | |
2769 DW_MUTEX_LOCK; | |
2770 | |
2771 if(GTK_IS_SCROLLED_WINDOW(handle) || GTK_IS_BOX(handle)) | |
2772 { | |
2773 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
2774 if(tmp) | |
2775 handle2 = tmp; | |
2776 } | |
2777 else if(GTK_IS_TABLE(handle)) | |
2778 { | |
2779 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_eventbox"); | |
2780 if(tmp) | |
2781 handle2 = tmp; | |
2782 } | |
2783 | |
2784 _set_color(handle2, fore, back); | |
2785 | |
2786 DW_MUTEX_UNLOCK; | |
2787 return TRUE; | |
2788 } | |
2789 | |
2790 /* | |
2791 * Sets the font used by a specified window (widget) handle. | |
2792 * Parameters: | |
2793 * handle: The window (widget) handle. | |
2794 * border: Size of the window border in pixels. | |
2795 */ | |
2796 int dw_window_set_border(HWND handle, int border) | |
2797 { | |
2798 /* TODO */ | |
2799 return 0; | |
2800 } | |
2801 | |
2802 /* | |
2803 * Captures the mouse input to this window. | |
2804 * Parameters: | |
2805 * handle: Handle to receive mouse input. | |
2806 */ | |
2807 void dw_window_capture(HWND handle) | |
2808 { | |
2809 int _locked_by_me = FALSE; | |
2810 | |
2811 DW_MUTEX_LOCK; | |
2812 gdk_pointer_grab(gtk_widget_get_window(handle), TRUE, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK, NULL, NULL, GDK_CURRENT_TIME); | |
2813 DW_MUTEX_UNLOCK; | |
2814 } | |
2815 | |
2816 /* | |
2817 * Changes the appearance of the mouse pointer. | |
2818 * Parameters: | |
2819 * handle: Handle to widget for which to change. | |
2820 * cursortype: ID of the pointer you want. | |
2821 */ | |
2822 void dw_window_set_pointer(HWND handle, int pointertype) | |
2823 { | |
2824 int _locked_by_me = FALSE; | |
2825 GdkCursor *cursor; | |
2826 | |
2827 DW_MUTEX_LOCK; | |
2828 if(pointertype & (1 << 31)) | |
2829 { | |
2830 GdkPixbuf *pixbuf = _find_private_pixbuf((pointertype & 0xFFFFFF), NULL, NULL); | |
2831 cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf, 8, 8); | |
2832 } | |
2833 else if(!pointertype) | |
2834 cursor = NULL; | |
2835 else | |
2836 cursor = gdk_cursor_new(pointertype); | |
2837 if(handle && gtk_widget_get_window(handle)) | |
2838 gdk_window_set_cursor(gtk_widget_get_window(handle), cursor); | |
2839 if(cursor) | |
2840 gdk_cursor_unref(cursor); | |
2841 DW_MUTEX_UNLOCK; | |
2842 } | |
2843 | |
2844 /* | |
2845 * Releases previous mouse capture. | |
2846 */ | |
2847 void dw_window_release(void) | |
2848 { | |
2849 int _locked_by_me = FALSE; | |
2850 | |
2851 DW_MUTEX_LOCK; | |
2852 gdk_pointer_ungrab(GDK_CURRENT_TIME); | |
2853 DW_MUTEX_UNLOCK; | |
2854 } | |
2855 | |
2856 /* | |
2857 * Create a new Window Frame. | |
2858 * Parameters: | |
2859 * owner: The Owner's window handle or HWND_DESKTOP. | |
2860 * title: The Window title. | |
2861 * flStyle: Style flags, see the PM reference. | |
2862 */ | |
2863 HWND dw_window_new(HWND hwndOwner, char *title, unsigned long flStyle) | |
2864 { | |
2865 GtkWidget *tmp; | |
2866 int _locked_by_me = FALSE; | |
2867 int flags = 0; | |
2868 | |
2869 DW_MUTEX_LOCK; | |
2870 if(hwndOwner && GTK_IS_MDI(hwndOwner)) | |
2871 { | |
2872 GtkWidget *label; | |
2873 | |
2874 tmp = dw_box_new(DW_VERT, 0); | |
2875 | |
2876 label = gtk_label_new(title); | |
2877 gtk_widget_show(label); | |
2878 g_object_set_data(G_OBJECT(tmp), "_dw_mdi_child", GINT_TO_POINTER(1)); | |
2879 g_object_set_data(G_OBJECT(tmp), "_dw_mdi_title", (gpointer)label); | |
2880 g_object_set_data(G_OBJECT(tmp), "_dw_mdi", (gpointer)hwndOwner); | |
2881 | |
2882 gtk_mdi_put(GTK_MDI(hwndOwner), tmp, 100, 75, label); | |
2883 } | |
2884 else | |
2885 { | |
2886 last_window = tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
2887 | |
2888 gtk_window_set_title(GTK_WINDOW(tmp), title); | |
2889 if(!(flStyle & DW_FCF_SIZEBORDER)) | |
2890 gtk_window_set_resizable(GTK_WINDOW(tmp), FALSE); | |
2891 | |
2892 gtk_widget_realize(tmp); | |
2893 | |
2894 if(flStyle & DW_FCF_TITLEBAR) | |
2895 flags |= GDK_DECOR_TITLE; | |
2896 | |
2897 if(flStyle & DW_FCF_MINMAX) | |
2898 flags |= GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE; | |
2899 | |
2900 if(flStyle & DW_FCF_SIZEBORDER) | |
2901 flags |= GDK_DECOR_RESIZEH | GDK_DECOR_BORDER; | |
2902 | |
2903 if(flStyle & DW_FCF_BORDER || flStyle & DW_FCF_DLGBORDER) | |
2904 flags |= GDK_DECOR_BORDER; | |
2905 | |
2906 if(flStyle & DW_FCF_MAXIMIZE) | |
2907 { | |
2908 flags &= ~DW_FCF_MAXIMIZE; | |
2909 gtk_window_maximize(GTK_WINDOW(tmp)); | |
2910 } | |
2911 if(flStyle & DW_FCF_MINIMIZE) | |
2912 { | |
2913 flags &= ~DW_FCF_MINIMIZE; | |
2914 gtk_window_iconify(GTK_WINDOW(tmp)); | |
2915 } | |
2916 | |
2917 gdk_window_set_decorations(gtk_widget_get_window(tmp), flags); | |
2918 | |
2919 if(hwndOwner) | |
2920 gdk_window_reparent(gtk_widget_get_window(GTK_WIDGET(tmp)), gtk_widget_get_window(GTK_WIDGET(hwndOwner)), 0, 0); | |
2921 | |
2922 if(flStyle & DW_FCF_SIZEBORDER) | |
2923 g_object_set_data(G_OBJECT(tmp), "_dw_size", GINT_TO_POINTER(1)); | |
2924 } | |
2925 g_object_set_data(G_OBJECT(tmp), "_dw_style", GINT_TO_POINTER(flStyle)); | |
2926 DW_MUTEX_UNLOCK; | |
2927 return tmp; | |
2928 } | |
2929 | |
2930 /* | |
2931 * Create a new Box to be packed. | |
2932 * Parameters: | |
2933 * type: Either DW_VERT (vertical) or DW_HORZ (horizontal). | |
2934 * pad: Number of pixels to pad around the box. | |
2935 */ | |
2936 HWND dw_box_new(int type, int pad) | |
2937 { | |
2938 GtkWidget *tmp, *eventbox; | |
2939 int _locked_by_me = FALSE; | |
2940 | |
2941 DW_MUTEX_LOCK; | |
2942 tmp = gtk_table_new(1, 1, FALSE); | |
2943 eventbox = gtk_event_box_new(); | |
2944 | |
2945 gtk_widget_show(eventbox); | |
2946 g_object_set_data(G_OBJECT(tmp), "_dw_eventbox", (gpointer)eventbox); | |
2947 g_object_set_data(G_OBJECT(tmp), "_dw_boxtype", GINT_TO_POINTER(type)); | |
2948 g_object_set_data(G_OBJECT(tmp), "_dw_boxpad", GINT_TO_POINTER(pad)); | |
2949 gtk_widget_show(tmp); | |
2950 DW_MUTEX_UNLOCK; | |
2951 return tmp; | |
2952 } | |
2953 | |
2954 #ifndef INCOMPLETE | |
2955 /* | |
2956 * Create a new scrollable Box to be packed. | |
2957 * Parameters: | |
2958 * type: Either DW_VERT (vertical) or DW_HORZ (horizontal). | |
2959 * pad: Number of pixels to pad around the box. | |
2960 * This works fine under GTK+, but is incomplete on other platforms | |
2961 */ | |
2962 HWND dw_scrollbox_new( int type, int pad ) | |
2963 { | |
2964 GtkWidget *tmp, *box, *eventbox; | |
2965 int _locked_by_me = FALSE; | |
2966 | |
2967 DW_MUTEX_LOCK; | |
2968 tmp = gtk_scrolled_window_new(NULL, NULL); | |
2969 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (tmp), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |
2970 | |
2971 box = gtk_table_new(1, 1, FALSE); | |
2972 eventbox = gtk_event_box_new(); | |
2973 | |
2974 gtk_widget_show(eventbox); | |
2975 g_object_set_data(G_OBJECT(box), "_dw_eventbox", (gpointer)eventbox); | |
2976 g_object_set_data(G_OBJECT(box), "_dw_boxtype", GINT_TO_POINTER(type)); | |
2977 g_object_set_data(G_OBJECT(box), "_dw_boxpad", GINT_TO_POINTER(pad)); | |
2978 g_object_set_data(G_OBJECT(tmp), "_dw_boxhandle", (gpointer)box); | |
2979 | |
2980 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(tmp),box); | |
2981 g_object_set_data(G_OBJECT(tmp), "_dw_user", box); | |
2982 gtk_widget_show(box); | |
2983 gtk_widget_show(tmp); | |
2984 | |
2985 DW_MUTEX_UNLOCK; | |
2986 return tmp; | |
2987 } | |
2988 | |
2989 /* | |
2990 * Returns the position of the scrollbar in the scrollbox | |
2991 * Parameters: | |
2992 * handle: Handle to the scrollbox to be queried. | |
2993 * orient: The vertical or horizontal scrollbar. | |
2994 */ | |
2995 int dw_scrollbox_get_pos(HWND handle, int orient) | |
2996 { | |
2997 int val = -1, _locked_by_me = FALSE; | |
2998 GtkAdjustment *adjustment; | |
2999 | |
3000 if (!handle) | |
3001 return -1; | |
3002 | |
3003 DW_MUTEX_LOCK; | |
3004 if ( orient == DW_HORZ ) | |
3005 adjustment = gtk_scrolled_window_get_hadjustment( GTK_SCROLLED_WINDOW(handle) ); | |
3006 else | |
3007 adjustment = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(handle) ); | |
3008 if (adjustment) | |
3009 val = _round_value(gtk_adjustment_get_value(adjustment)); | |
3010 DW_MUTEX_UNLOCK; | |
3011 return val; | |
3012 } | |
3013 | |
3014 /* | |
3015 * Gets the range for the scrollbar in the scrollbox. | |
3016 * Parameters: | |
3017 * handle: Handle to the scrollbox to be queried. | |
3018 * orient: The vertical or horizontal scrollbar. | |
3019 */ | |
3020 int API dw_scrollbox_get_range(HWND handle, int orient) | |
3021 { | |
3022 int range = -1, _locked_by_me = FALSE; | |
3023 GtkAdjustment *adjustment; | |
3024 | |
3025 if (!handle) | |
3026 return -1; | |
3027 | |
3028 DW_MUTEX_LOCK; | |
3029 if ( orient == DW_HORZ ) | |
3030 adjustment = gtk_scrolled_window_get_hadjustment( GTK_SCROLLED_WINDOW(handle) ); | |
3031 else | |
3032 adjustment = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(handle) ); | |
3033 if (adjustment) | |
3034 { | |
3035 range = _round_value(gtk_adjustment_get_upper(adjustment)); | |
3036 } | |
3037 DW_MUTEX_UNLOCK; | |
3038 return range; | |
3039 } | |
3040 #endif | |
3041 | |
3042 /* | |
3043 * Create a new Group Box to be packed. | |
3044 * Parameters: | |
3045 * type: Either DW_VERT (vertical) or DW_HORZ (horizontal). | |
3046 * pad: Number of pixels to pad around the box. | |
3047 * title: Text to be displayined in the group outline. | |
3048 */ | |
3049 HWND dw_groupbox_new(int type, int pad, char *title) | |
3050 { | |
3051 GtkWidget *tmp, *frame, *label; | |
3052 PangoFontDescription *pfont; | |
3053 PangoContext *pcontext; | |
3054 int _locked_by_me = FALSE; | |
3055 | |
3056 DW_MUTEX_LOCK; | |
3057 frame = gtk_frame_new(NULL); | |
3058 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); | |
3059 gtk_frame_set_label(GTK_FRAME(frame), title && *title ? title : NULL); | |
3060 /* | |
3061 * Get the current font for the frame's label and make it bold | |
3062 */ | |
3063 label = gtk_frame_get_label_widget(GTK_FRAME(frame)); | |
3064 pcontext = gtk_widget_get_pango_context( label ); | |
3065 if ( pcontext ) | |
3066 { | |
3067 pfont = pango_context_get_font_description( pcontext ); | |
3068 if ( pfont ) | |
3069 { | |
3070 pango_font_description_set_weight( pfont, PANGO_WEIGHT_BOLD ); | |
3071 gtk_widget_modify_font( label, pfont ); | |
3072 } | |
3073 } | |
3074 | |
3075 tmp = gtk_table_new(1, 1, FALSE); | |
3076 gtk_container_set_border_width(GTK_CONTAINER(tmp), pad); | |
3077 g_object_set_data(G_OBJECT(tmp), "_dw_boxtype", GINT_TO_POINTER(type)); | |
3078 g_object_set_data(G_OBJECT(tmp), "_dw_boxpad", GINT_TO_POINTER(pad)); | |
3079 g_object_set_data(G_OBJECT(frame), "_dw_boxhandle", (gpointer)tmp); | |
3080 gtk_container_add(GTK_CONTAINER(frame), tmp); | |
3081 gtk_widget_show(tmp); | |
3082 gtk_widget_show(frame); | |
3083 DW_MUTEX_UNLOCK; | |
3084 return frame; | |
3085 } | |
3086 | |
3087 /* | |
3088 * Create a new MDI Frame to be packed. | |
3089 * Parameters: | |
3090 * id: An ID to be used with dw_window_from_id or 0L. | |
3091 */ | |
3092 HWND dw_mdi_new(unsigned long id) | |
3093 { | |
3094 GtkWidget *tmp; | |
3095 int _locked_by_me = FALSE; | |
3096 | |
3097 DW_MUTEX_LOCK; | |
3098 tmp = gtk_mdi_new(); | |
3099 gtk_widget_show(tmp); | |
3100 DW_MUTEX_UNLOCK; | |
3101 return tmp; | |
3102 } | |
3103 | |
3104 /* | |
3105 * Create a bitmap object to be packed. | |
3106 * Parameters: | |
3107 * id: An ID to be used with dw_window_from_id() or 0L. | |
3108 */ | |
3109 HWND dw_bitmap_new(unsigned long id) | |
3110 { | |
3111 GtkWidget *tmp; | |
3112 int _locked_by_me = FALSE; | |
3113 | |
3114 DW_MUTEX_LOCK; | |
3115 tmp = gtk_image_new(); | |
3116 gtk_widget_show(tmp); | |
3117 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3118 DW_MUTEX_UNLOCK; | |
3119 return tmp; | |
3120 } | |
3121 | |
3122 /* | |
3123 * Create a notebook object to be packed. | |
3124 * Parameters: | |
3125 * id: An ID to be used for getting the resource from the | |
3126 * resource file. | |
3127 */ | |
3128 HWND dw_notebook_new(unsigned long id, int top) | |
3129 { | |
3130 GtkWidget *tmp, **pagearray = calloc(sizeof(GtkWidget *), 256); | |
3131 int _locked_by_me = FALSE; | |
3132 | |
3133 DW_MUTEX_LOCK; | |
3134 tmp = gtk_notebook_new(); | |
3135 if(top) | |
3136 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tmp), GTK_POS_TOP); | |
3137 else | |
3138 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tmp), GTK_POS_BOTTOM); | |
3139 gtk_notebook_set_scrollable(GTK_NOTEBOOK(tmp), TRUE); | |
3140 #if 0 | |
3141 gtk_notebook_popup_enable(GTK_NOTEBOOK(tmp)); | |
3142 #endif | |
3143 gtk_widget_show(tmp); | |
3144 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3145 g_object_set_data(G_OBJECT(tmp), "_dw_pagearray", (gpointer)pagearray); | |
3146 DW_MUTEX_UNLOCK; | |
3147 return tmp; | |
3148 } | |
3149 | |
3150 /* | |
3151 * Create a menu object to be popped up. | |
3152 * Parameters: | |
3153 * id: An ID to be used for getting the resource from the | |
3154 * resource file. | |
3155 */ | |
3156 HMENUI dw_menu_new(unsigned long id) | |
3157 { | |
3158 int _locked_by_me = FALSE; | |
3159 GtkAccelGroup *accel_group; | |
3160 HMENUI tmp; | |
3161 | |
3162 DW_MUTEX_LOCK; | |
3163 tmp = gtk_menu_new(); | |
3164 gtk_widget_show(tmp); | |
3165 accel_group = gtk_accel_group_new(); | |
3166 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3167 g_object_set_data(G_OBJECT(tmp), "_dw_accel", (gpointer)accel_group); | |
3168 DW_MUTEX_UNLOCK; | |
3169 return tmp; | |
3170 } | |
3171 | |
3172 /* | |
3173 * Create a menubar on a window. | |
3174 * Parameters: | |
3175 * location: Handle of a window frame to be attached to. | |
3176 * If there is no box already packed into the "location", the menu will not appear | |
3177 * so tell the user. | |
3178 */ | |
3179 HMENUI dw_menubar_new(HWND location) | |
3180 { | |
3181 GtkWidget *box; | |
3182 int _locked_by_me = FALSE; | |
3183 GtkAccelGroup *accel_group; | |
3184 HMENUI tmp; | |
3185 | |
3186 DW_MUTEX_LOCK; | |
3187 tmp = gtk_menu_bar_new(); | |
3188 box = (GtkWidget *)g_object_get_data(G_OBJECT(location), "_dw_user"); | |
3189 gtk_widget_show(tmp); | |
3190 accel_group = gtk_accel_group_new(); | |
3191 g_object_set_data(G_OBJECT(tmp), "_dw_accel", (gpointer)accel_group); | |
3192 | |
3193 if (box) | |
3194 gtk_box_pack_end(GTK_BOX(box), tmp, FALSE, FALSE, 0); | |
3195 else | |
3196 fprintf(stderr,"dw_menubar_new(): Coding error: You MUST pack a box into the window in which this menubar is to be added BEFORE calling this function.\n"); | |
3197 | |
3198 DW_MUTEX_UNLOCK; | |
3199 return tmp; | |
3200 } | |
3201 | |
3202 /* | |
3203 * Destroys a menu created with dw_menubar_new or dw_menu_new. | |
3204 * Parameters: | |
3205 * menu: Handle of a menu. | |
3206 */ | |
3207 void dw_menu_destroy(HMENUI *menu) | |
3208 { | |
3209 if(menu && *menu) | |
3210 { | |
3211 int _locked_by_me = FALSE; | |
3212 | |
3213 DW_MUTEX_LOCK; | |
3214 gtk_widget_destroy(*menu); | |
3215 *menu = NULL; | |
3216 DW_MUTEX_UNLOCK; | |
3217 } | |
3218 } | |
3219 | |
3220 char _removetilde(char *dest, char *src) | |
3221 { | |
3222 int z, cur=0; | |
3223 char accel = '\0'; | |
3224 | |
3225 for(z=0;z<strlen(src);z++) | |
3226 { | |
3227 if(src[z] != '~') | |
3228 { | |
3229 dest[cur] = src[z]; | |
3230 cur++; | |
3231 } | |
3232 else | |
3233 { | |
3234 dest[cur] = '_'; | |
3235 accel = src[z+1]; | |
3236 cur++; | |
3237 } | |
3238 } | |
3239 dest[cur] = 0; | |
3240 return accel; | |
3241 } | |
3242 | |
3243 /* | |
3244 * Adds a menuitem or submenu to an existing menu. | |
3245 * Parameters: | |
3246 * menu: The handle to the existing menu. | |
3247 * title: The title text on the menu item to be added. | |
3248 * id: An ID to be used for message passing. | |
3249 * flags: Extended attributes to set on the menu. | |
3250 * end: If TRUE memu is positioned at the end of the menu. | |
3251 * check: If TRUE menu is "check"able. | |
3252 * submenu: Handle to an existing menu to be a submenu or NULL. | |
3253 */ | |
3254 HWND dw_menu_append_item(HMENUI menu, char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu) | |
3255 { | |
3256 GtkWidget *tmphandle; | |
3257 char accel, *tempbuf = malloc(strlen(title)+1); | |
3258 int _locked_by_me = FALSE, submenucount; | |
3259 guint tmp_key; | |
3260 GtkAccelGroup *accel_group; | |
3261 | |
3262 if (!menu) | |
3263 { | |
3264 free(tempbuf); | |
3265 return NULL; | |
3266 } | |
3267 | |
3268 DW_MUTEX_LOCK; | |
3269 accel = _removetilde(tempbuf, title); | |
3270 | |
3271 accel_group = (GtkAccelGroup *)g_object_get_data(G_OBJECT(menu), "_dw_accel"); | |
3272 submenucount = (int)g_object_get_data(G_OBJECT(menu), "_dw_submenucount"); | |
3273 | |
3274 if (strlen(tempbuf) == 0) | |
3275 tmphandle=gtk_menu_item_new(); | |
3276 else | |
3277 { | |
3278 if (check) | |
3279 { | |
3280 char numbuf[10]; | |
3281 | |
3282 tmphandle = gtk_check_menu_item_new_with_label(tempbuf); | |
3283 if (accel && accel_group) | |
3284 { | |
3285 gtk_label_set_use_underline(GTK_LABEL(gtk_bin_get_child(GTK_BIN(tmphandle))), TRUE); | |
3286 #if 0 /* TODO: This isn't working right */ | |
3287 gtk_widget_add_accelerator(tmphandle, "activate", accel_group, tmp_key, GDK_MOD1_MASK, 0); | |
3288 #endif | |
3289 } | |
3290 sprintf(numbuf, "%lu", id); | |
3291 g_object_set_data(G_OBJECT(menu), numbuf, (gpointer)tmphandle); | |
3292 } | |
3293 else | |
3294 { | |
3295 char numbuf[10]; | |
3296 | |
3297 tmphandle=gtk_menu_item_new_with_label(tempbuf); | |
3298 if (accel && accel_group) | |
3299 { | |
3300 gtk_label_set_use_underline(GTK_LABEL(gtk_bin_get_child(GTK_BIN(tmphandle))), TRUE); | |
3301 #if 0 /* TODO: This isn't working right */ | |
3302 gtk_widget_add_accelerator(tmphandle, "activate", accel_group, tmp_key, GDK_MOD1_MASK, 0); | |
3303 #endif | |
3304 } | |
3305 sprintf(numbuf, "%lu", id); | |
3306 g_object_set_data(G_OBJECT(menu), numbuf, (gpointer)tmphandle); | |
3307 } | |
3308 } | |
3309 | |
3310 gtk_widget_show(tmphandle); | |
3311 | |
3312 if (submenu) | |
3313 { | |
3314 char tempbuf[100]; | |
3315 | |
3316 sprintf(tempbuf, "_dw_submenu%d", submenucount); | |
3317 submenucount++; | |
3318 gtk_menu_item_set_submenu(GTK_MENU_ITEM(tmphandle), submenu); | |
3319 g_object_set_data(G_OBJECT(menu), tempbuf, (gpointer)submenu); | |
3320 g_object_set_data(G_OBJECT(menu), "_dw_submenucount", (gpointer)submenucount); | |
3321 } | |
3322 | |
3323 if (GTK_IS_MENU_BAR(menu)) | |
3324 gtk_menu_shell_append(GTK_MENU_SHELL(menu), tmphandle); | |
3325 else | |
3326 gtk_menu_shell_append(GTK_MENU_SHELL(menu), tmphandle); | |
3327 | |
3328 g_object_set_data(G_OBJECT(tmphandle), "_dw_id", GINT_TO_POINTER(id)); | |
3329 free(tempbuf); | |
3330 /* | |
3331 * Set flags | |
3332 */ | |
3333 if ( check && (flags & DW_MIS_CHECKED) ) | |
3334 { | |
3335 _dw_ignore_click = 1; | |
3336 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), 1); | |
3337 _dw_ignore_click = 0; | |
3338 } | |
3339 | |
3340 if ( flags & DW_MIS_DISABLED ) | |
3341 gtk_widget_set_sensitive( tmphandle, FALSE ); | |
3342 | |
3343 DW_MUTEX_UNLOCK; | |
3344 return tmphandle; | |
3345 } | |
3346 | |
3347 GtkWidget *_find_submenu_id(GtkWidget *start, char *name) | |
3348 { | |
3349 GtkWidget *tmp; | |
3350 int z, submenucount = (int)g_object_get_data(G_OBJECT(start), "_dw_submenucount"); | |
3351 | |
3352 if((tmp = g_object_get_data(G_OBJECT(start), name))) | |
3353 return tmp; | |
3354 | |
3355 for(z=0;z<submenucount;z++) | |
3356 { | |
3357 char tempbuf[100]; | |
3358 GtkWidget *submenu, *menuitem; | |
3359 | |
3360 sprintf(tempbuf, "_dw_submenu%d", z); | |
3361 | |
3362 if((submenu = g_object_get_data(G_OBJECT(start), tempbuf))) | |
3363 { | |
3364 if((menuitem = _find_submenu_id(submenu, name))) | |
3365 return menuitem; | |
3366 } | |
3367 } | |
3368 return NULL; | |
3369 } | |
3370 | |
3371 /* | |
3372 * Sets the state of a menu item check. | |
3373 * Parameters: | |
3374 * menu: The handle the the existing menu. | |
3375 * id: Menuitem id. | |
3376 * check: TRUE for checked FALSE for not checked. | |
3377 * deprecated: use dw_menu_item_set_state() | |
3378 */ | |
3379 void dw_menu_item_set_check(HMENUI menu, unsigned long id, int check) | |
3380 { | |
3381 char numbuf[10]; | |
3382 GtkWidget *tmphandle; | |
3383 int _locked_by_me = FALSE; | |
3384 | |
3385 if(!menu) | |
3386 return; | |
3387 | |
3388 DW_MUTEX_LOCK; | |
3389 sprintf(numbuf, "%lu", id); | |
3390 tmphandle = _find_submenu_id(menu, numbuf); | |
3391 | |
3392 if(tmphandle) | |
3393 { | |
3394 _dw_ignore_click = 1; | |
3395 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) | |
3396 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); | |
3397 _dw_ignore_click = 0; | |
3398 } | |
3399 DW_MUTEX_UNLOCK; | |
3400 } | |
3401 | |
3402 /* | |
3403 * Sets the state of a menu item. | |
3404 * Parameters: | |
3405 * menu: The handle the the existing menu. | |
3406 * id: Menuitem id. | |
3407 * state: TRUE for checked FALSE for not checked. | |
3408 */ | |
3409 void dw_menu_item_set_state(HMENUI menu, unsigned long id, unsigned long state) | |
3410 { | |
3411 char numbuf[10]; | |
3412 GtkWidget *tmphandle; | |
3413 int check; | |
3414 int _locked_by_me = FALSE; | |
3415 | |
3416 if(!menu) | |
3417 return; | |
3418 | |
3419 DW_MUTEX_LOCK; | |
3420 sprintf(numbuf, "%lu", id); | |
3421 tmphandle = _find_submenu_id(menu, numbuf); | |
3422 | |
3423 if ( (state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED) ) | |
3424 { | |
3425 if ( state & DW_MIS_CHECKED ) | |
3426 check = 1; | |
3427 else | |
3428 check = 0; | |
3429 | |
3430 if (tmphandle) | |
3431 { | |
3432 _dw_ignore_click = 1; | |
3433 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(tmphandle)) != check) | |
3434 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check); | |
3435 _dw_ignore_click = 0; | |
3436 } | |
3437 } | |
3438 if ( (state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED) ) | |
3439 { | |
3440 if (tmphandle ) | |
3441 { | |
3442 _dw_ignore_click = 1; | |
3443 if ( state & DW_MIS_ENABLED ) | |
3444 gtk_widget_set_sensitive( tmphandle, TRUE ); | |
3445 else | |
3446 gtk_widget_set_sensitive( tmphandle, FALSE ); | |
3447 _dw_ignore_click = 0; | |
3448 } | |
3449 } | |
3450 DW_MUTEX_UNLOCK; | |
3451 } | |
3452 | |
3453 /* | |
3454 * Pops up a context menu at given x and y coordinates. | |
3455 * Parameters: | |
3456 * menu: The handle the the existing menu. | |
3457 * parent: Handle to the window initiating the popup. | |
3458 * x: X coordinate. | |
3459 * y: Y coordinate. | |
3460 */ | |
3461 void dw_menu_popup(HMENUI *menu, HWND parent, int x, int y) | |
3462 { | |
3463 int _locked_by_me = FALSE; | |
3464 | |
3465 if(!menu || !*menu) | |
3466 return; | |
3467 | |
3468 popup = parent; | |
3469 | |
3470 DW_MUTEX_LOCK; | |
3471 gtk_menu_popup(GTK_MENU(*menu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME); | |
3472 *menu = NULL; | |
3473 DW_MUTEX_UNLOCK; | |
3474 } | |
3475 | |
3476 | |
3477 /* | |
3478 * Returns the current X and Y coordinates of the mouse pointer. | |
3479 * Parameters: | |
3480 * x: Pointer to variable to store X coordinate. | |
3481 * y: Pointer to variable to store Y coordinate. | |
3482 */ | |
3483 void dw_pointer_query_pos(long *x, long *y) | |
3484 { | |
3485 GdkModifierType state; | |
3486 int gx, gy; | |
3487 int _locked_by_me = FALSE; | |
3488 | |
3489 DW_MUTEX_LOCK; | |
3490 #ifdef GDK_WINDOWING_X11 | |
3491 gdk_window_get_pointer (gdk_x11_window_lookup_for_display(gdk_display_get_default(), GDK_ROOT_WINDOW()), &gx, &gy, &state); | |
3492 #endif | |
3493 *x = gx; | |
3494 *y = gy; | |
3495 DW_MUTEX_UNLOCK; | |
3496 } | |
3497 | |
3498 /* | |
3499 * Sets the X and Y coordinates of the mouse pointer. | |
3500 * Parameters: | |
3501 * x: X coordinate. | |
3502 * y: Y coordinate. | |
3503 */ | |
3504 void dw_pointer_set_pos(long x, long y) | |
3505 { | |
3506 int _locked_by_me = FALSE; | |
3507 | |
3508 DW_MUTEX_LOCK; | |
3509 #ifdef GDK_WINDOWING_X11 | |
3510 # if GTK_CHECK_VERSION(2,8,0) | |
3511 gdk_display_warp_pointer( gdk_display_get_default(), gdk_screen_get_default(), x, y ); | |
3512 // gdk_display_warp_pointer( GDK_DISPLAY(), gdk_screen_get_default(), x, y ); | |
3513 # else | |
3514 XWarpPointer(GDK_DISPLAY(), None, GDK_ROOT_WINDOW(), 0,0,0,0, x, y); | |
3515 # endif | |
3516 #endif | |
3517 DW_MUTEX_UNLOCK; | |
3518 } | |
3519 | |
3520 #define _DW_TREE_CONTAINER 1 | |
3521 #define _DW_TREE_TREE 2 | |
3522 #define _DW_TREE_LISTBOX 3 | |
3523 | |
3524 GtkWidget *_tree_create(unsigned long id) | |
3525 { | |
3526 GtkWidget *tmp; | |
3527 | |
3528 tmp = gtk_scrolled_window_new(NULL, NULL); | |
3529 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (tmp), | |
3530 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
3531 | |
3532 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3533 gtk_widget_show(tmp); | |
3534 return tmp; | |
3535 } | |
3536 | |
3537 GtkWidget *_tree_setup(GtkWidget *tmp, GtkTreeModel *store) | |
3538 { | |
3539 GtkWidget *tree = gtk_tree_view_new_with_model(store); | |
3540 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(tmp), tree); | |
3541 g_object_set_data(G_OBJECT(tmp), "_dw_user", (gpointer)tree); | |
3542 return tree; | |
3543 } | |
3544 | |
3545 /* | |
3546 * Create a container object to be packed. | |
3547 * Parameters: | |
3548 * id: An ID to be used for getting the resource from the | |
3549 * resource file. | |
3550 */ | |
3551 HWND dw_container_new(unsigned long id, int multi) | |
3552 { | |
3553 GtkWidget *tmp; | |
3554 int _locked_by_me = FALSE; | |
3555 | |
3556 DW_MUTEX_LOCK; | |
3557 if(!(tmp = _tree_create(id))) | |
3558 { | |
3559 DW_MUTEX_UNLOCK; | |
3560 return 0; | |
3561 } | |
3562 g_object_set_data(G_OBJECT(tmp), "_dw_tree_type", (gpointer)1); | |
3563 g_object_set_data(G_OBJECT(tmp), "_dw_multi_sel", GINT_TO_POINTER(multi)); | |
3564 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3565 gtk_widget_show(tmp); | |
3566 DW_MUTEX_UNLOCK; | |
3567 return tmp; | |
3568 } | |
3569 | |
3570 /* | |
3571 * Create a tree object to be packed. | |
3572 * Parameters: | |
3573 * id: An ID to be used for getting the resource from the | |
3574 * resource file. | |
3575 */ | |
3576 HWND dw_tree_new(ULONG id) | |
3577 { | |
3578 GtkWidget *tmp, *tree; | |
3579 GtkTreeStore *store; | |
3580 GtkTreeViewColumn *col; | |
3581 GtkCellRenderer *rend; | |
3582 GtkTreeSelection *sel; | |
3583 int _locked_by_me = FALSE; | |
3584 | |
3585 DW_MUTEX_LOCK; | |
3586 if(!(tmp = _tree_create(id))) | |
3587 { | |
3588 DW_MUTEX_UNLOCK; | |
3589 return 0; | |
3590 } | |
3591 store = gtk_tree_store_new(4, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER, G_TYPE_POINTER); | |
3592 tree = _tree_setup(tmp, GTK_TREE_MODEL(store)); | |
3593 g_object_set_data(G_OBJECT(tmp), "_dw_tree_type", (gpointer)2); | |
3594 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3595 col = gtk_tree_view_column_new(); | |
3596 | |
3597 rend = gtk_cell_renderer_pixbuf_new(); | |
3598 gtk_tree_view_column_pack_start(col, rend, FALSE); | |
3599 gtk_tree_view_column_add_attribute(col, rend, "pixbuf", 1); | |
3600 rend = gtk_cell_renderer_text_new(); | |
3601 gtk_tree_view_column_pack_start(col, rend, TRUE); | |
3602 gtk_tree_view_column_add_attribute(col, rend, "text", 0); | |
3603 | |
3604 gtk_tree_view_append_column(GTK_TREE_VIEW (tree), col); | |
3605 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(tree), col); | |
3606 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE); | |
3607 | |
3608 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); | |
3609 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); | |
3610 gtk_widget_show(tree); | |
3611 | |
3612 DW_MUTEX_UNLOCK; | |
3613 return tmp; | |
3614 } | |
3615 | |
3616 | |
3617 /* | |
3618 * Create a new static text window (widget) to be packed. | |
3619 * Parameters: | |
3620 * text: The text to be display by the static text widget. | |
3621 * id: An ID to be used with dw_window_from_id() or 0L. | |
3622 */ | |
3623 HWND dw_text_new(char *text, unsigned long id) | |
3624 { | |
3625 GtkWidget *tmp; | |
3626 int _locked_by_me = FALSE; | |
3627 | |
3628 DW_MUTEX_LOCK; | |
3629 tmp = gtk_label_new(text); | |
3630 | |
3631 /* Left and centered */ | |
3632 gtk_misc_set_alignment(GTK_MISC(tmp), 0.0f, 0.5f); | |
3633 gtk_widget_show(tmp); | |
3634 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3635 gtk_misc_set_alignment(GTK_MISC(tmp), DW_LEFT, DW_LEFT); | |
3636 DW_MUTEX_UNLOCK; | |
3637 return tmp; | |
3638 } | |
3639 | |
3640 /* | |
3641 * Create a new status text window (widget) to be packed. | |
3642 * Parameters: | |
3643 * text: The text to be display by the static text widget. | |
3644 * id: An ID to be used with dw_window_from_id() or 0L. | |
3645 */ | |
3646 HWND dw_status_text_new(char *text, ULONG id) | |
3647 { | |
3648 GtkWidget *tmp, *frame; | |
3649 int _locked_by_me = FALSE; | |
3650 | |
3651 DW_MUTEX_LOCK; | |
3652 frame = gtk_frame_new(NULL); | |
3653 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); | |
3654 tmp = gtk_label_new(text); | |
3655 gtk_container_add(GTK_CONTAINER(frame), tmp); | |
3656 gtk_widget_show(tmp); | |
3657 gtk_widget_show(frame); | |
3658 | |
3659 /* Left and centered */ | |
3660 gtk_misc_set_alignment(GTK_MISC(tmp), 0.0f, 0.5f); | |
3661 g_object_set_data(G_OBJECT(frame), "_dw_id", GINT_TO_POINTER(id)); | |
3662 g_object_set_data(G_OBJECT(frame), "_dw_label", (gpointer)tmp); | |
3663 DW_MUTEX_UNLOCK; | |
3664 return frame; | |
3665 } | |
3666 | |
3667 /* | |
3668 * Create a new Multiline Editbox window (widget) to be packed. | |
3669 * Parameters: | |
3670 * id: An ID to be used with dw_window_from_id() or 0L. | |
3671 */ | |
3672 HWND dw_mle_new(unsigned long id) | |
3673 { | |
3674 GtkWidget *tmp, *tmpbox, *scroller; | |
3675 int _locked_by_me = FALSE; | |
3676 | |
3677 DW_MUTEX_LOCK; | |
3678 tmpbox = gtk_scrolled_window_new (NULL, NULL); | |
3679 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(tmpbox), | |
3680 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |
3681 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(tmpbox), GTK_SHADOW_ETCHED_IN); | |
3682 tmp = gtk_text_view_new(); | |
3683 gtk_container_add (GTK_CONTAINER(tmpbox), tmp); | |
3684 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(tmp), GTK_WRAP_NONE); | |
3685 | |
3686 scroller = NULL; | |
3687 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3688 g_object_set_data(G_OBJECT(tmpbox), "_dw_user", (gpointer)tmp); | |
3689 gtk_widget_show(tmp); | |
3690 gtk_widget_show(tmpbox); | |
3691 DW_MUTEX_UNLOCK; | |
3692 return tmpbox; | |
3693 } | |
3694 | |
3695 /* | |
3696 * Create a new Entryfield window (widget) to be packed. | |
3697 * Parameters: | |
3698 * text: The default text to be in the entryfield widget. | |
3699 * id: An ID to be used with dw_window_from_id() or 0L. | |
3700 */ | |
3701 HWND dw_entryfield_new(char *text, unsigned long id) | |
3702 { | |
3703 GtkWidget *tmp; | |
3704 int _locked_by_me = FALSE; | |
3705 | |
3706 DW_MUTEX_LOCK; | |
3707 tmp = gtk_entry_new(); | |
3708 | |
3709 gtk_entry_set_text(GTK_ENTRY(tmp), text); | |
3710 | |
3711 gtk_widget_show(tmp); | |
3712 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3713 | |
3714 DW_MUTEX_UNLOCK; | |
3715 return tmp; | |
3716 } | |
3717 | |
3718 /* | |
3719 * Create a new Entryfield (password) window (widget) to be packed. | |
3720 * Parameters: | |
3721 * text: The default text to be in the entryfield widget. | |
3722 * id: An ID to be used with dw_window_from_id() or 0L. | |
3723 */ | |
3724 HWND dw_entryfield_password_new(char *text, ULONG id) | |
3725 { | |
3726 GtkWidget *tmp; | |
3727 int _locked_by_me = FALSE; | |
3728 | |
3729 DW_MUTEX_LOCK; | |
3730 tmp = gtk_entry_new(); | |
3731 | |
3732 gtk_entry_set_visibility(GTK_ENTRY(tmp), FALSE); | |
3733 gtk_entry_set_text(GTK_ENTRY(tmp), text); | |
3734 | |
3735 gtk_widget_show(tmp); | |
3736 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3737 | |
3738 DW_MUTEX_UNLOCK; | |
3739 return tmp; | |
3740 } | |
3741 | |
3742 /* | |
3743 * Create a new Combobox window (widget) to be packed. | |
3744 * Parameters: | |
3745 * text: The default text to be in the combpbox widget. | |
3746 * id: An ID to be used with dw_window_from_id() or 0L. | |
3747 */ | |
3748 HWND dw_combobox_new(char *text, unsigned long id) | |
3749 { | |
3750 GtkWidget *tmp; | |
3751 GtkListStore *store; | |
3752 int sigid, _locked_by_me = FALSE; | |
3753 gint cid; | |
3754 | |
3755 DW_MUTEX_LOCK; | |
3756 store = gtk_list_store_new(1, G_TYPE_STRING); | |
3757 tmp = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(store)); | |
3758 gtk_widget_show(tmp); | |
3759 g_object_set_data(G_OBJECT(tmp), "_dw_tree_type", (gpointer)3); | |
3760 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3761 DW_MUTEX_UNLOCK; | |
3762 return tmp; | |
3763 } | |
3764 | |
3765 /* | |
3766 * Create a new button window (widget) to be packed. | |
3767 * Parameters: | |
3768 * text: The text to be display by the static text widget. | |
3769 * id: An ID to be used with dw_window_from_id() or 0L. | |
3770 */ | |
3771 HWND dw_button_new(char *text, unsigned long id) | |
3772 { | |
3773 GtkWidget *tmp; | |
3774 int _locked_by_me = FALSE; | |
3775 | |
3776 DW_MUTEX_LOCK; | |
3777 tmp = gtk_button_new_with_label(text); | |
3778 gtk_widget_show(tmp); | |
3779 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3780 DW_MUTEX_UNLOCK; | |
3781 return tmp; | |
3782 } | |
3783 | |
3784 /* | |
3785 * Create a new bitmap button window (widget) to be packed. | |
3786 * Parameters: | |
3787 * text: Bubble help text to be displayed. | |
3788 * id: An ID of a bitmap in the resource file. | |
3789 */ | |
3790 HWND dw_bitmapbutton_new(char *text, unsigned long id) | |
3791 { | |
3792 GtkWidget *tmp; | |
3793 GtkWidget *bitmap; | |
3794 int _locked_by_me = FALSE; | |
3795 | |
3796 DW_MUTEX_LOCK; | |
3797 tmp = gtk_button_new(); | |
3798 bitmap = dw_bitmap_new(id); | |
3799 | |
3800 if(bitmap) | |
3801 { | |
3802 dw_window_set_bitmap(bitmap, id, NULL); | |
3803 gtk_container_add (GTK_CONTAINER(tmp), bitmap); | |
3804 } | |
3805 gtk_widget_show(tmp); | |
3806 if(text) | |
3807 { | |
3808 gtk_widget_set_tooltip_text(tmp, text); | |
3809 } | |
3810 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3811 DW_MUTEX_UNLOCK; | |
3812 return tmp; | |
3813 } | |
3814 | |
3815 /* | |
3816 * Create a new bitmap button window (widget) to be packed from a file. | |
3817 * Parameters: | |
3818 * label_text: Text to display on button. TBD when Windows works | |
3819 * text: Bubble help text to be displayed. | |
3820 * id: An ID to be used with dw_window_from_id() or 0L. | |
3821 * filename: Name of the file, omit extention to have | |
3822 * DW pick the appropriate file extension. | |
3823 * (BMP on OS/2 or Windows, XPM on Unix) | |
3824 */ | |
3825 HWND dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename) | |
3826 { | |
3827 GtkWidget *bitmap; | |
3828 GtkWidget *box; | |
3829 GtkWidget *label; | |
3830 GtkWidget *button; | |
3831 char *label_text=NULL; | |
3832 int _locked_by_me = FALSE; | |
3833 | |
3834 DW_MUTEX_LOCK; | |
3835 | |
3836 /* Create box for image and label */ | |
3837 box = gtk_hbox_new (FALSE, 0); | |
3838 gtk_container_set_border_width (GTK_CONTAINER (box), 2); | |
3839 | |
3840 /* Now on to the image stuff */ | |
3841 bitmap = dw_bitmap_new(id); | |
3842 if(bitmap) | |
3843 { | |
3844 dw_window_set_bitmap( bitmap, 0, filename ); | |
3845 /* Pack the image into the box */ | |
3846 gtk_box_pack_start( GTK_BOX(box), bitmap, TRUE, FALSE, 3 ); | |
3847 gtk_widget_show( bitmap ); | |
3848 } | |
3849 if(label_text) | |
3850 { | |
3851 /* Create a label for the button */ | |
3852 label = gtk_label_new( label_text ); | |
3853 /* Pack the label into the box */ | |
3854 gtk_box_pack_start( GTK_BOX(box), label, TRUE, FALSE, 3 ); | |
3855 gtk_widget_show( label ); | |
3856 } | |
3857 /* Create a new button */ | |
3858 button = gtk_button_new(); | |
3859 | |
3860 /* Pack and show all our widgets */ | |
3861 gtk_widget_show( box ); | |
3862 gtk_container_add( GTK_CONTAINER(button), box ); | |
3863 gtk_widget_show( button ); | |
3864 if(text) | |
3865 { | |
3866 gtk_widget_set_tooltip_text(button, text); | |
3867 } | |
3868 g_object_set_data(G_OBJECT(button), "_dw_id", GINT_TO_POINTER(id)); | |
3869 DW_MUTEX_UNLOCK; | |
3870 return button; | |
3871 } | |
3872 | |
3873 /* | |
3874 * Create a new bitmap button window (widget) to be packed from data. | |
3875 * Parameters: | |
3876 * text: Bubble help text to be displayed. | |
3877 * id: An ID to be used with dw_window_from_id() or 0L. | |
3878 * data: Raw data of image. | |
3879 * (BMP on OS/2 or Windows, XPM on Unix) | |
3880 * len: Length of raw data | |
3881 */ | |
3882 HWND dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *data, int len) | |
3883 { | |
3884 GtkWidget *tmp; | |
3885 GtkWidget *bitmap; | |
3886 int _locked_by_me = FALSE; | |
3887 | |
3888 DW_MUTEX_LOCK; | |
3889 tmp = gtk_button_new(); | |
3890 bitmap = dw_bitmap_new(id); | |
3891 | |
3892 if ( bitmap ) | |
3893 { | |
3894 dw_window_set_bitmap_from_data(bitmap, 0, data, len); | |
3895 gtk_container_add (GTK_CONTAINER(tmp), bitmap); | |
3896 } | |
3897 gtk_widget_show(tmp); | |
3898 if(text) | |
3899 { | |
3900 gtk_widget_set_tooltip_text(tmp, text); | |
3901 } | |
3902 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3903 DW_MUTEX_UNLOCK; | |
3904 return tmp; | |
3905 } | |
3906 | |
3907 /* | |
3908 * Create a new spinbutton window (widget) to be packed. | |
3909 * Parameters: | |
3910 * text: The text to be display by the static text widget. | |
3911 * id: An ID to be used with dw_window_from_id() or 0L. | |
3912 */ | |
3913 HWND dw_spinbutton_new(char *text, unsigned long id) | |
3914 { | |
3915 GtkAdjustment *adj; | |
3916 GtkWidget *tmp; | |
3917 int _locked_by_me = FALSE; | |
3918 | |
3919 DW_MUTEX_LOCK; | |
3920 adj = (GtkAdjustment *)gtk_adjustment_new (1.0, 0.0, 100.0, 1.0, 5.0, 0.0); | |
3921 tmp = gtk_spin_button_new (adj, 0, 0); | |
3922 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(tmp), TRUE); | |
3923 gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(tmp), TRUE); | |
3924 gtk_widget_show(tmp); | |
3925 g_object_set_data(G_OBJECT(tmp), "_dw_adjustment", (gpointer)adj); | |
3926 g_object_set_data(G_OBJECT(adj), "_dw_spinbutton", (gpointer)tmp); | |
3927 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3928 DW_MUTEX_UNLOCK; | |
3929 return tmp; | |
3930 } | |
3931 | |
3932 /* | |
3933 * Create a new radiobutton window (widget) to be packed. | |
3934 * Parameters: | |
3935 * text: The text to be display by the static text widget. | |
3936 * id: An ID to be used with dw_window_from_id() or 0L. | |
3937 */ | |
3938 HWND dw_radiobutton_new(char *text, ULONG id) | |
3939 { | |
3940 /* This will have to be fixed in the future. */ | |
3941 GtkWidget *tmp; | |
3942 int _locked_by_me = FALSE; | |
3943 | |
3944 DW_MUTEX_LOCK; | |
3945 tmp = gtk_radio_button_new_with_label(NULL, text); | |
3946 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3947 gtk_widget_show(tmp); | |
3948 | |
3949 DW_MUTEX_UNLOCK; | |
3950 return tmp; | |
3951 } | |
3952 | |
3953 /* | |
3954 * Create a new slider window (widget) to be packed. | |
3955 * Parameters: | |
3956 * vertical: TRUE or FALSE if slider is vertical. | |
3957 * increments: Number of increments available. | |
3958 * id: An ID to be used with dw_window_from_id() or 0L. | |
3959 */ | |
3960 HWND dw_slider_new(int vertical, int increments, ULONG id) | |
3961 { | |
3962 GtkWidget *tmp; | |
3963 GtkAdjustment *adjustment; | |
3964 int _locked_by_me = FALSE; | |
3965 | |
3966 DW_MUTEX_LOCK; | |
3967 adjustment = (GtkAdjustment *)gtk_adjustment_new(0, 0, (gfloat)increments, 1, 1, 1); | |
3968 if(vertical) | |
3969 tmp = gtk_vscale_new(adjustment); | |
3970 else | |
3971 tmp = gtk_hscale_new(adjustment); | |
3972 gtk_widget_show(tmp); | |
3973 gtk_scale_set_draw_value(GTK_SCALE(tmp), 0); | |
3974 gtk_scale_set_digits(GTK_SCALE(tmp), 0); | |
3975 g_object_set_data(G_OBJECT(tmp), "_dw_adjustment", (gpointer)adjustment); | |
3976 g_object_set_data(G_OBJECT(adjustment), "_dw_slider", (gpointer)tmp); | |
3977 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
3978 DW_MUTEX_UNLOCK; | |
3979 return tmp; | |
3980 } | |
3981 | |
3982 /* | |
3983 * Create a new scrollbar window (widget) to be packed. | |
3984 * Parameters: | |
3985 * vertical: TRUE or FALSE if scrollbar is vertical. | |
3986 * increments: Number of increments available. | |
3987 * id: An ID to be used with dw_window_from_id() or 0L. | |
3988 */ | |
3989 HWND dw_scrollbar_new(int vertical, ULONG id) | |
3990 { | |
3991 GtkWidget *tmp; | |
3992 GtkAdjustment *adjustment; | |
3993 int _locked_by_me = FALSE; | |
3994 | |
3995 DW_MUTEX_LOCK; | |
3996 adjustment = (GtkAdjustment *)gtk_adjustment_new(0, 0, 0, 1, 1, 1); | |
3997 if(vertical) | |
3998 tmp = gtk_vscrollbar_new(adjustment); | |
3999 else | |
4000 tmp = gtk_hscrollbar_new(adjustment); | |
4001 gtk_widget_set_can_focus(tmp, FALSE); | |
4002 gtk_widget_show(tmp); | |
4003 g_object_set_data(G_OBJECT(tmp), "_dw_adjustment", (gpointer)adjustment); | |
4004 g_object_set_data(G_OBJECT(adjustment), "_dw_scrollbar", (gpointer)tmp); | |
4005 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
4006 DW_MUTEX_UNLOCK; | |
4007 return tmp; | |
4008 } | |
4009 | |
4010 /* | |
4011 * Create a new percent bar window (widget) to be packed. | |
4012 * Parameters: | |
4013 * id: An ID to be used with dw_window_from_id() or 0L. | |
4014 */ | |
4015 HWND dw_percent_new(unsigned long id) | |
4016 { | |
4017 GtkWidget *tmp; | |
4018 int _locked_by_me = FALSE; | |
4019 | |
4020 DW_MUTEX_LOCK; | |
4021 tmp = gtk_progress_bar_new(); | |
4022 gtk_widget_show(tmp); | |
4023 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
4024 DW_MUTEX_UNLOCK; | |
4025 return tmp; | |
4026 } | |
4027 | |
4028 /* | |
4029 * Create a new checkbox window (widget) to be packed. | |
4030 * Parameters: | |
4031 * text: The text to be display by the static text widget. | |
4032 * id: An ID to be used with dw_window_from_id() or 0L. | |
4033 */ | |
4034 HWND dw_checkbox_new(char *text, unsigned long id) | |
4035 { | |
4036 GtkWidget *tmp; | |
4037 int _locked_by_me = FALSE; | |
4038 | |
4039 DW_MUTEX_LOCK; | |
4040 tmp = gtk_check_button_new_with_label(text); | |
4041 gtk_widget_show(tmp); | |
4042 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
4043 DW_MUTEX_UNLOCK; | |
4044 return tmp; | |
4045 } | |
4046 | |
4047 /* | |
4048 * Create a new listbox window (widget) to be packed. | |
4049 * Parameters: | |
4050 * id: An ID to be used with dw_window_from_id() or 0L. | |
4051 * multi: Multiple select TRUE or FALSE. | |
4052 */ | |
4053 HWND dw_listbox_new(unsigned long id, int multi) | |
4054 { | |
4055 GtkWidget *tmp, *tree; | |
4056 GtkListStore *store; | |
4057 GtkTreeViewColumn *col; | |
4058 GtkCellRenderer *rend; | |
4059 GtkTreeSelection *sel; | |
4060 int _locked_by_me = FALSE; | |
4061 | |
4062 DW_MUTEX_LOCK; | |
4063 if(!(tmp = _tree_create(id))) | |
4064 { | |
4065 DW_MUTEX_UNLOCK; | |
4066 return 0; | |
4067 } | |
4068 store = gtk_list_store_new(1, G_TYPE_STRING); | |
4069 tree = _tree_setup(tmp, GTK_TREE_MODEL(store)); | |
4070 g_object_set_data(G_OBJECT(tmp), "_dw_tree_type", (gpointer)3); | |
4071 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
4072 | |
4073 col = gtk_tree_view_column_new(); | |
4074 rend = gtk_cell_renderer_text_new(); | |
4075 gtk_tree_view_column_pack_start(col, rend, TRUE); | |
4076 gtk_tree_view_column_add_attribute(col, rend, "text", 0); | |
4077 | |
4078 gtk_tree_view_append_column(GTK_TREE_VIEW (tree), col); | |
4079 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(tree), col); | |
4080 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE); | |
4081 | |
4082 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); | |
4083 if(multi) | |
4084 { | |
4085 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); | |
4086 } | |
4087 else | |
4088 { | |
4089 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); | |
4090 } | |
4091 gtk_widget_show(tmp); | |
4092 DW_MUTEX_UNLOCK; | |
4093 return tmp; | |
4094 } | |
4095 | |
4096 /* | |
4097 * Sets the icon used for a given window. | |
4098 * Parameters: | |
4099 * handle: Handle to the window. | |
4100 * id: An ID to be used to specify the icon. | |
4101 */ | |
4102 void dw_window_set_icon(HWND handle, HICN icon) | |
4103 { | |
4104 GdkPixbuf *icon_pixbuf; | |
4105 int _locked_by_me = FALSE; | |
4106 | |
4107 DW_MUTEX_LOCK; | |
4108 icon_pixbuf = _find_pixbuf(icon, NULL, NULL); | |
4109 | |
4110 if(gtk_widget_get_window(handle) && icon_pixbuf) | |
4111 { | |
4112 GList *list = g_list_alloc(); | |
4113 list = g_list_append(list, icon_pixbuf); | |
4114 gdk_window_set_icon_list(gtk_widget_get_window(handle), list); | |
4115 g_object_unref(G_OBJECT(list)); | |
4116 } | |
4117 DW_MUTEX_UNLOCK; | |
4118 } | |
4119 | |
4120 /* | |
4121 * Sets the bitmap used for a given static window. | |
4122 * Parameters: | |
4123 * handle: Handle to the window. | |
4124 * id: An ID to be used to specify the icon, | |
4125 * (pass 0 if you use the filename param) | |
4126 * filename: a path to a file (Bitmap on OS/2 or | |
4127 * Windows and a pixmap on Unix, pass | |
4128 * NULL if you use the id param) | |
4129 */ | |
4130 void dw_window_set_bitmap(HWND handle, unsigned long id, char *filename) | |
4131 { | |
4132 GdkPixbuf *tmp = NULL; | |
4133 int found_ext = 0; | |
4134 int i; | |
4135 int _locked_by_me = FALSE; | |
4136 | |
4137 if(!id && !filename) | |
4138 return; | |
4139 | |
4140 DW_MUTEX_LOCK; | |
4141 if(id) | |
4142 tmp = _find_pixbuf(id, NULL, NULL); | |
4143 else | |
4144 { | |
4145 char *file = alloca(strlen(filename) + 5); | |
4146 | |
4147 if (!file) | |
4148 { | |
4149 DW_MUTEX_UNLOCK; | |
4150 return; | |
4151 } | |
4152 | |
4153 strcpy(file, filename); | |
4154 | |
4155 /* check if we can read from this file (it exists and read permission) */ | |
4156 if ( access(file, 04 ) != 0 ) | |
4157 { | |
4158 /* Try with various extentions */ | |
4159 for ( i = 0; i < NUM_EXTS; i++ ) | |
4160 { | |
4161 strcpy( file, filename ); | |
4162 strcat( file, image_exts[i] ); | |
4163 if ( access( file, 04 ) == 0 ) | |
4164 { | |
4165 found_ext = 1; | |
4166 break; | |
4167 } | |
4168 } | |
4169 if ( found_ext == 0 ) | |
4170 { | |
4171 DW_MUTEX_UNLOCK; | |
4172 return; | |
4173 } | |
4174 } | |
4175 tmp = gdk_pixbuf_new_from_file(file, NULL ); | |
4176 } | |
4177 | |
4178 if (tmp) | |
4179 { | |
4180 if ( GTK_IS_BUTTON(handle) ) | |
4181 { | |
4182 GtkWidget *image = gtk_button_get_image( GTK_BUTTON(handle) ); | |
4183 gtk_image_set_from_pixbuf(GTK_IMAGE(image), tmp); | |
4184 } | |
4185 else | |
4186 { | |
4187 gtk_image_set_from_pixbuf(GTK_IMAGE(handle), tmp); | |
4188 } | |
4189 } | |
4190 DW_MUTEX_UNLOCK; | |
4191 } | |
4192 | |
4193 /* | |
4194 * Sets the bitmap used for a given static window. | |
4195 * Parameters: | |
4196 * handle: Handle to the window. | |
4197 * id: An ID to be used to specify the icon, | |
4198 * (pass 0 if you use the filename param) | |
4199 * data: the image data | |
4200 * Bitmap on Windows and a pixmap on Unix, pass | |
4201 * NULL if you use the id param) | |
4202 * len: length of data | |
4203 */ | |
4204 void dw_window_set_bitmap_from_data(HWND handle, unsigned long id, char *data, int len) | |
4205 { | |
4206 GdkPixbuf *tmp; | |
4207 int _locked_by_me = FALSE; | |
4208 char *file; | |
4209 FILE *fp; | |
4210 | |
4211 if (!id && !data) | |
4212 return; | |
4213 | |
4214 DW_MUTEX_LOCK; | |
4215 if (id) | |
4216 tmp = _find_pixbuf(id, NULL, NULL); | |
4217 else | |
4218 { | |
4219 GdkPixbuf *pixbuf; | |
4220 if (!data) | |
4221 { | |
4222 DW_MUTEX_UNLOCK; | |
4223 return; | |
4224 } | |
4225 /* | |
4226 * A real hack; create a temporary file and write the contents | |
4227 * of the data to the file | |
4228 */ | |
4229 file = tmpnam( NULL ); | |
4230 fp = fopen( file, "wb" ); | |
4231 if ( fp ) | |
4232 { | |
4233 fwrite( data, len, 1, fp ); | |
4234 fclose( fp ); | |
4235 } | |
4236 else | |
4237 { | |
4238 DW_MUTEX_UNLOCK; | |
4239 return; | |
4240 } | |
4241 pixbuf = gdk_pixbuf_new_from_file(file, NULL ); | |
4242 /* remove our temporary file */ | |
4243 unlink (file ); | |
4244 } | |
4245 | |
4246 if(tmp) | |
4247 { | |
4248 gtk_image_set_from_pixbuf(GTK_IMAGE(handle), tmp); | |
4249 } | |
4250 DW_MUTEX_UNLOCK; | |
4251 } | |
4252 | |
4253 /* | |
4254 * Sets the text used for a given window. | |
4255 * Parameters: | |
4256 * handle: Handle to the window. | |
4257 * text: The text associated with a given window. | |
4258 */ | |
4259 void dw_window_set_text(HWND handle, char *text) | |
4260 { | |
4261 int _locked_by_me = FALSE; | |
4262 GtkWidget *tmp; | |
4263 | |
4264 DW_MUTEX_LOCK; | |
4265 if((tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi_title"))) | |
4266 handle = tmp; | |
4267 if(GTK_IS_ENTRY(handle)) | |
4268 gtk_entry_set_text(GTK_ENTRY(handle), text); | |
4269 #if 0 | |
4270 else if(GTK_IS_COMBO_BOX(handle)) | |
4271 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO_BOX(handle)->entry), text); | |
4272 #endif | |
4273 else if(GTK_IS_LABEL(handle)) | |
4274 gtk_label_set_text(GTK_LABEL(handle), text); | |
4275 else if(GTK_IS_BUTTON(handle)) | |
4276 { | |
4277 gtk_button_set_label(GTK_BUTTON(handle), text); | |
4278 } | |
4279 else if(gtk_widget_is_toplevel(handle)) | |
4280 gtk_window_set_title(GTK_WINDOW(handle), text); | |
4281 else if (GTK_IS_FRAME(handle)) | |
4282 { | |
4283 /* | |
4284 * This is a groupbox or status_text | |
4285 */ | |
4286 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_label"); | |
4287 if ( tmp && GTK_IS_LABEL(tmp) ) | |
4288 gtk_label_set_text(GTK_LABEL(tmp), text); | |
4289 else /* assume groupbox */ | |
4290 gtk_frame_set_label(GTK_FRAME(handle), text && *text ? text : NULL); | |
4291 } | |
4292 DW_MUTEX_UNLOCK; | |
4293 } | |
4294 | |
4295 /* | |
4296 * Gets the text used for a given window. | |
4297 * Parameters: | |
4298 * handle: Handle to the window. | |
4299 * Returns: | |
4300 * text: The text associsated with a given window. | |
4301 */ | |
4302 char *dw_window_get_text(HWND handle) | |
4303 { | |
4304 const char *possible = ""; | |
4305 int _locked_by_me = FALSE; | |
4306 | |
4307 DW_MUTEX_LOCK; | |
4308 if(GTK_IS_ENTRY(handle)) | |
4309 possible = gtk_entry_get_text(GTK_ENTRY(handle)); | |
4310 #if 0 | |
4311 else if(GTK_IS_COMBO_BOX(handle)) | |
4312 possible = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO_BOX(handle)->entry)); | |
4313 #endif | |
4314 | |
4315 DW_MUTEX_UNLOCK; | |
4316 return strdup(possible); | |
4317 } | |
4318 | |
4319 /* | |
4320 * Disables given window (widget). | |
4321 * Parameters: | |
4322 * handle: Handle to the window. | |
4323 */ | |
4324 void dw_window_disable(HWND handle) | |
4325 { | |
4326 int _locked_by_me = FALSE; | |
4327 | |
4328 DW_MUTEX_LOCK; | |
4329 gtk_widget_set_sensitive(handle, FALSE); | |
4330 DW_MUTEX_UNLOCK; | |
4331 } | |
4332 | |
4333 /* | |
4334 * Enables given window (widget). | |
4335 * Parameters: | |
4336 * handle: Handle to the window. | |
4337 */ | |
4338 void dw_window_enable(HWND handle) | |
4339 { | |
4340 int _locked_by_me = FALSE; | |
4341 | |
4342 DW_MUTEX_LOCK; | |
4343 gtk_widget_set_sensitive(handle, TRUE); | |
4344 DW_MUTEX_UNLOCK; | |
4345 } | |
4346 | |
4347 /* | |
4348 * Gets the child window handle with specified ID. | |
4349 * Parameters: | |
4350 * handle: Handle to the parent window. | |
4351 * id: Integer ID of the child. | |
4352 */ | |
4353 HWND API dw_window_from_id(HWND handle, int id) | |
4354 { | |
4355 GList *orig = NULL, *list = NULL; | |
4356 int _locked_by_me = FALSE; | |
4357 | |
4358 DW_MUTEX_LOCK; | |
4359 if(handle && GTK_IS_CONTAINER(handle)) | |
4360 { | |
4361 orig = list = gtk_container_get_children(GTK_CONTAINER(handle)); | |
4362 } | |
4363 while(list) | |
4364 { | |
4365 if(GTK_IS_WIDGET(list->data)) | |
4366 { | |
4367 if(id == (int)g_object_get_data(G_OBJECT(list->data), "_dw_id")) | |
4368 { | |
4369 HWND ret = (HWND)list->data; | |
4370 g_list_free(orig); | |
4371 DW_MUTEX_UNLOCK; | |
4372 return ret; | |
4373 } | |
4374 } | |
4375 list = list->next; | |
4376 } | |
4377 if(orig) | |
4378 g_list_free(orig); | |
4379 DW_MUTEX_UNLOCK; | |
4380 return 0L; | |
4381 } | |
4382 | |
4383 void _strip_cr(char *dest, char *src) | |
4384 { | |
4385 int z, x = 0; | |
4386 | |
4387 for(z=0;z<strlen(src);z++) | |
4388 { | |
4389 if(src[z] != '\r') | |
4390 { | |
4391 dest[x] = src[z]; | |
4392 x++; | |
4393 } | |
4394 } | |
4395 dest[x] = 0; | |
4396 } | |
4397 | |
4398 /* | |
4399 * Adds text to an MLE box and returns the current point. | |
4400 * Parameters: | |
4401 * handle: Handle to the MLE to be queried. | |
4402 * buffer: Text buffer to be imported. | |
4403 * startpoint: Point to start entering text. | |
4404 */ | |
4405 unsigned int dw_mle_import(HWND handle, char *buffer, int startpoint) | |
4406 { | |
4407 unsigned int tmppoint = startpoint; | |
4408 int _locked_by_me = FALSE; | |
4409 | |
4410 DW_MUTEX_LOCK; | |
4411 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4412 { | |
4413 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4414 | |
4415 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4416 { | |
4417 char *impbuf = malloc(strlen(buffer)+1); | |
4418 GtkTextBuffer *tbuffer; | |
4419 GtkTextIter iter; | |
4420 | |
4421 _strip_cr(impbuf, buffer); | |
4422 | |
4423 tbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tmp)); | |
4424 gtk_text_buffer_get_iter_at_offset(tbuffer, &iter, startpoint); | |
4425 gtk_text_buffer_place_cursor(tbuffer, &iter); | |
4426 gtk_text_buffer_insert_at_cursor(tbuffer, impbuf, -1); | |
4427 tmppoint = (startpoint > -1 ? startpoint : 0) + strlen(impbuf); | |
4428 free(impbuf); | |
4429 } | |
4430 } | |
4431 DW_MUTEX_UNLOCK; | |
4432 return tmppoint; | |
4433 } | |
4434 | |
4435 /* | |
4436 * Grabs text from an MLE box. | |
4437 * Parameters: | |
4438 * handle: Handle to the MLE to be queried. | |
4439 * buffer: Text buffer to be exported. MUST allow for trailing nul character. | |
4440 * startpoint: Point to start grabbing text. | |
4441 * length: Amount of text to be grabbed. | |
4442 */ | |
4443 void dw_mle_export(HWND handle, char *buffer, int startpoint, int length) | |
4444 { | |
4445 int _locked_by_me = FALSE; | |
4446 gchar *text; | |
4447 | |
4448 DW_MUTEX_LOCK; | |
4449 /* force the return value to nul in case the following tests fail */ | |
4450 if(buffer) | |
4451 buffer[0] = '\0'; | |
4452 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4453 { | |
4454 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4455 | |
4456 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4457 { | |
4458 GtkTextBuffer *tbuffer; | |
4459 GtkTextIter start, end; | |
4460 | |
4461 tbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tmp)); | |
4462 gtk_text_buffer_get_iter_at_offset(tbuffer, &start, startpoint); | |
4463 gtk_text_buffer_get_iter_at_offset(tbuffer, &end, startpoint + length); | |
4464 text = gtk_text_iter_get_text(&start, &end); | |
4465 if(text) /* Should this get freed? */ | |
4466 { | |
4467 if(buffer) | |
4468 strcpy(buffer, text); | |
4469 } | |
4470 } | |
4471 } | |
4472 DW_MUTEX_UNLOCK; | |
4473 } | |
4474 | |
4475 /* | |
4476 * Obtains information about an MLE box. | |
4477 * Parameters: | |
4478 * handle: Handle to the MLE to be queried. | |
4479 * bytes: A pointer to a variable to return the total bytes. | |
4480 * lines: A pointer to a variable to return the number of lines. | |
4481 */ | |
4482 void dw_mle_get_size(HWND handle, unsigned long *bytes, unsigned long *lines) | |
4483 { | |
4484 int _locked_by_me = FALSE; | |
4485 | |
4486 if(bytes) | |
4487 *bytes = 0; | |
4488 if(lines) | |
4489 *lines = 0; | |
4490 | |
4491 DW_MUTEX_LOCK; | |
4492 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4493 { | |
4494 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4495 | |
4496 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4497 { | |
4498 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tmp)); | |
4499 | |
4500 if(bytes) | |
4501 *bytes = gtk_text_buffer_get_char_count(buffer) + 1; | |
4502 if(lines) | |
4503 *lines = gtk_text_buffer_get_line_count(buffer) + 1; | |
4504 } | |
4505 } | |
4506 DW_MUTEX_UNLOCK; | |
4507 } | |
4508 | |
4509 /* | |
4510 * Deletes text from an MLE box. | |
4511 * Parameters: | |
4512 * handle: Handle to the MLE to be deleted from. | |
4513 * startpoint: Point to start deleting text. | |
4514 * length: Amount of text to be deleted. | |
4515 */ | |
4516 void dw_mle_delete(HWND handle, int startpoint, int length) | |
4517 { | |
4518 int _locked_by_me = FALSE; | |
4519 | |
4520 DW_MUTEX_LOCK; | |
4521 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4522 { | |
4523 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4524 | |
4525 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4526 { | |
4527 GtkTextBuffer *tbuffer; | |
4528 GtkTextIter start, end; | |
4529 | |
4530 tbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tmp)); | |
4531 gtk_text_buffer_get_iter_at_offset(tbuffer, &start, startpoint); | |
4532 gtk_text_buffer_get_iter_at_offset(tbuffer, &end, startpoint + length); | |
4533 gtk_text_buffer_delete(tbuffer, &start, &end); | |
4534 } | |
4535 } | |
4536 DW_MUTEX_UNLOCK; | |
4537 } | |
4538 | |
4539 /* | |
4540 * Clears all text from an MLE box. | |
4541 * Parameters: | |
4542 * handle: Handle to the MLE to be cleared. | |
4543 */ | |
4544 void dw_mle_clear(HWND handle) | |
4545 { | |
4546 int length, _locked_by_me = FALSE; | |
4547 | |
4548 DW_MUTEX_LOCK; | |
4549 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4550 { | |
4551 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4552 | |
4553 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4554 { | |
4555 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tmp)); | |
4556 | |
4557 length = -1; | |
4558 gtk_text_buffer_set_text(buffer, "", length); | |
4559 } | |
4560 } | |
4561 DW_MUTEX_UNLOCK; | |
4562 } | |
4563 | |
4564 /* | |
4565 * Sets the visible line of an MLE box. | |
4566 * Parameters: | |
4567 * handle: Handle to the MLE. | |
4568 * line: Line to be visible. | |
4569 */ | |
4570 void dw_mle_set_visible(HWND handle, int line) | |
4571 { | |
4572 int _locked_by_me = FALSE; | |
4573 | |
4574 DW_MUTEX_LOCK; | |
4575 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4576 { | |
4577 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4578 | |
4579 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4580 { | |
4581 GtkTextBuffer *tbuffer; | |
4582 GtkTextIter iter; | |
4583 GtkTextMark *mark = (GtkTextMark *)g_object_get_data(G_OBJECT(handle), "_dw_mark"); | |
4584 | |
4585 tbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tmp)); | |
4586 gtk_text_buffer_get_iter_at_offset(tbuffer, &iter, 0); | |
4587 gtk_text_iter_set_line(&iter, line); | |
4588 if(!mark) | |
4589 { | |
4590 mark = gtk_text_buffer_create_mark(tbuffer, NULL, &iter, FALSE); | |
4591 g_object_set_data(G_OBJECT(handle), "_dw_mark", (gpointer)mark); | |
4592 } | |
4593 else | |
4594 gtk_text_buffer_move_mark(tbuffer, mark, &iter); | |
4595 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(tmp), mark, | |
4596 0, FALSE, 0, 0); | |
4597 } | |
4598 } | |
4599 DW_MUTEX_UNLOCK; | |
4600 } | |
4601 | |
4602 /* | |
4603 * Sets the editablity of an MLE box. | |
4604 * Parameters: | |
4605 * handle: Handle to the MLE. | |
4606 * state: TRUE if it can be edited, FALSE for readonly. | |
4607 */ | |
4608 void dw_mle_set_editable(HWND handle, int state) | |
4609 { | |
4610 int _locked_by_me = FALSE; | |
4611 | |
4612 DW_MUTEX_LOCK; | |
4613 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4614 { | |
4615 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4616 | |
4617 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4618 gtk_text_view_set_editable(GTK_TEXT_VIEW(tmp), state); | |
4619 } | |
4620 DW_MUTEX_UNLOCK; | |
4621 } | |
4622 | |
4623 /* | |
4624 * Sets the word wrap state of an MLE box. | |
4625 * Parameters: | |
4626 * handle: Handle to the MLE. | |
4627 * state: TRUE if it wraps, FALSE if it doesn't. | |
4628 */ | |
4629 void dw_mle_set_word_wrap(HWND handle, int state) | |
4630 { | |
4631 int _locked_by_me = FALSE; | |
4632 | |
4633 DW_MUTEX_LOCK; | |
4634 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4635 { | |
4636 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4637 | |
4638 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4639 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(tmp), GTK_WRAP_WORD); | |
4640 } | |
4641 DW_MUTEX_UNLOCK; | |
4642 } | |
4643 | |
4644 /* | |
4645 * Sets the current cursor position of an MLE box. | |
4646 * Parameters: | |
4647 * handle: Handle to the MLE to be positioned. | |
4648 * point: Point to position cursor. | |
4649 */ | |
4650 void dw_mle_set_cursor(HWND handle, int point) | |
4651 { | |
4652 int _locked_by_me = FALSE; | |
4653 | |
4654 DW_MUTEX_LOCK; | |
4655 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4656 { | |
4657 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4658 | |
4659 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4660 { | |
4661 GtkTextBuffer *tbuffer; | |
4662 GtkTextIter iter; | |
4663 GtkTextMark *mark = (GtkTextMark *)g_object_get_data(G_OBJECT(handle), "_dw_mark"); | |
4664 | |
4665 tbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tmp)); | |
4666 gtk_text_buffer_get_iter_at_offset(tbuffer, &iter, point); | |
4667 if(!mark) | |
4668 { | |
4669 mark = gtk_text_buffer_create_mark(tbuffer, NULL, &iter, FALSE); | |
4670 g_object_set_data(G_OBJECT(handle), "_dw_mark", (gpointer)mark); | |
4671 } | |
4672 else | |
4673 gtk_text_buffer_move_mark(tbuffer, mark, &iter); | |
4674 gtk_text_buffer_place_cursor(tbuffer, &iter); | |
4675 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(tmp), mark, | |
4676 0, FALSE, 0, 0); | |
4677 } | |
4678 } | |
4679 DW_MUTEX_UNLOCK; | |
4680 } | |
4681 | |
4682 /* | |
4683 * Finds text in an MLE box. | |
4684 * Parameters: | |
4685 * handle: Handle to the MLE to be cleared. | |
4686 * text: Text to search for. | |
4687 * point: Start point of search. | |
4688 * flags: Search specific flags. | |
4689 */ | |
4690 int dw_mle_search(HWND handle, char *text, int point, unsigned long flags) | |
4691 { | |
4692 int _locked_by_me = FALSE, retval = 0; | |
4693 | |
4694 DW_MUTEX_LOCK; | |
4695 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
4696 { | |
4697 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
4698 | |
4699 if(tmp && GTK_IS_TEXT_VIEW(tmp)) | |
4700 { | |
4701 GtkTextBuffer *tbuffer; | |
4702 GtkTextIter iter, found; | |
4703 | |
4704 tbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tmp)); | |
4705 gtk_text_buffer_get_iter_at_offset(tbuffer, &iter, point); | |
4706 gtk_text_iter_forward_search(&iter, text, GTK_TEXT_SEARCH_TEXT_ONLY, &found, NULL, NULL); | |
4707 retval = gtk_text_iter_get_offset(&found); | |
4708 } | |
4709 } | |
4710 DW_MUTEX_UNLOCK; | |
4711 return retval; | |
4712 } | |
4713 | |
4714 /* | |
4715 * Stops redrawing of an MLE box. | |
4716 * Parameters: | |
4717 * handle: Handle to the MLE to freeze. | |
4718 */ | |
4719 void dw_mle_freeze(HWND handle) | |
4720 { | |
4721 } | |
4722 | |
4723 /* | |
4724 * Resumes redrawing of an MLE box. | |
4725 * Parameters: | |
4726 * handle: Handle to the MLE to thaw. | |
4727 */ | |
4728 void dw_mle_thaw(HWND handle) | |
4729 { | |
4730 } | |
4731 | |
4732 /* | |
4733 * Sets the percent bar position. | |
4734 * Parameters: | |
4735 * handle: Handle to the percent bar to be set. | |
4736 * position: Position of the percent bar withing the range. | |
4737 */ | |
4738 void dw_percent_set_pos(HWND handle, unsigned int position) | |
4739 { | |
4740 int _locked_by_me = FALSE; | |
4741 | |
4742 DW_MUTEX_LOCK; | |
4743 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(handle), (gfloat)position/100); | |
4744 DW_MUTEX_UNLOCK; | |
4745 } | |
4746 | |
4747 /* | |
4748 * Returns the position of the slider. | |
4749 * Parameters: | |
4750 * handle: Handle to the slider to be queried. | |
4751 */ | |
4752 unsigned int dw_slider_get_pos(HWND handle) | |
4753 { | |
4754 int val = 0, _locked_by_me = FALSE; | |
4755 GtkAdjustment *adjustment; | |
4756 | |
4757 if(!handle) | |
4758 return 0; | |
4759 | |
4760 DW_MUTEX_LOCK; | |
4761 adjustment = (GtkAdjustment *)g_object_get_data(G_OBJECT(handle), "_dw_adjustment"); | |
4762 if(adjustment) | |
4763 { | |
4764 int max = _round_value(gtk_adjustment_get_upper(adjustment)) - 1; | |
4765 int thisval = _round_value(gtk_adjustment_get_value(adjustment)); | |
4766 | |
4767 if(GTK_IS_VSCALE(handle)) | |
4768 val = max - thisval; | |
4769 else | |
4770 val = thisval; | |
4771 } | |
4772 DW_MUTEX_UNLOCK; | |
4773 return val; | |
4774 } | |
4775 | |
4776 /* | |
4777 * Sets the slider position. | |
4778 * Parameters: | |
4779 * handle: Handle to the slider to be set. | |
4780 * position: Position of the slider withing the range. | |
4781 */ | |
4782 void dw_slider_set_pos(HWND handle, unsigned int position) | |
4783 { | |
4784 int _locked_by_me = FALSE; | |
4785 GtkAdjustment *adjustment; | |
4786 | |
4787 if(!handle) | |
4788 return; | |
4789 | |
4790 DW_MUTEX_LOCK; | |
4791 adjustment = (GtkAdjustment *)g_object_get_data(G_OBJECT(handle), "_dw_adjustment"); | |
4792 if(adjustment) | |
4793 { | |
4794 int max = _round_value(gtk_adjustment_get_upper(adjustment)) - 1; | |
4795 | |
4796 if(GTK_IS_VSCALE(handle)) | |
4797 gtk_adjustment_set_value(adjustment, (gfloat)(max - position)); | |
4798 else | |
4799 gtk_adjustment_set_value(adjustment, (gfloat)position); | |
4800 } | |
4801 DW_MUTEX_UNLOCK; | |
4802 } | |
4803 | |
4804 /* | |
4805 * Returns the position of the scrollbar. | |
4806 * Parameters: | |
4807 * handle: Handle to the scrollbar to be queried. | |
4808 */ | |
4809 unsigned int dw_scrollbar_get_pos(HWND handle) | |
4810 { | |
4811 int val = 0, _locked_by_me = FALSE; | |
4812 GtkAdjustment *adjustment; | |
4813 | |
4814 if(!handle) | |
4815 return 0; | |
4816 | |
4817 DW_MUTEX_LOCK; | |
4818 adjustment = (GtkAdjustment *)g_object_get_data(G_OBJECT(handle), "_dw_adjustment"); | |
4819 if(adjustment) | |
4820 val = _round_value(gtk_adjustment_get_value(adjustment)); | |
4821 DW_MUTEX_UNLOCK; | |
4822 return val; | |
4823 } | |
4824 | |
4825 /* | |
4826 * Sets the scrollbar position. | |
4827 * Parameters: | |
4828 * handle: Handle to the scrollbar to be set. | |
4829 * position: Position of the scrollbar withing the range. | |
4830 */ | |
4831 void dw_scrollbar_set_pos(HWND handle, unsigned int position) | |
4832 { | |
4833 int _locked_by_me = FALSE; | |
4834 GtkAdjustment *adjustment; | |
4835 | |
4836 if(!handle) | |
4837 return; | |
4838 | |
4839 DW_MUTEX_LOCK; | |
4840 adjustment = (GtkAdjustment *)g_object_get_data(G_OBJECT(handle), "_dw_adjustment"); | |
4841 if(adjustment) | |
4842 gtk_adjustment_set_value(adjustment, (gfloat)position); | |
4843 DW_MUTEX_UNLOCK; | |
4844 } | |
4845 | |
4846 /* | |
4847 * Sets the scrollbar range. | |
4848 * Parameters: | |
4849 * handle: Handle to the scrollbar to be set. | |
4850 * range: Maximum range value. | |
4851 * visible: Visible area relative to the range. | |
4852 */ | |
4853 void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible) | |
4854 { | |
4855 int _locked_by_me = FALSE; | |
4856 GtkAdjustment *adjustment; | |
4857 | |
4858 if(!handle) | |
4859 return; | |
4860 | |
4861 DW_MUTEX_LOCK; | |
4862 adjustment = (GtkAdjustment *)g_object_get_data(G_OBJECT(handle), "_dw_adjustment"); | |
4863 if(adjustment) | |
4864 { | |
4865 gtk_adjustment_set_upper(adjustment, (gdouble)range); | |
4866 gtk_adjustment_set_page_increment(adjustment,(gdouble)visible); | |
4867 gtk_adjustment_set_page_size(adjustment, (gdouble)visible); | |
4868 } | |
4869 DW_MUTEX_UNLOCK; | |
4870 } | |
4871 | |
4872 /* | |
4873 * Sets the spinbutton value. | |
4874 * Parameters: | |
4875 * handle: Handle to the spinbutton to be set. | |
4876 * position: Current value of the spinbutton. | |
4877 */ | |
4878 void dw_spinbutton_set_pos(HWND handle, long position) | |
4879 { | |
4880 int _locked_by_me = FALSE; | |
4881 | |
4882 DW_MUTEX_LOCK; | |
4883 gtk_spin_button_set_value(GTK_SPIN_BUTTON(handle), (gfloat)position); | |
4884 DW_MUTEX_UNLOCK; | |
4885 } | |
4886 | |
4887 /* | |
4888 * Sets the spinbutton limits. | |
4889 * Parameters: | |
4890 * handle: Handle to the spinbutton to be set. | |
4891 * position: Current value of the spinbutton. | |
4892 * position: Current value of the spinbutton. | |
4893 */ | |
4894 void dw_spinbutton_set_limits(HWND handle, long upper, long lower) | |
4895 { | |
4896 long curval; | |
4897 GtkAdjustment *adj; | |
4898 int _locked_by_me = FALSE; | |
4899 | |
4900 curval = dw_spinbutton_get_pos(handle); | |
4901 DW_MUTEX_LOCK; | |
4902 adj = (GtkAdjustment *)gtk_adjustment_new((gfloat)curval, (gfloat)lower, (gfloat)upper, 1.0, 5.0, 0.0); | |
4903 gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(handle), adj); | |
4904 /* | |
4905 * Set our internal relationships between the adjustment and the spinbutton | |
4906 */ | |
4907 g_object_set_data(G_OBJECT(handle), "_dw_adjustment", (gpointer)adj); | |
4908 g_object_set_data(G_OBJECT(adj), "_dw_spinbutton", (gpointer)handle); | |
4909 DW_MUTEX_UNLOCK; | |
4910 } | |
4911 | |
4912 /* | |
4913 * Sets the entryfield character limit. | |
4914 * Parameters: | |
4915 * handle: Handle to the spinbutton to be set. | |
4916 * limit: Number of characters the entryfield will take. | |
4917 */ | |
4918 void dw_entryfield_set_limit(HWND handle, ULONG limit) | |
4919 { | |
4920 int _locked_by_me = FALSE; | |
4921 | |
4922 DW_MUTEX_LOCK; | |
4923 gtk_entry_set_max_length(GTK_ENTRY(handle), limit); | |
4924 DW_MUTEX_UNLOCK; | |
4925 } | |
4926 | |
4927 /* | |
4928 * Returns the current value of the spinbutton. | |
4929 * Parameters: | |
4930 * handle: Handle to the spinbutton to be queried. | |
4931 */ | |
4932 long dw_spinbutton_get_pos(HWND handle) | |
4933 { | |
4934 long retval; | |
4935 int _locked_by_me = FALSE; | |
4936 | |
4937 DW_MUTEX_LOCK; | |
4938 retval = (long)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(handle)); | |
4939 DW_MUTEX_UNLOCK; | |
4940 | |
4941 return retval; | |
4942 } | |
4943 | |
4944 /* | |
4945 * Returns the state of the checkbox. | |
4946 * Parameters: | |
4947 * handle: Handle to the checkbox to be queried. | |
4948 */ | |
4949 int dw_checkbox_get(HWND handle) | |
4950 { | |
4951 int retval; | |
4952 int _locked_by_me = FALSE; | |
4953 | |
4954 DW_MUTEX_LOCK; | |
4955 retval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(handle)); | |
4956 DW_MUTEX_UNLOCK; | |
4957 | |
4958 return retval; | |
4959 } | |
4960 | |
4961 /* | |
4962 * Sets the state of the checkbox. | |
4963 * Parameters: | |
4964 * handle: Handle to the checkbox to be queried. | |
4965 * value: TRUE for checked, FALSE for unchecked. | |
4966 */ | |
4967 void dw_checkbox_set(HWND handle, int value) | |
4968 { | |
4969 int _locked_by_me = FALSE; | |
4970 | |
4971 DW_MUTEX_LOCK; | |
4972 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(handle), value); | |
4973 DW_MUTEX_UNLOCK; | |
4974 } | |
4975 | |
4976 /* | |
4977 * Inserts an item into a tree window (widget) after another item. | |
4978 * Parameters: | |
4979 * handle: Handle to the tree to be inserted. | |
4980 * item: Handle to the item to be positioned after. | |
4981 * title: The text title of the entry. | |
4982 * icon: Handle to coresponding icon. | |
4983 * parent: Parent handle or 0 if root. | |
4984 * itemdata: Item specific data. | |
4985 */ | |
4986 HTREEITEM dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, HICN icon, HTREEITEM parent, void *itemdata) | |
4987 { | |
4988 GtkWidget *tree; | |
4989 GtkTreeIter *iter; | |
4990 GtkTreeStore *store; | |
4991 GdkPixbuf *pixbuf; | |
4992 HTREEITEM retval = 0; | |
4993 int _locked_by_me = FALSE; | |
4994 | |
4995 if(!handle) | |
4996 return NULL; | |
4997 | |
4998 DW_MUTEX_LOCK; | |
4999 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5000 && GTK_IS_TREE_VIEW(tree) && | |
5001 (store = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5002 { | |
5003 iter = (GtkTreeIter *)malloc(sizeof(GtkTreeIter)); | |
5004 | |
5005 pixbuf = _find_pixbuf(icon, NULL, NULL); | |
5006 | |
5007 gtk_tree_store_insert_after(store, iter, (GtkTreeIter *)parent, (GtkTreeIter *)item); | |
5008 gtk_tree_store_set (store, iter, 0, title, 1, pixbuf, 2, itemdata, 3, iter, -1); | |
5009 if(pixbuf && !(icon & (1 << 31))) | |
5010 g_object_unref(pixbuf); | |
5011 retval = (HTREEITEM)iter; | |
5012 } | |
5013 DW_MUTEX_UNLOCK; | |
5014 | |
5015 return retval; | |
5016 } | |
5017 | |
5018 /* | |
5019 * Inserts an item into a tree window (widget). | |
5020 * Parameters: | |
5021 * handle: Handle to the tree to be inserted. | |
5022 * title: The text title of the entry. | |
5023 * icon: Handle to coresponding icon. | |
5024 * parent: Parent handle or 0 if root. | |
5025 * itemdata: Item specific data. | |
5026 */ | |
5027 HTREEITEM dw_tree_insert(HWND handle, char *title, HICN icon, HTREEITEM parent, void *itemdata) | |
5028 { | |
5029 GtkWidget *tree; | |
5030 GtkTreeIter *iter; | |
5031 GtkTreeStore *store; | |
5032 GdkPixbuf *pixbuf; | |
5033 HTREEITEM retval = 0; | |
5034 int _locked_by_me = FALSE; | |
5035 | |
5036 if(!handle) | |
5037 return NULL; | |
5038 | |
5039 DW_MUTEX_LOCK; | |
5040 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5041 && GTK_IS_TREE_VIEW(tree) && | |
5042 (store = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5043 { | |
5044 iter = (GtkTreeIter *)malloc(sizeof(GtkTreeIter)); | |
5045 | |
5046 pixbuf = _find_pixbuf(icon, NULL, NULL); | |
5047 | |
5048 gtk_tree_store_append (store, iter, (GtkTreeIter *)parent); | |
5049 gtk_tree_store_set (store, iter, 0, title, 1, pixbuf, 2, itemdata, 3, iter, -1); | |
5050 if(pixbuf && !(icon & (1 << 31))) | |
5051 g_object_unref(pixbuf); | |
5052 retval = (HTREEITEM)iter; | |
5053 } | |
5054 DW_MUTEX_UNLOCK; | |
5055 | |
5056 return retval; | |
5057 } | |
5058 | |
5059 /* | |
5060 * Sets the text and icon of an item in a tree window (widget). | |
5061 * Parameters: | |
5062 * handle: Handle to the tree containing the item. | |
5063 * item: Handle of the item to be modified. | |
5064 * title: The text title of the entry. | |
5065 * icon: Handle to coresponding icon. | |
5066 */ | |
5067 void dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon) | |
5068 { | |
5069 GtkWidget *tree; | |
5070 GtkTreeStore *store; | |
5071 GdkPixbuf *pixbuf; | |
5072 int _locked_by_me = FALSE; | |
5073 | |
5074 if(!handle) | |
5075 return; | |
5076 | |
5077 DW_MUTEX_LOCK; | |
5078 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5079 && GTK_IS_TREE_VIEW(tree) && | |
5080 (store = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5081 { | |
5082 pixbuf = _find_pixbuf(icon, NULL, NULL); | |
5083 | |
5084 gtk_tree_store_set(store, (GtkTreeIter *)item, 0, title, 1, pixbuf, -1); | |
5085 if(pixbuf && !(icon & (1 << 31))) | |
5086 g_object_unref(pixbuf); | |
5087 } | |
5088 DW_MUTEX_UNLOCK; | |
5089 } | |
5090 | |
5091 /* | |
5092 * Sets the item data of a tree item. | |
5093 * Parameters: | |
5094 * handle: Handle to the tree containing the item. | |
5095 * item: Handle of the item to be modified. | |
5096 * itemdata: User defined data to be associated with item. | |
5097 */ | |
5098 void dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata) | |
5099 { | |
5100 GtkWidget *tree; | |
5101 GtkTreeStore *store; | |
5102 int _locked_by_me = FALSE; | |
5103 | |
5104 if(!handle || !item) | |
5105 return; | |
5106 | |
5107 DW_MUTEX_LOCK; | |
5108 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5109 && GTK_IS_TREE_VIEW(tree) && | |
5110 (store = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5111 gtk_tree_store_set(store, (GtkTreeIter *)item, 2, itemdata, -1); | |
5112 DW_MUTEX_UNLOCK; | |
5113 } | |
5114 | |
5115 /* | |
5116 * Gets the text an item in a tree window (widget). | |
5117 * Parameters: | |
5118 * handle: Handle to the tree containing the item. | |
5119 * item: Handle of the item to be modified. | |
5120 */ | |
5121 char * API dw_tree_get_title(HWND handle, HTREEITEM item) | |
5122 { | |
5123 int _locked_by_me = FALSE; | |
5124 char *text = NULL; | |
5125 GtkWidget *tree; | |
5126 GtkTreeModel *store; | |
5127 | |
5128 if(!handle || !item) | |
5129 return text; | |
5130 | |
5131 DW_MUTEX_LOCK; | |
5132 tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
5133 | |
5134 if(tree && GTK_IS_TREE_VIEW(tree) && | |
5135 (store = (GtkTreeModel *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5136 gtk_tree_model_get(store, (GtkTreeIter *)item, 0, &text, -1); | |
5137 DW_MUTEX_UNLOCK; | |
5138 return text; | |
5139 } | |
5140 | |
5141 /* | |
5142 * Gets the text an item in a tree window (widget). | |
5143 * Parameters: | |
5144 * handle: Handle to the tree containing the item. | |
5145 * item: Handle of the item to be modified. | |
5146 */ | |
5147 HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item) | |
5148 { | |
5149 int _locked_by_me = FALSE; | |
5150 HTREEITEM parent = (HTREEITEM)0; | |
5151 GtkWidget *tree; | |
5152 GtkTreeModel *store; | |
5153 | |
5154 if(!handle || !item) | |
5155 return parent; | |
5156 | |
5157 DW_MUTEX_LOCK; | |
5158 tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
5159 | |
5160 if(tree && GTK_IS_TREE_VIEW(tree) && | |
5161 (store = (GtkTreeModel *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5162 { | |
5163 GtkTreeIter *p = malloc(sizeof(GtkTreeIter)); | |
5164 | |
5165 if(gtk_tree_model_iter_parent(store, p, (GtkTreeIter *)item)) | |
5166 parent = p; | |
5167 else | |
5168 free(p); | |
5169 } | |
5170 DW_MUTEX_UNLOCK; | |
5171 return parent; | |
5172 } | |
5173 | |
5174 /* | |
5175 * Gets the item data of a tree item. | |
5176 * Parameters: | |
5177 * handle: Handle to the tree containing the item. | |
5178 * item: Handle of the item to be modified. | |
5179 */ | |
5180 void *dw_tree_item_get_data(HWND handle, HTREEITEM item) | |
5181 { | |
5182 void *ret = NULL; | |
5183 GtkWidget *tree; | |
5184 GtkTreeModel *store; | |
5185 int _locked_by_me = FALSE; | |
5186 | |
5187 if(!handle || !item) | |
5188 return NULL; | |
5189 | |
5190 DW_MUTEX_LOCK; | |
5191 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5192 && GTK_IS_TREE_VIEW(tree) && | |
5193 (store = (GtkTreeModel *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5194 gtk_tree_model_get(store, (GtkTreeIter *)item, 2, &ret, -1); | |
5195 DW_MUTEX_UNLOCK; | |
5196 return ret; | |
5197 } | |
5198 | |
5199 /* | |
5200 * Sets this item as the active selection. | |
5201 * Parameters: | |
5202 * handle: Handle to the tree window (widget) to be selected. | |
5203 * item: Handle to the item to be selected. | |
5204 */ | |
5205 void dw_tree_item_select(HWND handle, HTREEITEM item) | |
5206 { | |
5207 GtkWidget *tree; | |
5208 GtkTreeStore *store; | |
5209 int _locked_by_me = FALSE; | |
5210 | |
5211 if(!handle || !item) | |
5212 return; | |
5213 | |
5214 DW_MUTEX_LOCK; | |
5215 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5216 && GTK_IS_TREE_VIEW(tree) && | |
5217 (store = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5218 { | |
5219 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), (GtkTreeIter *)item); | |
5220 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); | |
5221 | |
5222 gtk_tree_view_set_cursor(GTK_TREE_VIEW(tree), path, NULL, FALSE); | |
5223 gtk_tree_selection_select_iter(sel, (GtkTreeIter *)item); | |
5224 gtk_tree_path_free(path); | |
5225 } | |
5226 DW_MUTEX_UNLOCK; | |
5227 } | |
5228 | |
5229 static void _dw_recursive_free(GtkTreeModel *store, GtkTreeIter parent) | |
5230 { | |
5231 void *data; | |
5232 GtkTreeIter iter; | |
5233 | |
5234 gtk_tree_model_get(store, &parent, 3, &data, -1); | |
5235 if(data) | |
5236 free(data); | |
5237 gtk_tree_store_set(GTK_TREE_STORE(store), &parent, 3, NULL, -1); | |
5238 | |
5239 if(gtk_tree_model_iter_children(store, &iter, &parent)) | |
5240 { | |
5241 do { | |
5242 _dw_recursive_free(GTK_TREE_MODEL(store), iter); | |
5243 } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)); | |
5244 } | |
5245 } | |
5246 | |
5247 /* | |
5248 * Removes all nodes from a tree. | |
5249 * Parameters: | |
5250 * handle: Handle to the window (widget) to be cleared. | |
5251 */ | |
5252 void dw_tree_clear(HWND handle) | |
5253 { | |
5254 GtkWidget *tree; | |
5255 GtkTreeStore *store; | |
5256 int _locked_by_me = FALSE; | |
5257 | |
5258 if(!handle) | |
5259 return; | |
5260 | |
5261 DW_MUTEX_LOCK; | |
5262 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5263 && GTK_IS_TREE_VIEW(tree) && | |
5264 (store = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5265 { | |
5266 GtkTreeIter iter; | |
5267 | |
5268 if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) | |
5269 { | |
5270 do { | |
5271 _dw_recursive_free(GTK_TREE_MODEL(store), iter); | |
5272 } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)); | |
5273 } | |
5274 gtk_tree_store_clear(store); | |
5275 } | |
5276 DW_MUTEX_UNLOCK; | |
5277 } | |
5278 | |
5279 /* | |
5280 * Expands a node on a tree. | |
5281 * Parameters: | |
5282 * handle: Handle to the tree window (widget). | |
5283 * item: Handle to node to be expanded. | |
5284 */ | |
5285 void dw_tree_item_expand(HWND handle, HTREEITEM item) | |
5286 { | |
5287 GtkWidget *tree; | |
5288 GtkTreeStore *store; | |
5289 int _locked_by_me = FALSE; | |
5290 | |
5291 if(!handle) | |
5292 return; | |
5293 | |
5294 DW_MUTEX_LOCK; | |
5295 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5296 && GTK_IS_TREE_VIEW(tree) && | |
5297 (store = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5298 { | |
5299 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), (GtkTreeIter *)item); | |
5300 gtk_tree_view_expand_row(GTK_TREE_VIEW(tree), path, FALSE); | |
5301 gtk_tree_path_free(path); | |
5302 } | |
5303 DW_MUTEX_UNLOCK; | |
5304 } | |
5305 | |
5306 /* | |
5307 * Collapses a node on a tree. | |
5308 * Parameters: | |
5309 * handle: Handle to the tree window (widget). | |
5310 * item: Handle to node to be collapsed. | |
5311 */ | |
5312 void dw_tree_item_collapse(HWND handle, HTREEITEM item) | |
5313 { | |
5314 GtkWidget *tree; | |
5315 GtkTreeStore *store; | |
5316 int _locked_by_me = FALSE; | |
5317 | |
5318 if(!handle) | |
5319 return; | |
5320 | |
5321 DW_MUTEX_LOCK; | |
5322 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5323 && GTK_IS_TREE_VIEW(tree) && | |
5324 (store = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5325 { | |
5326 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), (GtkTreeIter *)item); | |
5327 gtk_tree_view_collapse_row(GTK_TREE_VIEW(tree), path); | |
5328 gtk_tree_path_free(path); | |
5329 } | |
5330 DW_MUTEX_UNLOCK; | |
5331 } | |
5332 | |
5333 /* | |
5334 * Removes a node from a tree. | |
5335 * Parameters: | |
5336 * handle: Handle to the window (widget) to be cleared. | |
5337 * item: Handle to node to be deleted. | |
5338 */ | |
5339 void dw_tree_item_delete(HWND handle, HTREEITEM item) | |
5340 { | |
5341 GtkWidget *tree; | |
5342 GtkTreeStore *store; | |
5343 int _locked_by_me = FALSE; | |
5344 | |
5345 if(!handle) | |
5346 return; | |
5347 | |
5348 DW_MUTEX_LOCK; | |
5349 if((tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user")) | |
5350 && GTK_IS_TREE_VIEW(tree) && | |
5351 (store = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) | |
5352 { | |
5353 gtk_tree_store_remove(store, (GtkTreeIter *)item); | |
5354 free(item); | |
5355 } | |
5356 DW_MUTEX_UNLOCK; | |
5357 } | |
5358 | |
5359 static int _dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator, int extra) | |
5360 { | |
5361 int z; | |
5362 GtkWidget *tree; | |
5363 GtkListStore *store; | |
5364 GtkTreeViewColumn *col; | |
5365 GtkCellRenderer *rend; | |
5366 GtkTreeSelection *sel; | |
5367 int _locked_by_me = FALSE; | |
5368 GType *array = calloc(count, sizeof(gint)); | |
5369 | |
5370 DW_MUTEX_LOCK; | |
5371 /* First loop... create array to create the store */ | |
5372 for(z=0;z<count;z++) | |
5373 { | |
5374 if(flags[z] & DW_CFA_BITMAPORICON) | |
5375 { | |
5376 array[z] = GDK_TYPE_PIXBUF; | |
5377 } | |
5378 else if(flags[z] & DW_CFA_STRING) | |
5379 { | |
5380 array[z] = G_TYPE_STRING; | |
5381 } | |
5382 else if(flags[z] & DW_CFA_ULONG) | |
5383 { | |
5384 array[z] = G_TYPE_ULONG; | |
5385 } | |
5386 else if(flags[z] & DW_CFA_TIME) | |
5387 { | |
5388 array[z] = G_TYPE_STRING; | |
5389 } | |
5390 else if(flags[z] & DW_CFA_DATE) | |
5391 { | |
5392 array[z] = G_TYPE_STRING; | |
5393 } | |
5394 } | |
5395 /* Create the store and then the tree */ | |
5396 store = gtk_list_store_newv(count, array); | |
5397 tree = _tree_setup(handle, GTK_TREE_MODEL(store)); | |
5398 /* Second loop... create the columns */ | |
5399 for(z=0;z<count;z++) | |
5400 { | |
5401 col = gtk_tree_view_column_new(); | |
5402 if(flags[z] & DW_CFA_BITMAPORICON) | |
5403 { | |
5404 rend = gtk_cell_renderer_pixbuf_new(); | |
5405 gtk_tree_view_column_pack_start(col, rend, FALSE); | |
5406 gtk_tree_view_column_add_attribute(col, rend, "pixbuf", z); | |
5407 } | |
5408 else if(flags[z] & DW_CFA_STRING) | |
5409 { | |
5410 rend = gtk_cell_renderer_text_new(); | |
5411 gtk_tree_view_column_pack_start(col, rend, TRUE); | |
5412 gtk_tree_view_column_add_attribute(col, rend, "text", z); | |
5413 } | |
5414 else if(flags[z] & DW_CFA_ULONG) | |
5415 { | |
5416 rend = gtk_cell_renderer_text_new(); | |
5417 gtk_tree_view_column_pack_start(col, rend, TRUE); | |
5418 gtk_tree_view_column_add_attribute(col, rend, "text", z); | |
5419 } | |
5420 else if(flags[z] & DW_CFA_TIME) | |
5421 { | |
5422 rend = gtk_cell_renderer_text_new(); | |
5423 gtk_tree_view_column_pack_start(col, rend, TRUE); | |
5424 gtk_tree_view_column_add_attribute(col, rend, "text", z); | |
5425 } | |
5426 else if(flags[z] & DW_CFA_DATE) | |
5427 { | |
5428 rend = gtk_cell_renderer_text_new(); | |
5429 gtk_tree_view_column_pack_start(col, rend, TRUE); | |
5430 gtk_tree_view_column_add_attribute(col, rend, "text", z); | |
5431 } | |
5432 gtk_tree_view_append_column(GTK_TREE_VIEW (tree), col); | |
5433 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(tree), col); | |
5434 } | |
5435 /* Finish up */ | |
5436 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), TRUE); | |
5437 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); | |
5438 if(g_object_get_data(G_OBJECT(handle), "_dw_multi_sel")) | |
5439 { | |
5440 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); | |
5441 } | |
5442 else | |
5443 { | |
5444 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); | |
5445 } | |
5446 gtk_widget_show(handle); | |
5447 free(array); | |
5448 DW_MUTEX_UNLOCK; | |
5449 return TRUE; | |
5450 } | |
5451 | |
5452 /* | |
5453 * Sets up the container columns. | |
5454 * Parameters: | |
5455 * handle: Handle to the container to be configured. | |
5456 * flags: An array of unsigned longs with column flags. | |
5457 * titles: An array of strings with column text titles. | |
5458 * count: The number of columns (this should match the arrays). | |
5459 * separator: The column number that contains the main separator. | |
5460 * (this item may only be used in OS/2) | |
5461 */ | |
5462 int dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator) | |
5463 { | |
5464 return _dw_container_setup(handle, flags, titles, count, separator, 0); | |
5465 } | |
5466 | |
5467 /* | |
5468 * Sets up the filesystem columns, note: filesystem always has an icon/filename field. | |
5469 * Parameters: | |
5470 * handle: Handle to the container to be configured. | |
5471 * flags: An array of unsigned longs with column flags. | |
5472 * titles: An array of strings with column text titles. | |
5473 * count: The number of columns (this should match the arrays). | |
5474 */ | |
5475 int dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count) | |
5476 { | |
5477 char **newtitles = malloc(sizeof(char *) * (count + 2)); | |
5478 unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2)); | |
5479 | |
5480 newtitles[0] = "Filename"; | |
5481 newflags[0] = DW_CFA_STRINGANDICON | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR; | |
5482 | |
5483 memcpy(&newtitles[2], titles, sizeof(char *) * count); | |
5484 memcpy(&newflags[2], flags, sizeof(unsigned long) * count); | |
5485 | |
5486 _dw_container_setup(handle, newflags, newtitles, count + 1, 1, 1); | |
5487 | |
5488 if ( newtitles) free(newtitles); | |
5489 if ( newflags ) free(newflags); | |
5490 return TRUE; | |
5491 } | |
5492 | |
5493 /* | |
5494 * Obtains an icon from a module (or header in GTK). | |
5495 * Parameters: | |
5496 * module: Handle to module (DLL) in OS/2 and Windows. | |
5497 * id: A unsigned long id int the resources on OS/2 and | |
5498 * Windows, on GTK this is converted to a pointer | |
5499 * to an embedded XPM. | |
5500 */ | |
5501 HICN dw_icon_load(unsigned long module, unsigned long id) | |
5502 { | |
5503 return id; | |
5504 } | |
5505 | |
5506 HICN _dw_icon_load_internal(GdkPixbuf *pixbuf) | |
5507 { | |
5508 unsigned long z, ret = 0; | |
5509 int found = -1; | |
5510 | |
5511 /* Find a free entry in the array */ | |
5512 for (z=0;z<_PixmapCount;z++) | |
5513 { | |
5514 if (!_PixmapArray[z].used) | |
5515 { | |
5516 ret = found = z; | |
5517 break; | |
5518 } | |
5519 } | |
5520 | |
5521 /* If there are no free entries, expand the | |
5522 * array. | |
5523 */ | |
5524 if (found == -1) | |
5525 { | |
5526 DWPrivatePixmap *old = _PixmapArray; | |
5527 | |
5528 ret = found = _PixmapCount; | |
5529 _PixmapCount++; | |
5530 | |
5531 _PixmapArray = malloc(sizeof(DWPrivatePixmap) * _PixmapCount); | |
5532 | |
5533 if (found) | |
5534 memcpy(_PixmapArray, old, sizeof(DWPrivatePixmap) * found); | |
5535 if (old) | |
5536 free(old); | |
5537 _PixmapArray[found].used = 1; | |
5538 _PixmapArray[found].pixbuf = NULL; | |
5539 } | |
5540 | |
5541 _PixmapArray[found].pixbuf = pixbuf; | |
5542 _PixmapArray[found].width = gdk_pixbuf_get_width(pixbuf); | |
5543 _PixmapArray[found].height = gdk_pixbuf_get_height(pixbuf); | |
5544 | |
5545 if (!_PixmapArray[found].pixbuf) | |
5546 { | |
5547 _PixmapArray[found].used = 0; | |
5548 _PixmapArray[found].pixbuf = NULL; | |
5549 return 0; | |
5550 } | |
5551 return (HICN)ret | (1 << 31); | |
5552 } | |
5553 | |
5554 /* | |
5555 * Obtains an icon from a file. | |
5556 * Parameters: | |
5557 * filename: Name of the file, omit extention to have | |
5558 * DW pick the appropriate file extension. | |
5559 * (ICO on OS/2 or Windows, XPM on Unix) | |
5560 */ | |
5561 HICN API dw_icon_load_from_file(char *filename) | |
5562 { | |
5563 int _locked_by_me = FALSE; | |
5564 GdkPixbuf *pixbuf; | |
5565 char *file = alloca(strlen(filename) + 5); | |
5566 int found_ext = 0; | |
5567 int i, ret = 0; | |
5568 | |
5569 if (!file) | |
5570 return 0; | |
5571 | |
5572 strcpy(file, filename); | |
5573 | |
5574 /* check if we can read from this file (it exists and read permission) */ | |
5575 if (access(file, 04) != 0) | |
5576 { | |
5577 /* Try with various extentions */ | |
5578 for ( i = 0; i < NUM_EXTS; i++ ) | |
5579 { | |
5580 strcpy( file, filename ); | |
5581 strcat( file, image_exts[i] ); | |
5582 if ( access( file, 04 ) == 0 ) | |
5583 { | |
5584 found_ext = 1; | |
5585 break; | |
5586 } | |
5587 } | |
5588 if ( found_ext == 0 ) | |
5589 { | |
5590 return 0; | |
5591 } | |
5592 } | |
5593 | |
5594 DW_MUTEX_LOCK; | |
5595 pixbuf = gdk_pixbuf_new_from_file(file, NULL); | |
5596 if (pixbuf) | |
5597 { | |
5598 ret = _dw_icon_load_internal(pixbuf); | |
5599 } | |
5600 DW_MUTEX_UNLOCK; | |
5601 return ret; | |
5602 } | |
5603 | |
5604 /* | |
5605 * Obtains an icon from data. | |
5606 * Parameters: | |
5607 * data: Source of data for image. | |
5608 * len: length of data | |
5609 */ | |
5610 HICN API dw_icon_load_from_data(char *data, int len) | |
5611 { | |
5612 int _locked_by_me = FALSE; | |
5613 char *file; | |
5614 FILE *fp; | |
5615 GdkPixbuf *pixbuf; | |
5616 unsigned long z, ret = 0; | |
5617 | |
5618 /* | |
5619 * A real hack; create a temporary file and write the contents | |
5620 * of the data to the file | |
5621 */ | |
5622 file = tmpnam( NULL ); | |
5623 fp = fopen( file, "wb" ); | |
5624 if ( fp ) | |
5625 { | |
5626 fwrite( data, len, 1, fp ); | |
5627 fclose( fp ); | |
5628 } | |
5629 else | |
5630 { | |
5631 return 0; | |
5632 } | |
5633 DW_MUTEX_LOCK; | |
5634 pixbuf = gdk_pixbuf_new_from_file(file, NULL); | |
5635 if (pixbuf) | |
5636 { | |
5637 ret = _dw_icon_load_internal(pixbuf); | |
5638 } | |
5639 DW_MUTEX_UNLOCK; | |
5640 return ret; | |
5641 } | |
5642 | |
5643 /* | |
5644 * Frees a loaded resource in OS/2 and Windows. | |
5645 * Parameters: | |
5646 * handle: Handle to icon returned by dw_icon_load(). | |
5647 */ | |
5648 void dw_icon_free(HICN handle) | |
5649 { | |
5650 /* If it is a private icon, find the item | |
5651 * free the associated structures and set | |
5652 * the entry to unused. | |
5653 */ | |
5654 if(handle & (1 << 31)) | |
5655 { | |
5656 unsigned long id = handle & 0xFFFFFF; | |
5657 | |
5658 if(id < _PixmapCount && _PixmapArray[id].used) | |
5659 { | |
5660 if(_PixmapArray[id].pixbuf) | |
5661 { | |
5662 g_object_unref(_PixmapArray[id].pixbuf); | |
5663 _PixmapArray[id].pixbuf = NULL; | |
5664 } | |
5665 _PixmapArray[id].used = 0; | |
5666 } | |
5667 } | |
5668 } | |
5669 | |
5670 /* | |
5671 * Allocates memory used to populate a container. | |
5672 * Parameters: | |
5673 * handle: Handle to the container window (widget). | |
5674 * rowcount: The number of items to be populated. | |
5675 */ | |
5676 void *dw_container_alloc(HWND handle, int rowcount) | |
5677 { | |
5678 #if 0 | |
5679 int z, count = 0, prevrowcount = 0; | |
5680 GtkWidget *clist; | |
5681 GdkColor *fore, *back; | |
5682 char **blah; | |
5683 int _locked_by_me = FALSE; | |
5684 | |
5685 DW_MUTEX_LOCK; | |
5686 clist = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
5687 if(!clist) | |
5688 { | |
5689 DW_MUTEX_UNLOCK; | |
5690 return NULL; | |
5691 } | |
5692 | |
5693 count = (int)g_object_get_data(G_OBJECT(clist), "_dw_colcount"); | |
5694 prevrowcount = (int)g_object_get_data(G_OBJECT(clist), "_dw_rowcount"); | |
5695 | |
5696 if(!count) | |
5697 { | |
5698 DW_MUTEX_UNLOCK; | |
5699 return NULL; | |
5700 } | |
5701 | |
5702 blah = malloc(sizeof(char *) * count); | |
5703 memset(blah, 0, sizeof(char *) * count); | |
5704 | |
5705 fore = (GdkColor *)g_object_get_data(G_OBJECT(clist), "_dw_foregdk"); | |
5706 back = (GdkColor *)g_object_get_data(G_OBJECT(clist), "_dw_backgdk"); | |
5707 gtk_clist_freeze(GTK_CLIST(clist)); | |
5708 for(z=0;z<rowcount;z++) | |
5709 { | |
5710 gtk_clist_append(GTK_CLIST(clist), blah); | |
5711 if(fore) | |
5712 gtk_clist_set_foreground(GTK_CLIST(clist), z + prevrowcount, fore); | |
5713 if(back) | |
5714 gtk_clist_set_background(GTK_CLIST(clist), z + prevrowcount, back); | |
5715 } | |
5716 g_object_set_data(G_OBJECT(clist), "_dw_insertpos", GINT_TO_POINTER(prevrowcount)); | |
5717 g_object_set_data(G_OBJECT(clist), "_dw_rowcount", GINT_TO_POINTER(rowcount + prevrowcount)); | |
5718 free(blah); | |
5719 DW_MUTEX_UNLOCK; | |
5720 return (void *)handle; | |
5721 #endif | |
5722 return NULL; | |
5723 } | |
5724 | |
5725 /* | |
5726 * Internal representation of dw_container_set_item() extracted so we can pass | |
5727 * two data pointers; icon and text for dw_filesystem_set_item(). | |
5728 */ | |
5729 void _dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data, char *text) | |
5730 { | |
5731 #if 0 | |
5732 char numbuf[10], textbuffer[100]; | |
5733 int flag = 0; | |
5734 GtkWidget *clist; | |
5735 int _locked_by_me = FALSE; | |
5736 | |
5737 DW_MUTEX_LOCK; | |
5738 clist = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
5739 if(!clist) | |
5740 { | |
5741 DW_MUTEX_UNLOCK; | |
5742 return; | |
5743 } | |
5744 | |
5745 sprintf(numbuf, "%d", column); | |
5746 flag = (int)g_object_get_data(G_OBJECT(clist), numbuf); | |
5747 row += (int)g_object_get_data(G_OBJECT(clist), "_dw_insertpos"); | |
5748 | |
5749 if(flag & DW_CFA_BITMAPORICON) | |
5750 { | |
5751 long hicon = *((long *)data); | |
5752 GdkBitmap *bitmap = NULL; | |
5753 GdkPixmap *pixmap = _find_pixmap(&bitmap, hicon, clist, NULL, NULL); | |
5754 | |
5755 if(pixmap) | |
5756 gtk_clist_set_pixmap(GTK_CLIST(clist), row, column, pixmap, bitmap); | |
5757 } | |
5758 else if(flag & DW_CFA_STRINGANDICON) | |
5759 { | |
5760 long hicon = *((long *)data); | |
5761 GdkBitmap *bitmap = NULL; | |
5762 GdkPixmap *pixmap = _find_pixmap(&bitmap, hicon, clist, NULL, NULL); | |
5763 | |
5764 if(pixmap) | |
5765 gtk_clist_set_pixtext(GTK_CLIST(clist), row, column, text, 2, pixmap, bitmap); | |
5766 } | |
5767 else if(flag & DW_CFA_STRING) | |
5768 { | |
5769 char *tmp = *((char **)data); | |
5770 gtk_clist_set_text(GTK_CLIST(clist), row, column, tmp); | |
5771 } | |
5772 else if(flag & DW_CFA_ULONG) | |
5773 { | |
5774 ULONG tmp = *((ULONG *)data); | |
5775 | |
5776 sprintf(textbuffer, "%lu", tmp); | |
5777 | |
5778 gtk_clist_set_text(GTK_CLIST(clist), row, column, textbuffer); | |
5779 } | |
5780 else if(flag & DW_CFA_DATE) | |
5781 { | |
5782 struct tm curtm; | |
5783 CDATE cdate = *((CDATE *)data); | |
5784 | |
5785 memset( &curtm, 0, sizeof(curtm) ); | |
5786 curtm.tm_mday = cdate.day; | |
5787 curtm.tm_mon = cdate.month - 1; | |
5788 curtm.tm_year = cdate.year - 1900; | |
5789 | |
5790 strftime(textbuffer, 100, "%x", &curtm); | |
5791 | |
5792 gtk_clist_set_text(GTK_CLIST(clist), row, column, textbuffer); | |
5793 } | |
5794 else if(flag & DW_CFA_TIME) | |
5795 { | |
5796 struct tm curtm; | |
5797 CTIME ctime = *((CTIME *)data); | |
5798 | |
5799 memset( &curtm, 0, sizeof(curtm) ); | |
5800 curtm.tm_hour = ctime.hours; | |
5801 curtm.tm_min = ctime.minutes; | |
5802 curtm.tm_sec = ctime.seconds; | |
5803 | |
5804 strftime(textbuffer, 100, "%X", &curtm); | |
5805 | |
5806 gtk_clist_set_text(GTK_CLIST(clist), row, column, textbuffer); | |
5807 } | |
5808 DW_MUTEX_UNLOCK; | |
5809 #endif | |
5810 } | |
5811 | |
5812 /* | |
5813 * Sets an item in specified row and column to the given data. | |
5814 * Parameters: | |
5815 * handle: Handle to the container window (widget). | |
5816 * pointer: Pointer to the allocated memory in dw_container_alloc(). | |
5817 * column: Zero based column of data being set. | |
5818 * row: Zero based row of data being set. | |
5819 * data: Pointer to the data to be added. | |
5820 */ | |
5821 void dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data) | |
5822 { | |
5823 _dw_container_set_item(handle, NULL, column, row, data, NULL); | |
5824 } | |
5825 | |
5826 /* | |
5827 * Changes an existing item in specified row and column to the given data. | |
5828 * Parameters: | |
5829 * handle: Handle to the container window (widget). | |
5830 * column: Zero based column of data being set. | |
5831 * row: Zero based row of data being set. | |
5832 * data: Pointer to the data to be added. | |
5833 */ | |
5834 void dw_container_change_item(HWND handle, int column, int row, void *data) | |
5835 { | |
5836 _dw_container_set_item(handle, NULL, column, row, data, NULL); | |
5837 } | |
5838 | |
5839 /* | |
5840 * Changes an existing item in specified row and column to the given data. | |
5841 * Parameters: | |
5842 * handle: Handle to the container window (widget). | |
5843 * column: Zero based column of data being set. | |
5844 * row: Zero based row of data being set. | |
5845 * data: Pointer to the data to be added. | |
5846 */ | |
5847 void API dw_filesystem_change_item(HWND handle, int column, int row, void *data) | |
5848 { | |
5849 dw_filesystem_set_item(handle, NULL, column, row, data); | |
5850 } | |
5851 | |
5852 /* | |
5853 * Changes an item in specified row and column to the given data. | |
5854 * Parameters: | |
5855 * handle: Handle to the container window (widget). | |
5856 * pointer: Pointer to the allocated memory in dw_container_alloc(). | |
5857 * column: Zero based column of data being set. | |
5858 * row: Zero based row of data being set. | |
5859 * data: Pointer to the data to be added. | |
5860 */ | |
5861 void API dw_filesystem_change_file(HWND handle, int row, char *filename, HICN icon) | |
5862 { | |
5863 dw_filesystem_set_file(handle, NULL, row, filename, icon); | |
5864 } | |
5865 | |
5866 /* | |
5867 * Sets an item in specified row and column to the given data. | |
5868 * Parameters: | |
5869 * handle: Handle to the container window (widget). | |
5870 * pointer: Pointer to the allocated memory in dw_container_alloc(). | |
5871 * column: Zero based column of data being set. | |
5872 * row: Zero based row of data being set. | |
5873 * data: Pointer to the data to be added. | |
5874 */ | |
5875 void dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, HICN icon) | |
5876 { | |
5877 _dw_container_set_item(handle, pointer, 0, row, (void *)&icon, filename); | |
5878 } | |
5879 | |
5880 /* | |
5881 * Sets an item in specified row and column to the given data. | |
5882 * Parameters: | |
5883 * handle: Handle to the container window (widget). | |
5884 * pointer: Pointer to the allocated memory in dw_container_alloc(). | |
5885 * column: Zero based column of data being set. | |
5886 * row: Zero based row of data being set. | |
5887 * data: Pointer to the data to be added. | |
5888 */ | |
5889 void dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data) | |
5890 { | |
5891 _dw_container_set_item(handle, pointer, column + 1, row, data, NULL); | |
5892 } | |
5893 | |
5894 /* | |
5895 * Gets column type for a container column | |
5896 * Parameters: | |
5897 * handle: Handle to the container window (widget). | |
5898 * column: Zero based column. | |
5899 */ | |
5900 int dw_container_get_column_type(HWND handle, int column) | |
5901 { | |
5902 char numbuf[10]; | |
5903 int flag, rc; | |
5904 #if 0 | |
5905 GtkWidget *clist; | |
5906 int _locked_by_me = FALSE; | |
5907 | |
5908 DW_MUTEX_LOCK; | |
5909 clist = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
5910 if(!clist) | |
5911 { | |
5912 DW_MUTEX_UNLOCK; | |
5913 return 0; | |
5914 } | |
5915 | |
5916 sprintf(numbuf, "%d", column); | |
5917 flag = (int)g_object_get_data(G_OBJECT(clist), numbuf); | |
5918 | |
5919 if(flag & DW_CFA_BITMAPORICON) | |
5920 rc = DW_CFA_BITMAPORICON; | |
5921 else if(flag & DW_CFA_STRING) | |
5922 rc = DW_CFA_STRING; | |
5923 else if(flag & DW_CFA_ULONG) | |
5924 rc = DW_CFA_ULONG; | |
5925 else if(flag & DW_CFA_DATE) | |
5926 rc = DW_CFA_DATE; | |
5927 else if(flag & DW_CFA_TIME) | |
5928 rc = DW_CFA_TIME; | |
5929 else | |
5930 rc = 0; | |
5931 DW_MUTEX_UNLOCK; | |
5932 #endif | |
5933 return rc; | |
5934 } | |
5935 | |
5936 /* | |
5937 * Gets column type for a filesystem container column | |
5938 * Parameters: | |
5939 * handle: Handle to the container window (widget). | |
5940 * column: Zero based column. | |
5941 */ | |
5942 int API dw_filesystem_get_column_type(HWND handle, int column) | |
5943 { | |
5944 return dw_container_get_column_type( handle, column + 1 ); | |
5945 } | |
5946 | |
5947 /* | |
5948 * Sets the width of a column in the container. | |
5949 * Parameters: | |
5950 * handle: Handle to window (widget) of container. | |
5951 * column: Zero based column of width being set. | |
5952 * width: Width of column in pixels. | |
5953 */ | |
5954 void dw_container_set_column_width(HWND handle, int column, int width) | |
5955 { | |
5956 } | |
5957 | |
5958 /* | |
5959 * Sets the title of a row in the container. | |
5960 * Parameters: | |
5961 * pointer: Pointer to the allocated memory in dw_container_alloc(). | |
5962 * row: Zero based row of data being set. | |
5963 * title: String title of the item. | |
5964 */ | |
5965 void dw_container_set_row_title(void *pointer, int row, char *title) | |
5966 { | |
5967 } | |
5968 | |
5969 /* | |
5970 * Sets the title of a row in the container. | |
5971 * Parameters: | |
5972 * handle: Handle to the container window (widget). | |
5973 * pointer: Pointer to the allocated memory in dw_container_alloc(). | |
5974 * rowcount: The number of rows to be inserted. | |
5975 */ | |
5976 void dw_container_insert(HWND handle, void *pointer, int rowcount) | |
5977 { | |
5978 } | |
5979 | |
5980 /* | |
5981 * Removes the first x rows from a container. | |
5982 * Parameters: | |
5983 * handle: Handle to the window (widget) to be deleted from. | |
5984 * rowcount: The number of rows to be deleted. | |
5985 */ | |
5986 void dw_container_delete(HWND handle, int rowcount) | |
5987 { | |
5988 } | |
5989 | |
5990 /* | |
5991 * Removes all rows from a container. | |
5992 * Parameters: | |
5993 * handle: Handle to the window (widget) to be cleared. | |
5994 * redraw: TRUE to cause the container to redraw immediately. | |
5995 */ | |
5996 void dw_container_clear(HWND handle, int redraw) | |
5997 { | |
5998 } | |
5999 | |
6000 /* | |
6001 * Scrolls container up or down. | |
6002 * Parameters: | |
6003 * handle: Handle to the window (widget) to be scrolled. | |
6004 * direction: DW_SCROLL_UP, DW_SCROLL_DOWN, DW_SCROLL_TOP or | |
6005 * DW_SCROLL_BOTTOM. (rows is ignored for last two) | |
6006 * rows: The number of rows to be scrolled. | |
6007 */ | |
6008 void dw_container_scroll(HWND handle, int direction, long rows) | |
6009 { | |
6010 } | |
6011 | |
6012 /* | |
6013 * Starts a new query of a container. | |
6014 * Parameters: | |
6015 * handle: Handle to the window (widget) to be queried. | |
6016 * flags: If this parameter is DW_CRA_SELECTED it will only | |
6017 * return items that are currently selected. Otherwise | |
6018 * it will return all records in the container. | |
6019 */ | |
6020 char *dw_container_query_start(HWND handle, unsigned long flags) | |
6021 { | |
6022 char *retval = NULL; | |
6023 int _locked_by_me = FALSE; | |
6024 | |
6025 return retval; | |
6026 } | |
6027 | |
6028 /* | |
6029 * Continues an existing query of a container. | |
6030 * Parameters: | |
6031 * handle: Handle to the window (widget) to be queried. | |
6032 * flags: If this parameter is DW_CRA_SELECTED it will only | |
6033 * return items that are currently selected. Otherwise | |
6034 * it will return all records in the container. | |
6035 */ | |
6036 char *dw_container_query_next(HWND handle, unsigned long flags) | |
6037 { | |
6038 char *retval = NULL; | |
6039 int _locked_by_me = FALSE; | |
6040 | |
6041 return retval; | |
6042 } | |
6043 | |
6044 /* | |
6045 * Cursors the item with the text speficied, and scrolls to that item. | |
6046 * Parameters: | |
6047 * handle: Handle to the window (widget) to be queried. | |
6048 * text: Text usually returned by dw_container_query(). | |
6049 */ | |
6050 void dw_container_cursor(HWND handle, char *text) | |
6051 { | |
6052 } | |
6053 | |
6054 /* | |
6055 * Deletes the item with the text speficied. | |
6056 * Parameters: | |
6057 * handle: Handle to the window (widget). | |
6058 * text: Text usually returned by dw_container_query(). | |
6059 */ | |
6060 void dw_container_delete_row(HWND handle, char *text) | |
6061 { | |
6062 } | |
6063 | |
6064 /* | |
6065 * Optimizes the column widths so that all data is visible. | |
6066 * Parameters: | |
6067 * handle: Handle to the window (widget) to be optimized. | |
6068 */ | |
6069 void dw_container_optimize(HWND handle) | |
6070 { | |
6071 } | |
6072 | |
6073 /* | |
6074 * Inserts an icon into the taskbar. | |
6075 * Parameters: | |
6076 * handle: Window handle that will handle taskbar icon messages. | |
6077 * icon: Icon handle to display in the taskbar. | |
6078 * bubbletext: Text to show when the mouse is above the icon. | |
6079 */ | |
6080 void dw_taskbar_insert(HWND handle, HICN icon, char *bubbletext) | |
6081 { | |
6082 /* TODO */ | |
6083 } | |
6084 | |
6085 /* | |
6086 * Deletes an icon from the taskbar. | |
6087 * Parameters: | |
6088 * handle: Window handle that was used with dw_taskbar_insert(). | |
6089 * icon: Icon handle that was used with dw_taskbar_insert(). | |
6090 */ | |
6091 void dw_taskbar_delete(HWND handle, HICN icon) | |
6092 { | |
6093 /* TODO */ | |
6094 } | |
6095 | |
6096 /* | |
6097 * Creates a rendering context widget (window) to be packed. | |
6098 * Parameters: | |
6099 * id: An id to be used with dw_window_from_id. | |
6100 * Returns: | |
6101 * A handle to the widget or NULL on failure. | |
6102 */ | |
6103 HWND dw_render_new(unsigned long id) | |
6104 { | |
6105 int _locked_by_me = FALSE; | |
6106 GtkWidget *tmp; | |
6107 | |
6108 DW_MUTEX_LOCK; | |
6109 tmp = gtk_drawing_area_new(); | |
6110 gtk_widget_set_events(tmp, GDK_EXPOSURE_MASK | |
6111 | GDK_LEAVE_NOTIFY_MASK | |
6112 | GDK_BUTTON_PRESS_MASK | |
6113 | GDK_BUTTON_RELEASE_MASK | |
6114 | GDK_KEY_PRESS_MASK | |
6115 | GDK_POINTER_MOTION_MASK | |
6116 | GDK_POINTER_MOTION_HINT_MASK); | |
6117 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
6118 gtk_widget_set_can_focus(tmp, TRUE); | |
6119 gtk_widget_show(tmp); | |
6120 DW_MUTEX_UNLOCK; | |
6121 return tmp; | |
6122 } | |
6123 | |
6124 /* Returns a GdkColor from a DW color */ | |
6125 static GdkColor _internal_color(unsigned long value) | |
6126 { | |
6127 if(DW_RGB_COLOR & value) | |
6128 { | |
6129 GdkColor color = { 0, DW_RED_VALUE(value) << 8, DW_GREEN_VALUE(value) << 8, DW_BLUE_VALUE(value) << 8 }; | |
6130 return color; | |
6131 } | |
6132 if (value < 16) | |
6133 return _colors[value]; | |
6134 return _colors[0]; | |
6135 } | |
6136 | |
6137 /* Sets the current foreground drawing color. | |
6138 * Parameters: | |
6139 * red: red value. | |
6140 * green: green value. | |
6141 * blue: blue value. | |
6142 */ | |
6143 void dw_color_foreground_set(unsigned long value) | |
6144 { | |
6145 int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id()); | |
6146 GdkColor color = _internal_color(value); | |
6147 | |
6148 DW_MUTEX_LOCK; | |
6149 _foreground[index] = color; | |
6150 DW_MUTEX_UNLOCK; | |
6151 } | |
6152 | |
6153 /* Sets the current background drawing color. | |
6154 * Parameters: | |
6155 * red: red value. | |
6156 * green: green value. | |
6157 * blue: blue value. | |
6158 */ | |
6159 void dw_color_background_set(unsigned long value) | |
6160 { | |
6161 int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id()); | |
6162 GdkColor color = _internal_color(value); | |
6163 | |
6164 DW_MUTEX_LOCK; | |
6165 if(value == DW_CLR_DEFAULT) | |
6166 _transparent[index] = 1; | |
6167 else | |
6168 _transparent[index] = 0; | |
6169 | |
6170 _background[index] = color; | |
6171 DW_MUTEX_UNLOCK; | |
6172 } | |
6173 | |
6174 /* Internal function to handle the color OK press */ | |
6175 static gint _gtk_color_ok(GtkWidget *widget, DWDialog *dwwait) | |
6176 { | |
6177 GdkColor color; | |
6178 unsigned long dw_color; | |
6179 GtkColorSelection *colorsel; | |
6180 | |
6181 if(!dwwait) | |
6182 return FALSE; | |
6183 | |
6184 colorsel = (GtkColorSelection *)gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(dwwait->data)); | |
6185 gtk_color_selection_get_current_color(colorsel, &color); | |
6186 gtk_widget_destroy(GTK_WIDGET(dwwait->data)); | |
6187 _dw_color_active = 0; | |
6188 dw_color = DW_RGB( (color.red & 0xFF), (color.green & 0xFF), (color.blue & 0xFF)); | |
6189 dw_dialog_dismiss(dwwait, (void *)dw_color); | |
6190 return FALSE; | |
6191 } | |
6192 | |
6193 /* Internal function to handle the color Cancel press */ | |
6194 static gint _gtk_color_cancel(GtkWidget *widget, DWDialog *dwwait) | |
6195 { | |
6196 if(!dwwait) | |
6197 return FALSE; | |
6198 | |
6199 gtk_widget_destroy(GTK_WIDGET(dwwait->data)); | |
6200 _dw_color_active = 0; | |
6201 dw_dialog_dismiss(dwwait, (void *)-1); | |
6202 return FALSE; | |
6203 } | |
6204 | |
6205 /* Allows the user to choose a color using the system's color chooser dialog. | |
6206 * Parameters: | |
6207 * value: current color | |
6208 * Returns: | |
6209 * The selected color or the current color if cancelled. | |
6210 */ | |
6211 unsigned long API dw_color_choose(unsigned long value) | |
6212 { | |
6213 GtkWidget *colorw; | |
6214 int _locked_by_me = FALSE; | |
6215 DWDialog *dwwait; | |
6216 GtkColorSelection *colorsel; | |
6217 GdkColor color = _internal_color(value); | |
6218 GObject *part; | |
6219 unsigned long dw_color; | |
6220 | |
6221 DW_MUTEX_LOCK; | |
6222 | |
6223 /* The DW mutex should be sufficient for | |
6224 * insuring no thread changes this unknowingly. | |
6225 */ | |
6226 if(_dw_color_active) | |
6227 { | |
6228 DW_MUTEX_UNLOCK; | |
6229 return value; | |
6230 } | |
6231 | |
6232 _dw_color_active = 1; | |
6233 | |
6234 colorw = gtk_color_selection_dialog_new("Select Color"); | |
6235 | |
6236 dwwait = dw_dialog_new((void *)colorw); | |
6237 | |
6238 colorsel = (GtkColorSelection *)gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(colorw)); | |
6239 #if 0 /* TODO */ | |
6240 part = gtk_buildable_get_internal_child(GTK_BUILDABLE(colorsel, | |
6241 g_signal_connect(G_OBJECT(colorsel->ok_button), "clicked", G_CALLBACK(_gtk_color_ok), dwwait); | |
6242 g_signal_connect(G_OBJECT(colorsel->cancel_button), "clicked", G_CALLBACK(_gtk_color_cancel), dwwait); | |
6243 #endif | |
6244 | |
6245 gtk_color_selection_set_previous_color(colorsel,&color); | |
6246 gtk_color_selection_set_current_color(colorsel,&color); | |
6247 gtk_color_selection_set_has_palette(colorsel,TRUE); | |
6248 | |
6249 gtk_widget_show(colorw); | |
6250 | |
6251 dw_color = (unsigned long)dw_dialog_wait(dwwait); | |
6252 if ((unsigned long)dw_color == -1) | |
6253 dw_color = value; | |
6254 DW_MUTEX_UNLOCK; | |
6255 return (unsigned long)dw_color; | |
6256 /* | |
6257 dw_messagebox("Not implemented", DW_MB_OK|DW_MB_INFORMATION, "This feature not yet supported."); | |
6258 return value; | |
6259 */ | |
6260 } | |
6261 | |
6262 /* Draw a point on a window (preferably a render window). | |
6263 * Parameters: | |
6264 * handle: Handle to the window. | |
6265 * pixmap: Handle to the pixmap. (choose only one of these) | |
6266 * x: X coordinate. | |
6267 * y: Y coordinate. | |
6268 */ | |
6269 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) | |
6270 { | |
6271 int _locked_by_me = FALSE; | |
6272 cairo_t *cr = NULL; | |
6273 | |
6274 DW_MUTEX_LOCK; | |
6275 if(handle) | |
6276 cr = gdk_cairo_create(gtk_widget_get_window(handle)); | |
6277 #if 0 /* TODO */ | |
6278 else if(pixmap) | |
6279 gc = _set_colors(pixmap->pixbuf); | |
6280 #endif | |
6281 if(cr) | |
6282 { | |
6283 int index = _find_thread_index(dw_thread_id()); | |
6284 | |
6285 cairo_set_source_rgb(cr, _foreground[index].red, _foreground[index].green, _foreground[index].blue); | |
6286 cairo_set_line_width(cr, 1); | |
6287 cairo_move_to(cr, x, y); | |
6288 cairo_stroke(cr); | |
6289 cairo_destroy(cr); | |
6290 } | |
6291 DW_MUTEX_UNLOCK; | |
6292 } | |
6293 | |
6294 /* Draw a line on a window (preferably a render window). | |
6295 * Parameters: | |
6296 * handle: Handle to the window. | |
6297 * pixmap: Handle to the pixmap. (choose only one of these) | |
6298 * x1: First X coordinate. | |
6299 * y1: First Y coordinate. | |
6300 * x2: Second X coordinate. | |
6301 * y2: Second Y coordinate. | |
6302 */ | |
6303 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2) | |
6304 { | |
6305 int _locked_by_me = FALSE; | |
6306 cairo_t *cr = NULL; | |
6307 | |
6308 DW_MUTEX_LOCK; | |
6309 if(handle) | |
6310 cr = gdk_cairo_create(gtk_widget_get_window(handle)); | |
6311 #if 0 /* TODO */ | |
6312 else if(pixmap) | |
6313 gc = _set_colors(pixmap->pixbuf); | |
6314 #endif | |
6315 if(cr) | |
6316 { | |
6317 int index = _find_thread_index(dw_thread_id()); | |
6318 | |
6319 cairo_set_source_rgb(cr, _foreground[index].red, _foreground[index].green, _foreground[index].blue); | |
6320 cairo_set_line_width(cr, 1); | |
6321 cairo_move_to(cr, x1, y1); | |
6322 cairo_line_to(cr, x2, y2); | |
6323 cairo_stroke(cr); | |
6324 cairo_destroy(cr); | |
6325 } | |
6326 DW_MUTEX_UNLOCK; | |
6327 } | |
6328 | |
6329 /* Draw a closed polygon on a window (preferably a render window). | |
6330 * Parameters: | |
6331 * handle: Handle to the window. | |
6332 * pixmap: Handle to the pixmap. (choose only one of these) | |
6333 * fill: if true filled | |
6334 * number of points | |
6335 * x[]: X coordinates. | |
6336 * y[]: Y coordinates. | |
6337 */ | |
6338 void dw_draw_polygon(HWND handle, HPIXMAP pixmap, int fill, int npoints, int *x, int *y) | |
6339 { | |
6340 int _locked_by_me = FALSE; | |
6341 cairo_t *cr = NULL; | |
6342 int z; | |
6343 | |
6344 DW_MUTEX_LOCK; | |
6345 if(handle) | |
6346 cr = gdk_cairo_create(gtk_widget_get_window(handle)); | |
6347 #if 0 /* TODO */ | |
6348 else if(pixmap) | |
6349 gc = _set_colors(pixmap->pixbuf); | |
6350 #endif | |
6351 if(cr) | |
6352 { | |
6353 int index = _find_thread_index(dw_thread_id()); | |
6354 | |
6355 cairo_set_source_rgb(cr, _foreground[index].red, _foreground[index].green, _foreground[index].blue); | |
6356 cairo_set_line_width(cr, 1); | |
6357 cairo_move_to(cr, x[0], y[0]); | |
6358 for(z=1;z<npoints;z++) | |
6359 { | |
6360 cairo_line_to(cr, x[z], y[z]); | |
6361 } | |
6362 if(fill) | |
6363 cairo_fill(cr); | |
6364 cairo_stroke(cr); | |
6365 cairo_destroy(cr); | |
6366 } | |
6367 DW_MUTEX_UNLOCK; | |
6368 } | |
6369 | |
6370 /* Draw a rectangle on a window (preferably a render window). | |
6371 * Parameters: | |
6372 * handle: Handle to the window. | |
6373 * pixmap: Handle to the pixmap. (choose only one of these) | |
6374 * fill: if true filled | |
6375 * x: X coordinate. | |
6376 * y: Y coordinate. | |
6377 * width: Width of rectangle. | |
6378 * height: Height of rectangle. | |
6379 */ | |
6380 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height) | |
6381 { | |
6382 int _locked_by_me = FALSE; | |
6383 cairo_t *cr = NULL; | |
6384 | |
6385 DW_MUTEX_LOCK; | |
6386 if(handle) | |
6387 cr = gdk_cairo_create(gtk_widget_get_window(handle)); | |
6388 #if 0 /* TODO */ | |
6389 else if(pixmap) | |
6390 gc = _set_colors(pixmap->pixbuf); | |
6391 #endif | |
6392 if(cr) | |
6393 { | |
6394 int index = _find_thread_index(dw_thread_id()); | |
6395 | |
6396 cairo_set_source_rgb(cr, _foreground[index].red, _foreground[index].green, _foreground[index].blue); | |
6397 cairo_set_line_width(cr, 1); | |
6398 cairo_move_to(cr, x, y); | |
6399 cairo_line_to(cr, x, y + height); | |
6400 cairo_line_to(cr, x + width, y + height); | |
6401 cairo_line_to(cr, x + width, y); | |
6402 if(fill) | |
6403 cairo_fill(cr); | |
6404 cairo_stroke(cr); | |
6405 cairo_destroy(cr); | |
6406 } | |
6407 DW_MUTEX_UNLOCK; | |
6408 } | |
6409 | |
6410 /* Draw text on a window (preferably a render window). | |
6411 * Parameters: | |
6412 * handle: Handle to the window. | |
6413 * pixmap: Handle to the pixmap. (choose only one of these) | |
6414 * x: X coordinate. | |
6415 * y: Y coordinate. | |
6416 * text: Text to be displayed. | |
6417 */ | |
6418 void dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text) | |
6419 { | |
6420 int _locked_by_me = FALSE; | |
6421 cairo_t *cr = NULL; | |
6422 PangoFontDescription *font; | |
6423 char *fontname = "fixed"; | |
6424 | |
6425 if(!text) | |
6426 return; | |
6427 | |
6428 DW_MUTEX_LOCK; | |
6429 if(handle) | |
6430 { | |
6431 cr = gdk_cairo_create(gtk_widget_get_window(handle)); | |
6432 fontname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname"); | |
6433 } | |
6434 #if 0 /* TODO */ | |
6435 else if(pixmap) | |
6436 { | |
6437 fontname = (char *)g_object_get_data(G_OBJECT(pixmap->handle), "_dw_fontname"); | |
6438 gc = _set_colors(pixmap->pixbuf); | |
6439 } | |
6440 #endif | |
6441 if(cr) | |
6442 { | |
6443 font = pango_font_description_from_string(fontname); | |
6444 if(font) | |
6445 { | |
6446 PangoContext *context = pango_cairo_create_context(cr); | |
6447 | |
6448 if(context) | |
6449 { | |
6450 PangoLayout *layout = pango_layout_new(context); | |
6451 | |
6452 if(layout) | |
6453 { | |
6454 int index = _find_thread_index(dw_thread_id()); | |
6455 | |
6456 pango_layout_set_font_description(layout, font); | |
6457 pango_layout_set_text(layout, text, strlen(text)); | |
6458 | |
6459 cairo_set_source_rgb(cr, _foreground[index].red, _foreground[index].green, _foreground[index].blue); | |
6460 cairo_move_to(cr, x, y); | |
6461 pango_cairo_show_layout (cr, layout); | |
6462 | |
6463 g_object_unref(layout); | |
6464 } | |
6465 g_object_unref(context); | |
6466 } | |
6467 pango_font_description_free(font); | |
6468 } | |
6469 cairo_destroy(cr); | |
6470 } | |
6471 DW_MUTEX_UNLOCK; | |
6472 } | |
6473 | |
6474 /* Query the width and height of a text string. | |
6475 * Parameters: | |
6476 * handle: Handle to the window. | |
6477 * pixmap: Handle to the pixmap. (choose only one of these) | |
6478 * text: Text to be queried. | |
6479 * width: Pointer to a variable to be filled in with the width. | |
6480 * height Pointer to a variable to be filled in with the height. | |
6481 */ | |
6482 void dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height) | |
6483 { | |
6484 int _locked_by_me = FALSE; | |
6485 PangoFontDescription *font; | |
6486 char *fontname = NULL; | |
6487 int free_fontname = 0; | |
6488 | |
6489 if(!text) | |
6490 return; | |
6491 | |
6492 DW_MUTEX_LOCK; | |
6493 if(handle) | |
6494 { | |
6495 fontname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname"); | |
6496 if ( fontname == NULL ) | |
6497 { | |
6498 fontname = dw_window_get_font(handle); | |
6499 free_fontname = 1; | |
6500 } | |
6501 } | |
6502 else if(pixmap) | |
6503 fontname = (char *)g_object_get_data(G_OBJECT(pixmap->handle), "_dw_fontname"); | |
6504 | |
6505 font = pango_font_description_from_string(fontname ? fontname : "monospace 10"); | |
6506 if(font) | |
6507 { | |
6508 PangoContext *context = gdk_pango_context_get(); | |
6509 | |
6510 if(context) | |
6511 { | |
6512 PangoLayout *layout = pango_layout_new(context); | |
6513 | |
6514 if(layout) | |
6515 { | |
6516 PangoRectangle rect; | |
6517 | |
6518 pango_layout_set_font_description(layout, font); | |
6519 pango_layout_set_text(layout, text, -1); | |
6520 pango_layout_get_pixel_extents(layout, NULL, &rect); | |
6521 | |
6522 if(width) | |
6523 *width = rect.width; | |
6524 if(height) | |
6525 *height = rect.height; | |
6526 | |
6527 g_object_unref(layout); | |
6528 } | |
6529 g_object_unref(context); | |
6530 } | |
6531 pango_font_description_free(font); | |
6532 } | |
6533 if ( free_fontname ) | |
6534 free( fontname ); | |
6535 DW_MUTEX_UNLOCK; | |
6536 } | |
6537 | |
6538 /* | |
6539 * Creates a pixmap with given parameters. | |
6540 * Parameters: | |
6541 * handle: Window handle the pixmap is associated with. | |
6542 * or zero to enable this pixmap to be written | |
6543 * off the screen to reduce flicker | |
6544 * width: Width of the pixmap in pixels. | |
6545 * height: Height of the pixmap in pixels. | |
6546 * depth: Color depth of the pixmap. | |
6547 * Returns: | |
6548 * A handle to a pixmap or NULL on failure. | |
6549 */ | |
6550 HPIXMAP dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth) | |
6551 { | |
6552 int _locked_by_me = FALSE; | |
6553 HPIXMAP pixmap; | |
6554 | |
6555 if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) | |
6556 return NULL; | |
6557 | |
6558 if (!depth) | |
6559 depth = -1; | |
6560 | |
6561 pixmap->width = width; pixmap->height = height; | |
6562 | |
6563 | |
6564 DW_MUTEX_LOCK; | |
6565 pixmap->handle = handle; | |
6566 /* Depth needs to be divided by 3... but for the RGB colorspace... | |
6567 * only 8 bits per sample is allowed, so to avoid issues just pass 8 for now. | |
6568 */ | |
6569 if ( handle ) | |
6570 pixmap->pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, FALSE, 8, width, height ); | |
6571 else | |
6572 pixmap->pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, FALSE, 8, width, height ); | |
6573 DW_MUTEX_UNLOCK; | |
6574 return pixmap; | |
6575 } | |
6576 | |
6577 /* | |
6578 * Creates a pixmap from a file. | |
6579 * Parameters: | |
6580 * handle: Window handle the pixmap is associated with. | |
6581 * filename: Name of the file, omit extention to have | |
6582 * DW pick the appropriate file extension. | |
6583 * (BMP on OS/2 or Windows, XPM on Unix) | |
6584 * Returns: | |
6585 * A handle to a pixmap or NULL on failure. | |
6586 */ | |
6587 HPIXMAP dw_pixmap_new_from_file(HWND handle, char *filename) | |
6588 { | |
6589 int _locked_by_me = FALSE; | |
6590 HPIXMAP pixmap; | |
6591 char *file = alloca(strlen(filename) + 5); | |
6592 int found_ext = 0; | |
6593 int i; | |
6594 | |
6595 if (!file || !(pixmap = calloc(1,sizeof(struct _hpixmap)))) | |
6596 return NULL; | |
6597 | |
6598 strcpy(file, filename); | |
6599 | |
6600 /* check if we can read from this file (it exists and read permission) */ | |
6601 if(access(file, 04) != 0) | |
6602 { | |
6603 /* Try with various extentions */ | |
6604 for ( i = 0; i < NUM_EXTS; i++ ) | |
6605 { | |
6606 strcpy( file, filename ); | |
6607 strcat( file, image_exts[i] ); | |
6608 if ( access( file, 04 ) == 0 ) | |
6609 { | |
6610 found_ext = 1; | |
6611 break; | |
6612 } | |
6613 } | |
6614 if ( found_ext == 0 ) | |
6615 { | |
6616 free(pixmap); | |
6617 return NULL; | |
6618 } | |
6619 } | |
6620 | |
6621 DW_MUTEX_LOCK; | |
6622 pixmap->pixbuf = gdk_pixbuf_new_from_file(file, NULL); | |
6623 pixmap->width = gdk_pixbuf_get_width(pixmap->pixbuf); | |
6624 pixmap->height = gdk_pixbuf_get_height(pixmap->pixbuf); | |
6625 pixmap->handle = handle; | |
6626 DW_MUTEX_UNLOCK; | |
6627 return pixmap; | |
6628 } | |
6629 | |
6630 /* | |
6631 * Creates a pixmap from data | |
6632 * Parameters: | |
6633 * handle: Window handle the pixmap is associated with. | |
6634 * data: Source of image data | |
6635 * DW pick the appropriate file extension. | |
6636 * (BMP on OS/2 or Windows, XPM on Unix) | |
6637 * Returns: | |
6638 * A handle to a pixmap or NULL on failure. | |
6639 */ | |
6640 HPIXMAP dw_pixmap_new_from_data(HWND handle, char *data, int len) | |
6641 { | |
6642 int _locked_by_me = FALSE; | |
6643 char *file; | |
6644 FILE *fp; | |
6645 HPIXMAP pixmap; | |
6646 | |
6647 if (!data || !(pixmap = calloc(1,sizeof(struct _hpixmap)))) | |
6648 return NULL; | |
6649 | |
6650 DW_MUTEX_LOCK; | |
6651 /* | |
6652 * A real hack; create a temporary file and write the contents | |
6653 * of the data to the file | |
6654 */ | |
6655 file = tmpnam( NULL ); | |
6656 fp = fopen( file, "wb" ); | |
6657 if ( fp ) | |
6658 { | |
6659 fwrite( data, len, 1, fp ); | |
6660 fclose( fp ); | |
6661 } | |
6662 else | |
6663 { | |
6664 DW_MUTEX_UNLOCK; | |
6665 return 0; | |
6666 } | |
6667 pixmap->pixbuf = gdk_pixbuf_new_from_file(file, NULL); | |
6668 pixmap->width = gdk_pixbuf_get_width(pixmap->pixbuf); | |
6669 pixmap->height = gdk_pixbuf_get_height(pixmap->pixbuf); | |
6670 /* remove our temporary file */ | |
6671 unlink (file ); | |
6672 pixmap->handle = handle; | |
6673 DW_MUTEX_UNLOCK; | |
6674 return pixmap; | |
6675 } | |
6676 | |
6677 /* | |
6678 * Sets the transparent color for a pixmap | |
6679 * Parameters: | |
6680 * pixmap: Handle to a pixmap returned by | |
6681 * dw_pixmap_new.. | |
6682 * color: transparent color | |
6683 * Note: This does nothing on GTK+ as transparency | |
6684 * is handled automatically | |
6685 */ | |
6686 void dw_pixmap_set_transparent_color(HPIXMAP pixmap, unsigned long color) | |
6687 { | |
6688 int _locked_by_me = FALSE; | |
6689 | |
6690 DW_MUTEX_LOCK; | |
6691 pixmap = pixmap; | |
6692 color = color; | |
6693 DW_MUTEX_UNLOCK; | |
6694 } | |
6695 | |
6696 /* | |
6697 * Creates a pixmap from internal resource graphic specified by id. | |
6698 * Parameters: | |
6699 * handle: Window handle the pixmap is associated with. | |
6700 * id: Resource ID associated with requested pixmap. | |
6701 * Returns: | |
6702 * A handle to a pixmap or NULL on failure. | |
6703 */ | |
6704 HPIXMAP dw_pixmap_grab(HWND handle, ULONG id) | |
6705 { | |
6706 HPIXMAP pixmap; | |
6707 int _locked_by_me = FALSE; | |
6708 | |
6709 if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) | |
6710 return NULL; | |
6711 | |
6712 | |
6713 DW_MUTEX_LOCK; | |
6714 pixmap->pixbuf = gdk_pixbuf_copy(_find_pixbuf(id, &pixmap->width, &pixmap->height)); | |
6715 DW_MUTEX_UNLOCK; | |
6716 return pixmap; | |
6717 } | |
6718 | |
6719 /* Call this after drawing to the screen to make sure | |
6720 * anything you have drawn is visible. | |
6721 */ | |
6722 void dw_flush(void) | |
6723 { | |
6724 } | |
6725 | |
6726 /* | |
6727 * Destroys an allocated pixmap. | |
6728 * Parameters: | |
6729 * pixmap: Handle to a pixmap returned by | |
6730 * dw_pixmap_new.. | |
6731 */ | |
6732 void dw_pixmap_destroy(HPIXMAP pixmap) | |
6733 { | |
6734 int _locked_by_me = FALSE; | |
6735 | |
6736 DW_MUTEX_LOCK; | |
6737 g_object_unref(G_OBJECT(pixmap->pixbuf)); | |
6738 free(pixmap); | |
6739 DW_MUTEX_UNLOCK; | |
6740 } | |
6741 | |
6742 /* | |
6743 * Copies from one item to another. | |
6744 * Parameters: | |
6745 * dest: Destination window handle. | |
6746 * destp: Destination pixmap. (choose only one). | |
6747 * xdest: X coordinate of destination. | |
6748 * ydest: Y coordinate of destination. | |
6749 * width: Width of area to copy. | |
6750 * height: Height of area to copy. | |
6751 * src: Source window handle. | |
6752 * srcp: Source pixmap. (choose only one). | |
6753 * xsrc: X coordinate of source. | |
6754 * ysrc: Y coordinate of source. | |
6755 */ | |
6756 void dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc) | |
6757 { | |
6758 /* Ok, these #ifdefs are going to get a bit confusing because | |
6759 * when using gdk-pixbuf, pixmaps are really pixbufs, so we | |
6760 * have to use the pixbuf functions on them, and thus convoluting | |
6761 * the code here a bit. -Brian | |
6762 */ | |
6763 int _locked_by_me = FALSE; | |
6764 cairo_t *cr = NULL; | |
6765 | |
6766 if((!dest && (!destp || !destp->pixbuf)) || (!src && (!srcp || !srcp->pixbuf))) | |
6767 return; | |
6768 | |
6769 DW_MUTEX_LOCK; | |
6770 if(dest) | |
6771 cr = gdk_cairo_create(gtk_widget_get_window(dest)); | |
6772 #if 0 /* TODO */ | |
6773 else if(destp) | |
6774 gc = gdk_gc_new(destp->pixbuf); | |
6775 #endif | |
6776 | |
6777 if(cr) | |
6778 { | |
6779 if(src) | |
6780 gdk_cairo_set_source_window (cr, gtk_widget_get_window(src), xsrc, ysrc); | |
6781 else if(srcp) | |
6782 gdk_cairo_set_source_pixbuf (cr, srcp->pixbuf, xsrc, ysrc); | |
6783 | |
6784 cairo_paint(cr); | |
6785 cairo_destroy(cr); | |
6786 } | |
6787 DW_MUTEX_UNLOCK; | |
6788 } | |
6789 | |
6790 /* | |
6791 * Emits a beep. | |
6792 * Parameters: | |
6793 * freq: Frequency. | |
6794 * dur: Duration. | |
6795 */ | |
6796 void dw_beep(int freq, int dur) | |
6797 { | |
6798 int _locked_by_me = FALSE; | |
6799 | |
6800 DW_MUTEX_LOCK; | |
6801 gdk_beep(); | |
6802 DW_MUTEX_UNLOCK; | |
6803 } | |
6804 | |
6805 void _my_strlwr(char *buf) | |
6806 { | |
6807 int z, len = strlen(buf); | |
6808 | |
6809 for(z=0;z<len;z++) | |
6810 { | |
6811 if(buf[z] >= 'A' && buf[z] <= 'Z') | |
6812 buf[z] -= 'A' - 'a'; | |
6813 } | |
6814 } | |
6815 | |
6816 /* Open a shared library and return a handle. | |
6817 * Parameters: | |
6818 * name: Base name of the shared library. | |
6819 * handle: Pointer to a module handle, | |
6820 * will be filled in with the handle. | |
6821 */ | |
6822 int dw_module_load(char *name, HMOD *handle) | |
6823 { | |
6824 int len; | |
6825 char *newname; | |
6826 char errorbuf[1024]; | |
6827 | |
6828 | |
6829 if(!handle) | |
6830 return -1; | |
6831 | |
6832 if((len = strlen(name)) == 0) | |
6833 return -1; | |
6834 | |
6835 /* Lenth + "lib" + ".so" + NULL */ | |
6836 newname = malloc(len + 7); | |
6837 | |
6838 if(!newname) | |
6839 return -1; | |
6840 | |
6841 sprintf(newname, "lib%s.so", name); | |
6842 _my_strlwr(newname); | |
6843 | |
6844 *handle = dlopen(newname, RTLD_NOW); | |
6845 if(*handle == NULL) | |
6846 { | |
6847 strncpy(errorbuf, dlerror(), 1024); | |
6848 printf("%s\n", errorbuf); | |
6849 sprintf(newname, "lib%s.so", name); | |
6850 *handle = dlopen(newname, RTLD_NOW); | |
6851 } | |
6852 | |
6853 free(newname); | |
6854 | |
6855 return (NULL == *handle) ? -1 : 0; | |
6856 } | |
6857 | |
6858 /* Queries the address of a symbol within open handle. | |
6859 * Parameters: | |
6860 * handle: Module handle returned by dw_module_load() | |
6861 * name: Name of the symbol you want the address of. | |
6862 * func: A pointer to a function pointer, to obtain | |
6863 * the address. | |
6864 */ | |
6865 int dw_module_symbol(HMOD handle, char *name, void**func) | |
6866 { | |
6867 if(!func || !name) | |
6868 return -1; | |
6869 | |
6870 if(strlen(name) == 0) | |
6871 return -1; | |
6872 | |
6873 *func = (void*)dlsym(handle, name); | |
6874 return (NULL == *func); | |
6875 } | |
6876 | |
6877 /* Frees the shared library previously opened. | |
6878 * Parameters: | |
6879 * handle: Module handle returned by dw_module_load() | |
6880 */ | |
6881 int dw_module_close(HMOD handle) | |
6882 { | |
6883 if(handle) | |
6884 return dlclose(handle); | |
6885 return 0; | |
6886 } | |
6887 | |
6888 /* | |
6889 * Returns the handle to an unnamed mutex semaphore. | |
6890 */ | |
6891 HMTX dw_mutex_new(void) | |
6892 { | |
6893 HMTX mutex = malloc(sizeof(pthread_mutex_t)); | |
6894 | |
6895 pthread_mutex_init(mutex, NULL); | |
6896 return mutex; | |
6897 } | |
6898 | |
6899 /* | |
6900 * Closes a semaphore created by dw_mutex_new(). | |
6901 * Parameters: | |
6902 * mutex: The handle to the mutex returned by dw_mutex_new(). | |
6903 */ | |
6904 void dw_mutex_close(HMTX mutex) | |
6905 { | |
6906 if(mutex) | |
6907 { | |
6908 pthread_mutex_destroy(mutex); | |
6909 free(mutex); | |
6910 } | |
6911 } | |
6912 | |
6913 /* | |
6914 * Tries to gain access to the semaphore, if it can't it blocks. | |
6915 * Parameters: | |
6916 * mutex: The handle to the mutex returned by dw_mutex_new(). | |
6917 */ | |
6918 void dw_mutex_lock(HMTX mutex) | |
6919 { | |
6920 /* If we are being called from an event handler we must release | |
6921 * the GTK mutex so we don't deadlock. | |
6922 */ | |
6923 if(pthread_self() == _dw_thread) | |
6924 gdk_threads_leave(); | |
6925 | |
6926 pthread_mutex_lock(mutex); | |
6927 | |
6928 /* And of course relock it when we have acquired the mutext */ | |
6929 if(pthread_self() == _dw_thread) | |
6930 gdk_threads_enter(); | |
6931 } | |
6932 | |
6933 /* | |
6934 * Reliquishes the access to the semaphore. | |
6935 * Parameters: | |
6936 * mutex: The handle to the mutex returned by dw_mutex_new(). | |
6937 */ | |
6938 void dw_mutex_unlock(HMTX mutex) | |
6939 { | |
6940 pthread_mutex_unlock(mutex); | |
6941 } | |
6942 | |
6943 /* | |
6944 * Returns the handle to an unnamed event semaphore. | |
6945 */ | |
6946 HEV dw_event_new(void) | |
6947 { | |
6948 HEV eve = (HEV)malloc(sizeof(struct _dw_unix_event)); | |
6949 | |
6950 if(!eve) | |
6951 return NULL; | |
6952 | |
6953 /* We need to be careful here, mutexes on Linux are | |
6954 * FAST by default but are error checking on other | |
6955 * systems such as FreeBSD and OS/2, perhaps others. | |
6956 */ | |
6957 pthread_mutex_init (&(eve->mutex), NULL); | |
6958 pthread_mutex_lock (&(eve->mutex)); | |
6959 pthread_cond_init (&(eve->event), NULL); | |
6960 | |
6961 pthread_mutex_unlock (&(eve->mutex)); | |
6962 eve->alive = 1; | |
6963 eve->posted = 0; | |
6964 | |
6965 return eve; | |
6966 } | |
6967 | |
6968 /* | |
6969 * Resets a semaphore created by dw_event_new(). | |
6970 * Parameters: | |
6971 * eve: The handle to the event returned by dw_event_new(). | |
6972 */ | |
6973 int dw_event_reset (HEV eve) | |
6974 { | |
6975 if(!eve) | |
6976 return FALSE; | |
6977 | |
6978 pthread_mutex_lock (&(eve->mutex)); | |
6979 pthread_cond_broadcast (&(eve->event)); | |
6980 pthread_cond_init (&(eve->event), NULL); | |
6981 eve->posted = 0; | |
6982 pthread_mutex_unlock (&(eve->mutex)); | |
6983 return 0; | |
6984 } | |
6985 | |
6986 /* | |
6987 * Posts a semaphore created by dw_event_new(). Causing all threads | |
6988 * waiting on this event in dw_event_wait to continue. | |
6989 * Parameters: | |
6990 * eve: The handle to the event returned by dw_event_new(). | |
6991 */ | |
6992 int dw_event_post (HEV eve) | |
6993 { | |
6994 if(!eve) | |
6995 return FALSE; | |
6996 | |
6997 pthread_mutex_lock (&(eve->mutex)); | |
6998 pthread_cond_broadcast (&(eve->event)); | |
6999 eve->posted = 1; | |
7000 pthread_mutex_unlock (&(eve->mutex)); | |
7001 return 0; | |
7002 } | |
7003 | |
7004 /* | |
7005 * Waits on a semaphore created by dw_event_new(), until the | |
7006 * event gets posted or until the timeout expires. | |
7007 * Parameters: | |
7008 * eve: The handle to the event returned by dw_event_new(). | |
7009 */ | |
7010 int dw_event_wait(HEV eve, unsigned long timeout) | |
7011 { | |
7012 int rc; | |
7013 struct timeval now; | |
7014 struct timespec timeo; | |
7015 | |
7016 if(!eve) | |
7017 return FALSE; | |
7018 | |
7019 if(eve->posted) | |
7020 return 0; | |
7021 | |
7022 pthread_mutex_lock (&(eve->mutex)); | |
7023 gettimeofday(&now, 0); | |
7024 timeo.tv_sec = now.tv_sec + (timeout / 1000); | |
7025 timeo.tv_nsec = now.tv_usec * 1000; | |
7026 rc = pthread_cond_timedwait (&(eve->event), &(eve->mutex), &timeo); | |
7027 pthread_mutex_unlock (&(eve->mutex)); | |
7028 if(!rc) | |
7029 return 1; | |
7030 if(rc == ETIMEDOUT) | |
7031 return -1; | |
7032 return 0; | |
7033 } | |
7034 | |
7035 /* | |
7036 * Closes a semaphore created by dw_event_new(). | |
7037 * Parameters: | |
7038 * eve: The handle to the event returned by dw_event_new(). | |
7039 */ | |
7040 int dw_event_close(HEV *eve) | |
7041 { | |
7042 if(!eve || !(*eve)) | |
7043 return FALSE; | |
7044 | |
7045 pthread_mutex_lock (&((*eve)->mutex)); | |
7046 pthread_cond_destroy (&((*eve)->event)); | |
7047 pthread_mutex_unlock (&((*eve)->mutex)); | |
7048 pthread_mutex_destroy (&((*eve)->mutex)); | |
7049 free(*eve); | |
7050 *eve = NULL; | |
7051 | |
7052 return TRUE; | |
7053 } | |
7054 | |
7055 struct _seminfo { | |
7056 int fd; | |
7057 int waiting; | |
7058 }; | |
7059 | |
7060 static void _handle_sem(int *tmpsock) | |
7061 { | |
7062 fd_set rd; | |
7063 struct _seminfo *array = (struct _seminfo *)malloc(sizeof(struct _seminfo)); | |
7064 int listenfd = tmpsock[0]; | |
7065 int bytesread, connectcount = 1, maxfd, z, posted = 0; | |
7066 char command; | |
7067 sigset_t mask; | |
7068 | |
7069 sigfillset(&mask); /* Mask all allowed signals */ | |
7070 pthread_sigmask(SIG_BLOCK, &mask, NULL); | |
7071 | |
7072 /* problems */ | |
7073 if(tmpsock[1] == -1) | |
7074 { | |
7075 free(array); | |
7076 return; | |
7077 } | |
7078 | |
7079 array[0].fd = tmpsock[1]; | |
7080 array[0].waiting = 0; | |
7081 | |
7082 /* Free the memory allocated in dw_named_event_new. */ | |
7083 free(tmpsock); | |
7084 | |
7085 while(1) | |
7086 { | |
7087 FD_ZERO(&rd); | |
7088 FD_SET(listenfd, &rd); | |
7089 | |
7090 maxfd = listenfd; | |
7091 | |
7092 /* Added any connections to the named event semaphore */ | |
7093 for(z=0;z<connectcount;z++) | |
7094 { | |
7095 if(array[z].fd > maxfd) | |
7096 maxfd = array[z].fd; | |
7097 | |
7098 FD_SET(array[z].fd, &rd); | |
7099 } | |
7100 | |
7101 if(select(maxfd+1, &rd, NULL, NULL, NULL) == -1) | |
7102 return; | |
7103 | |
7104 if(FD_ISSET(listenfd, &rd)) | |
7105 { | |
7106 struct _seminfo *newarray; | |
7107 int newfd = accept(listenfd, 0, 0); | |
7108 | |
7109 if(newfd > -1) | |
7110 { | |
7111 /* Add new connections to the set */ | |
7112 newarray = (struct _seminfo *)malloc(sizeof(struct _seminfo)*(connectcount+1)); | |
7113 memcpy(newarray, array, sizeof(struct _seminfo)*(connectcount)); | |
7114 | |
7115 newarray[connectcount].fd = newfd; | |
7116 newarray[connectcount].waiting = 0; | |
7117 | |
7118 connectcount++; | |
7119 | |
7120 /* Replace old array with new one */ | |
7121 free(array); | |
7122 array = newarray; | |
7123 } | |
7124 } | |
7125 | |
7126 /* Handle any events posted to the semaphore */ | |
7127 for(z=0;z<connectcount;z++) | |
7128 { | |
7129 if(FD_ISSET(array[z].fd, &rd)) | |
7130 { | |
7131 if((bytesread = read(array[z].fd, &command, 1)) < 1) | |
7132 { | |
7133 struct _seminfo *newarray; | |
7134 | |
7135 /* Remove this connection from the set */ | |
7136 newarray = (struct _seminfo *)malloc(sizeof(struct _seminfo)*(connectcount-1)); | |
7137 if(!z) | |
7138 memcpy(newarray, &array[1], sizeof(struct _seminfo)*(connectcount-1)); | |
7139 else | |
7140 { | |
7141 memcpy(newarray, array, sizeof(struct _seminfo)*z); | |
7142 if(z!=(connectcount-1)) | |
7143 memcpy(&newarray[z], &array[z+1], sizeof(struct _seminfo)*(z-connectcount-1)); | |
7144 } | |
7145 connectcount--; | |
7146 | |
7147 /* Replace old array with new one */ | |
7148 free(array); | |
7149 array = newarray; | |
7150 } | |
7151 else if(bytesread == 1) | |
7152 { | |
7153 switch(command) | |
7154 { | |
7155 case 0: | |
7156 { | |
7157 /* Reset */ | |
7158 posted = 0; | |
7159 } | |
7160 break; | |
7161 case 1: | |
7162 /* Post */ | |
7163 { | |
7164 int s; | |
7165 char tmp = (char)0; | |
7166 | |
7167 posted = 1; | |
7168 | |
7169 for(s=0;s<connectcount;s++) | |
7170 { | |
7171 /* The semaphore has been posted so | |
7172 * we tell all the waiting threads to | |
7173 * continue. | |
7174 */ | |
7175 if(array[s].waiting) | |
7176 write(array[s].fd, &tmp, 1); | |
7177 } | |
7178 } | |
7179 break; | |
7180 case 2: | |
7181 /* Wait */ | |
7182 { | |
7183 char tmp = (char)0; | |
7184 | |
7185 array[z].waiting = 1; | |
7186 | |
7187 /* If we are posted exit immeditately */ | |
7188 if(posted) | |
7189 write(array[z].fd, &tmp, 1); | |
7190 } | |
7191 break; | |
7192 case 3: | |
7193 { | |
7194 /* Done Waiting */ | |
7195 array[z].waiting = 0; | |
7196 } | |
7197 break; | |
7198 } | |
7199 } | |
7200 } | |
7201 } | |
7202 | |
7203 } | |
7204 | |
7205 } | |
7206 | |
7207 /* Using domain sockets on unix for IPC */ | |
7208 /* Create a named event semaphore which can be | |
7209 * opened from other processes. | |
7210 * Parameters: | |
7211 * eve: Pointer to an event handle to receive handle. | |
7212 * name: Name given to semaphore which can be opened | |
7213 * by other processes. | |
7214 */ | |
7215 HEV dw_named_event_new(char *name) | |
7216 { | |
7217 struct sockaddr_un un; | |
7218 int ev, *tmpsock = (int *)malloc(sizeof(int)*2); | |
7219 DWTID dwthread; | |
7220 | |
7221 if(!tmpsock) | |
7222 return NULL; | |
7223 | |
7224 tmpsock[0] = socket(AF_UNIX, SOCK_STREAM, 0); | |
7225 ev = socket(AF_UNIX, SOCK_STREAM, 0); | |
7226 memset(&un, 0, sizeof(un)); | |
7227 un.sun_family=AF_UNIX; | |
7228 mkdir("/tmp/.dw", S_IWGRP|S_IWOTH); | |
7229 strcpy(un.sun_path, "/tmp/.dw/"); | |
7230 strcat(un.sun_path, name); | |
7231 | |
7232 /* just to be safe, this should be changed | |
7233 * to support multiple instances. | |
7234 */ | |
7235 remove(un.sun_path); | |
7236 | |
7237 bind(tmpsock[0], (struct sockaddr *)&un, sizeof(un)); | |
7238 listen(tmpsock[0], 0); | |
7239 connect(ev, (struct sockaddr *)&un, sizeof(un)); | |
7240 tmpsock[1] = accept(tmpsock[0], 0, 0); | |
7241 | |
7242 if(tmpsock[0] < 0 || tmpsock[1] < 0 || ev < 0) | |
7243 { | |
7244 if(tmpsock[0] > -1) | |
7245 close(tmpsock[0]); | |
7246 if(tmpsock[1] > -1) | |
7247 close(tmpsock[1]); | |
7248 if(ev > -1) | |
7249 close(ev); | |
7250 free(tmpsock); | |
7251 return NULL; | |
7252 } | |
7253 | |
7254 /* Create a thread to handle this event semaphore */ | |
7255 pthread_create(&dwthread, NULL, (void *)_handle_sem, (void *)tmpsock); | |
7256 return (HEV)ev; | |
7257 } | |
7258 | |
7259 /* Open an already existing named event semaphore. | |
7260 * Parameters: | |
7261 * eve: Pointer to an event handle to receive handle. | |
7262 * name: Name given to semaphore which can be opened | |
7263 * by other processes. | |
7264 */ | |
7265 HEV dw_named_event_get(char *name) | |
7266 { | |
7267 struct sockaddr_un un; | |
7268 int ev = socket(AF_UNIX, SOCK_STREAM, 0); | |
7269 if(ev < 0) | |
7270 return NULL; | |
7271 | |
7272 un.sun_family=AF_UNIX; | |
7273 mkdir("/tmp/.dw", S_IWGRP|S_IWOTH); | |
7274 strcpy(un.sun_path, "/tmp/.dw/"); | |
7275 strcat(un.sun_path, name); | |
7276 connect(ev, (struct sockaddr *)&un, sizeof(un)); | |
7277 return (HEV)ev; | |
7278 } | |
7279 | |
7280 /* Resets the event semaphore so threads who call wait | |
7281 * on this semaphore will block. | |
7282 * Parameters: | |
7283 * eve: Handle to the semaphore obtained by | |
7284 * an open or create call. | |
7285 */ | |
7286 int dw_named_event_reset(HEV eve) | |
7287 { | |
7288 /* signal reset */ | |
7289 char tmp = (char)0; | |
7290 | |
7291 if((int)eve < 0) | |
7292 return 0; | |
7293 | |
7294 if(write((int)eve, &tmp, 1) == 1) | |
7295 return 0; | |
7296 return 1; | |
7297 } | |
7298 | |
7299 /* Sets the posted state of an event semaphore, any threads | |
7300 * waiting on the semaphore will no longer block. | |
7301 * Parameters: | |
7302 * eve: Handle to the semaphore obtained by | |
7303 * an open or create call. | |
7304 */ | |
7305 int dw_named_event_post(HEV eve) | |
7306 { | |
7307 | |
7308 /* signal post */ | |
7309 char tmp = (char)1; | |
7310 | |
7311 if((int)eve < 0) | |
7312 return 0; | |
7313 | |
7314 if(write((int)eve, &tmp, 1) == 1) | |
7315 return 0; | |
7316 return 1; | |
7317 } | |
7318 | |
7319 /* Waits on the specified semaphore until it becomes | |
7320 * posted, or returns immediately if it already is posted. | |
7321 * Parameters: | |
7322 * eve: Handle to the semaphore obtained by | |
7323 * an open or create call. | |
7324 * timeout: Number of milliseconds before timing out | |
7325 * or -1 if indefinite. | |
7326 */ | |
7327 int dw_named_event_wait(HEV eve, unsigned long timeout) | |
7328 { | |
7329 fd_set rd; | |
7330 struct timeval tv, *useme; | |
7331 int retval = 0; | |
7332 char tmp; | |
7333 | |
7334 if((int)eve < 0) | |
7335 return DW_ERROR_NON_INIT; | |
7336 | |
7337 /* Set the timout or infinite */ | |
7338 if(timeout == -1) | |
7339 useme = NULL; | |
7340 else | |
7341 { | |
7342 tv.tv_sec = timeout / 1000; | |
7343 tv.tv_usec = timeout % 1000; | |
7344 | |
7345 useme = &tv; | |
7346 } | |
7347 | |
7348 FD_ZERO(&rd); | |
7349 FD_SET((int)eve, &rd); | |
7350 | |
7351 /* Signal wait */ | |
7352 tmp = (char)2; | |
7353 write((int)eve, &tmp, 1); | |
7354 | |
7355 retval = select((int)eve+1, &rd, NULL, NULL, useme); | |
7356 | |
7357 /* Signal done waiting. */ | |
7358 tmp = (char)3; | |
7359 write((int)eve, &tmp, 1); | |
7360 | |
7361 if(retval == 0) | |
7362 return DW_ERROR_TIMEOUT; | |
7363 else if(retval == -1) | |
7364 return DW_ERROR_INTERRUPT; | |
7365 | |
7366 /* Clear the entry from the pipe so | |
7367 * we don't loop endlessly. :) | |
7368 */ | |
7369 read((int)eve, &tmp, 1); | |
7370 return 0; | |
7371 } | |
7372 | |
7373 /* Release this semaphore, if there are no more open | |
7374 * handles on this semaphore the semaphore will be destroyed. | |
7375 * Parameters: | |
7376 * eve: Handle to the semaphore obtained by | |
7377 * an open or create call. | |
7378 */ | |
7379 int dw_named_event_close(HEV eve) | |
7380 { | |
7381 /* Finally close the domain socket, | |
7382 * cleanup will continue in _handle_sem. | |
7383 */ | |
7384 close((int)eve); | |
7385 return 0; | |
7386 } | |
7387 | |
7388 /* | |
7389 * Setup thread independent color sets. | |
7390 */ | |
7391 void _dwthreadstart(void *data) | |
7392 { | |
7393 void (*threadfunc)(void *) = NULL; | |
7394 void **tmp = (void **)data; | |
7395 | |
7396 threadfunc = (void (*)(void *))tmp[0]; | |
7397 | |
7398 _dw_thread_add(dw_thread_id()); | |
7399 threadfunc(tmp[1]); | |
7400 _dw_thread_remove(dw_thread_id()); | |
7401 free(tmp); | |
7402 } | |
7403 | |
7404 /* | |
7405 * Allocates a shared memory region with a name. | |
7406 * Parameters: | |
7407 * handle: A pointer to receive a SHM identifier. | |
7408 * dest: A pointer to a pointer to receive the memory address. | |
7409 * size: Size in bytes of the shared memory region to allocate. | |
7410 * name: A string pointer to a unique memory name. | |
7411 */ | |
7412 HSHM dw_named_memory_new(void **dest, int size, char *name) | |
7413 { | |
7414 char namebuf[1024]; | |
7415 struct _dw_unix_shm *handle = malloc(sizeof(struct _dw_unix_shm)); | |
7416 | |
7417 mkdir("/tmp/.dw", S_IWGRP|S_IWOTH); | |
7418 sprintf(namebuf, "/tmp/.dw/%s", name); | |
7419 | |
7420 if((handle->fd = open(namebuf, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) | |
7421 { | |
7422 free(handle); | |
7423 return NULL; | |
7424 } | |
7425 | |
7426 ftruncate(handle->fd, size); | |
7427 | |
7428 /* attach the shared memory segment to our process's address space. */ | |
7429 *dest = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd, 0); | |
7430 | |
7431 if(*dest == MAP_FAILED) | |
7432 { | |
7433 close(handle->fd); | |
7434 *dest = NULL; | |
7435 free(handle); | |
7436 return NULL; | |
7437 } | |
7438 | |
7439 handle->size = size; | |
7440 handle->sid = getsid(0); | |
7441 handle->path = strdup(namebuf); | |
7442 | |
7443 return handle; | |
7444 } | |
7445 | |
7446 /* | |
7447 * Aquires shared memory region with a name. | |
7448 * Parameters: | |
7449 * dest: A pointer to a pointer to receive the memory address. | |
7450 * size: Size in bytes of the shared memory region to requested. | |
7451 * name: A string pointer to a unique memory name. | |
7452 */ | |
7453 HSHM dw_named_memory_get(void **dest, int size, char *name) | |
7454 { | |
7455 char namebuf[1024]; | |
7456 struct _dw_unix_shm *handle = malloc(sizeof(struct _dw_unix_shm)); | |
7457 | |
7458 mkdir("/tmp/.dw", S_IWGRP|S_IWOTH); | |
7459 sprintf(namebuf, "/tmp/.dw/%s", name); | |
7460 | |
7461 if((handle->fd = open(namebuf, O_RDWR)) < 0) | |
7462 { | |
7463 free(handle); | |
7464 return NULL; | |
7465 } | |
7466 | |
7467 /* attach the shared memory segment to our process's address space. */ | |
7468 *dest = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd, 0); | |
7469 | |
7470 if(*dest == MAP_FAILED) | |
7471 { | |
7472 close(handle->fd); | |
7473 *dest = NULL; | |
7474 free(handle); | |
7475 return NULL; | |
7476 } | |
7477 | |
7478 handle->size = size; | |
7479 handle->sid = -1; | |
7480 handle->path = NULL; | |
7481 | |
7482 return handle; | |
7483 } | |
7484 | |
7485 /* | |
7486 * Frees a shared memory region previously allocated. | |
7487 * Parameters: | |
7488 * handle: Handle obtained from DB_named_memory_allocate. | |
7489 * ptr: The memory address aquired with DB_named_memory_allocate. | |
7490 */ | |
7491 int dw_named_memory_free(HSHM handle, void *ptr) | |
7492 { | |
7493 struct _dw_unix_shm *h = handle; | |
7494 int rc = munmap(ptr, h->size); | |
7495 | |
7496 close(h->fd); | |
7497 if(h->path) | |
7498 { | |
7499 /* Only remove the actual file if we are the | |
7500 * creator of the file. | |
7501 */ | |
7502 if(h->sid != -1 && h->sid == getsid(0)) | |
7503 remove(h->path); | |
7504 free(h->path); | |
7505 } | |
7506 return rc; | |
7507 } | |
7508 /* | |
7509 * Creates a new thread with a starting point of func. | |
7510 * Parameters: | |
7511 * func: Function which will be run in the new thread. | |
7512 * data: Parameter(s) passed to the function. | |
7513 * stack: Stack size of new thread (OS/2 and Windows only). | |
7514 */ | |
7515 DWTID dw_thread_new(void *func, void *data, int stack) | |
7516 { | |
7517 DWTID gtkthread; | |
7518 void **tmp = malloc(sizeof(void *) * 2); | |
7519 int rc; | |
7520 | |
7521 tmp[0] = func; | |
7522 tmp[1] = data; | |
7523 | |
7524 rc = pthread_create(>kthread, NULL, (void *)_dwthreadstart, (void *)tmp); | |
7525 if ( rc == 0 ) | |
7526 return gtkthread; | |
7527 else | |
7528 return rc; | |
7529 } | |
7530 | |
7531 /* | |
7532 * Ends execution of current thread immediately. | |
7533 */ | |
7534 void dw_thread_end(void) | |
7535 { | |
7536 pthread_exit(NULL); | |
7537 } | |
7538 | |
7539 /* | |
7540 * Returns the current thread's ID. | |
7541 */ | |
7542 DWTID dw_thread_id(void) | |
7543 { | |
7544 return (DWTID)pthread_self(); | |
7545 } | |
7546 | |
7547 /* | |
7548 * Cleanly terminates a DW session, should be signal handler safe. | |
7549 * Parameters: | |
7550 * exitcode: Exit code reported to the operating system. | |
7551 */ | |
7552 void dw_exit(int exitcode) | |
7553 { | |
7554 if ( dbgfp != NULL ) | |
7555 { | |
7556 fclose( dbgfp ); | |
7557 } | |
7558 exit(exitcode); | |
7559 } | |
7560 | |
7561 #define DW_EXPAND (GTK_EXPAND | GTK_SHRINK | GTK_FILL) | |
7562 | |
7563 /* | |
7564 * Pack windows (widgets) into a box from the end (or bottom). | |
7565 * Parameters: | |
7566 * box: Window handle of the box to be packed into. | |
7567 * item: Window handle of the item to be back. | |
7568 * width: Width in pixels of the item or -1 to be self determined. | |
7569 * height: Height in pixels of the item or -1 to be self determined. | |
7570 * hsize: TRUE if the window (widget) should expand horizontally to fill space given. | |
7571 * vsize: TRUE if the window (widget) should expand vertically to fill space given. | |
7572 * pad: Number of pixels of padding around the item. | |
7573 */ | |
7574 void dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) | |
7575 { | |
7576 int warn = FALSE, _locked_by_me = FALSE; | |
7577 GtkWidget *tmp, *tmpitem; | |
7578 | |
7579 if(!box) | |
7580 return; | |
7581 | |
7582 /* | |
7583 * If you try and pack an item into itself VERY bad things can happen; like at least an | |
7584 * infinite loop on GTK! Lets be safe! | |
7585 */ | |
7586 if(box == item) | |
7587 { | |
7588 dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); | |
7589 return; | |
7590 } | |
7591 | |
7592 DW_MUTEX_LOCK; | |
7593 | |
7594 if((tmp = g_object_get_data(G_OBJECT(box), "_dw_boxhandle"))) | |
7595 box = tmp; | |
7596 | |
7597 if(!item) | |
7598 { | |
7599 item = gtk_label_new(""); | |
7600 gtk_widget_show_all(item); | |
7601 } | |
7602 | |
7603 tmpitem = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_boxhandle"); | |
7604 | |
7605 if(GTK_IS_TABLE(box)) | |
7606 { | |
7607 int boxcount = (int)g_object_get_data(G_OBJECT(box), "_dw_boxcount"); | |
7608 int boxtype = (int)g_object_get_data(G_OBJECT(box), "_dw_boxtype"); | |
7609 | |
7610 /* If the item being packed is a box, then we use it's padding | |
7611 * instead of the padding specified on the pack line, this is | |
7612 * due to a bug in the OS/2 and Win32 renderer and a limitation | |
7613 * of the GtkTable class. | |
7614 */ | |
7615 if(GTK_IS_TABLE(item) || (tmpitem && GTK_IS_TABLE(tmpitem))) | |
7616 { | |
7617 GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_eventbox"); | |
7618 | |
7619 /* NOTE: I left in the ability to pack boxes with a size, | |
7620 * this eliminates that by forcing the size to 0. | |
7621 */ | |
7622 height = width = 0; | |
7623 | |
7624 if(eventbox) | |
7625 { | |
7626 int boxpad = (int)g_object_get_data(G_OBJECT(item), "_dw_boxpad"); | |
7627 gtk_container_add(GTK_CONTAINER(eventbox), item); | |
7628 gtk_container_set_border_width(GTK_CONTAINER(eventbox), boxpad); | |
7629 item = eventbox; | |
7630 } | |
7631 } | |
7632 else | |
7633 { | |
7634 /* Only show warning if item is not a box */ | |
7635 warn = TRUE; | |
7636 } | |
7637 | |
7638 if(boxtype == DW_VERT) | |
7639 gtk_table_resize(GTK_TABLE(box), boxcount + 1, 1); | |
7640 else | |
7641 gtk_table_resize(GTK_TABLE(box), 1, boxcount + 1); | |
7642 | |
7643 gtk_table_attach(GTK_TABLE(box), item, 0, 1, 0, 1, hsize ? DW_EXPAND : 0, vsize ? DW_EXPAND : 0, pad, pad); | |
7644 g_object_set_data(G_OBJECT(box), "_dw_boxcount", GINT_TO_POINTER(boxcount + 1)); | |
7645 gtk_widget_set_size_request(item, width, height); | |
7646 if(GTK_IS_RADIO_BUTTON(item)) | |
7647 { | |
7648 GSList *group; | |
7649 GtkWidget *groupstart = (GtkWidget *)g_object_get_data(G_OBJECT(box), "_dw_group"); | |
7650 | |
7651 if(groupstart) | |
7652 { | |
7653 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(groupstart)); | |
7654 gtk_radio_button_set_group(GTK_RADIO_BUTTON(item), group); | |
7655 } | |
7656 else | |
7657 g_object_set_data(G_OBJECT(box), "_dw_group", (gpointer)item); | |
7658 } | |
7659 } | |
7660 else | |
7661 { | |
7662 GtkWidget *vbox = gtk_vbox_new(FALSE, 0); | |
7663 | |
7664 if(GTK_IS_TABLE(item) || (tmpitem && GTK_IS_TABLE(tmpitem))) | |
7665 { | |
7666 GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_eventbox"); | |
7667 | |
7668 /* NOTE: I left in the ability to pack boxes with a size, | |
7669 * this eliminates that by forcing the size to 0. | |
7670 */ | |
7671 height = width = 0; | |
7672 | |
7673 if(eventbox) | |
7674 { | |
7675 int boxpad = (int)g_object_get_data(G_OBJECT(item), "_dw_boxpad"); | |
7676 gtk_container_add(GTK_CONTAINER(eventbox), item); | |
7677 gtk_container_set_border_width(GTK_CONTAINER(eventbox), boxpad); | |
7678 item = eventbox; | |
7679 } | |
7680 } | |
7681 else | |
7682 { | |
7683 /* Only show warning if item is not a box */ | |
7684 warn = TRUE; | |
7685 } | |
7686 | |
7687 gtk_container_set_border_width(GTK_CONTAINER(box), pad); | |
7688 gtk_container_add(GTK_CONTAINER(box), vbox); | |
7689 gtk_box_pack_end(GTK_BOX(vbox), item, TRUE, TRUE, 0); | |
7690 gtk_widget_show(vbox); | |
7691 | |
7692 gtk_widget_set_size_request(item, width, height); | |
7693 g_object_set_data(G_OBJECT(box), "_dw_user", vbox); | |
7694 } | |
7695 DW_MUTEX_UNLOCK; | |
7696 | |
7697 if(warn) | |
7698 { | |
7699 if ( width == 0 && hsize == FALSE ) | |
7700 dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); | |
7701 if ( height == 0 && vsize == FALSE ) | |
7702 dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); | |
7703 } | |
7704 } | |
7705 | |
7706 #ifdef GDK_WINDOWING_X11 | |
7707 static void _size_allocate(GtkWindow *window) | |
7708 { | |
7709 XSizeHints sizehints; | |
7710 | |
7711 sizehints.base_width = 1; | |
7712 sizehints.base_height = 1; | |
7713 sizehints.width_inc = 1; | |
7714 sizehints.height_inc = 1; | |
7715 sizehints.min_width = 8; | |
7716 sizehints.min_height = 8; | |
7717 | |
7718 sizehints.flags = (PBaseSize|PMinSize|PResizeInc); | |
7719 | |
7720 XSetWMNormalHints (gdk_x11_display_get_xdisplay(gdk_display_get_default()), | |
7721 GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(window))),&sizehints); | |
7722 gdk_flush (); | |
7723 } | |
7724 #endif | |
7725 | |
7726 /* | |
7727 * Sets the size of a given window (widget). | |
7728 * Parameters: | |
7729 * handle: Window (widget) handle. | |
7730 * width: New width in pixels. | |
7731 * height: New height in pixels. | |
7732 */ | |
7733 void dw_window_set_size(HWND handle, unsigned long width, unsigned long height) | |
7734 { | |
7735 int _locked_by_me = FALSE; | |
7736 long default_width = width - _dw_border_width; | |
7737 long default_height = height - _dw_border_height; | |
7738 | |
7739 if(!handle) | |
7740 return; | |
7741 | |
7742 DW_MUTEX_LOCK; | |
7743 if(GTK_IS_WINDOW(handle)) | |
7744 { | |
7745 if ( width == 0 ) | |
7746 default_width = -1; | |
7747 if ( height == 0 ) | |
7748 default_height = -1; | |
7749 | |
7750 #ifdef GDK_WINDOWING_X11 | |
7751 _size_allocate(GTK_WINDOW(handle)); | |
7752 #endif | |
7753 | |
7754 if(gtk_widget_get_window(handle) && default_width > 0 && default_height > 0) | |
7755 gdk_window_resize(gtk_widget_get_window(handle), default_width , default_height ); | |
7756 | |
7757 gtk_window_set_default_size(GTK_WINDOW(handle), default_width , default_height ); | |
7758 if(!g_object_get_data(G_OBJECT(handle), "_dw_size")) | |
7759 { | |
7760 g_object_set_data(G_OBJECT(handle), "_dw_width", GINT_TO_POINTER(default_width) ); | |
7761 g_object_set_data(G_OBJECT(handle), "_dw_height", GINT_TO_POINTER(default_height) ); | |
7762 } | |
7763 } | |
7764 else | |
7765 gtk_widget_set_size_request(handle, width, height); | |
7766 DW_MUTEX_UNLOCK; | |
7767 } | |
7768 | |
7769 /* | |
7770 * Returns the width of the screen. | |
7771 */ | |
7772 int dw_screen_width(void) | |
7773 { | |
7774 int retval; | |
7775 int _locked_by_me = FALSE; | |
7776 | |
7777 DW_MUTEX_LOCK; | |
7778 retval = gdk_screen_width(); | |
7779 DW_MUTEX_UNLOCK; | |
7780 return retval; | |
7781 } | |
7782 | |
7783 /* | |
7784 * Returns the height of the screen. | |
7785 */ | |
7786 int dw_screen_height(void) | |
7787 { | |
7788 int retval; | |
7789 int _locked_by_me = FALSE; | |
7790 | |
7791 DW_MUTEX_UNLOCK; | |
7792 retval = gdk_screen_height(); | |
7793 DW_MUTEX_UNLOCK; | |
7794 return retval; | |
7795 } | |
7796 | |
7797 /* This should return the current color depth */ | |
7798 unsigned long dw_color_depth_get(void) | |
7799 { | |
7800 int retval; | |
7801 GdkVisual *vis; | |
7802 int _locked_by_me = FALSE; | |
7803 | |
7804 DW_MUTEX_UNLOCK; | |
7805 vis = gdk_visual_get_system(); | |
7806 retval = gdk_visual_get_depth(vis); | |
7807 DW_MUTEX_UNLOCK; | |
7808 return retval; | |
7809 } | |
7810 | |
7811 /* | |
7812 * Sets the position of a given window (widget). | |
7813 * Parameters: | |
7814 * handle: Window (widget) handle. | |
7815 * x: X location from the bottom left. | |
7816 * y: Y location from the bottom left. | |
7817 */ | |
7818 void dw_window_set_pos(HWND handle, long x, long y) | |
7819 { | |
7820 int _locked_by_me = FALSE; | |
7821 GtkWidget *mdi; | |
7822 | |
7823 DW_MUTEX_LOCK; | |
7824 if((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi)) | |
7825 { | |
7826 gtk_mdi_move(GTK_MDI(mdi), handle, x, y); | |
7827 } | |
7828 else | |
7829 { | |
7830 if(handle && gtk_widget_get_window(handle)) | |
7831 gdk_window_move(gtk_widget_get_window(handle), x, y); | |
7832 } | |
7833 DW_MUTEX_UNLOCK; | |
7834 } | |
7835 | |
7836 /* | |
7837 * Sets the position and size of a given window (widget). | |
7838 * Parameters: | |
7839 * handle: Window (widget) handle. | |
7840 * x: X location from the bottom left. | |
7841 * y: Y location from the bottom left. | |
7842 * width: Width of the widget. | |
7843 * height: Height of the widget. | |
7844 */ | |
7845 void dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height) | |
7846 { | |
7847 int _locked_by_me = FALSE; | |
7848 GtkWidget *mdi; | |
7849 | |
7850 if(!handle) | |
7851 return; | |
7852 DW_MUTEX_LOCK; | |
7853 if((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi)) | |
7854 { | |
7855 gtk_mdi_move(GTK_MDI(mdi), handle, x, y); | |
7856 } | |
7857 else | |
7858 { | |
7859 if(GTK_IS_WINDOW(handle)) | |
7860 { | |
7861 dw_window_set_size(handle, width, height); | |
7862 #if 0 /* TODO: Deprecated with no replaced... what to do here? */ | |
7863 gtk_widget_set_uposition(handle, x, y); | |
7864 #endif | |
7865 } | |
7866 else if(gtk_widget_get_window(handle)) | |
7867 { | |
7868 gdk_window_resize(gtk_widget_get_window(handle), width, height); | |
7869 gdk_window_move(gtk_widget_get_window(handle), x, y); | |
7870 } | |
7871 } | |
7872 DW_MUTEX_UNLOCK; | |
7873 } | |
7874 | |
7875 /* | |
7876 * Gets the position and size of a given window (widget). | |
7877 * Parameters: | |
7878 * handle: Window (widget) handle. | |
7879 * x: X location from the bottom left. | |
7880 * y: Y location from the bottom left. | |
7881 * width: Width of the widget. | |
7882 * height: Height of the widget. | |
7883 */ | |
7884 void dw_window_get_pos_size(HWND handle, long *x, long *y, ULONG *width, ULONG *height) | |
7885 { | |
7886 int _locked_by_me = FALSE; | |
7887 gint gx, gy, gwidth, gheight; | |
7888 GtkWidget *mdi; | |
7889 | |
7890 DW_MUTEX_LOCK; | |
7891 if((mdi = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_mdi")) && GTK_IS_MDI(mdi)) | |
7892 { | |
7893 gint myx=0, myy=0; | |
7894 | |
7895 gtk_mdi_get_pos(GTK_MDI(mdi), handle, &myx, &myy); | |
7896 *x = myx; | |
7897 *y = myy; | |
7898 } | |
7899 else | |
7900 { | |
7901 if(handle && gtk_widget_get_window(handle)) | |
7902 { | |
7903 | |
7904 gdk_window_get_geometry(gtk_widget_get_window(handle), &gx, &gy, &gwidth, &gheight); | |
7905 gdk_window_get_root_origin(gtk_widget_get_window(handle), &gx, &gy); | |
7906 if(x) | |
7907 *x = gx; | |
7908 if(y) | |
7909 *y = gy; | |
7910 if(GTK_IS_WINDOW(handle)) | |
7911 { | |
7912 if(width) | |
7913 *width = gwidth + _dw_border_width; | |
7914 if(height) | |
7915 *height = gheight + _dw_border_height; | |
7916 } | |
7917 else | |
7918 { | |
7919 if(width) | |
7920 *width = gwidth; | |
7921 if(height) | |
7922 *height = gheight; | |
7923 } | |
7924 } | |
7925 } | |
7926 DW_MUTEX_UNLOCK; | |
7927 } | |
7928 | |
7929 /* | |
7930 * Sets the style of a given window (widget). | |
7931 * Parameters: | |
7932 * handle: Window (widget) handle. | |
7933 * width: New width in pixels. | |
7934 * height: New height in pixels. | |
7935 */ | |
7936 void dw_window_set_style(HWND handle, unsigned long style, unsigned long mask) | |
7937 { | |
7938 GtkWidget *handle2 = handle; | |
7939 int _locked_by_me = FALSE; | |
7940 | |
7941 DW_MUTEX_LOCK; | |
7942 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
7943 { | |
7944 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
7945 if(tmp) | |
7946 handle2 = tmp; | |
7947 } | |
7948 else if(GTK_IS_FRAME(handle)) | |
7949 { | |
7950 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_label"); | |
7951 if(tmp && GTK_IS_LABEL(tmp)) | |
7952 handle2 = tmp; | |
7953 } | |
7954 else if(GTK_IS_BUTTON(handle)) | |
7955 { | |
7956 if(mask & DW_BS_NOBORDER) | |
7957 { | |
7958 if(style & DW_BS_NOBORDER) | |
7959 { | |
7960 gtk_button_set_relief((GtkButton *)handle, GTK_RELIEF_NONE); | |
7961 } | |
7962 else | |
7963 { | |
7964 gtk_button_set_relief((GtkButton *)handle, GTK_RELIEF_NORMAL); | |
7965 } | |
7966 } | |
7967 } | |
7968 if ( GTK_IS_LABEL(handle2) ) | |
7969 { | |
7970 gfloat x=DW_LEFT, y=DW_CENTER; | |
7971 /* horizontal... */ | |
7972 if ( style & DW_DT_CENTER ) | |
7973 x = DW_CENTER; | |
7974 if ( style & DW_DT_RIGHT ) | |
7975 x = DW_RIGHT; | |
7976 if ( style & DW_DT_LEFT ) | |
7977 x = DW_LEFT; | |
7978 /* vertical... */ | |
7979 if ( style & DW_DT_VCENTER ) | |
7980 y = DW_CENTER; | |
7981 if ( style & DW_DT_TOP ) | |
7982 y = DW_TOP; | |
7983 if ( style & DW_DT_BOTTOM ) | |
7984 y = DW_BOTTOM; | |
7985 gtk_misc_set_alignment( GTK_MISC(handle2), x, y ); | |
7986 if ( style & DW_DT_WORDBREAK ) | |
7987 gtk_label_set_line_wrap( GTK_LABEL(handle), TRUE ); | |
7988 } | |
7989 DW_MUTEX_UNLOCK; | |
7990 } | |
7991 | |
7992 /* | |
7993 * Adds a new page to specified notebook. | |
7994 * Parameters: | |
7995 * handle: Window (widget) handle. | |
7996 * flags: Any additional page creation flags. | |
7997 * front: If TRUE page is added at the beginning. | |
7998 */ | |
7999 unsigned long dw_notebook_page_new(HWND handle, unsigned long flags, int front) | |
8000 { | |
8001 int z; | |
8002 int _locked_by_me = FALSE; | |
8003 GtkWidget **pagearray; | |
8004 | |
8005 DW_MUTEX_LOCK; | |
8006 pagearray = (GtkWidget **)g_object_get_data(G_OBJECT(handle), "_dw_pagearray"); | |
8007 | |
8008 if(pagearray) | |
8009 { | |
8010 for(z=0;z<256;z++) | |
8011 { | |
8012 if(!pagearray[z]) | |
8013 { | |
8014 char text[100]; | |
8015 int num = z; | |
8016 | |
8017 if(front) | |
8018 num |= 1 << 16; | |
8019 | |
8020 sprintf(text, "_dw_page%d", z); | |
8021 /* Save the real id and the creation flags */ | |
8022 g_object_set_data(G_OBJECT(handle), text, GINT_TO_POINTER(num)); | |
8023 DW_MUTEX_UNLOCK; | |
8024 return z; | |
8025 } | |
8026 } | |
8027 } | |
8028 DW_MUTEX_UNLOCK; | |
8029 | |
8030 /* Hopefully this won't happen. */ | |
8031 return 256; | |
8032 } | |
8033 | |
8034 /* Return the physical page id from the logical page id */ | |
8035 int _get_physical_page(HWND handle, unsigned long pageid) | |
8036 { | |
8037 int z; | |
8038 GtkWidget *thispage, **pagearray = g_object_get_data(G_OBJECT(handle), "_dw_pagearray"); | |
8039 | |
8040 if(pagearray) | |
8041 { | |
8042 for(z=0;z<256;z++) | |
8043 { | |
8044 if((thispage = gtk_notebook_get_nth_page(GTK_NOTEBOOK(handle), z))) | |
8045 { | |
8046 if(thispage == pagearray[pageid]) | |
8047 return z; | |
8048 } | |
8049 } | |
8050 } | |
8051 return 256; | |
8052 } | |
8053 | |
8054 /* | |
8055 * Remove a page from a notebook. | |
8056 * Parameters: | |
8057 * handle: Handle to the notebook widget. | |
8058 * pageid: ID of the page to be destroyed. | |
8059 */ | |
8060 void dw_notebook_page_destroy(HWND handle, unsigned int pageid) | |
8061 { | |
8062 int realpage, _locked_by_me = FALSE; | |
8063 GtkWidget **pagearray; | |
8064 | |
8065 DW_MUTEX_LOCK; | |
8066 realpage = _get_physical_page(handle, pageid); | |
8067 if(realpage > -1 && realpage < 256) | |
8068 { | |
8069 gtk_notebook_remove_page(GTK_NOTEBOOK(handle), realpage); | |
8070 if((pagearray = g_object_get_data(G_OBJECT(handle), "_dw_pagearray"))) | |
8071 pagearray[pageid] = NULL; | |
8072 } | |
8073 DW_MUTEX_UNLOCK; | |
8074 } | |
8075 | |
8076 /* | |
8077 * Queries the currently visible page ID. | |
8078 * Parameters: | |
8079 * handle: Handle to the notebook widget. | |
8080 */ | |
8081 unsigned long dw_notebook_page_get(HWND handle) | |
8082 { | |
8083 int retval, phys; | |
8084 int _locked_by_me = FALSE; | |
8085 | |
8086 DW_MUTEX_LOCK; | |
8087 phys = gtk_notebook_get_current_page(GTK_NOTEBOOK(handle)); | |
8088 retval = _get_logical_page(handle, phys); | |
8089 DW_MUTEX_UNLOCK; | |
8090 return retval; | |
8091 } | |
8092 | |
8093 /* | |
8094 * Sets the currently visibale page ID. | |
8095 * Parameters: | |
8096 * handle: Handle to the notebook widget. | |
8097 * pageid: ID of the page to be made visible. | |
8098 */ | |
8099 void dw_notebook_page_set(HWND handle, unsigned int pageid) | |
8100 { | |
8101 int realpage, _locked_by_me = FALSE; | |
8102 | |
8103 DW_MUTEX_LOCK; | |
8104 realpage = _get_physical_page(handle, pageid); | |
8105 if(realpage > -1 && realpage < 256) | |
8106 gtk_notebook_set_current_page(GTK_NOTEBOOK(handle), pageid); | |
8107 DW_MUTEX_UNLOCK; | |
8108 } | |
8109 | |
8110 | |
8111 /* | |
8112 * Sets the text on the specified notebook tab. | |
8113 * Parameters: | |
8114 * handle: Notebook handle. | |
8115 * pageid: Page ID of the tab to set. | |
8116 * text: Pointer to the text to set. | |
8117 */ | |
8118 void dw_notebook_page_set_text(HWND handle, unsigned long pageid, char *text) | |
8119 { | |
8120 GtkWidget *child; | |
8121 int realpage, _locked_by_me = FALSE; | |
8122 | |
8123 DW_MUTEX_LOCK; | |
8124 realpage = _get_physical_page(handle, pageid); | |
8125 if(realpage < 0 || realpage > 255) | |
8126 { | |
8127 char ptext[100]; | |
8128 int num; | |
8129 | |
8130 sprintf(ptext, "_dw_page%d", (int)pageid); | |
8131 num = (int)g_object_get_data(G_OBJECT(handle), ptext); | |
8132 realpage = 0xFF & num; | |
8133 } | |
8134 | |
8135 if(realpage > -1 && realpage < 256) | |
8136 { | |
8137 child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(handle), realpage); | |
8138 if(child) | |
8139 gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(handle), child, text); | |
8140 } | |
8141 DW_MUTEX_UNLOCK; | |
8142 } | |
8143 | |
8144 /* | |
8145 * Sets the text on the specified notebook tab status area. | |
8146 * Parameters: | |
8147 * handle: Notebook handle. | |
8148 * pageid: Page ID of the tab to set. | |
8149 * text: Pointer to the text to set. | |
8150 */ | |
8151 void dw_notebook_page_set_status_text(HWND handle, unsigned long pageid, char *text) | |
8152 { | |
8153 /* TODO (if possible) */ | |
8154 } | |
8155 | |
8156 /* | |
8157 * Packs the specified box into the notebook page. | |
8158 * Parameters: | |
8159 * handle: Handle to the notebook to be packed. | |
8160 * pageid: Page ID in the notebook which is being packed. | |
8161 * page: Box handle to be packed. | |
8162 */ | |
8163 void dw_notebook_pack(HWND handle, unsigned long pageid, HWND page) | |
8164 { | |
8165 GtkWidget *label, *child, *oldlabel, **pagearray; | |
8166 gchar *text = NULL; | |
8167 int num, z, realpage = -1, pad, _locked_by_me = FALSE; | |
8168 char ptext[100]; | |
8169 | |
8170 DW_MUTEX_LOCK; | |
8171 sprintf(ptext, "_dw_page%d", (int)pageid); | |
8172 num = (int)g_object_get_data(G_OBJECT(handle), ptext); | |
8173 g_object_set_data(G_OBJECT(handle), ptext, NULL); | |
8174 pagearray = (GtkWidget **)g_object_get_data(G_OBJECT(handle), "_dw_pagearray"); | |
8175 | |
8176 if(!pagearray) | |
8177 { | |
8178 DW_MUTEX_UNLOCK; | |
8179 return; | |
8180 } | |
8181 | |
8182 /* The page already exists... so get it's current page */ | |
8183 if(pagearray[pageid]) | |
8184 { | |
8185 for(z=0;z<256;z++) | |
8186 { | |
8187 child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(handle), z); | |
8188 if(child == pagearray[pageid]) | |
8189 { | |
8190 oldlabel = gtk_notebook_get_tab_label(GTK_NOTEBOOK(handle), child); | |
8191 #if 0 /* TODO: gtk_label_get is deprecated with no replacement */ | |
8192 if(oldlabel) | |
8193 gtk_label_get(GTK_LABEL(oldlabel), &text); | |
8194 #endif | |
8195 gtk_notebook_remove_page(GTK_NOTEBOOK(handle), z); | |
8196 realpage = z; | |
8197 break; | |
8198 } | |
8199 } | |
8200 } | |
8201 | |
8202 pagearray[pageid] = page; | |
8203 | |
8204 label = gtk_label_new(text ? text : ""); | |
8205 | |
8206 if(GTK_IS_TABLE(page)) | |
8207 { | |
8208 pad = (int)g_object_get_data(G_OBJECT(page), "_dw_boxpad"); | |
8209 gtk_container_set_border_width(GTK_CONTAINER(page), pad); | |
8210 } | |
8211 | |
8212 if(realpage != -1) | |
8213 gtk_notebook_insert_page(GTK_NOTEBOOK(handle), page, label, realpage); | |
8214 else if(num & ~(0xFF)) | |
8215 gtk_notebook_insert_page(GTK_NOTEBOOK(handle), page, label, 0); | |
8216 else | |
8217 gtk_notebook_insert_page(GTK_NOTEBOOK(handle), page, label, 256); | |
8218 DW_MUTEX_UNLOCK; | |
8219 } | |
8220 | |
8221 /* | |
8222 * Appends the specified text to the listbox's (or combobox) entry list. | |
8223 * Parameters: | |
8224 * handle: Handle to the listbox to be appended to. | |
8225 * text: Text to append into listbox. | |
8226 */ | |
8227 void dw_listbox_append(HWND handle, char *text) | |
8228 { | |
8229 GtkWidget *handle2 = handle; | |
8230 int _locked_by_me = FALSE; | |
8231 | |
8232 DW_MUTEX_LOCK; | |
8233 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8234 { | |
8235 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8236 if(tmp) | |
8237 handle2 = tmp; | |
8238 } | |
8239 #if 0 | |
8240 g_object_set_data(G_OBJECT(handle), "_dw_appending", GINT_TO_POINTER(1)); | |
8241 if(GTK_IS_LIST(handle2)) | |
8242 { | |
8243 GtkWidget *list_item; | |
8244 GList *tmp; | |
8245 char *font = (char *)g_object_get_data(G_OBJECT(handle), "_dw_font"); | |
8246 GdkColor *fore = (GdkColor *)g_object_get_data(G_OBJECT(handle2), "_dw_foregdk"); | |
8247 GdkColor *back = (GdkColor *)g_object_get_data(G_OBJECT(handle2), "_dw_backgdk"); | |
8248 | |
8249 list_item=gtk_list_item_new_with_label(text); | |
8250 | |
8251 if(font) | |
8252 _set_font(GTK_LIST_ITEM(list_item)->item.bin.child, font); | |
8253 if(fore && back) | |
8254 _set_color(GTK_LIST_ITEM(list_item)->item.bin.child, | |
8255 DW_RGB(fore->red, fore->green, fore->blue), | |
8256 DW_RGB(back->red, back->green, back->blue)); | |
8257 | |
8258 tmp = g_list_append(NULL, list_item); | |
8259 gtk_widget_show(list_item); | |
8260 gtk_list_append_items(GTK_LIST(handle2),tmp); | |
8261 } | |
8262 else if(GTK_IS_COMBO_BOX(handle2)) | |
8263 { | |
8264 GList *tmp = (GList *)gtk_object_get_user_data(GTK_OBJECT(handle2)); | |
8265 char *addtext = strdup(text); | |
8266 | |
8267 if(addtext) | |
8268 { | |
8269 char *defstr = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO_BOX(handle2)->entry)); | |
8270 tmp = g_list_append(tmp, addtext); | |
8271 g_object_set_data(G_OBJECT(handle2), "_dw_user", tmp); | |
8272 gtk_combo_set_popdown_strings(GTK_COMBO_BOX(handle2), tmp); | |
8273 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO_BOX(handle2)->entry), defstr); | |
8274 } | |
8275 } | |
8276 g_object_set_data(G_OBJECT(handle), "_dw_appending", NULL); | |
8277 #endif | |
8278 DW_MUTEX_UNLOCK; | |
8279 } | |
8280 | |
8281 /* | |
8282 * Inserts the specified text int the listbox's (or combobox) entry list at the | |
8283 * position indicated. | |
8284 * Parameters: | |
8285 * handle: Handle to the listbox to be appended to. | |
8286 * text: Text to insert into listbox. | |
8287 * pos: 0-based index into listbox. -1 will append | |
8288 */ | |
8289 void dw_listbox_insert(HWND handle, char *text, int pos) | |
8290 { | |
8291 GtkWidget *handle2 = handle; | |
8292 int _locked_by_me = FALSE; | |
8293 | |
8294 DW_MUTEX_LOCK; | |
8295 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8296 { | |
8297 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8298 if(tmp) | |
8299 handle2 = tmp; | |
8300 } | |
8301 #if 0 | |
8302 g_object_set_data(G_OBJECT(handle), "_dw_appending", GINT_TO_POINTER(1)); | |
8303 if(GTK_IS_LIST(handle2)) | |
8304 { | |
8305 GtkWidget *list_item; | |
8306 GList *tmp; | |
8307 char *font = (char *)g_object_get_data(G_OBJECT(handle), "_dw_font"); | |
8308 GdkColor *fore = (GdkColor *)g_object_get_data(G_OBJECT(handle2), "_dw_foregdk"); | |
8309 GdkColor *back = (GdkColor *)g_object_get_data(G_OBJECT(handle2), "_dw_backgdk"); | |
8310 | |
8311 list_item=gtk_list_item_new_with_label(text); | |
8312 | |
8313 if(font) | |
8314 _set_font(GTK_LIST_ITEM(list_item)->item.bin.child, font); | |
8315 if(fore && back) | |
8316 _set_color(GTK_LIST_ITEM(list_item)->item.bin.child, | |
8317 DW_RGB(fore->red, fore->green, fore->blue), | |
8318 DW_RGB(back->red, back->green, back->blue)); | |
8319 | |
8320 tmp = g_list_insert(NULL, list_item, pos); | |
8321 gtk_widget_show(list_item); | |
8322 gtk_list_append_items(GTK_LIST(handle2),tmp); | |
8323 } | |
8324 else if(GTK_IS_COMBO_BOX(handle2)) | |
8325 { | |
8326 GList *tmp = (GList *)gtk_object_get_user_data(GTK_OBJECT(handle2)); | |
8327 char *addtext = strdup(text); | |
8328 | |
8329 if(addtext) | |
8330 { | |
8331 tmp = g_list_insert(tmp, addtext, pos); | |
8332 g_object_set_data(GTK_OBJECT(handle2), "_dw_user", tmp); | |
8333 gtk_combo_set_popdown_strings(GTK_COMBO_BOX(handle2), tmp); | |
8334 } | |
8335 } | |
8336 g_object_set_data(G_OBJECT(handle), "_dw_appending", NULL); | |
8337 #endif | |
8338 DW_MUTEX_UNLOCK; | |
8339 } | |
8340 | |
8341 /* | |
8342 * Appends the specified text items to the listbox's (or combobox) entry list. | |
8343 * Parameters: | |
8344 * handle: Handle to the listbox to be appended to. | |
8345 * text: Text strings to append into listbox. | |
8346 * count: Number of text strings to append | |
8347 */ | |
8348 void dw_listbox_list_append(HWND handle, char **text, int count) | |
8349 { | |
8350 GtkWidget *handle2 = handle; | |
8351 int _locked_by_me = FALSE; | |
8352 | |
8353 if ( count == 0 ) | |
8354 return; | |
8355 | |
8356 DW_MUTEX_LOCK; | |
8357 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8358 { | |
8359 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8360 if(tmp) | |
8361 handle2 = tmp; | |
8362 } | |
8363 #if 0 | |
8364 g_object_set_data(G_OBJECT(handle), "_dw_appending", GINT_TO_POINTER(1)); | |
8365 if(GTK_IS_LIST(handle2)) | |
8366 { | |
8367 GtkWidget *list_item; | |
8368 GList *tmp; | |
8369 char *font = (char *)g_object_get_data(G_OBJECT(handle), "_dw_font"); | |
8370 GdkColor *fore = (GdkColor *)g_object_get_data(G_OBJECT(handle2), "_dw_foregdk"); | |
8371 GdkColor *back = (GdkColor *)g_object_get_data(G_OBJECT(handle2), "_dw_backgdk"); | |
8372 | |
8373 list_item=gtk_list_item_new_with_label(*text); | |
8374 | |
8375 if(font) | |
8376 _set_font(GTK_LIST_ITEM(list_item)->item.bin.child, font); | |
8377 if(fore && back) | |
8378 _set_color(GTK_LIST_ITEM(list_item)->item.bin.child, | |
8379 DW_RGB(fore->red, fore->green, fore->blue), | |
8380 DW_RGB(back->red, back->green, back->blue)); | |
8381 | |
8382 tmp = g_list_append(NULL, list_item); | |
8383 gtk_widget_show(list_item); | |
8384 gtk_list_append_items(GTK_LIST(handle2),tmp); | |
8385 } | |
8386 else if(GTK_IS_COMBO_BOX(handle2)) | |
8387 { | |
8388 GList *tmp = (GList *)gtk_object_get_user_data(GTK_OBJECT(handle2)); | |
8389 char *addtext; | |
8390 int i; | |
8391 | |
8392 for (i=0;i<count;i++) | |
8393 { | |
8394 addtext = strdup(text[i]); | |
8395 tmp = g_list_append(tmp, addtext); | |
8396 } | |
8397 g_object_set_data(GTK_OBJECT(handle2), "_dw_user", tmp); | |
8398 gtk_combo_set_popdown_strings(GTK_COMBO_BOX(handle2), tmp); | |
8399 } | |
8400 g_object_set_data(G_OBJECT(handle), "_dw_appending", NULL); | |
8401 #endif | |
8402 DW_MUTEX_UNLOCK; | |
8403 } | |
8404 | |
8405 /* | |
8406 * Clears the listbox's (or combobox) list of all entries. | |
8407 * Parameters: | |
8408 * handle: Handle to the listbox to be cleared. | |
8409 */ | |
8410 void dw_listbox_clear(HWND handle) | |
8411 { | |
8412 GtkWidget *handle2 = handle; | |
8413 int _locked_by_me = FALSE; | |
8414 | |
8415 DW_MUTEX_LOCK; | |
8416 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8417 { | |
8418 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8419 if(tmp) | |
8420 handle2 = tmp; | |
8421 } | |
8422 #if 0 | |
8423 if(GTK_IS_COMBO_BOX(handle2)) | |
8424 { | |
8425 GList *list, *tmp = (GList *)g_object_get_data(G_OBJECT(handle2)); | |
8426 | |
8427 if(tmp) | |
8428 { | |
8429 list = tmp; | |
8430 while(list) | |
8431 { | |
8432 if(list->data) | |
8433 free(list->data); | |
8434 list=list->next; | |
8435 } | |
8436 g_list_free(tmp); | |
8437 } | |
8438 g_object_set_data(G_OBJECT(handle2), "_dw_user", NULL); | |
8439 } | |
8440 else if(GTK_IS_LIST(handle2)) | |
8441 { | |
8442 int count = dw_listbox_count(handle); | |
8443 | |
8444 gtk_list_clear_items(GTK_LIST(handle2), 0, count); | |
8445 } | |
8446 #endif | |
8447 DW_MUTEX_UNLOCK; | |
8448 } | |
8449 | |
8450 /* | |
8451 * Returns the listbox's item count. | |
8452 * Parameters: | |
8453 * handle: Handle to the listbox to be counted | |
8454 */ | |
8455 int dw_listbox_count(HWND handle) | |
8456 { | |
8457 GtkWidget *handle2 = handle; | |
8458 int retval = 0; | |
8459 int _locked_by_me = FALSE; | |
8460 | |
8461 DW_MUTEX_LOCK; | |
8462 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8463 { | |
8464 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8465 if(tmp) | |
8466 handle2 = tmp; | |
8467 } | |
8468 #if 0 | |
8469 else if(GTK_IS_COMBO_BOX(handle)) | |
8470 { | |
8471 handle2 = GTK_COMBO_BOX(handle)->list; | |
8472 } | |
8473 if(GTK_IS_LIST(handle2)) | |
8474 { | |
8475 GList *list = GTK_LIST(handle2)->children; | |
8476 while(list) | |
8477 { | |
8478 list = list->next; | |
8479 retval++; | |
8480 } | |
8481 } | |
8482 #endif | |
8483 DW_MUTEX_UNLOCK; | |
8484 return retval; | |
8485 } | |
8486 | |
8487 /* | |
8488 * Sets the topmost item in the viewport. | |
8489 * Parameters: | |
8490 * handle: Handle to the listbox to be cleared. | |
8491 * top: Index to the top item. | |
8492 */ | |
8493 void dw_listbox_set_top(HWND handle, int top) | |
8494 { | |
8495 GtkWidget *handle2 = handle; | |
8496 int _locked_by_me = FALSE; | |
8497 | |
8498 DW_MUTEX_LOCK; | |
8499 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8500 { | |
8501 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8502 if(tmp) | |
8503 handle2 = tmp; | |
8504 } | |
8505 #if 0 | |
8506 if(GTK_IS_LIST(handle2)) | |
8507 { | |
8508 int count = dw_listbox_count(handle); | |
8509 GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(handle)); | |
8510 float pos, ratio; | |
8511 | |
8512 if(count) | |
8513 { | |
8514 ratio = (float)top/(float)count; | |
8515 | |
8516 pos = (ratio * (float)(adj->upper - adj->lower)) + adj->lower; | |
8517 | |
8518 gtk_adjustment_set_value(adj, pos); | |
8519 } | |
8520 } | |
8521 #endif | |
8522 DW_MUTEX_UNLOCK; | |
8523 } | |
8524 | |
8525 /* | |
8526 * Copies the given index item's text into buffer. | |
8527 * Parameters: | |
8528 * handle: Handle to the listbox to be queried. | |
8529 * index: Index into the list to be queried. | |
8530 * buffer: Buffer where text will be copied. | |
8531 * length: Length of the buffer (including NULL). | |
8532 */ | |
8533 void dw_listbox_get_text(HWND handle, unsigned int index, char *buffer, unsigned int length) | |
8534 { | |
8535 GtkWidget *handle2 = handle; | |
8536 int _locked_by_me = FALSE; | |
8537 | |
8538 DW_MUTEX_LOCK; | |
8539 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8540 { | |
8541 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8542 if(tmp) | |
8543 handle2 = tmp; | |
8544 } | |
8545 #if 0 | |
8546 else if(GTK_IS_COMBO_BOX(handle)) | |
8547 { | |
8548 handle2 = GTK_COMBO_BOX(handle)->list; | |
8549 } | |
8550 if(GTK_IS_LIST(handle2)) | |
8551 { | |
8552 int counter = 0; | |
8553 GList *list = GTK_LIST(handle2)->children; | |
8554 | |
8555 while(list) | |
8556 { | |
8557 if(counter == index) | |
8558 { | |
8559 gchar *text = ""; | |
8560 | |
8561 if(GTK_IS_LIST_ITEM(list->data)) | |
8562 { | |
8563 GtkListItem *li = GTK_LIST_ITEM(list->data); | |
8564 | |
8565 if(GTK_IS_ITEM(&(li->item))) | |
8566 { | |
8567 GtkItem *i = &(li->item); | |
8568 | |
8569 if(GTK_IS_BIN(&(i->bin))) | |
8570 { | |
8571 GtkBin *b = &(i->bin); | |
8572 | |
8573 if(GTK_IS_LABEL(b->child)) | |
8574 gtk_label_get(GTK_LABEL(b->child), &text); | |
8575 } | |
8576 } | |
8577 } | |
8578 else if(GTK_IS_COMBO_BOX(handle) && list->data) | |
8579 text = (gchar *)list->data; | |
8580 | |
8581 strncpy(buffer, (char *)text, length); | |
8582 break; | |
8583 } | |
8584 list = list->next; | |
8585 counter++; | |
8586 } | |
8587 } | |
8588 #endif | |
8589 DW_MUTEX_UNLOCK; | |
8590 } | |
8591 | |
8592 /* | |
8593 * Sets the text of a given listbox entry. | |
8594 * Parameters: | |
8595 * handle: Handle to the listbox to be queried. | |
8596 * index: Index into the list to be queried. | |
8597 * buffer: Buffer where text will be copied. | |
8598 */ | |
8599 void dw_listbox_set_text(HWND handle, unsigned int index, char *buffer) | |
8600 { | |
8601 GtkWidget *handle2 = handle; | |
8602 int _locked_by_me = FALSE; | |
8603 | |
8604 DW_MUTEX_LOCK; | |
8605 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8606 { | |
8607 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8608 if(tmp) | |
8609 handle2 = tmp; | |
8610 } | |
8611 #if 0 | |
8612 else if(GTK_IS_COMBO_BOX(handle)) | |
8613 { | |
8614 handle2 = GTK_COMBO_BOX(handle)->list; | |
8615 } | |
8616 if(GTK_IS_LIST(handle2)) | |
8617 { | |
8618 int counter = 0; | |
8619 GList *list = GTK_LIST(handle2)->children; | |
8620 | |
8621 while(list) | |
8622 { | |
8623 if(counter == index) | |
8624 { | |
8625 | |
8626 if(GTK_IS_LIST_ITEM(list->data)) | |
8627 { | |
8628 GtkListItem *li = GTK_LIST_ITEM(list->data); | |
8629 | |
8630 if(GTK_IS_ITEM(&(li->item))) | |
8631 { | |
8632 GtkItem *i = &(li->item); | |
8633 | |
8634 if(GTK_IS_BIN(&(i->bin))) | |
8635 { | |
8636 GtkBin *b = &(i->bin); | |
8637 | |
8638 if(GTK_IS_LABEL(b->child)) | |
8639 gtk_label_set_text(GTK_LABEL(b->child), buffer); | |
8640 } | |
8641 } | |
8642 } | |
8643 else if(GTK_IS_COMBO_BOX(handle)) | |
8644 { | |
8645 if(list->data) | |
8646 g_free(list->data); | |
8647 list->data = g_strdup(buffer); | |
8648 } | |
8649 break; | |
8650 } | |
8651 list = list->next; | |
8652 counter++; | |
8653 } | |
8654 } | |
8655 #endif | |
8656 DW_MUTEX_UNLOCK; | |
8657 } | |
8658 | |
8659 /* | |
8660 * Returns the index to the current selected item or -1 when done. | |
8661 * Parameters: | |
8662 * handle: Handle to the listbox to be queried. | |
8663 * where: Either the previous return or -1 to restart. | |
8664 */ | |
8665 int dw_listbox_selected_multi(HWND handle, int where) | |
8666 { | |
8667 GtkWidget *handle2 = handle; | |
8668 int retval = DW_LIT_NONE; | |
8669 int _locked_by_me = FALSE; | |
8670 | |
8671 DW_MUTEX_LOCK; | |
8672 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8673 { | |
8674 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8675 if(tmp) | |
8676 handle2 = tmp; | |
8677 } | |
8678 #if 0 | |
8679 if(GTK_IS_LIST(handle2)) | |
8680 { | |
8681 int counter = 0; | |
8682 GList *list = GTK_LIST(handle2)->children; | |
8683 | |
8684 while(list) | |
8685 { | |
8686 GtkItem *item = (GtkItem *)list->data; | |
8687 | |
8688 if(item && | |
8689 item->bin.container.widget.state == GTK_STATE_SELECTED | |
8690 && counter > where) | |
8691 { | |
8692 retval = counter; | |
8693 break; | |
8694 } | |
8695 | |
8696 | |
8697 list = list->next; | |
8698 counter++; | |
8699 } | |
8700 } | |
8701 #endif | |
8702 DW_MUTEX_UNLOCK; | |
8703 return retval; | |
8704 } | |
8705 | |
8706 /* | |
8707 * Returns the index to the item in the list currently selected. | |
8708 * Parameters: | |
8709 * handle: Handle to the listbox to be queried. | |
8710 */ | |
8711 unsigned int dw_listbox_selected(HWND handle) | |
8712 { | |
8713 GtkWidget *handle2 = handle; | |
8714 int retval = DW_LIT_NONE; | |
8715 int _locked_by_me = FALSE; | |
8716 | |
8717 DW_MUTEX_LOCK; | |
8718 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8719 { | |
8720 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8721 if(tmp) | |
8722 handle2 = tmp; | |
8723 } | |
8724 #if 0 | |
8725 else if(GTK_IS_COMBO_BOX(handle)) | |
8726 { | |
8727 retval = (unsigned int)g_object_get_data(G_OBJECT(handle), "_dw_item"); | |
8728 DW_MUTEX_UNLOCK; | |
8729 return retval; | |
8730 } | |
8731 if(GTK_IS_LIST(handle2)) | |
8732 { | |
8733 int counter = 0; | |
8734 GList *list = GTK_LIST(handle2)->children; | |
8735 | |
8736 while(list) | |
8737 { | |
8738 GtkItem *item = (GtkItem *)list->data; | |
8739 | |
8740 if(item && item->bin.container.widget.state == GTK_STATE_SELECTED) | |
8741 { | |
8742 retval = counter; | |
8743 break; | |
8744 } | |
8745 | |
8746 list = list->next; | |
8747 counter++; | |
8748 } | |
8749 } | |
8750 #endif | |
8751 DW_MUTEX_UNLOCK; | |
8752 return retval; | |
8753 } | |
8754 | |
8755 /* | |
8756 * Sets the selection state of a given index. | |
8757 * Parameters: | |
8758 * handle: Handle to the listbox to be set. | |
8759 * index: Item index. | |
8760 * state: TRUE if selected FALSE if unselected. | |
8761 */ | |
8762 void dw_listbox_select(HWND handle, int index, int state) | |
8763 { | |
8764 GtkWidget *handle2 = handle; | |
8765 int _locked_by_me = FALSE; | |
8766 | |
8767 DW_MUTEX_LOCK; | |
8768 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8769 { | |
8770 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8771 if(tmp) | |
8772 handle2 = tmp; | |
8773 } | |
8774 #if 0 | |
8775 else if(GTK_IS_COMBO_BOX(handle)) | |
8776 { | |
8777 handle2 = GTK_COMBO_BOX(handle)->list; | |
8778 } | |
8779 if(GTK_IS_LIST(handle2)) | |
8780 { | |
8781 if(state) | |
8782 gtk_list_select_item(GTK_LIST(handle2), index); | |
8783 else | |
8784 gtk_list_unselect_item(GTK_LIST(handle2), index); | |
8785 } | |
8786 #endif | |
8787 DW_MUTEX_UNLOCK; | |
8788 } | |
8789 | |
8790 /* | |
8791 * Deletes the item with given index from the list. | |
8792 * Parameters: | |
8793 * handle: Handle to the listbox to be set. | |
8794 * index: Item index. | |
8795 */ | |
8796 void dw_listbox_delete(HWND handle, int index) | |
8797 { | |
8798 GtkWidget *handle2 = handle; | |
8799 int _locked_by_me = FALSE; | |
8800 | |
8801 DW_MUTEX_LOCK; | |
8802 if(GTK_IS_SCROLLED_WINDOW(handle)) | |
8803 { | |
8804 GtkWidget *tmp = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); | |
8805 if(tmp) | |
8806 handle2 = tmp; | |
8807 } | |
8808 #if 0 | |
8809 else if(GTK_IS_COMBO_BOX(handle)) | |
8810 { | |
8811 handle2 = GTK_COMBO_BOX(handle)->list; | |
8812 } | |
8813 if(GTK_IS_LIST(handle2)) | |
8814 { | |
8815 gtk_list_clear_items(GTK_LIST(handle2), index, index+1); | |
8816 } | |
8817 #endif | |
8818 DW_MUTEX_UNLOCK; | |
8819 } | |
8820 | |
8821 /* Reposition the bar according to the percentage */ | |
8822 static gint _splitbar_size_allocate(GtkWidget *widget, GtkAllocation *event, gpointer data) | |
8823 { | |
8824 float *percent = (float *)g_object_get_data(G_OBJECT(widget), "_dw_percent"); | |
8825 int lastwidth = (int)g_object_get_data(G_OBJECT(widget), "_dw_lastwidth"); | |
8826 int lastheight = (int)g_object_get_data(G_OBJECT(widget), "_dw_lastheight"); | |
8827 | |
8828 /* Prevent infinite recursion ;) */ | |
8829 if(!percent || (lastwidth == event->width && lastheight == event->height)) | |
8830 return FALSE; | |
8831 | |
8832 lastwidth = event->width; lastheight = event->height; | |
8833 | |
8834 g_object_set_data(G_OBJECT(widget), "_dw_lastwidth", GINT_TO_POINTER(lastwidth)); | |
8835 g_object_set_data(G_OBJECT(widget), "_dw_lastheight", GINT_TO_POINTER(lastheight)); | |
8836 | |
8837 if(GTK_IS_HPANED(widget)) | |
8838 gtk_paned_set_position(GTK_PANED(widget), (int)(event->width * (*percent / 100.0))); | |
8839 if(GTK_IS_VPANED(widget)) | |
8840 gtk_paned_set_position(GTK_PANED(widget), (int)(event->height * (*percent / 100.0))); | |
8841 g_object_set_data(G_OBJECT(widget), "_dw_waiting", NULL); | |
8842 return FALSE; | |
8843 } | |
8844 | |
8845 /* Figure out the new percentage */ | |
8846 static void _splitbar_accept_position(GObject *object, GParamSpec *pspec, gpointer data) | |
8847 { | |
8848 GtkWidget *widget = (GtkWidget *)data; | |
8849 float *percent = (float *)g_object_get_data(G_OBJECT(widget), "_dw_percent"); | |
8850 int size = 0, position = gtk_paned_get_position(GTK_PANED(widget)); | |
8851 | |
8852 if(!percent || g_object_get_data(G_OBJECT(widget), "_dw_waiting")) | |
8853 return; | |
8854 | |
8855 if(GTK_IS_VPANED(widget)) | |
8856 size = gtk_widget_get_allocated_height(widget); | |
8857 else if(GTK_IS_HPANED(widget)) | |
8858 size = gtk_widget_get_allocated_width(widget); | |
8859 | |
8860 if(size > 0) | |
8861 *percent = ((float)(position * 100) / (float)size); | |
8862 } | |
8863 | |
8864 /* | |
8865 * Creates a splitbar window (widget) with given parameters. | |
8866 * Parameters: | |
8867 * type: Value can be DW_VERT or DW_HORZ. | |
8868 * topleft: Handle to the window to be top or left. | |
8869 * bottomright: Handle to the window to be bottom or right. | |
8870 * Returns: | |
8871 * A handle to a splitbar window or NULL on failure. | |
8872 */ | |
8873 HWND dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id) | |
8874 { | |
8875 GtkWidget *tmp = NULL; | |
8876 int _locked_by_me = FALSE; | |
8877 float *percent = malloc(sizeof(float)); | |
8878 | |
8879 DW_MUTEX_LOCK; | |
8880 if(type == DW_HORZ) | |
8881 tmp = gtk_hpaned_new(); | |
8882 else | |
8883 tmp = gtk_vpaned_new(); | |
8884 gtk_paned_add1(GTK_PANED(tmp), topleft); | |
8885 gtk_paned_add2(GTK_PANED(tmp), bottomright); | |
8886 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
8887 *percent = 50.0; | |
8888 g_object_set_data(G_OBJECT(tmp), "_dw_percent", (gpointer)percent); | |
8889 g_object_set_data(G_OBJECT(tmp), "_dw_waiting", GINT_TO_POINTER(1)); | |
8890 g_signal_connect(G_OBJECT(tmp), "size-allocate", G_CALLBACK(_splitbar_size_allocate), NULL); | |
8891 g_signal_connect(G_OBJECT(tmp), "notify::position", G_CALLBACK(_splitbar_accept_position), (gpointer)tmp); | |
8892 gtk_widget_show(tmp); | |
8893 DW_MUTEX_UNLOCK; | |
8894 return tmp; | |
8895 } | |
8896 | |
8897 /* | |
8898 * Sets the position of a splitbar (pecentage). | |
8899 * Parameters: | |
8900 * handle: The handle to the splitbar returned by dw_splitbar_new(). | |
8901 */ | |
8902 void dw_splitbar_set(HWND handle, float percent) | |
8903 { | |
8904 float *mypercent = (float *)dw_window_get_data(handle, "_dw_percent"); | |
8905 int size = 0, position; | |
8906 | |
8907 if(GTK_IS_VPANED(handle)) | |
8908 size = gtk_widget_get_allocated_height(handle); | |
8909 else if(GTK_IS_HPANED(handle)) | |
8910 size = gtk_widget_get_allocated_width(handle); | |
8911 | |
8912 if(mypercent) | |
8913 *mypercent = percent; | |
8914 | |
8915 if(size > 10) | |
8916 { | |
8917 position = (int)((float)size * (percent / 100.0)); | |
8918 | |
8919 gtk_paned_set_position(GTK_PANED(handle), position); | |
8920 } | |
8921 } | |
8922 | |
8923 /* | |
8924 * Gets the position of a splitbar (pecentage). | |
8925 * Parameters: | |
8926 * handle: The handle to the splitbar returned by dw_splitbar_new(). | |
8927 */ | |
8928 float dw_splitbar_get(HWND handle) | |
8929 { | |
8930 float *percent = (float *)dw_window_get_data(handle, "_dw_percent"); | |
8931 | |
8932 if(percent) | |
8933 return *percent; | |
8934 return 0.0; | |
8935 } | |
8936 | |
8937 /* | |
8938 * Creates a calendar window (widget) with given parameters. | |
8939 * Parameters: | |
8940 * id: Unique identifier for calendar widget | |
8941 * Returns: | |
8942 * A handle to a calendar window or NULL on failure. | |
8943 */ | |
8944 HWND dw_calendar_new(unsigned long id) | |
8945 { | |
8946 GtkWidget *tmp; | |
8947 int _locked_by_me = FALSE; | |
8948 GtkCalendarDisplayOptions flags; | |
8949 time_t now; | |
8950 struct tm *tmdata; | |
8951 | |
8952 DW_MUTEX_LOCK; | |
8953 tmp = gtk_calendar_new(); | |
8954 gtk_widget_show(tmp); | |
8955 g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); | |
8956 /* select today */ | |
8957 flags = GTK_CALENDAR_SHOW_HEADING|GTK_CALENDAR_SHOW_DAY_NAMES; | |
8958 gtk_calendar_set_display_options( GTK_CALENDAR(tmp), flags ); | |
8959 now = time( NULL ); | |
8960 tmdata = localtime( & now ); | |
8961 gtk_calendar_select_month( GTK_CALENDAR(tmp), tmdata->tm_mon, 1900+tmdata->tm_year ); | |
8962 gtk_calendar_select_day( GTK_CALENDAR(tmp), tmdata->tm_mday ); | |
8963 | |
8964 DW_MUTEX_UNLOCK; | |
8965 return tmp; | |
8966 } | |
8967 | |
8968 /* | |
8969 * Sets the current date of a calendar | |
8970 * Parameters: | |
8971 * handle: The handle to the calendar returned by dw_calendar_new(). | |
8972 * year... | |
8973 */ | |
8974 void dw_calendar_set_date(HWND handle, unsigned int year, unsigned int month, unsigned int day) | |
8975 { | |
8976 int _locked_by_me = FALSE; | |
8977 | |
8978 DW_MUTEX_LOCK; | |
8979 if(GTK_IS_CALENDAR(handle)) | |
8980 { | |
8981 gtk_calendar_select_month(GTK_CALENDAR(handle),month-1,year); | |
8982 gtk_calendar_select_day(GTK_CALENDAR(handle), day); | |
8983 } | |
8984 DW_MUTEX_UNLOCK; | |
8985 return; | |
8986 } | |
8987 | |
8988 /* | |
8989 * Gets the position of a splitbar (pecentage). | |
8990 * Parameters: | |
8991 * handle: The handle to the splitbar returned by dw_splitbar_new(). | |
8992 */ | |
8993 void dw_calendar_get_date(HWND handle, unsigned int *year, unsigned int *month, unsigned int *day) | |
8994 { | |
8995 int _locked_by_me = FALSE; | |
8996 | |
8997 DW_MUTEX_LOCK; | |
8998 if(GTK_IS_CALENDAR(handle)) | |
8999 { | |
9000 gtk_calendar_get_date(GTK_CALENDAR(handle),year,month,day); | |
9001 *month = *month + 1; | |
9002 } | |
9003 DW_MUTEX_UNLOCK; | |
9004 return; | |
9005 } | |
9006 | |
9007 /* | |
9008 * Pack windows (widgets) into a box from the start (or top). | |
9009 * Parameters: | |
9010 * box: Window handle of the box to be packed into. | |
9011 * item: Window handle of the item to be back. | |
9012 * width: Width in pixels of the item or -1 to be self determined. | |
9013 * height: Height in pixels of the item or -1 to be self determined. | |
9014 * hsize: TRUE if the window (widget) should expand horizontally to fill space given. | |
9015 * vsize: TRUE if the window (widget) should expand vertically to fill space given. | |
9016 * pad: Number of pixels of padding around the item. | |
9017 */ | |
9018 void dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) | |
9019 { | |
9020 int warn = FALSE, _locked_by_me = FALSE; | |
9021 GtkWidget *tmp, *tmpitem; | |
9022 | |
9023 if ( !box ) | |
9024 return; | |
9025 | |
9026 /* | |
9027 * If you try and pack an item into itself VERY bad things can happen; like at least an | |
9028 * infinite loop on GTK! Lets be safe! | |
9029 */ | |
9030 if ( box == item ) | |
9031 { | |
9032 dw_messagebox( "dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!" ); | |
9033 return; | |
9034 } | |
9035 | |
9036 DW_MUTEX_LOCK; | |
9037 | |
9038 if ((tmp = g_object_get_data(G_OBJECT(box), "_dw_boxhandle"))) | |
9039 box = tmp; | |
9040 | |
9041 if (!item) | |
9042 { | |
9043 item = gtk_label_new(""); | |
9044 gtk_widget_show_all(item); | |
9045 } | |
9046 | |
9047 tmpitem = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_boxhandle"); | |
9048 | |
9049 if (GTK_IS_TABLE(box)) | |
9050 { | |
9051 int boxcount = (int)g_object_get_data(G_OBJECT(box), "_dw_boxcount"); | |
9052 int boxtype = (int)g_object_get_data(G_OBJECT(box), "_dw_boxtype"); | |
9053 int x, y; | |
9054 | |
9055 /* If the item being packed is a box, then we use it's padding | |
9056 * instead of the padding specified on the pack line, this is | |
9057 * due to a bug in the OS/2 and Win32 renderer and a limitation | |
9058 * of the GtkTable class. | |
9059 */ | |
9060 if (GTK_IS_TABLE(item) || (tmpitem && GTK_IS_TABLE(tmpitem))) | |
9061 { | |
9062 GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_eventbox"); | |
9063 | |
9064 /* NOTE: I left in the ability to pack boxes with a size, | |
9065 * this eliminates that by forcing the size to 0. | |
9066 */ | |
9067 height = width = 0; | |
9068 | |
9069 if (eventbox) | |
9070 { | |
9071 int boxpad = (int)g_object_get_data(G_OBJECT(item), "_dw_boxpad"); | |
9072 gtk_container_add(GTK_CONTAINER(eventbox), item); | |
9073 gtk_container_set_border_width(GTK_CONTAINER(eventbox), boxpad); | |
9074 item = eventbox; | |
9075 } | |
9076 } | |
9077 else | |
9078 { | |
9079 /* Only show warning if item is not a box */ | |
9080 warn = TRUE; | |
9081 } | |
9082 | |
9083 if (boxtype == DW_VERT) | |
9084 { | |
9085 x = 0; | |
9086 y = boxcount; | |
9087 gtk_table_resize(GTK_TABLE(box), boxcount + 1, 1); | |
9088 } | |
9089 else | |
9090 { | |
9091 x = boxcount; | |
9092 y = 0; | |
9093 gtk_table_resize(GTK_TABLE(box), 1, boxcount + 1); | |
9094 } | |
9095 | |
9096 gtk_table_attach(GTK_TABLE(box), item, x, x + 1, y, y + 1, hsize ? DW_EXPAND : 0, vsize ? DW_EXPAND : 0, pad, pad); | |
9097 g_object_set_data(G_OBJECT(box), "_dw_boxcount", GINT_TO_POINTER(boxcount + 1)); | |
9098 gtk_widget_set_size_request(item, width, height); | |
9099 if (GTK_IS_RADIO_BUTTON(item)) | |
9100 { | |
9101 GSList *group; | |
9102 GtkWidget *groupstart = (GtkWidget *)g_object_get_data(G_OBJECT(box), "_dw_group"); | |
9103 | |
9104 if (groupstart) | |
9105 { | |
9106 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(groupstart)); | |
9107 gtk_radio_button_set_group(GTK_RADIO_BUTTON(item), group); | |
9108 } | |
9109 else | |
9110 { | |
9111 g_object_set_data(G_OBJECT(box), "_dw_group", (gpointer)item); | |
9112 } | |
9113 } | |
9114 } | |
9115 else | |
9116 { | |
9117 GtkWidget *vbox = gtk_vbox_new(FALSE, 0); | |
9118 | |
9119 if (GTK_IS_TABLE(item) || (tmpitem && GTK_IS_TABLE(tmpitem))) | |
9120 { | |
9121 GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_eventbox"); | |
9122 | |
9123 /* NOTE: I left in the ability to pack boxes with a size, | |
9124 * this eliminates that by forcing the size to 0. | |
9125 */ | |
9126 height = width = 0; | |
9127 | |
9128 if (eventbox) | |
9129 { | |
9130 int boxpad = (int)g_object_get_data(G_OBJECT(item), "_dw_boxpad"); | |
9131 gtk_container_add(GTK_CONTAINER(eventbox), item); | |
9132 gtk_container_set_border_width(GTK_CONTAINER(eventbox), boxpad); | |
9133 item = eventbox; | |
9134 } | |
9135 } | |
9136 else | |
9137 { | |
9138 /* Only show warning if item is not a box */ | |
9139 warn = TRUE; | |
9140 } | |
9141 | |
9142 gtk_container_set_border_width(GTK_CONTAINER(box), pad); | |
9143 gtk_container_add(GTK_CONTAINER(box), vbox); | |
9144 gtk_box_pack_end(GTK_BOX(vbox), item, TRUE, TRUE, 0); | |
9145 gtk_widget_show(vbox); | |
9146 | |
9147 gtk_widget_set_size_request(item, width, height); | |
9148 g_object_set_data(G_OBJECT(box), "_dw_user", vbox); | |
9149 } | |
9150 DW_MUTEX_UNLOCK; | |
9151 | |
9152 if (warn) | |
9153 { | |
9154 if ( width == 0 && hsize == FALSE ) | |
9155 dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); | |
9156 if ( height == 0 && vsize == FALSE ) | |
9157 dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); | |
9158 } | |
9159 } | |
9160 | |
9161 /* | |
9162 * Sets the default focus item for a window/dialog. | |
9163 * Parameters: | |
9164 * window: Toplevel window or dialog. | |
9165 * defaultitem: Handle to the dialog item to be default. | |
9166 */ | |
9167 void dw_window_default(HWND window, HWND defaultitem) | |
9168 { | |
9169 int _locked_by_me = FALSE; | |
9170 | |
9171 if(!window) | |
9172 return; | |
9173 | |
9174 DW_MUTEX_LOCK; | |
9175 g_object_set_data(G_OBJECT(window), "_dw_defaultitem", (gpointer)defaultitem); | |
9176 DW_MUTEX_UNLOCK; | |
9177 } | |
9178 | |
9179 /* | |
9180 * Sets window to click the default dialog item when an ENTER is pressed. | |
9181 * Parameters: | |
9182 * window: Window (widget) to look for the ENTER press. | |
9183 * next: Window (widget) to move to next (or click) | |
9184 */ | |
9185 void dw_window_click_default(HWND window, HWND next) | |
9186 { | |
9187 int _locked_by_me = FALSE; | |
9188 | |
9189 if(!window) | |
9190 return; | |
9191 | |
9192 DW_MUTEX_LOCK; | |
9193 g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(_default_key_press_event), next); | |
9194 DW_MUTEX_UNLOCK; | |
9195 } | |
9196 | |
9197 /* | |
9198 * Returns some information about the current operating environment. | |
9199 * Parameters: | |
9200 * env: Pointer to a DWEnv struct. | |
9201 */ | |
9202 void dw_environment_query(DWEnv *env) | |
9203 { | |
9204 struct utsname name; | |
9205 char tempbuf[100]; | |
9206 int len, z; | |
9207 | |
9208 uname(&name); | |
9209 strcpy(env->osName, name.sysname); | |
9210 strcpy(tempbuf, name.release); | |
9211 | |
9212 env->MajorBuild = env->MinorBuild = 0; | |
9213 | |
9214 len = strlen(tempbuf); | |
9215 | |
9216 strcpy(env->buildDate, __DATE__); | |
9217 strcpy(env->buildTime, __TIME__); | |
9218 env->DWMajorVersion = DW_MAJOR_VERSION; | |
9219 env->DWMinorVersion = DW_MINOR_VERSION; | |
9220 env->DWSubVersion = DW_SUB_VERSION; | |
9221 | |
9222 for(z=1;z<len;z++) | |
9223 { | |
9224 if(tempbuf[z] == '.') | |
9225 { | |
9226 tempbuf[z] = '\0'; | |
9227 env->MajorVersion = atoi(&tempbuf[z-1]); | |
9228 env->MinorVersion = atoi(&tempbuf[z+1]); | |
9229 return; | |
9230 } | |
9231 } | |
9232 env->MajorVersion = atoi(tempbuf); | |
9233 env->MinorVersion = 0; | |
9234 } | |
9235 | |
9236 /* | |
9237 * Opens a file dialog and queries user selection. | |
9238 * Parameters: | |
9239 * title: Title bar text for dialog. | |
9240 * defpath: The default path of the open dialog. | |
9241 * ext: Default file extention. | |
9242 * flags: DW_FILE_OPEN or DW_FILE_SAVE or DW_DIRECTORY_OPEN | |
9243 * Returns: | |
9244 * NULL on error. A malloced buffer containing | |
9245 * the file path on success. | |
9246 * | |
9247 */ | |
9248 char *dw_file_browse(char *title, char *defpath, char *ext, int flags) | |
9249 { | |
9250 GtkWidget *filew; | |
9251 | |
9252 GtkFileChooserAction action; | |
9253 GtkFileFilter *filter1 = NULL; | |
9254 GtkFileFilter *filter2 = NULL; | |
9255 gchar *button; | |
9256 char *filename = NULL; | |
9257 char buf[1000]; | |
9258 char mypath[PATH_MAX+1]; | |
9259 char cwd[PATH_MAX+1]; | |
9260 | |
9261 switch (flags ) | |
9262 { | |
9263 case DW_DIRECTORY_OPEN: | |
9264 action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; | |
9265 button = GTK_STOCK_OPEN; | |
9266 break; | |
9267 case DW_FILE_OPEN: | |
9268 action = GTK_FILE_CHOOSER_ACTION_OPEN; | |
9269 button = GTK_STOCK_OPEN; | |
9270 break; | |
9271 case DW_FILE_SAVE: | |
9272 action = GTK_FILE_CHOOSER_ACTION_SAVE; | |
9273 button = GTK_STOCK_SAVE; | |
9274 break; | |
9275 default: | |
9276 dw_messagebox( "Coding error", DW_MB_OK|DW_MB_ERROR, "dw_file_browse() flags argument invalid."); | |
9277 return NULL; | |
9278 break; | |
9279 } | |
9280 | |
9281 filew = gtk_file_chooser_dialog_new ( title, | |
9282 NULL, | |
9283 action, | |
9284 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
9285 button, GTK_RESPONSE_ACCEPT, | |
9286 NULL); | |
9287 | |
9288 if ( flags == DW_FILE_SAVE ) | |
9289 gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER( filew ), TRUE ); | |
9290 | |
9291 if ( ext ) | |
9292 { | |
9293 filter1 = gtk_file_filter_new(); | |
9294 sprintf( buf, "*.%s", ext ); | |
9295 gtk_file_filter_add_pattern( filter1, (gchar *)buf ); | |
9296 sprintf( buf, "\"%s\" files", ext ); | |
9297 gtk_file_filter_set_name( filter1, (gchar *)buf ); | |
9298 filter2 = gtk_file_filter_new(); | |
9299 gtk_file_filter_add_pattern( filter2, (gchar *)"*" ); | |
9300 gtk_file_filter_set_name( filter2, (gchar *)"All Files" ); | |
9301 gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( filew ), filter1 ); | |
9302 gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( filew ), filter2 ); | |
9303 } | |
9304 | |
9305 if ( defpath ) | |
9306 { | |
9307 if ( g_path_is_absolute( defpath ) ) | |
9308 { | |
9309 strcpy( mypath, defpath ); | |
9310 } | |
9311 else | |
9312 { | |
9313 if ( !getcwd(cwd, PATH_MAX ) ) | |
9314 { | |
9315 } | |
9316 else | |
9317 { | |
9318 if ( rel2abs( defpath, cwd, mypath, PATH_MAX ) ) | |
9319 { | |
9320 } | |
9321 } | |
9322 } | |
9323 gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( filew ), mypath ); | |
9324 } | |
9325 | |
9326 if ( gtk_dialog_run( GTK_DIALOG( filew ) ) == GTK_RESPONSE_ACCEPT ) | |
9327 { | |
9328 filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( filew ) ); | |
9329 /*g_free (filename);*/ | |
9330 } | |
9331 | |
9332 gtk_widget_destroy( filew ); | |
9333 return filename; | |
9334 } | |
9335 | |
9336 | |
9337 /* | |
9338 * Execute and external program in a seperate session. | |
9339 * Parameters: | |
9340 * program: Program name with optional path. | |
9341 * type: Either DW_EXEC_CON or DW_EXEC_GUI. | |
9342 * params: An array of pointers to string arguements. | |
9343 * Returns: | |
9344 * -1 on error. | |
9345 */ | |
9346 int dw_exec(char *program, int type, char **params) | |
9347 { | |
9348 int ret = -1; | |
9349 | |
9350 if((ret = fork()) == 0) | |
9351 { | |
9352 int i; | |
9353 | |
9354 for (i = 3; i < 256; i++) | |
9355 close(i); | |
9356 setsid(); | |
9357 if(type == DW_EXEC_GUI) | |
9358 { | |
9359 execvp(program, params); | |
9360 } | |
9361 else if(type == DW_EXEC_CON) | |
9362 { | |
9363 char **tmpargs; | |
9364 | |
9365 if(!params) | |
9366 { | |
9367 tmpargs = malloc(sizeof(char *)); | |
9368 tmpargs[0] = NULL; | |
9369 } | |
9370 else | |
9371 { | |
9372 int z = 0; | |
9373 | |
9374 while(params[z]) | |
9375 { | |
9376 z++; | |
9377 } | |
9378 tmpargs = malloc(sizeof(char *)*(z+3)); | |
9379 z=0; | |
9380 tmpargs[0] = "xterm"; | |
9381 tmpargs[1] = "-e"; | |
9382 while(params[z]) | |
9383 { | |
9384 tmpargs[z+2] = params[z]; | |
9385 z++; | |
9386 } | |
9387 tmpargs[z+2] = NULL; | |
9388 } | |
9389 execvp("xterm", tmpargs); | |
9390 free(tmpargs); | |
9391 } | |
9392 /* If we got here exec failed */ | |
9393 _exit(-1); | |
9394 } | |
9395 return ret; | |
9396 } | |
9397 | |
9398 /* | |
9399 * Loads a web browser pointed at the given URL. | |
9400 * Parameters: | |
9401 * url: Uniform resource locator. | |
9402 */ | |
9403 int dw_browse(char *url) | |
9404 { | |
9405 /* Is there a way to find the webbrowser in Unix? */ | |
9406 char *execargs[3], *browser = "netscape", *tmp; | |
9407 | |
9408 tmp = getenv( "DW_BROWSER" ); | |
9409 if(tmp) browser = tmp; | |
9410 execargs[0] = browser; | |
9411 execargs[1] = url; | |
9412 execargs[2] = NULL; | |
9413 | |
9414 return dw_exec(browser, DW_EXEC_GUI, execargs); | |
9415 } | |
9416 | |
9417 /* | |
9418 * Causes the embedded HTML widget to take action. | |
9419 * Parameters: | |
9420 * handle: Handle to the window. | |
9421 * action: One of the DW_HTML_* constants. | |
9422 */ | |
9423 void dw_html_action(HWND handle, int action) | |
9424 { | |
9425 #ifdef USE_GTKMOZEMBED | |
9426 int _locked_by_me = FALSE; | |
9427 | |
9428 if(!_gtk_moz_embed_new) | |
9429 return; | |
9430 | |
9431 DW_MUTEX_LOCK; | |
9432 switch(action) | |
9433 { | |
9434 case DW_HTML_GOBACK: | |
9435 _gtk_moz_embed_go_back(GTK_MOZ_EMBED(handle)); | |
9436 break; | |
9437 case DW_HTML_GOFORWARD: | |
9438 _gtk_moz_embed_go_forward(GTK_MOZ_EMBED(handle)); | |
9439 break; | |
9440 case DW_HTML_GOHOME: | |
9441 _gtk_moz_embed_load_url(GTK_MOZ_EMBED(handle), "http://dwindows.netlabs.org"); | |
9442 break; | |
9443 case DW_HTML_RELOAD: | |
9444 _gtk_moz_embed_reload(GTK_MOZ_EMBED(handle), 0); | |
9445 break; | |
9446 case DW_HTML_STOP: | |
9447 _gtk_moz_embed_stop_load(GTK_MOZ_EMBED(handle)); | |
9448 break; | |
9449 } | |
9450 DW_MUTEX_UNLOCK; | |
9451 #elif defined(USE_WEBKIT) | |
9452 int _locked_by_me = FALSE; | |
9453 WebKitWebView *web_view; | |
9454 WebKitWebFrame *frame; | |
9455 | |
9456 if (!_webkit_web_view_open) | |
9457 return; | |
9458 | |
9459 DW_MUTEX_LOCK; | |
9460 web_view = (WebKitWebView *)g_object_get_data(G_OBJECT(handle), "_dw_web_view"); | |
9461 if ( web_view ) | |
9462 { | |
9463 switch( action ) | |
9464 { | |
9465 case DW_HTML_GOBACK: | |
9466 _webkit_web_view_go_back( web_view ); | |
9467 break; | |
9468 case DW_HTML_GOFORWARD: | |
9469 _webkit_web_view_go_forward( web_view ); | |
9470 break; | |
9471 case DW_HTML_GOHOME: | |
9472 _webkit_web_view_open( web_view, "http://dwindows.netlabs.org" ); | |
9473 break; | |
9474 case DW_HTML_RELOAD: | |
9475 _webkit_web_view_reload( web_view ); | |
9476 break; | |
9477 case DW_HTML_STOP: | |
9478 _webkit_web_view_stop_loading( web_view ); | |
9479 break; | |
9480 # ifdef WEBKIT_CHECK_VERSION | |
9481 # if WEBKIT_CHECK_VERSION(1,1,5) | |
9482 case DW_HTML_PRINT: | |
9483 frame = _webkit_web_view_get_focused_frame( web_view ); | |
9484 _webkit_web_frame_print( frame ); | |
9485 break; | |
9486 # endif | |
9487 # endif | |
9488 } | |
9489 } | |
9490 DW_MUTEX_UNLOCK; | |
9491 #endif | |
9492 } | |
9493 | |
9494 #ifdef USE_LIBGTKHTML2 | |
9495 void _dw_html_render_data( HWND handle, char *string, int i ) | |
9496 { | |
9497 HtmlDocument *document; | |
9498 | |
9499 html_view_set_document (HTML_VIEW(handle), NULL); | |
9500 document = (HtmlDocument *)g_object_get_data(G_OBJECT(handle), "_dw_html_document" ); | |
9501 /* html_document_clear (document);*/ | |
9502 if ( document ) | |
9503 { | |
9504 html_view_set_document (HTML_VIEW(handle), document); | |
9505 if ( html_document_open_stream( document, "text/html" ) ) | |
9506 { | |
9507 html_document_write_stream( document, string, i ); | |
9508 } | |
9509 html_document_close_stream (document); | |
9510 } | |
9511 } | |
9512 #endif | |
9513 /* | |
9514 * Render raw HTML code in the embedded HTML widget.. | |
9515 * Parameters: | |
9516 * handle: Handle to the window. | |
9517 * string: String buffer containt HTML code to | |
9518 * be rendered. | |
9519 * Returns: | |
9520 * 0 on success. | |
9521 */ | |
9522 int dw_html_raw(HWND handle, char *string) | |
9523 { | |
9524 #ifdef USE_GTKMOZEMBED | |
9525 int _locked_by_me = FALSE; | |
9526 | |
9527 if (!_gtk_moz_embed_new) | |
9528 return -1; | |
9529 | |
9530 DW_MUTEX_LOCK; | |
9531 _gtk_moz_embed_render_data(GTK_MOZ_EMBED(handle), string, strlen(string), "file:///", "text/html"); | |
9532 gtk_widget_show(GTK_WIDGET(handle)); | |
9533 DW_MUTEX_UNLOCK; | |
9534 return 0; | |
9535 #elif defined(USE_LIBGTKHTML2) | |
9536 int _locked_by_me = FALSE; | |
9537 | |
9538 if ( !_html_document_new ) | |
9539 return -1; | |
9540 | |
9541 DW_MUTEX_LOCK; | |
9542 _dw_html_render_data( handle, string, strlen(string) ); | |
9543 gtk_widget_show( GTK_WIDGET(handle) ); | |
9544 DW_MUTEX_UNLOCK; | |
9545 return 0; | |
9546 #elif defined(USE_WEBKIT) | |
9547 int _locked_by_me = FALSE; | |
9548 WebKitWebView *web_view; | |
9549 | |
9550 if (!_webkit_web_view_open) | |
9551 return -1; | |
9552 | |
9553 DW_MUTEX_LOCK; | |
9554 web_view = (WebKitWebView *)g_object_get_data(G_OBJECT(handle), "_dw_web_view"); | |
9555 if ( web_view ) | |
9556 { | |
9557 _webkit_web_view_load_html_string( web_view, string, "file:///"); | |
9558 gtk_widget_show( GTK_WIDGET(handle) ); | |
9559 } | |
9560 DW_MUTEX_UNLOCK; | |
9561 return 0; | |
9562 #endif | |
9563 return -1; | |
9564 } | |
9565 | |
9566 /* | |
9567 * Render file or web page in the embedded HTML widget.. | |
9568 * Parameters: | |
9569 * handle: Handle to the window. | |
9570 * url: Universal Resource Locator of the web or | |
9571 * file object to be rendered. | |
9572 * Returns: | |
9573 * 0 on success. | |
9574 */ | |
9575 int dw_html_url(HWND handle, char *url) | |
9576 { | |
9577 #ifdef USE_GTKMOZEMBED | |
9578 int _locked_by_me = FALSE; | |
9579 | |
9580 if (!_gtk_moz_embed_new) | |
9581 return -1; | |
9582 | |
9583 DW_MUTEX_LOCK; | |
9584 _gtk_moz_embed_load_url( GTK_MOZ_EMBED(handle), url ); | |
9585 gtk_widget_show(GTK_WIDGET(handle)); | |
9586 DW_MUTEX_UNLOCK; | |
9587 return 0; | |
9588 #elif defined( USE_WEBKIT ) | |
9589 int _locked_by_me = FALSE; | |
9590 WebKitWebView *web_view; | |
9591 | |
9592 if (!_webkit_web_view_open) | |
9593 return -1; | |
9594 | |
9595 DW_MUTEX_LOCK; | |
9596 web_view = (WebKitWebView *)g_object_get_data(G_OBJECT(handle), "_dw_web_view"); | |
9597 if ( web_view ) | |
9598 { | |
9599 _webkit_web_view_open( web_view, url ); | |
9600 gtk_widget_show(GTK_WIDGET(handle)); | |
9601 } | |
9602 DW_MUTEX_UNLOCK; | |
9603 return 0; | |
9604 #endif | |
9605 return -1; | |
9606 } | |
9607 | |
9608 #ifdef USE_GTKMOZEMBED | |
9609 /* | |
9610 * Callback for a HTML widget when the "Forward" menu item is selected | |
9611 */ | |
9612 static int _dw_html_forward_callback(HWND window, void *data) | |
9613 { | |
9614 HWND handle=(HWND)data; | |
9615 dw_html_action( handle, DW_HTML_GOFORWARD ); | |
9616 return TRUE; | |
9617 } | |
9618 | |
9619 /* | |
9620 * Callback for a HTML widget when the "Back" menu item is selected | |
9621 */ | |
9622 static int _dw_html_backward_callback(HWND window, void *data) | |
9623 { | |
9624 HWND handle=(HWND)data; | |
9625 dw_html_action( handle, DW_HTML_GOBACK ); | |
9626 return TRUE; | |
9627 } | |
9628 | |
9629 /* | |
9630 * Callback for a HTML widget when the "Reload" menu item is selected | |
9631 */ | |
9632 static int _dw_html_reload_callback(HWND window, void *data) | |
9633 { | |
9634 HWND handle=(HWND)data; | |
9635 dw_html_action( handle, DW_HTML_RELOAD ); | |
9636 return TRUE; | |
9637 } | |
9638 | |
9639 /* | |
9640 * Callback for a HTML widget when a page has completed loading | |
9641 * Once the page has finished loading, show the widget. | |
9642 */ | |
9643 void _dw_html_net_stop_cb( GtkMozEmbed *embed, gpointer data ) | |
9644 { | |
9645 gtk_widget_show(GTK_WIDGET(data)); | |
9646 } | |
9647 | |
9648 /* | |
9649 * Callback for a HTML widget when a mouse button is clicked inside the widget | |
9650 * If the right mouse button is clicked, popup a context menu | |
9651 */ | |
9652 static gint _dw_dom_mouse_click_cb (GtkMozEmbed *dummy, gpointer dom_event, gpointer embed) | |
9653 { | |
9654 gint button,rc; | |
9655 glong x,y; | |
9656 int flags; | |
9657 | |
9658 button = mozilla_get_mouse_event_button( dom_event ); | |
9659 if ( button == 2 ) | |
9660 { | |
9661 HWND menuitem; | |
9662 HMENUI popup; | |
9663 /* | |
9664 * Right mouse button; display context menu | |
9665 */ | |
9666 rc = mozilla_get_mouse_location( dom_event, &x, &y); | |
9667 popup = dw_menu_new( 0 ); | |
9668 if ( _gtk_moz_embed_can_go_forward(GTK_MOZ_EMBED(embed) ) ) | |
9669 flags = DW_MIS_ENABLED; | |
9670 else | |
9671 flags = DW_MIS_DISABLED; | |
9672 menuitem = dw_menu_append_item( popup, "Forward", 1, flags, TRUE, FALSE, 0 ); | |
9673 dw_signal_connect( menuitem, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_html_forward_callback), embed ); | |
9674 | |
9675 if ( _gtk_moz_embed_can_go_back(GTK_MOZ_EMBED(embed) ) ) | |
9676 flags = DW_MIS_ENABLED; | |
9677 else | |
9678 flags = DW_MIS_DISABLED; | |
9679 menuitem = dw_menu_append_item( popup, "Back", 2, flags, TRUE, FALSE, 0 ); | |
9680 dw_signal_connect( menuitem, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_html_backward_callback), embed ); | |
9681 | |
9682 dw_menu_append_item( popup, DW_MENU_SEPARATOR, 99, 0, TRUE, FALSE, 0 ); | |
9683 | |
9684 menuitem = dw_menu_append_item( popup, "Reload", 3, 0, TRUE, FALSE, 0 ); | |
9685 dw_signal_connect( menuitem, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_html_reload_callback), embed ); | |
9686 | |
9687 dw_menu_popup( &popup, embed, x, y ); | |
9688 rc = TRUE; | |
9689 } | |
9690 else | |
9691 { | |
9692 rc = FALSE; | |
9693 } | |
9694 return rc; | |
9695 } | |
9696 #endif | |
9697 | |
9698 #ifdef USE_LIBGTKHTML2 | |
9699 static gboolean dom_mouse_down( HtmlDocument *doc, DomMouseEvent *event, gpointer data ) | |
9700 { | |
9701 fprintf(stderr,"mouse down\n"); | |
9702 return TRUE; | |
9703 } | |
9704 static gboolean dom_mouse_up( HtmlDocument *doc, DomMouseEvent *event, gpointer data ) | |
9705 { | |
9706 fprintf(stderr,"mouse up\n"); | |
9707 return TRUE; | |
9708 } | |
9709 static gboolean dom_mouse_click( HtmlDocument *doc, DomMouseEvent *event, gpointer data ) | |
9710 { | |
9711 fprintf(stderr,"mouse click\n"); | |
9712 return TRUE; | |
9713 } | |
9714 static gboolean url_requested (HtmlDocument *doc, const gchar *url, HtmlStream *stream) | |
9715 { | |
9716 fprintf(stderr,"URL IS REQUESTED: %s\n",url); | |
9717 return TRUE; | |
9718 } | |
9719 static void link_clicked (HtmlDocument *doc, const gchar *url) | |
9720 { | |
9721 fprintf(stderr,"link clicked: %s!\n", url); | |
9722 } | |
9723 #endif | |
9724 | |
9725 #ifdef USE_WEBKIT | |
9726 # ifdef WEBKIT_CHECK_VERSION | |
9727 # if WEBKIT_CHECK_VERSION(1,1,5) | |
9728 static void _dw_html_print_cb( GtkWidget *widget, gpointer *data ) | |
9729 { | |
9730 WebKitWebView *web_view = DW_WEBKIT_WEB_VIEW(data); | |
9731 WebKitWebFrame *frame; | |
9732 | |
9733 frame = _webkit_web_view_get_focused_frame( web_view ); | |
9734 _webkit_web_frame_print( frame ); | |
9735 } | |
9736 /* | |
9737 * Fired when the user right-clicks to get the popup-menu on the HTML widget | |
9738 * We add a "Print" menu item to enable printing | |
9739 * user_data is not used | |
9740 */ | |
9741 static void _dw_html_populate_popup_cb( WebKitWebView *web_view, GtkMenu *menu, gpointer user_data ) | |
9742 { | |
9743 GtkWidget *image = gtk_image_new_from_stock( GTK_STOCK_PRINT, GTK_ICON_SIZE_MENU ); | |
9744 GtkWidget *item = gtk_image_menu_item_new_with_label( "Print" ); | |
9745 | |
9746 gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM(item), image ); | |
9747 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
9748 g_signal_connect( item, "activate", G_CALLBACK(_dw_html_print_cb), web_view ); | |
9749 gtk_widget_show(item); | |
9750 } | |
9751 # endif | |
9752 # endif | |
9753 #endif | |
9754 | |
9755 /* | |
9756 * Create a new Entryfield window (widget) to be packed. | |
9757 * Parameters: | |
9758 * text: The default text to be in the entryfield widget. | |
9759 * id: An ID to be used with dw_window_from_id() or 0L. | |
9760 */ | |
9761 HWND dw_html_new(unsigned long id) | |
9762 { | |
9763 GtkWidget *widget,*stext; | |
9764 int _locked_by_me = FALSE; | |
9765 | |
9766 DW_MUTEX_LOCK; | |
9767 #ifdef USE_GTKMOZEMBED | |
9768 if (!_gtk_moz_embed_new) | |
9769 { | |
9770 widget = dw_box_new(DW_HORZ, 0); | |
9771 stext = dw_text_new( "HTML widget not available; you do not have access to gtkmozembed.", 0); | |
9772 dw_box_pack_start(widget, stext, 0, 0, TRUE, TRUE, 10); | |
9773 } | |
9774 else | |
9775 { | |
9776 widget = _gtk_moz_embed_new(); | |
9777 /* | |
9778 * Connect some signals | |
9779 */ | |
9780 g_signal_connect( G_OBJECT(widget), "net-stop", G_CALLBACK(_dw_html_net_stop_cb), widget ); | |
9781 g_signal_connect( G_OBJECT(widget), "dom_mouse_click", G_CALLBACK(_dw_dom_mouse_click_cb), widget ); | |
9782 } | |
9783 #elif defined(USE_LIBGTKHTML2) | |
9784 if ( !_html_document_new ) | |
9785 { | |
9786 widget = dw_box_new(DW_HORZ, 0); | |
9787 stext = dw_text_new( "HTML widget not available; you do not have access to libgtkhtml-2.", 0); | |
9788 dw_box_pack_start(widget, stext, 0, 0, TRUE, TRUE, 10); | |
9789 } | |
9790 else | |
9791 { | |
9792 HtmlDocument *document; | |
9793 document = html_document_new (); | |
9794 g_signal_connect (G_OBJECT (document), "dom_mouse_down", G_CALLBACK (dom_mouse_down), NULL); | |
9795 g_signal_connect (G_OBJECT (document), "dom_mouse_up", G_CALLBACK (dom_mouse_up), NULL); | |
9796 g_signal_connect (G_OBJECT (document), "dom_mouse_click", G_CALLBACK (dom_mouse_click), NULL); | |
9797 g_signal_connect (G_OBJECT (document), "request_url", G_CALLBACK (url_requested), NULL); | |
9798 g_signal_connect (G_OBJECT (document), "link_clicked", G_CALLBACK (link_clicked), NULL); | |
9799 widget = _html_view_new(); | |
9800 g_object_set_data(G_OBJECT(widget), "_dw_html_document", (gpointer)document); | |
9801 } | |
9802 #elif defined(USE_WEBKIT) | |
9803 if (!_webkit_web_view_open) | |
9804 { | |
9805 widget = dw_box_new(DW_HORZ, 0); | |
9806 stext = dw_text_new( "HTML widget not available; you do not have access to webkit.", 0); | |
9807 dw_box_pack_start(widget, stext, 0, 0, TRUE, TRUE, 10); | |
9808 } | |
9809 else | |
9810 { | |
9811 WebKitWebView *web_view; | |
9812 widget = gtk_scrolled_window_new (NULL, NULL); | |
9813 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); | |
9814 web_view = (WebKitWebView *)_webkit_web_view_new(); | |
9815 /* web_view = WEBKIT_WEB_VIEW(_webkit_web_view_new() ); */ | |
9816 gtk_container_add( GTK_CONTAINER (widget), GTK_WIDGET(web_view) ); | |
9817 gtk_widget_show( GTK_WIDGET(web_view) ); | |
9818 g_object_set_data(G_OBJECT(widget), "_dw_web_view", (gpointer)web_view); | |
9819 # ifdef WEBKIT_CHECK_VERSION | |
9820 # if WEBKIT_CHECK_VERSION(1,1,5) | |
9821 g_signal_connect( web_view, "populate-popup", G_CALLBACK(_dw_html_populate_popup_cb), NULL ); | |
9822 # endif | |
9823 # endif | |
9824 } | |
9825 #else | |
9826 widget = dw_box_new(DW_HORZ, 0); | |
9827 stext = dw_text_new( "HTML widget not available; you do not have access to gtkmozembed.", 0); | |
9828 dw_box_pack_start(widget, stext, 0, 0, TRUE, TRUE, 10); | |
9829 #endif | |
9830 gtk_widget_show(widget); | |
9831 DW_MUTEX_UNLOCK; | |
9832 return widget; | |
9833 } | |
9834 | |
9835 /* | |
9836 * Gets the contents of the default clipboard as text. | |
9837 * Parameters: | |
9838 * None. | |
9839 * Returns: | |
9840 * Pointer to an allocated string of text or NULL if clipboard empty or contents could not | |
9841 * be converted to text. | |
9842 */ | |
9843 char *dw_clipboard_get_text() | |
9844 { | |
9845 int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id()); | |
9846 | |
9847 DW_MUTEX_LOCK; | |
9848 if ( _clipboard_object[index] == NULL ) | |
9849 { | |
9850 _clipboard_object[index] = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); | |
9851 } | |
9852 if ( _clipboard_contents[index] != NULL ) | |
9853 { | |
9854 g_free( _clipboard_contents[index] ); | |
9855 } | |
9856 _clipboard_contents[index] = gtk_clipboard_wait_for_text( _clipboard_object[index] ); | |
9857 DW_MUTEX_UNLOCK; | |
9858 return (char *)_clipboard_contents[index]; | |
9859 } | |
9860 | |
9861 /* | |
9862 * Sets the contents of the default clipboard to the supplied text. | |
9863 * Parameters: | |
9864 * Text. | |
9865 */ | |
9866 void dw_clipboard_set_text( char *str, int len ) | |
9867 { | |
9868 int _locked_by_me = FALSE, index = _find_thread_index(dw_thread_id()); | |
9869 | |
9870 DW_MUTEX_LOCK; | |
9871 if ( _clipboard_object[index] == NULL ) | |
9872 { | |
9873 _clipboard_object[index] = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); | |
9874 } | |
9875 gtk_clipboard_set_text( _clipboard_object[index], str, len ); | |
9876 DW_MUTEX_UNLOCK; | |
9877 } | |
9878 | |
9879 /* | |
9880 * Returns a pointer to a static buffer which containes the | |
9881 * current user directory. Or the root directory (C:\ on | |
9882 * OS/2 and Windows). | |
9883 */ | |
9884 char *dw_user_dir(void) | |
9885 { | |
9886 static char _user_dir[1024] = ""; | |
9887 | |
9888 if(!_user_dir[0]) | |
9889 { | |
9890 char *home = getenv("HOME"); | |
9891 | |
9892 if(home) | |
9893 strcpy(_user_dir, home); | |
9894 else | |
9895 strcpy(_user_dir, "/"); | |
9896 } | |
9897 return _user_dir; | |
9898 } | |
9899 | |
9900 /* | |
9901 * Call a function from the window (widget)'s context. | |
9902 * Parameters: | |
9903 * handle: Window handle of the widget. | |
9904 * function: Function pointer to be called. | |
9905 * data: Pointer to the data to be passed to the function. | |
9906 */ | |
9907 void dw_window_function(HWND handle, void *function, void *data) | |
9908 { | |
9909 void (* windowfunc)(void *); | |
9910 | |
9911 windowfunc = function; | |
9912 | |
9913 if(windowfunc) | |
9914 windowfunc(data); | |
9915 } | |
9916 | |
9917 /* | |
9918 * Add a named user data item to a window handle. | |
9919 * Parameters: | |
9920 * window: Window handle of signal to be called back. | |
9921 * dataname: A string pointer identifying which signal to be hooked. | |
9922 * data: User data to be passed to the handler function. | |
9923 */ | |
9924 void dw_window_set_data(HWND window, char *dataname, void *data) | |
9925 { | |
9926 int _locked_by_me = FALSE; | |
9927 | |
9928 if(!window) | |
9929 return; | |
9930 | |
9931 DW_MUTEX_LOCK; | |
9932 if(GTK_IS_SCROLLED_WINDOW(window)) | |
9933 { | |
9934 HWND thiswindow = (HWND)g_object_get_data(G_OBJECT(window), "_dw_user"); | |
9935 | |
9936 if(thiswindow && G_IS_OBJECT(thiswindow)) | |
9937 g_object_set_data(G_OBJECT(thiswindow), dataname, (gpointer)data); | |
9938 #if 0 | |
9939 if(GTK_IS_COMBO_BOX(window)) | |
9940 g_object_set_data(G_OBJECT(GTK_COMBO_BOX(window)->entry), dataname, (gpointer)data); | |
9941 #endif | |
9942 g_object_set_data(G_OBJECT(window), dataname, (gpointer)data); | |
9943 } | |
9944 DW_MUTEX_UNLOCK; | |
9945 } | |
9946 | |
9947 /* | |
9948 * Gets a named user data item to a window handle. | |
9949 * Parameters: | |
9950 * window: Window handle of signal to be called back. | |
9951 * dataname: A string pointer identifying which signal to be hooked. | |
9952 * data: User data to be passed to the handler function. | |
9953 */ | |
9954 void *dw_window_get_data(HWND window, char *dataname) | |
9955 { | |
9956 int _locked_by_me = FALSE; | |
9957 void *ret = NULL; | |
9958 | |
9959 if(!window) | |
9960 return NULL; | |
9961 | |
9962 DW_MUTEX_LOCK; | |
9963 if(G_IS_OBJECT(window)) | |
9964 ret = (void *)g_object_get_data(G_OBJECT(window), dataname); | |
9965 DW_MUTEX_UNLOCK; | |
9966 return ret; | |
9967 } | |
9968 | |
9969 /* | |
9970 * Add a callback to a timer event. | |
9971 * Parameters: | |
9972 * interval: Milliseconds to delay between calls. | |
9973 * sigfunc: The pointer to the function to be used as the callback. | |
9974 * data: User data to be passed to the handler function. | |
9975 * Returns: | |
9976 * Timer ID for use with dw_timer_disconnect(), 0 on error. | |
9977 */ | |
9978 int API dw_timer_connect(int interval, void *sigfunc, void *data) | |
9979 { | |
9980 int tag, _locked_by_me = FALSE; | |
9981 | |
9982 DW_MUTEX_LOCK; | |
9983 tag = g_timeout_add(interval, (GSourceFunc)sigfunc, data); | |
9984 DW_MUTEX_UNLOCK; | |
9985 return tag; | |
9986 } | |
9987 | |
9988 /* | |
9989 * Removes timer callback. | |
9990 * Parameters: | |
9991 * id: Timer ID returned by dw_timer_connect(). | |
9992 */ | |
9993 void API dw_timer_disconnect(int id) | |
9994 { | |
9995 #if 0 /* TODO: Can't remove by ID anymore apparently... | |
9996 * need to rewrite it to return FALSE from the signal handler to stop. | |
9997 */ | |
9998 int _locked_by_me = FALSE; | |
9999 | |
10000 DW_MUTEX_LOCK; | |
10001 g_timeout_remove(id); | |
10002 DW_MUTEX_UNLOCK; | |
10003 #endif | |
10004 } | |
10005 | |
10006 /* Get the actual signal window handle not the user window handle | |
10007 * Should mimic the code in dw_signal_connect() below. | |
10008 */ | |
10009 static HWND _find_signal_window(HWND window, char *signame) | |
10010 { | |
10011 HWND thiswindow = window; | |
10012 | |
10013 if(GTK_IS_SCROLLED_WINDOW(thiswindow)) | |
10014 thiswindow = (HWND)g_object_get_data(G_OBJECT(window), "_dw_user"); | |
10015 #if 0 | |
10016 else if(GTK_IS_COMBO_BOX(thiswindow) && signame && strcmp(signame, DW_SIGNAL_LIST_SELECT) == 0) | |
10017 thiswindow = GTK_COMBO_BOX(thiswindow)->list; | |
10018 else if(GTK_IS_COMBO_BOX(thiswindow) && signame && strcmp(signame, DW_SIGNAL_SET_FOCUS) == 0) | |
10019 thiswindow = GTK_COMBO_BOX(thiswindow)->entry; | |
10020 #endif | |
10021 else if(GTK_IS_VSCALE(thiswindow) || GTK_IS_HSCALE(thiswindow) || | |
10022 GTK_IS_VSCROLLBAR(thiswindow) || GTK_IS_HSCROLLBAR(thiswindow) || | |
10023 GTK_IS_SPIN_BUTTON(thiswindow)) | |
10024 thiswindow = (GtkWidget *)g_object_get_data(G_OBJECT(thiswindow), "_dw_adjustment"); | |
10025 else if(GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_SELECT) == 0) | |
10026 thiswindow = (GtkWidget *)gtk_tree_view_get_selection(GTK_TREE_VIEW(thiswindow)); | |
10027 return thiswindow; | |
10028 } | |
10029 | |
10030 /* | |
10031 * Add a callback to a window event. | |
10032 * Parameters: | |
10033 * window: Window handle of signal to be called back. | |
10034 * signame: A string pointer identifying which signal to be hooked. | |
10035 * sigfunc: The pointer to the function to be used as the callback. | |
10036 * data: User data to be passed to the handler function. | |
10037 */ | |
10038 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) | |
10039 { | |
10040 void *thisfunc = _findsigfunc(signame); | |
10041 char *thisname = signame; | |
10042 HWND thiswindow = window; | |
10043 int sigid, _locked_by_me = FALSE; | |
10044 gint cid; | |
10045 | |
10046 DW_MUTEX_LOCK; | |
10047 /* | |
10048 * If the window we are setting the signal on is a scrolled window we need to get | |
10049 * the "real" widget type. thiswindow is the "real" widget type | |
10050 */ | |
10051 if (GTK_IS_SCROLLED_WINDOW(thiswindow)) | |
10052 { | |
10053 thiswindow = (HWND)g_object_get_data(G_OBJECT(window), "_dw_user"); | |
10054 } | |
10055 | |
10056 if (GTK_IS_MENU_ITEM(thiswindow) && strcmp(signame, DW_SIGNAL_CLICKED) == 0) | |
10057 { | |
10058 thisname = "activate"; | |
10059 thisfunc = _findsigfunc(thisname); | |
10060 } | |
10061 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_CONTEXT) == 0) | |
10062 { | |
10063 thisfunc = _findsigfunc("tree-context"); | |
10064 | |
10065 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); | |
10066 cid = g_signal_connect(G_OBJECT(thiswindow), "button_press_event", G_CALLBACK(thisfunc), (gpointer)sigid); | |
10067 _set_signal_handler_id(thiswindow, sigid, cid); | |
10068 | |
10069 #if 0 | |
10070 sigid = _set_signal_handler(window, window, sigfunc, data, thisfunc); | |
10071 cid = g_signal_connect(G_OBJECT(window), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), (gpointer)sigid); | |
10072 _set_signal_handler_id(window, sigid, cid); | |
10073 #endif | |
10074 | |
10075 DW_MUTEX_UNLOCK; | |
10076 return; | |
10077 } | |
10078 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_SELECT) == 0) | |
10079 { | |
10080 GtkWidget *treeview = thiswindow; | |
10081 | |
10082 thiswindow = (GtkWidget *)gtk_tree_view_get_selection(GTK_TREE_VIEW(thiswindow)); | |
10083 thisname = "changed"; | |
10084 | |
10085 sigid = _set_signal_handler(treeview, window, sigfunc, data, thisfunc); | |
10086 cid = g_signal_connect(G_OBJECT(thiswindow), thisname, (GCallback)thisfunc, (gpointer)sigid); | |
10087 _set_signal_handler_id(treeview, sigid, cid); | |
10088 DW_MUTEX_UNLOCK; | |
10089 return; | |
10090 } | |
10091 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_TREE_EXPAND) == 0) | |
10092 { | |
10093 thisname = "row-expanded"; | |
10094 } | |
10095 #if 0 | |
10096 else if (GTK_IS_CLIST(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_ENTER) == 0) | |
10097 { | |
10098 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _container_enter_event); | |
10099 cid = g_signal_connect(G_OBJECT(thiswindow), "key_press_event", GTK_SIGNAL_FUNC(_container_enter_event), (gpointer)sigid); | |
10100 _set_signal_handler_id(thiswindow, sigid, cid); | |
10101 | |
10102 thisname = "button_press_event"; | |
10103 thisfunc = _findsigfunc(DW_SIGNAL_ITEM_ENTER); | |
10104 } | |
10105 else if (GTK_IS_CLIST(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_SELECT) == 0) | |
10106 { | |
10107 thisname = "select_row"; | |
10108 thisfunc = (void *)_container_select_row; | |
10109 } | |
10110 else if (GTK_IS_CLIST(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_CONTEXT) == 0) | |
10111 { | |
10112 thisname = "button_press_event"; | |
10113 thisfunc = _findsigfunc(DW_SIGNAL_ITEM_CONTEXT); | |
10114 } | |
10115 else if (GTK_IS_CLIST(thiswindow) && strcmp(signame, DW_SIGNAL_COLUMN_CLICK) == 0) | |
10116 { | |
10117 thisname = "click-column"; | |
10118 } | |
10119 else if (GTK_IS_COMBO_BOX(thiswindow) && strcmp(signame, DW_SIGNAL_LIST_SELECT) == 0) | |
10120 { | |
10121 thisname = "select_child"; | |
10122 thiswindow = GTK_COMBO_BOX(thiswindow)->list; | |
10123 } | |
10124 else if (GTK_IS_LIST(thiswindow) && strcmp(signame, DW_SIGNAL_LIST_SELECT) == 0) | |
10125 { | |
10126 thisname = "select_child"; | |
10127 } | |
10128 else if (strcmp(signame, DW_SIGNAL_SET_FOCUS) == 0) | |
10129 { | |
10130 thisname = "focus-in-event"; | |
10131 if (GTK_IS_COMBO_BOX(thiswindow)) | |
10132 thiswindow = GTK_COMBO_BOX(thiswindow)->entry; | |
10133 } | |
10134 #endif | |
10135 #if 0 | |
10136 else if (strcmp(signame, DW_SIGNAL_LOSE_FOCUS) == 0) | |
10137 { | |
10138 thisname = "focus-out-event"; | |
10139 if(GTK_IS_COMBO_BOX(thiswindow)) | |
10140 thiswindow = GTK_COMBO_BOX(thiswindow)->entry; | |
10141 } | |
10142 #endif | |
10143 else if (GTK_IS_VSCALE(thiswindow) || GTK_IS_HSCALE(thiswindow) || | |
10144 GTK_IS_VSCROLLBAR(thiswindow) || GTK_IS_HSCROLLBAR(thiswindow) || | |
10145 GTK_IS_SPIN_BUTTON(thiswindow) ) | |
10146 { | |
10147 thiswindow = (GtkWidget *)g_object_get_data(G_OBJECT(thiswindow), "_dw_adjustment"); | |
10148 } | |
10149 else if (GTK_IS_NOTEBOOK(thiswindow) && strcmp(signame, DW_SIGNAL_SWITCH_PAGE) == 0) | |
10150 { | |
10151 thisname = "switch-page"; | |
10152 } | |
10153 | |
10154 if (!thisfunc || !thiswindow) | |
10155 { | |
10156 DW_MUTEX_UNLOCK; | |
10157 return; | |
10158 } | |
10159 | |
10160 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); | |
10161 cid = g_signal_connect(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc),(gpointer)sigid); | |
10162 _set_signal_handler_id(thiswindow, sigid, cid); | |
10163 DW_MUTEX_UNLOCK; | |
10164 } | |
10165 | |
10166 /* | |
10167 * Removes callbacks for a given window with given name. | |
10168 * Parameters: | |
10169 * window: Window handle of callback to be removed. | |
10170 */ | |
10171 void dw_signal_disconnect_by_name(HWND window, char *signame) | |
10172 { | |
10173 HWND thiswindow; | |
10174 int z, count; | |
10175 void *thisfunc; | |
10176 int _locked_by_me = FALSE; | |
10177 | |
10178 DW_MUTEX_LOCK; | |
10179 thiswindow = _find_signal_window(window, signame); | |
10180 count = (int)g_object_get_data(G_OBJECT(thiswindow), "_dw_sigcounter"); | |
10181 thisfunc = _findsigfunc(signame); | |
10182 | |
10183 for(z=0;z<count;z++) | |
10184 { | |
10185 SignalHandler sh = _get_signal_handler(thiswindow, (gpointer)z); | |
10186 | |
10187 if(sh.intfunc == thisfunc) | |
10188 _remove_signal_handler(thiswindow, z); | |
10189 } | |
10190 DW_MUTEX_UNLOCK; | |
10191 } | |
10192 | |
10193 /* | |
10194 * Removes all callbacks for a given window. | |
10195 * Parameters: | |
10196 * window: Window handle of callback to be removed. | |
10197 */ | |
10198 void dw_signal_disconnect_by_window(HWND window) | |
10199 { | |
10200 HWND thiswindow; | |
10201 int z, count; | |
10202 int _locked_by_me = FALSE; | |
10203 | |
10204 DW_MUTEX_LOCK; | |
10205 thiswindow = _find_signal_window(window, NULL); | |
10206 count = (int)g_object_get_data(G_OBJECT(thiswindow), "_dw_sigcounter"); | |
10207 | |
10208 for(z=0;z<count;z++) | |
10209 _remove_signal_handler(thiswindow, z); | |
10210 g_object_set_data(G_OBJECT(thiswindow), "_dw_sigcounter", NULL); | |
10211 DW_MUTEX_UNLOCK; | |
10212 } | |
10213 | |
10214 /* | |
10215 * Removes all callbacks for a given window with specified data. | |
10216 * Parameters: | |
10217 * window: Window handle of callback to be removed. | |
10218 * data: Pointer to the data to be compared against. | |
10219 */ | |
10220 void dw_signal_disconnect_by_data(HWND window, void *data) | |
10221 { | |
10222 HWND thiswindow; | |
10223 int z, count; | |
10224 int _locked_by_me = FALSE; | |
10225 | |
10226 DW_MUTEX_LOCK; | |
10227 thiswindow = _find_signal_window(window, NULL); | |
10228 count = (int)g_object_get_data(G_OBJECT(thiswindow), "_dw_sigcounter"); | |
10229 | |
10230 for(z=0;z<count;z++) | |
10231 { | |
10232 SignalHandler sh = _get_signal_handler(thiswindow, (gpointer)z); | |
10233 | |
10234 if(sh.data == data) | |
10235 _remove_signal_handler(thiswindow, z); | |
10236 } | |
10237 DW_MUTEX_UNLOCK; | |
10238 } | |
10239 |