comparison gtk/dw.c @ 3:67a643a734d9

Import
author ktk@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 03 Jul 2001 07:50:39 +0000
parents
children 005fa766e8c2
comparison
equal deleted inserted replaced
2:36c5f0ce3fbe 3:67a643a734d9
1 /*
2 * Dynamic Windows:
3 * A GTK like implementation of the PM GUI
4 * GTK forwarder module for portabilty.
5 *
6 * (C) 2000,2001 Brian Smith <dbsoft@technologist.com>
7 *
8 */
9 #include "dw.h"
10 #include <string.h>
11 #include <stdlib.h>
12 #include <sys/utsname.h>
13 #include <stdarg.h>
14 #include <stdio.h>
15 #include <unistd.h>
16 #include <errno.h>
17 #include <sys/time.h>
18 #include "config.h"
19 #ifdef USE_IMLIB
20 #include <gdk_imlib.h>
21 #endif
22
23 /* These are used for resource management */
24 #if defined(DW_RESOURCES) && !defined(BUILD_DLL)
25 extern DWResources _resources;
26 #endif
27
28 char monthlist[][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
29 "Sep", "Oct", "Nov", "Dec" };
30 GdkColor _colors[] =
31 {
32 { 0, 0x0000, 0x0000, 0x0000 }, /* 0 black */
33 { 0, 0xbbbb, 0x0000, 0x0000 }, /* 1 red */
34 { 0, 0x0000, 0xbbbb, 0x0000 }, /* 2 green */
35 { 0, 0xaaaa, 0xaaaa, 0x0000 }, /* 3 yellow */
36 { 0, 0x0000, 0x0000, 0xcccc }, /* 4 blue */
37 { 0, 0xbbbb, 0x0000, 0xbbbb }, /* 5 magenta */
38 { 0, 0x0000, 0xbbbb, 0xbbbb }, /* 6 cyan */
39 { 0, 0xaaaa, 0xaaaa, 0xaaaa }, /* 7 white */
40 { 0, 0x7777, 0x7777, 0x7777 }, /* 8 grey */
41 { 0, 0xffff, 0x0000, 0x0000 }, /* 9 bright red */
42 { 0, 0x0000, 0xffff, 0x0000 }, /* 10 bright green */
43 { 0, 0xeeee, 0xeeee, 0x0000 }, /* 11 bright yellow */
44 { 0, 0x0000, 0x0000, 0xffff }, /* 12 bright blue */
45 { 0, 0xffff, 0x0000, 0xffff }, /* 13 bright magenta */
46 { 0, 0x0000, 0xeeee, 0xeeee }, /* 14 bright cyan */
47 { 0, 0xffff, 0xffff, 0xffff }, /* 15 bright white */
48 };
49
50 GdkColor _foreground = { 0, 0x0000, 0x0000, 0x0000 };
51 GdkColor _background = { 0, 0xaaaa, 0xaaaa, 0xaaaa };
52
53 char *_dw_browse_file = NULL;
54 int _dw_file_active = 0, _dw_file_ready = 0;
55 pthread_t _dw_thread = (pthread_t)-1;
56 int _dw_mutex_locked = FALSE;
57
58 #define DW_MUTEX_LOCK { if(pthread_self() != _dw_thread && _dw_mutex_locked == FALSE) { gdk_threads_enter(); _dw_mutex_locked = TRUE; _locked_by_me = TRUE; } }
59 #define DW_MUTEX_UNLOCK { if(pthread_self() != _dw_thread && _locked_by_me == TRUE) { gdk_threads_leave(); _dw_mutex_locked = FALSE; _locked_by_me = FALSE; } }
60
61 /* Currently the non Imlib method does not work */
62 #ifndef USE_IMLIB
63 #define USE_IMLIB
64 #endif
65
66 GdkColormap *_dw_cmap = NULL;
67
68 /* Signal forwarder prototypes */
69 gint _button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data);
70 gint _button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data);
71 gint _motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data);
72 gint _delete_event(GtkWidget *widget, GdkEvent *event, gpointer data);
73 gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data);
74 gint _generic_event(GtkWidget *widget, gpointer data);
75 gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data);
76 void _activate_event(GtkWidget *widget, gpointer data);
77 void _container_select_event(GtkWidget *widget, GdkEventButton *event, gpointer data);
78 void _container_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data);
79 void _item_select_event(GtkWidget *widget, GtkWidget *child, gpointer data);
80 void _expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data);
81
82 typedef struct
83 {
84 void *func;
85 char name[30];
86
87 } SignalList;
88
89 typedef struct
90 {
91 HWND window;
92 void *func;
93 gpointer data;
94
95 } SignalHandler;
96
97 #define SIGNALMAX 12
98
99 /* A list of signal forwarders, to account for paramater differences. */
100 SignalList SignalTranslate[SIGNALMAX] = {
101 { _configure_event, "configure_event" },
102 { _key_press_event, "key_press_event" },
103 { _button_press_event, "button_press_event" },
104 { _button_release_event, "button_release_event" },
105 { _motion_notify_event, "motion_notify_event" },
106 { _delete_event, "delete_event" },
107 { _expose_event, "expose_event" },
108 { _activate_event, "activate" },
109 { _generic_event, "clicked" },
110 { _container_select_event, "container-select" },
111 { _container_context_event, "container-context" },
112 { _item_select_event, "item-select" }
113 };
114
115 /* Finds the translation function for a given signal name */
116 void *_findsigfunc(char *signame)
117 {
118 int z;
119
120 for(z=0;z<SIGNALMAX;z++)
121 {
122 if(strcasecmp(signame, SignalTranslate[z].name) == 0)
123 return SignalTranslate[z].func;
124 }
125 return NULL;
126 }
127
128 gint _button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
129 {
130 SignalHandler *work = (SignalHandler *)data;
131
132 if(work)
133 {
134 int (*buttonfunc)(HWND, int, int, int, void *) = work->func;
135 int mybutton = event->button;
136
137 if(event->button == 3)
138 mybutton = 2;
139 else if(event->button == 2)
140 mybutton = 3;
141
142 buttonfunc(widget, event->x, event->y, mybutton, work->data);
143 }
144 return TRUE;
145 }
146
147 gint _button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
148 {
149 SignalHandler *work = (SignalHandler *)data;
150
151 if(work)
152 {
153 int (*buttonfunc)(HWND, int, int, int, void *) = work->func;
154 int mybutton = event->button;
155
156 if(event->button == 3)
157 mybutton = 2;
158 else if(event->button == 2)
159 mybutton = 3;
160
161 buttonfunc(widget, event->x, event->y, mybutton, work->data);
162 }
163 return TRUE;
164 }
165
166 gint _motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
167 {
168 SignalHandler *work = (SignalHandler *)data;
169
170 if(work)
171 {
172 int (*motionfunc)(HWND, int, int, int, void *) = work->func;
173 int keys = 0, x, y;
174 GdkModifierType state;
175
176 if (event->is_hint)
177 gdk_window_get_pointer (event->window, &x, &y, &state);
178 else
179 {
180 x = event->x;
181 y = event->y;
182 state = event->state;
183 }
184
185 if (state & GDK_BUTTON1_MASK)
186 keys = DW_BUTTON1_MASK;
187 if (state & GDK_BUTTON3_MASK)
188 keys |= DW_BUTTON2_MASK;
189 if (state & GDK_BUTTON2_MASK)
190 keys |= DW_BUTTON3_MASK;
191
192 motionfunc(widget, x, y, keys, work->data);
193 }
194 return TRUE;
195 }
196
197 gint _delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
198 {
199 SignalHandler *work = (SignalHandler *)data;
200
201 if(work)
202 {
203 int (*closefunc)(HWND, void *) = work->func;
204
205 closefunc(widget, data);
206 }
207 return TRUE;
208 }
209
210 gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
211 {
212 SignalHandler *work = (SignalHandler *)data;
213
214 if(work)
215 {
216 int (*keypressfunc)(HWND, int, void *) = work->func;
217
218 keypressfunc(widget, *event->string, work->data);
219 }
220 return TRUE;
221 }
222
223 gint _generic_event(GtkWidget *widget, gpointer data)
224 {
225 SignalHandler *work = (SignalHandler *)data;
226
227 if(work)
228 {
229 int (*genericfunc)(HWND, void *) = work->func;
230
231 genericfunc(widget, work->data);
232 }
233 return TRUE;
234 }
235
236 void _activate_event(GtkWidget *widget, gpointer data)
237 {
238 SignalHandler *work = (SignalHandler *)data;
239
240 if(work)
241 {
242 void (*activatefunc)(HWND, void *) = work->func;
243
244 activatefunc(work->window, work->data);
245 }
246 return;
247 }
248
249 gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
250 {
251 SignalHandler *work = (SignalHandler *)data;
252
253 if(work)
254 {
255 int (*sizefunc)(HWND, int, int, void *) = work->func;
256
257 sizefunc(widget, event->width, event->height, work->data);
258 }
259 return TRUE;
260 }
261
262 void _expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
263 {
264 SignalHandler *work = (SignalHandler *)data;
265
266 if(work)
267 {
268 DWExpose exp;
269 int (*exposefunc)(HWND, DWExpose *, void *) = work->func;
270
271 exp.x = event->area.x;
272 exp.y = event->area.y;
273 exp.width = event->area.width;
274 exp.height = event->area.height;
275 exposefunc(widget, &exp, work->data);
276 }
277 }
278
279 void _item_select_event(GtkWidget *widget, GtkWidget *child, gpointer data)
280 {
281 SignalHandler *work = (SignalHandler *)data;
282
283 if(work)
284 {
285 int (*selectfunc)(HWND, int, void *) = work->func;
286 GList *list;
287 int item = 0;
288
289 if(GTK_IS_COMBO(work->window))
290 list = GTK_LIST(GTK_COMBO(work->window)->list)->children;
291 else if(GTK_IS_LIST(widget))
292 list = GTK_LIST(widget)->children;
293 else
294 return;
295
296 while(list)
297 {
298 if(list->data == (gpointer)child)
299 {
300 gtk_object_set_data(GTK_OBJECT(work->window), "item", (gpointer)item);
301 selectfunc(work->window, item, work->data);
302 break;
303 }
304 item++;
305 list = list->next;
306 }
307 }
308 }
309
310 void _container_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
311 {
312 SignalHandler *work = (SignalHandler *)data;
313
314 if(work)
315 {
316 if(event->button == 3)
317 {
318 void (*contextfunc)(HWND, char *, int, int, void *) = work->func;
319 char *text;
320 int row, col;
321
322 gtk_clist_get_selection_info(GTK_CLIST(widget), event->x, event->y, &row, &col);
323
324 text = (char *)gtk_clist_get_row_data(GTK_CLIST(widget), row);
325 contextfunc(work->window, text, event->x, event->y, work->data);
326 }
327 }
328 }
329
330 void _container_select_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
331 {
332 SignalHandler *work = (SignalHandler *)data;
333
334 if(work)
335 {
336 if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
337 {
338 void (*contextfunc)(HWND, char *, void *) = work->func;
339 char *text;
340 int row, col;
341
342 gtk_clist_get_selection_info(GTK_CLIST(widget), event->x, event->y, &row, &col);
343
344 text = (char *)gtk_clist_get_row_data(GTK_CLIST(widget), row);
345 contextfunc(work->window, text, work->data);
346 }
347 }
348 }
349
350 void _select_row(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data)
351 {
352 GList *tmp = (GList *)gtk_object_get_data(GTK_OBJECT(widget), "selectlist");
353 char *rowdata = gtk_clist_get_row_data(GTK_CLIST(widget), row);
354
355 if(rowdata)
356 {
357 tmp = g_list_append(tmp, rowdata);
358 gtk_object_set_data(GTK_OBJECT(widget), "selectlist", tmp);
359 }
360
361 }
362
363 void _unselect_row(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data)
364 {
365 GList *tmp = (GList *)gtk_object_get_data(GTK_OBJECT(widget), "selectlist");
366 char *rowdata = gtk_clist_get_row_data(GTK_CLIST(widget), row);
367
368 if(rowdata)
369 {
370 g_list_remove(tmp, rowdata);
371 gtk_object_set_data(GTK_OBJECT(widget), "selectlist", tmp);
372 }
373 }
374
375 GdkPixmap *_find_pixmap(GdkBitmap **bitmap, long id, HWND handle)
376 {
377 char *data = NULL;
378 int z;
379
380 for(z=0;z<_resources.resource_max;z++)
381 {
382 if(_resources.resource_id[z] == id)
383 {
384 data = _resources.resource_data[z];
385 break;
386 }
387 }
388
389 if(data)
390 {
391 GdkPixmap *icon_pixmap = NULL;
392 #ifndef USE_IMLIB
393 GtkStyle *iconstyle;
394
395 /* hmmm why do we need the handle here? */
396 iconstyle = gtk_widget_get_style(handle);
397 if (!icon_pixmap)
398 icon_pixmap = gdk_pixmap_create_from_xpm_d(handle->window, bitmap, &iconstyle->bg[GTK_STATE_NORMAL], &data);
399 #else
400 gdk_imlib_data_to_pixmap((char **)data, &icon_pixmap, bitmap);
401 #endif
402 return icon_pixmap;
403 }
404 return NULL;
405 }
406
407 void _size_allocate(GtkWindow *window)
408 {
409 XSizeHints sizehints;
410
411 sizehints.base_width = 1;
412 sizehints.base_height = 1;
413 sizehints.width_inc = 1;
414 sizehints.height_inc = 1;
415 sizehints.min_width = 8;
416 sizehints.min_height = 8;
417
418 sizehints.flags = (PBaseSize|PMinSize|PResizeInc);
419
420 XSetWMNormalHints (GDK_DISPLAY(),
421 GDK_WINDOW_XWINDOW (GTK_WIDGET (window)->window),
422 &sizehints);
423 gdk_flush ();
424 }
425
426 /*
427 * Initializes the Dynamic Windows engine.
428 * Parameters:
429 * newthread: True if this is the only thread.
430 * False if there is already a message loop running.
431 */
432 int dw_int_init(DWResources *res, int newthread)
433 {
434 int z;
435
436 if(res)
437 {
438 _resources.resource_max = res->resource_max;
439 _resources.resource_id = res->resource_id;
440 _resources.resource_data = res->resource_data;
441 }
442 gtk_set_locale();
443 g_thread_init(NULL);
444 gtk_init(0, NULL);
445 #ifdef USE_IMLIB
446 gdk_imlib_init();
447 #endif
448 /* Add colors to the system colormap */
449 _dw_cmap = gdk_colormap_get_system();
450 for(z=0;z<16;z++)
451 gdk_color_alloc(_dw_cmap, &_colors[z]);
452 return TRUE;
453 }
454
455 /*
456 * Runs a message loop for Dynamic Windows.
457 * Parameters:
458 * currenthab: The handle to the current anchor block
459 * or NULL if this DW is handling the message loop.
460 * func: Function pointer to the message filter function.
461 */
462 void dw_main(HAB currenthab, void *func)
463 {
464 _dw_thread = pthread_self();
465 gdk_threads_enter();
466 gtk_main();
467 gdk_threads_leave();
468 }
469
470 /*
471 * Free's memory allocated by dynamic windows.
472 * Parameters:
473 * ptr: Pointer to dynamic windows allocated
474 * memory to be free()'d.
475 */
476 void dw_free(void *ptr)
477 {
478 free(ptr);
479 }
480
481 /*
482 * Allocates and initializes a dialog struct.
483 * Parameters:
484 * data: User defined data to be passed to functions.
485 */
486 DWDialog *dw_dialog_new(void *data)
487 {
488 DWDialog *tmp = malloc(sizeof(DWDialog));
489
490 tmp->eve = dw_event_new();
491 dw_event_reset(tmp->eve);
492 tmp->data = data;
493 tmp->done = FALSE;
494 tmp->result = NULL;
495
496 return tmp;
497 }
498
499 /*
500 * Accepts a dialog struct and returns the given data to the
501 * initial called of dw_dialog_wait().
502 * Parameters:
503 * dialog: Pointer to a dialog struct aquired by dw_dialog_new).
504 * result: Data to be returned by dw_dialog_wait().
505 */
506 int dw_dialog_dismiss(DWDialog *dialog, void *result)
507 {
508 dialog->result = result;
509 if(pthread_self() == _dw_thread)
510 gtk_main_quit();
511 else
512 dw_event_post(dialog->eve);
513 dialog->done = TRUE;
514 return 0;
515 }
516
517 /*
518 * Accepts a dialog struct waits for dw_dialog_dismiss() to be
519 * called by a signal handler with the given dialog struct.
520 * Parameters:
521 * dialog: Pointer to a dialog struct aquired by dw_dialog_new).
522 */
523 void *dw_dialog_wait(DWDialog *dialog)
524 {
525 void *tmp;
526
527 if(pthread_self() == _dw_thread)
528 gtk_main();
529 else
530 dw_event_wait(dialog->eve, -1);
531
532 dw_event_close(&dialog->eve);
533 tmp = dialog->result;
534 free(dialog);
535 return tmp;
536 }
537
538 void _delete(GtkWidget *widget, GtkWidget *event, gpointer param)
539 {
540 gtk_widget_destroy(GTK_WIDGET(param));
541 }
542
543 void _delete2(GtkWidget *widget, gpointer param)
544 {
545 gtk_widget_destroy(GTK_WIDGET(param));
546 }
547
548
549 /*
550 * Displays a Message Box with given text and title..
551 * Parameters:
552 * title: The title of the message box.
553 * format: printf style format string.
554 * ...: Additional variables for use in the format.
555 */
556 int dw_messagebox(char *title, char *format, ...)
557 {
558 va_list args;
559 char outbuf[256];
560 GtkWidget *dialog,
561 *button,
562 *label;
563 int _locked_by_me = FALSE;
564
565 DW_MUTEX_LOCK;
566 va_start(args, format);
567 vsprintf(outbuf, format, args);
568 va_end(args);
569
570 dialog = gtk_dialog_new();
571
572 gtk_window_set_title(GTK_WINDOW(dialog), title);
573
574 button = gtk_button_new_with_label("Ok");
575 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, TRUE, TRUE, 0);
576 gtk_widget_show(button);
577
578 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(_delete2), (gpointer)dialog);
579 gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", GTK_SIGNAL_FUNC(_delete), (gpointer)dialog);
580
581 label = gtk_label_new(outbuf);
582 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 20);
583 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
584 gtk_widget_show(label);
585
586 gtk_widget_show(dialog);
587
588 DW_MUTEX_UNLOCK;
589
590 return strlen(outbuf);
591 }
592
593 /*
594 * Displays a Message Box with given text and title..
595 * Parameters:
596 * title: The title of the message box.
597 * text: The text to display in the box.
598 * Returns:
599 * True if YES False of NO.
600 */
601 int dw_yesno(char *title, char *text)
602 {
603 return FALSE;
604 }
605
606 /*
607 * Makes the window visible.
608 * Parameters:
609 * handle: The window handle to make visible.
610 */
611 int dw_window_show(HWND handle)
612 {
613 int _locked_by_me = FALSE;
614
615 DW_MUTEX_LOCK;
616 gtk_widget_show(handle);
617 DW_MUTEX_UNLOCK;
618 return 0;
619 }
620
621 /*
622 * Makes the window invisible.
623 * Parameters:
624 * handle: The window handle to make visible.
625 */
626 int dw_window_hide(HWND handle)
627 {
628 int _locked_by_me = FALSE;
629
630 DW_MUTEX_LOCK;
631 gtk_widget_hide(handle);
632 DW_MUTEX_UNLOCK;
633 return 0;
634 }
635
636 /*
637 * Destroys a window and all of it's children.
638 * Parameters:
639 * handle: The window handle to destroy.
640 */
641 int dw_window_destroy(HWND handle)
642 {
643 int _locked_by_me = FALSE;
644
645 DW_MUTEX_LOCK;
646 gtk_widget_destroy(handle);
647 DW_MUTEX_UNLOCK;
648 return 0;
649 }
650
651 /*
652 * Changes a window's parent to newparent.
653 * Parameters:
654 * handle: The window handle to destroy.
655 * newparent: The window's new parent window.
656 */
657 void dw_window_reparent(HWND handle, HWND newparent)
658 {
659 gtk_widget_reparent(handle, newparent);
660 }
661
662 int _set_font(HWND handle, char *fontname)
663 {
664 GtkStyle *style;
665 GdkFont *font = NULL;
666 int retval = FALSE;
667
668 font = gdk_font_load(fontname);
669
670 if(font)
671 {
672 style = gtk_widget_get_style(handle);
673 style->font = font;
674 gtk_widget_set_style(handle, style);
675 retval = TRUE;
676 }
677 return retval;
678 }
679
680 /*
681 * Sets the font used by a specified window (widget) handle.
682 * Parameters:
683 * handle: The window (widget) handle.
684 * fontname: Name and size of the font in the form "size.fontname"
685 */
686 int dw_window_set_font(HWND handle, char *fontname)
687 {
688 GtkWidget *handle2 = handle;
689 char *font;
690 int _locked_by_me = FALSE;
691 gpointer data;
692
693 DW_MUTEX_LOCK;
694 if(GTK_IS_SCROLLED_WINDOW(handle))
695 {
696 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
697 if(tmp)
698 handle2 = tmp;
699 }
700 font = strdup(fontname);
701
702 data = gtk_object_get_data(GTK_OBJECT(handle2), "fontname");
703 if(data)
704 free(data);
705
706 if(font)
707 gtk_object_set_data(GTK_OBJECT(handle2), "fontname", (gpointer)font);
708
709 DW_MUTEX_UNLOCK;
710 return TRUE;
711 }
712
713 int _set_color(HWND handle, unsigned long fore, unsigned long back)
714 {
715 GtkStyle *style;
716
717 if(fore & DW_RGB_COLOR || back & DW_RGB_COLOR)
718 {
719 GdkColor forecolor = { 0, DW_RED_VALUE(fore) << 8, DW_GREEN_VALUE(fore) << 8, DW_BLUE_VALUE(fore) << 8 };
720 GdkColor backcolor = { 0, DW_RED_VALUE(back) << 8, DW_GREEN_VALUE(back) << 8, DW_BLUE_VALUE(back) << 8 };
721
722 gdk_color_alloc(_dw_cmap, &forecolor);
723 gdk_color_alloc(_dw_cmap, &backcolor);
724
725 style = gtk_widget_get_style(handle);
726 style->fg[0] = forecolor;
727 style->bg[0] = backcolor;
728 gtk_widget_set_style(handle, style);
729 }
730 else
731 {
732 style = gtk_widget_get_style(handle);
733 style->fg[0] = _colors[fore];
734 style->bg[0] = _colors[back];
735 gtk_widget_set_style(handle, style);
736 }
737
738 return TRUE;
739 }
740 /*
741 * Sets the colors used by a specified window (widget) handle.
742 * Parameters:
743 * handle: The window (widget) handle.
744 * fore: Foreground color in RGB format.
745 * back: Background color in RGB format.
746 */
747 int dw_window_set_color(HWND handle, unsigned long fore, unsigned long back)
748 {
749 GtkWidget *handle2 = handle;
750 int _locked_by_me = FALSE;
751
752 DW_MUTEX_LOCK;
753
754 if(GTK_IS_SCROLLED_WINDOW(handle))
755 {
756 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
757 if(tmp)
758 handle2 = tmp;
759 }
760
761 gtk_object_set_data(GTK_OBJECT(handle2), "fore", (gpointer)fore);
762 gtk_object_set_data(GTK_OBJECT(handle2), "back", (gpointer)back);
763
764 _set_color(handle2, fore, back);
765
766 DW_MUTEX_UNLOCK;
767 return TRUE;
768 }
769
770 /*
771 * Sets the font used by a specified window (widget) handle.
772 * Parameters:
773 * handle: The window (widget) handle.
774 * border: Size of the window border in pixels.
775 */
776 int dw_window_set_border(HWND handle, int border)
777 {
778 /* TODO */
779 return 0;
780 }
781
782 /*
783 * Captures the mouse input to this window.
784 * Parameters:
785 * handle: Handle to receive mouse input.
786 */
787 void dw_window_capture(HWND handle)
788 {
789 int _locked_by_me = FALSE;
790
791 DW_MUTEX_LOCK;
792 gdk_pointer_grab(handle->window, TRUE, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK, NULL, NULL, GDK_CURRENT_TIME);
793 DW_MUTEX_UNLOCK;
794 }
795
796 /*
797 * Releases previous mouse capture.
798 */
799 void dw_window_release(void)
800 {
801 int _locked_by_me = FALSE;
802
803 DW_MUTEX_LOCK;
804 gdk_pointer_ungrab(GDK_CURRENT_TIME);
805 DW_MUTEX_UNLOCK;
806 }
807
808 /*
809 * Create a new Window Frame.
810 * Parameters:
811 * owner: The Owner's window handle or HWND_DESKTOP.
812 * title: The Window title.
813 * flStyle: Style flags, see the PM reference.
814 */
815 HWND dw_window_new(HWND hwndOwner, char *title, unsigned long flStyle)
816 {
817 GtkWidget *tmp;
818 int _locked_by_me = FALSE;
819 int flags = 0;
820
821 DW_MUTEX_LOCK;
822 tmp = gtk_window_new(GTK_WINDOW_TOPLEVEL);
823
824 gtk_window_set_title(GTK_WINDOW(tmp), title);
825 if(!(flStyle & DW_FCF_SIZEBORDER))
826 gtk_window_set_policy(GTK_WINDOW(tmp), FALSE, FALSE, TRUE);
827
828 gtk_widget_realize(tmp);
829
830 if(flStyle & DW_FCF_TITLEBAR)
831 flags |= GDK_DECOR_TITLE;
832
833 if(flStyle & DW_FCF_MINMAX)
834 flags |= GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE;
835
836 if(flStyle & DW_FCF_SIZEBORDER)
837 flags |= GDK_DECOR_RESIZEH;
838
839 if(flStyle & DW_FCF_BORDER)
840 flags |= GDK_DECOR_BORDER;
841
842 gdk_window_set_decorations(tmp->window, flags);
843
844 DW_MUTEX_UNLOCK;
845 return tmp;
846 }
847
848 /*
849 * Create a new Box to be packed.
850 * Parameters:
851 * type: Either BOXVERT (vertical) or BOXHORZ (horizontal).
852 * pad: Number of pixels to pad around the box.
853 */
854 HWND dw_box_new(int type, int pad)
855 {
856 GtkWidget *tmp;
857 int _locked_by_me = FALSE;
858
859 DW_MUTEX_LOCK;
860 if(type == BOXVERT)
861 tmp = gtk_vbox_new(FALSE, pad);
862 else
863 tmp = gtk_hbox_new(FALSE, pad);
864 gtk_widget_show(tmp);
865 DW_MUTEX_UNLOCK;
866 return tmp;
867 }
868
869 /*
870 * Create a new Group Box to be packed.
871 * Parameters:
872 * type: Either BOXVERT (vertical) or BOXHORZ (horizontal).
873 * pad: Number of pixels to pad around the box.
874 * title: Text to be displayined in the group outline.
875 */
876 HWND dw_groupbox_new(int type, int pad, char *title)
877 {
878 return dw_box_new(type, pad);
879 }
880
881 /*
882 * Create a bitmap object to be packed.
883 * Parameters:
884 * id: An ID to be used with WinWindowFromID() or 0L.
885 */
886 HWND dw_bitmap_new(unsigned long id)
887 {
888 GdkPixmap *pixmap= NULL;
889 GdkBitmap *bitmap;
890 GtkWidget *tmp;
891 char * test_xpm[] = {
892 "1 1 1 1",
893 " c None",
894 " "};
895 int _locked_by_me = FALSE;
896
897 DW_MUTEX_LOCK;
898 #ifndef USE_IMLIB
899 GtkStyle *iconstyle;
900
901 /* hmmm why do we need the handle here? */
902 iconstyle = gtk_widget_get_style(handle);
903 if (!pixmap)
904 pixmap = gdk_pixmap_create_from_xpm_d(handle->window, &bitmap, &iconstyle->bg[GTK_STATE_NORMAL], &test_xpm);
905 #else
906 gdk_imlib_data_to_pixmap(test_xpm, &pixmap, &bitmap);
907 #endif
908 tmp = gtk_pixmap_new(pixmap, bitmap);
909 gtk_widget_show(tmp);
910 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
911 DW_MUTEX_UNLOCK;
912 return tmp;
913 }
914
915 /*
916 * Create a notebook object to be packed.
917 * Parameters:
918 * id: An ID to be used for getting the resource from the
919 * resource file.
920 */
921 HWND dw_notebook_new(unsigned long id, int top)
922 {
923 GtkWidget *tmp;
924 int _locked_by_me = FALSE;
925
926 DW_MUTEX_LOCK;
927 tmp = gtk_notebook_new();
928 if(top)
929 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tmp), GTK_POS_TOP);
930 else
931 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tmp), GTK_POS_BOTTOM);
932 gtk_widget_show(tmp);
933 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
934 DW_MUTEX_UNLOCK;
935 return tmp;
936 }
937
938 /*
939 * Create a menu object to be popped up.
940 * Parameters:
941 * id: An ID to be used for getting the resource from the
942 * resource file.
943 */
944 HMENUI dw_menu_new(unsigned long id)
945 {
946 int _locked_by_me = FALSE;
947 HMENUI tmp = malloc(sizeof(struct _hmenui));;
948
949 if(!tmp)
950 return NULL;
951
952 DW_MUTEX_LOCK;
953 tmp->menu = gtk_menu_new();
954 gtk_widget_show(tmp->menu);
955 gtk_object_set_data(GTK_OBJECT(tmp->menu), "id", (gpointer)id);
956 DW_MUTEX_UNLOCK;
957 return tmp;
958 }
959
960 /*
961 * Create a menubar on a window.
962 * Parameters:
963 * location: Handle of a window frame to be attached to.
964 */
965 HMENUI dw_menubar_new(HWND location)
966 {
967 GtkWidget *box;
968 int _locked_by_me = FALSE;
969 HMENUI tmp = malloc(sizeof(struct _hmenui));;
970
971 if(!tmp)
972 return NULL;
973
974 DW_MUTEX_LOCK;
975 tmp->menu = gtk_menu_bar_new();
976 box = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(location));
977 gtk_widget_show(tmp->menu);
978
979 if(box)
980 gtk_box_pack_end(GTK_BOX(box), tmp->menu, FALSE, FALSE, 0);
981
982 DW_MUTEX_UNLOCK;
983 return tmp;
984 }
985
986 /*
987 * Destroys a menu created with dw_menubar_new or dw_menu_new.
988 * Parameters:
989 * menu: Handle of a menu.
990 */
991 void dw_menu_destroy(HMENUI *menu)
992 {
993 if(menu && *menu)
994 {
995 int _locked_by_me = FALSE;
996
997 DW_MUTEX_LOCK;
998 gtk_widget_destroy((*menu)->menu);
999 free(*menu);
1000 *menu = NULL;
1001 DW_MUTEX_UNLOCK;
1002 }
1003 }
1004
1005 void _removetilde(char *dest, char *src)
1006 {
1007 int z, cur=0;
1008
1009 for(z=0;z<strlen(src);z++)
1010 {
1011 if(src[z] != '~')
1012 {
1013 dest[cur] = src[z];
1014 cur++;
1015 }
1016 }
1017 dest[cur] = 0;
1018 }
1019
1020 /*
1021 * Adds a menuitem or submenu to an existing menu.
1022 * Parameters:
1023 * menu: The handle the the existing menu.
1024 * title: The title text on the menu item to be added.
1025 * id: An ID to be used for message passing.
1026 * flags: Extended attributes to set on the menu.
1027 * end: If TRUE memu is positioned at the end of the menu.
1028 * check: If TRUE menu is "check"able.
1029 * submenu: Handle to an existing menu to be a submenu or NULL.
1030 */
1031 HWND dw_menu_append_item(HMENUI menu, char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu)
1032 {
1033 GtkWidget *tmphandle;
1034 char *tempbuf = malloc(strlen(title)+1);
1035 int _locked_by_me = FALSE;
1036
1037 if(!menu || !menu->menu)
1038 {
1039 free(tempbuf);
1040 return NULL;
1041 }
1042
1043 DW_MUTEX_LOCK;
1044 _removetilde(tempbuf, title);
1045
1046 if(strlen(tempbuf) == 0)
1047 tmphandle=gtk_menu_item_new();
1048 else
1049 {
1050 if(check)
1051 {
1052 char numbuf[10];
1053 tmphandle=gtk_check_menu_item_new_with_label(tempbuf);
1054 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(tmphandle), TRUE);
1055 sprintf(numbuf, "%lu", id);
1056 gtk_object_set_data(GTK_OBJECT(menu->menu), numbuf, (gpointer)tmphandle);
1057 }
1058 else
1059 tmphandle=gtk_menu_item_new_with_label(tempbuf);
1060 }
1061
1062 gtk_widget_show(tmphandle);
1063
1064 if(submenu)
1065 gtk_menu_item_set_submenu(GTK_MENU_ITEM(tmphandle), submenu->menu);
1066
1067 if(GTK_IS_MENU_BAR(menu->menu))
1068 gtk_menu_bar_append(GTK_MENU_BAR(menu->menu), tmphandle);
1069 else
1070 gtk_menu_append(GTK_MENU(menu->menu), tmphandle);
1071
1072 gtk_object_set_data(GTK_OBJECT(tmphandle), "id", (gpointer)id);
1073 free(tempbuf);
1074 DW_MUTEX_UNLOCK;
1075 return tmphandle;
1076 }
1077
1078 /*
1079 * Sets the state of a menu item check.
1080 * Parameters:
1081 * menu: The handle the the existing menu.
1082 * id: Menuitem id.
1083 * check: TRUE for checked FALSE for not checked.
1084 */
1085 void dw_menu_item_set_check(HMENUI menu, int id, int check)
1086 {
1087 char numbuf[10];
1088 GtkWidget *tmphandle;
1089 int _locked_by_me = FALSE;
1090
1091 if(!menu || !menu->menu)
1092 return;
1093
1094 DW_MUTEX_LOCK;
1095 sprintf(numbuf, "%d", id);
1096 tmphandle = gtk_object_get_data(GTK_OBJECT(menu->menu), numbuf);
1097
1098 if(tmphandle)
1099 {
1100 if(GTK_CHECK_MENU_ITEM(tmphandle)->active != check)
1101 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tmphandle), check);
1102 }
1103 DW_MUTEX_UNLOCK;
1104 }
1105
1106 /*
1107 * Pops up a context menu at given x and y coordinates.
1108 * Parameters:
1109 * menu: The handle the the existing menu.
1110 * parent: Handle to the window initiating the popup.
1111 * x: X coordinate.
1112 * y: Y coordinate.
1113 */
1114 void dw_menu_popup(HMENUI *menu, HWND parent, int x, int y)
1115 {
1116 int _locked_by_me = FALSE;
1117
1118 if(!menu || !*menu)
1119 return;
1120
1121 DW_MUTEX_LOCK;
1122 gtk_menu_popup(GTK_MENU((*menu)->menu), NULL, NULL, NULL, NULL, x, y);
1123 free(*menu);
1124 *menu = NULL;
1125 DW_MUTEX_UNLOCK;
1126 }
1127
1128
1129 /*
1130 * Returns the current X and Y coordinates of the mouse pointer.
1131 * Parameters:
1132 * x: Pointer to variable to store X coordinate.
1133 * y: Pointer to variable to store Y coordinate.
1134 */
1135 void dw_pointer_query_pos(long *x, long *y)
1136 {
1137 GdkModifierType state;
1138 int gx, gy;
1139
1140 gdk_window_get_pointer (GDK_ROOT_PARENT(), &gx, &gy, &state);
1141 *x = gx;
1142 *y = gy;
1143 }
1144
1145 /*
1146 * Sets the X and Y coordinates of the mouse pointer.
1147 * Parameters:
1148 * x: X coordinate.
1149 * y: Y coordinate.
1150 */
1151 void dw_pointer_set_pos(long x, long y)
1152 {
1153 XWarpPointer(GDK_DISPLAY(), None, GDK_ROOT_WINDOW(), 0,0,0,0, x, y);
1154 }
1155
1156 /*
1157 * Create a container object to be packed.
1158 * Parameters:
1159 * id: An ID to be used for getting the resource from the
1160 * resource file.
1161 */
1162 HWND dw_container_new(unsigned long id)
1163 {
1164 GtkWidget *tmp;
1165 int _locked_by_me = FALSE;
1166
1167 DW_MUTEX_LOCK;
1168 tmp = gtk_scrolled_window_new (NULL, NULL);
1169 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tmp),
1170 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
1171
1172 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1173 gtk_widget_show(tmp);
1174
1175 DW_MUTEX_UNLOCK;
1176 return tmp;
1177 }
1178
1179 /*
1180 * Create a new static text window (widget) to be packed.
1181 * Parameters:
1182 * text: The text to be display by the static text widget.
1183 * id: An ID to be used with WinWindowFromID() or 0L.
1184 */
1185 HWND dw_text_new(char *text, unsigned long id)
1186 {
1187 GtkWidget *tmp;
1188 int _locked_by_me = FALSE;
1189
1190 DW_MUTEX_LOCK;
1191 tmp = gtk_label_new(text);
1192 gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_LEFT);
1193 gtk_widget_show(tmp);
1194 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1195 DW_MUTEX_UNLOCK;
1196 return tmp;
1197 }
1198
1199 /*
1200 * Create a new Multiline Editbox window (widget) to be packed.
1201 * Parameters:
1202 * id: An ID to be used with WinWindowFromID() or 0L.
1203 */
1204 HWND dw_mle_new(unsigned long id)
1205 {
1206 GtkWidget *tmp, *tmpbox, *scroller;
1207 int _locked_by_me = FALSE;
1208
1209 DW_MUTEX_LOCK;
1210 tmpbox = gtk_hbox_new(FALSE, 0);
1211 tmp = gtk_text_new(NULL, NULL);
1212 gtk_text_set_word_wrap(GTK_TEXT(tmp), FALSE);
1213 gtk_text_set_line_wrap(GTK_TEXT(tmp), FALSE);
1214 scroller = gtk_vscrollbar_new(GTK_TEXT(tmp)->vadj);
1215 GTK_WIDGET_UNSET_FLAGS(scroller, GTK_CAN_FOCUS);
1216 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1217 gtk_object_set_data(GTK_OBJECT(tmpbox), "mle", (gpointer)tmp);
1218 gtk_box_pack_start(GTK_BOX(tmpbox), tmp, TRUE, TRUE, 0);
1219 gtk_box_pack_start(GTK_BOX(tmpbox), scroller, FALSE, TRUE, 0);
1220 gtk_widget_show(tmp);
1221 gtk_widget_show(scroller);
1222 gtk_widget_show(tmpbox);
1223 DW_MUTEX_UNLOCK;
1224 return tmpbox;
1225 }
1226
1227 /*
1228 * Create a new Entryfield window (widget) to be packed.
1229 * Parameters:
1230 * text: The default text to be in the entryfield widget.
1231 * id: An ID to be used with WinWindowFromID() or 0L.
1232 */
1233 HWND dw_entryfield_new(char *text, unsigned long id)
1234 {
1235 GtkWidget *tmp;
1236 int _locked_by_me = FALSE;
1237
1238 DW_MUTEX_LOCK;
1239 tmp = gtk_entry_new();
1240
1241 gtk_entry_set_text(GTK_ENTRY(tmp), text);
1242
1243 gtk_widget_show(tmp);
1244 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1245
1246 DW_MUTEX_UNLOCK;
1247 return tmp;
1248 }
1249
1250 /*
1251 * Create a new Entryfield (password) window (widget) to be packed.
1252 * Parameters:
1253 * text: The default text to be in the entryfield widget.
1254 * id: An ID to be used with WinWindowFromID() or 0L.
1255 */
1256 HWND dw_entryfield_password_new(char *text, ULONG id)
1257 {
1258 GtkWidget *tmp;
1259 int _locked_by_me = FALSE;
1260
1261 DW_MUTEX_LOCK;
1262 tmp = gtk_entry_new();
1263
1264 gtk_entry_set_visibility(GTK_ENTRY(tmp), FALSE);
1265 gtk_entry_set_text(GTK_ENTRY(tmp), text);
1266
1267 gtk_widget_show(tmp);
1268 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1269
1270 DW_MUTEX_UNLOCK;
1271 return tmp;
1272 }
1273
1274 /*
1275 * Create a new Combobox window (widget) to be packed.
1276 * Parameters:
1277 * text: The default text to be in the combpbox widget.
1278 * id: An ID to be used with WinWindowFromID() or 0L.
1279 */
1280 HWND dw_combobox_new(char *text, unsigned long id)
1281 {
1282 GtkWidget *tmp;
1283 int _locked_by_me = FALSE;
1284
1285 DW_MUTEX_LOCK;
1286 tmp = gtk_combo_new();
1287 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(tmp)->entry), text);
1288 gtk_combo_set_use_arrows(GTK_COMBO(tmp), TRUE);
1289 gtk_object_set_user_data(GTK_OBJECT(tmp), NULL);
1290 gtk_widget_show(tmp);
1291 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1292 DW_MUTEX_UNLOCK;
1293 return tmp;
1294 }
1295
1296 /*
1297 * Create a new button window (widget) to be packed.
1298 * Parameters:
1299 * text: The text to be display by the static text widget.
1300 * id: An ID to be used with WinWindowFromID() or 0L.
1301 */
1302 HWND dw_button_new(char *text, unsigned long id)
1303 {
1304 GtkWidget *tmp;
1305 int _locked_by_me = FALSE;
1306
1307 DW_MUTEX_LOCK;
1308 tmp = gtk_button_new_with_label(text);
1309 gtk_widget_show(tmp);
1310 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1311 DW_MUTEX_UNLOCK;
1312 return tmp;
1313 }
1314
1315 /*
1316 * Create a new bitmap button window (widget) to be packed.
1317 * Parameters:
1318 * text: Bubble help text to be displayed.
1319 * id: An ID of a bitmap in the resource file.
1320 */
1321 HWND dw_bitmapbutton_new(char *text, unsigned long id)
1322 {
1323 GtkWidget *tmp;
1324 GtkWidget *bitmap;
1325 GtkTooltips *tooltips;
1326 int _locked_by_me = FALSE;
1327
1328 DW_MUTEX_LOCK;
1329 tmp = gtk_button_new();
1330 bitmap = dw_bitmap_new(id);
1331
1332 if(bitmap)
1333 {
1334 dw_window_set_bitmap(bitmap, id);
1335 gtk_container_add (GTK_CONTAINER(tmp), bitmap);
1336 }
1337 gtk_widget_show(tmp);
1338 if(text)
1339 {
1340 tooltips = gtk_tooltips_new();
1341 gtk_tooltips_set_colors(tooltips, &_colors[DW_CLR_BLACK], &_colors[DW_CLR_YELLOW]);
1342 gtk_tooltips_set_tip(tooltips, tmp, text, NULL);
1343 gtk_object_set_data(GTK_OBJECT(tmp), "tooltip", (gpointer)tooltips);
1344 }
1345 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1346 DW_MUTEX_UNLOCK;
1347 return tmp;
1348 }
1349
1350 /*
1351 * Create a new spinbutton window (widget) to be packed.
1352 * Parameters:
1353 * text: The text to be display by the static text widget.
1354 * id: An ID to be used with WinWindowFromID() or 0L.
1355 */
1356 HWND dw_spinbutton_new(char *text, unsigned long id)
1357 {
1358 GtkAdjustment *adj;
1359 GtkWidget *tmp;
1360 int _locked_by_me = FALSE;
1361
1362 DW_MUTEX_LOCK;
1363 adj = (GtkAdjustment *)gtk_adjustment_new (1.0, 0.0, 100.0, 1.0, 5.0, 0.0);
1364 tmp = gtk_spin_button_new (adj, 0, 0);
1365 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(tmp), TRUE);
1366 gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(tmp), TRUE);
1367 gtk_widget_show(tmp);
1368 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1369 DW_MUTEX_UNLOCK;
1370 return tmp;
1371 }
1372
1373 /*
1374 * Create a new radiobutton window (widget) to be packed.
1375 * Parameters:
1376 * text: The text to be display by the static text widget.
1377 * id: An ID to be used with WinWindowFromID() or 0L.
1378 */
1379 HWND dw_radiobutton_new(char *text, ULONG id)
1380 {
1381 /* This will have to be fixed in the future. */
1382 GtkWidget *tmp;
1383 int _locked_by_me = FALSE;
1384
1385 DW_MUTEX_LOCK;
1386 tmp = gtk_radio_button_new_with_label(NULL, text);
1387 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1388 gtk_widget_show(tmp);
1389
1390 DW_MUTEX_UNLOCK;
1391 return tmp;
1392 }
1393
1394 /*
1395 * Create a new slider window (widget) to be packed.
1396 * Parameters:
1397 * id: An ID to be used with WinWindowFromID() or 0L.
1398 */
1399 HWND dw_slider_new(unsigned long id)
1400 {
1401 GtkWidget *tmp;
1402 int _locked_by_me = FALSE;
1403
1404 DW_MUTEX_LOCK;
1405 tmp = gtk_progress_bar_new();
1406 gtk_widget_show(tmp);
1407 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1408 DW_MUTEX_UNLOCK;
1409 return tmp;
1410 }
1411
1412 /*
1413 * Create a new checkbox window (widget) to be packed.
1414 * Parameters:
1415 * text: The text to be display by the static text widget.
1416 * id: An ID to be used with WinWindowFromID() or 0L.
1417 */
1418 HWND dw_checkbox_new(char *text, unsigned long id)
1419 {
1420 GtkWidget *tmp;
1421 int _locked_by_me = FALSE;
1422
1423 DW_MUTEX_LOCK;
1424 tmp = gtk_check_button_new_with_label(text);
1425 gtk_widget_show(tmp);
1426 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1427 DW_MUTEX_UNLOCK;
1428 return tmp;
1429 }
1430
1431 /*
1432 * Create a new listbox window (widget) to be packed.
1433 * Parameters:
1434 * id: An ID to be used with WinWindowFromID() or 0L.
1435 * multi: Multiple select TRUE or FALSE.
1436 */
1437 HWND dw_listbox_new(unsigned long id, int multi)
1438 {
1439 GtkWidget *tmp, *list;
1440 int _locked_by_me = FALSE;
1441
1442 DW_MUTEX_LOCK;
1443 tmp = gtk_scrolled_window_new(NULL, NULL);
1444 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (tmp),
1445 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
1446
1447 list = gtk_list_new();
1448 gtk_list_set_selection_mode(GTK_LIST(list), multi ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE);
1449
1450 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(tmp),
1451 list);
1452 gtk_object_set_user_data(GTK_OBJECT(tmp), list);
1453 gtk_widget_show(list);
1454 gtk_widget_show(tmp);
1455 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
1456
1457 DW_MUTEX_UNLOCK;
1458 return tmp;
1459 }
1460
1461 /*
1462 * Sets the icon used for a given window.
1463 * Parameters:
1464 * handle: Handle to the window.
1465 * id: An ID to be used to specify the icon.
1466 */
1467 void dw_window_set_icon(HWND handle, unsigned long id)
1468 {
1469 GdkBitmap *bitmap;
1470 GdkPixmap *icon_pixmap;
1471 int _locked_by_me = FALSE;
1472
1473 DW_MUTEX_LOCK;
1474 icon_pixmap = _find_pixmap(&bitmap, id, handle);
1475
1476 if(handle->window && icon_pixmap)
1477 gdk_window_set_icon(handle->window, NULL, icon_pixmap, bitmap);
1478
1479 DW_MUTEX_UNLOCK;
1480 }
1481
1482 /*
1483 * Sets the bitmap used for a given static window.
1484 * Parameters:
1485 * handle: Handle to the window.
1486 * id: An ID to be used to specify the icon.
1487 */
1488 void dw_window_set_bitmap(HWND handle, unsigned long id)
1489 {
1490 GdkBitmap *bitmap;
1491 GdkPixmap *tmp;
1492 int _locked_by_me = FALSE;
1493
1494 DW_MUTEX_LOCK;
1495 tmp = _find_pixmap(&bitmap, id, handle);
1496 if(tmp)
1497 gtk_pixmap_set(GTK_PIXMAP(handle), tmp, bitmap);
1498 DW_MUTEX_UNLOCK;
1499 }
1500
1501 /*
1502 * Sets the text used for a given window.
1503 * Parameters:
1504 * handle: Handle to the window.
1505 * text: The text associsated with a given window.
1506 */
1507 void dw_window_set_text(HWND handle, char *text)
1508 {
1509 int _locked_by_me = FALSE;
1510
1511 DW_MUTEX_LOCK;
1512 if(GTK_IS_ENTRY(handle))
1513 gtk_entry_set_text(GTK_ENTRY(handle), text);
1514 else if(GTK_IS_COMBO(handle))
1515 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(handle)->entry), text);
1516 else if(GTK_IS_LABEL(handle))
1517 gtk_label_set_text(GTK_LABEL(handle), text);
1518 DW_MUTEX_UNLOCK;
1519 }
1520
1521 /*
1522 * Gets the text used for a given window.
1523 * Parameters:
1524 * handle: Handle to the window.
1525 * Returns:
1526 * text: The text associsated with a given window.
1527 */
1528 char *dw_window_get_text(HWND handle)
1529 {
1530 char *possible = "";
1531 int _locked_by_me = FALSE;
1532
1533 DW_MUTEX_LOCK;
1534 if(GTK_IS_ENTRY(handle))
1535 possible = gtk_entry_get_text(GTK_ENTRY(handle));
1536 else if(GTK_IS_COMBO(handle))
1537 possible = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(handle)->entry));
1538
1539 DW_MUTEX_UNLOCK;
1540 return strdup(possible);
1541 }
1542
1543 /*
1544 * Disables given window (widget).
1545 * Parameters:
1546 * handle: Handle to the window.
1547 */
1548 void dw_window_disable(HWND handle)
1549 {
1550 int _locked_by_me = FALSE;
1551
1552 DW_MUTEX_LOCK;
1553 gtk_widget_set_sensitive(handle, FALSE);
1554 DW_MUTEX_UNLOCK;
1555 }
1556
1557 /*
1558 * Enables given window (widget).
1559 * Parameters:
1560 * handle: Handle to the window.
1561 */
1562 void dw_window_enable(HWND handle)
1563 {
1564 int _locked_by_me = FALSE;
1565
1566 DW_MUTEX_LOCK;
1567 gtk_widget_set_sensitive(handle, TRUE);
1568 DW_MUTEX_UNLOCK;
1569 }
1570
1571 /*
1572 * Adds text to an MLE box and returns the current point.
1573 * Parameters:
1574 * handle: Handle to the MLE to be queried.
1575 * buffer: Text buffer to be imported.
1576 * startpoint: Point to start entering text.
1577 */
1578 unsigned int dw_mle_import(HWND handle, char *buffer, int startpoint)
1579 {
1580 unsigned int tmppoint = startpoint;
1581 int _locked_by_me = FALSE;
1582
1583 DW_MUTEX_LOCK;
1584 if(GTK_IS_BOX(handle))
1585 {
1586 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1587
1588 if(tmp && GTK_IS_TEXT(tmp))
1589 {
1590 gtk_text_set_point(GTK_TEXT(tmp), startpoint < 0 ? 0 : startpoint);
1591 gtk_text_insert(GTK_TEXT(tmp), NULL, NULL, NULL, buffer, -1);
1592 tmppoint = gtk_text_get_point(GTK_TEXT(tmp));
1593 }
1594 }
1595 DW_MUTEX_UNLOCK;
1596 return tmppoint;
1597 }
1598
1599 /*
1600 * Grabs text from an MLE box.
1601 * Parameters:
1602 * handle: Handle to the MLE to be queried.
1603 * buffer: Text buffer to be exported.
1604 * startpoint: Point to start grabbing text.
1605 * length: Amount of text to be grabbed.
1606 */
1607 void dw_mle_export(HWND handle, char *buffer, int startpoint, int length)
1608 {
1609 int _locked_by_me = FALSE;
1610 gchar *text;
1611
1612 DW_MUTEX_LOCK;
1613 if(GTK_IS_BOX(handle))
1614 {
1615 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1616
1617 if(tmp && GTK_IS_TEXT(tmp))
1618 {
1619 text = gtk_editable_get_chars(GTK_EDITABLE(&(GTK_TEXT(tmp)->editable)), startpoint, startpoint + length);
1620 if(text)
1621 {
1622 strcpy(buffer, text);
1623 g_free(text);
1624 }
1625 }
1626 }
1627 DW_MUTEX_UNLOCK;
1628 }
1629
1630 /*
1631 * Obtains information about an MLE box.
1632 * Parameters:
1633 * handle: Handle to the MLE to be queried.
1634 * bytes: A pointer to a variable to return the total bytes.
1635 * lines: A pointer to a variable to return the number of lines.
1636 */
1637 void dw_mle_query(HWND handle, unsigned long *bytes, unsigned long *lines)
1638 {
1639 int _locked_by_me = FALSE;
1640
1641 if(bytes)
1642 *bytes = 0;
1643 if(lines)
1644 *lines = 0;
1645
1646 DW_MUTEX_LOCK;
1647 if(GTK_IS_BOX(handle))
1648 {
1649 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1650
1651 if(tmp && GTK_IS_TEXT(tmp))
1652 {
1653 if(bytes)
1654 *bytes = gtk_text_get_length(GTK_TEXT(tmp));
1655 if(lines)
1656 {
1657 gchar *text;
1658
1659 *lines = 0;
1660 text = gtk_editable_get_chars(GTK_EDITABLE(&(GTK_TEXT(tmp)->editable)), 0, bytes ? *bytes : gtk_text_get_length(GTK_TEXT(tmp)));
1661
1662 if(text)
1663 {
1664 int z, len = strlen(text);
1665
1666 for(z=0;z<len;z++)
1667 {
1668 if(text[z] == '\n')
1669 (*lines)++;
1670 }
1671 g_free(text);
1672 }
1673 }
1674 }
1675 }
1676 DW_MUTEX_UNLOCK;
1677 }
1678
1679 /*
1680 * Deletes text from an MLE box.
1681 * Parameters:
1682 * handle: Handle to the MLE to be deleted from.
1683 * startpoint: Point to start deleting text.
1684 * length: Amount of text to be deleted.
1685 */
1686 void dw_mle_delete(HWND handle, int startpoint, int length)
1687 {
1688 int _locked_by_me = FALSE;
1689
1690 DW_MUTEX_LOCK;
1691 if(GTK_IS_BOX(handle))
1692 {
1693 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1694
1695 if(tmp && GTK_IS_TEXT(tmp))
1696 {
1697 gtk_text_set_point(GTK_TEXT(tmp), startpoint);
1698 gtk_text_forward_delete(GTK_TEXT(tmp), length);
1699 }
1700 }
1701 DW_MUTEX_UNLOCK;
1702 }
1703
1704 /*
1705 * Clears all text from an MLE box.
1706 * Parameters:
1707 * handle: Handle to the MLE to be cleared.
1708 */
1709 void dw_mle_clear(HWND handle)
1710 {
1711 int length, _locked_by_me = FALSE;
1712
1713 DW_MUTEX_LOCK;
1714 if(GTK_IS_BOX(handle))
1715 {
1716 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1717
1718 if(tmp && GTK_IS_TEXT(tmp))
1719 {
1720 length = gtk_text_get_length(GTK_TEXT(tmp));
1721 gtk_text_set_point(GTK_TEXT(tmp), 0);
1722 gtk_text_forward_delete(GTK_TEXT(tmp), length);
1723 }
1724 }
1725 DW_MUTEX_UNLOCK;
1726 }
1727
1728 /*
1729 * Sets the visible line of an MLE box.
1730 * Parameters:
1731 * handle: Handle to the MLE.
1732 * line: Line to be visible.
1733 */
1734 void dw_mle_set_visible(HWND handle, int line)
1735 {
1736 int _locked_by_me = FALSE;
1737
1738 DW_MUTEX_LOCK;
1739 if(GTK_IS_BOX(handle))
1740 {
1741 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1742
1743 if(tmp && GTK_IS_TEXT(tmp))
1744 {
1745 unsigned long lines;
1746 float pos, ratio;
1747
1748 dw_mle_query(handle, NULL, &lines);
1749
1750 if(lines)
1751 {
1752 ratio = (float)line/(float)lines;
1753
1754 pos = (ratio * (float)(GTK_TEXT(tmp)->vadj->upper - GTK_TEXT(tmp)->vadj->lower)) + GTK_TEXT(tmp)->vadj->lower;
1755
1756 gtk_adjustment_set_value(GTK_TEXT(tmp)->vadj, pos);
1757 }
1758 }
1759 }
1760 DW_MUTEX_UNLOCK;
1761 }
1762
1763 /*
1764 * Sets the current cursor position of an MLE box.
1765 * Parameters:
1766 * handle: Handle to the MLE to be positioned.
1767 * point: Point to position cursor.
1768 */
1769 void dw_mle_set(HWND handle, int point)
1770 {
1771 int _locked_by_me = FALSE;
1772
1773 DW_MUTEX_LOCK;
1774 if(GTK_IS_BOX(handle))
1775 {
1776 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1777
1778 if(tmp && GTK_IS_TEXT(tmp))
1779 {
1780 gtk_text_set_point(GTK_TEXT(tmp), point);
1781 }
1782 }
1783 DW_MUTEX_UNLOCK;
1784 }
1785
1786 /*
1787 * Finds text in an MLE box.
1788 * Parameters:
1789 * handle: Handle to the MLE to be cleared.
1790 * text: Text to search for.
1791 * point: Start point of search.
1792 * flags: Search specific flags.
1793 */
1794 int dw_mle_search(HWND handle, char *text, int point, unsigned long flags)
1795 {
1796 int _locked_by_me = FALSE, retval = 0;
1797
1798 DW_MUTEX_LOCK;
1799 if(GTK_IS_BOX(handle))
1800 {
1801 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1802
1803 if(tmp && GTK_IS_TEXT(tmp))
1804 {
1805 int len = gtk_text_get_length(GTK_TEXT(tmp));
1806 gchar *tmpbuf;
1807
1808 tmpbuf = gtk_editable_get_chars(GTK_EDITABLE(&(GTK_TEXT(tmp)->editable)), 0, len);
1809 if(tmpbuf)
1810 {
1811 int z, textlen;
1812
1813 textlen = strlen(text);
1814
1815 if(flags & DW_MLE_CASESENSITIVE)
1816 {
1817 for(z=point;z<(len-textlen) && !retval;z++)
1818 {
1819 if(strncmp(&tmpbuf[z], text, textlen) == 0)
1820 retval = z + textlen;
1821 }
1822 }
1823 else
1824 {
1825 for(z=point;z<(len-textlen) && !retval;z++)
1826 {
1827 if(strncasecmp(&tmpbuf[z], text, textlen) == 0)
1828 retval = z + textlen;
1829 }
1830 }
1831
1832 if(retval)
1833 {
1834 gtk_text_set_point(GTK_TEXT(tmp), retval - textlen);
1835 gtk_editable_select_region(&(GTK_TEXT(tmp)->editable), retval - textlen, retval);
1836 }
1837
1838 g_free(tmpbuf);
1839 }
1840 }
1841 }
1842
1843 DW_MUTEX_UNLOCK;
1844 return retval;
1845 }
1846
1847 /*
1848 * Stops redrawing of an MLE box.
1849 * Parameters:
1850 * handle: Handle to the MLE to freeze.
1851 */
1852 void dw_mle_freeze(HWND handle)
1853 {
1854 int _locked_by_me = FALSE;
1855
1856 DW_MUTEX_LOCK;
1857 if(GTK_IS_BOX(handle))
1858 {
1859 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1860
1861 if(tmp && GTK_IS_TEXT(tmp))
1862 {
1863 gtk_text_freeze(GTK_TEXT(tmp));
1864 }
1865 }
1866 DW_MUTEX_UNLOCK;
1867 }
1868
1869 /*
1870 * Resumes redrawing of an MLE box.
1871 * Parameters:
1872 * handle: Handle to the MLE to thaw.
1873 */
1874 void dw_mle_thaw(HWND handle)
1875 {
1876 int _locked_by_me = FALSE;
1877
1878 DW_MUTEX_LOCK;
1879 if(GTK_IS_BOX(handle))
1880 {
1881 GtkWidget *tmp = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(handle), "mle");
1882
1883 if(tmp && GTK_IS_TEXT(tmp))
1884 {
1885 gtk_text_thaw(GTK_TEXT(tmp));
1886 }
1887 }
1888 DW_MUTEX_UNLOCK;
1889 }
1890
1891 /*
1892 * Returns the range of the slider.
1893 * Parameters:
1894 * handle: Handle to the slider to be queried.
1895 */
1896 unsigned int dw_slider_query_range(HWND handle)
1897 {
1898 return 100;
1899 }
1900
1901 /*
1902 * Sets the slider position.
1903 * Parameters:
1904 * handle: Handle to the slider to be set.
1905 * position: Position of the slider withing the range.
1906 */
1907 void dw_slider_set_pos(HWND handle, unsigned int position)
1908 {
1909 int _locked_by_me = FALSE;
1910
1911 DW_MUTEX_LOCK;
1912 gtk_progress_bar_update(GTK_PROGRESS_BAR(handle), (gfloat)position/100);
1913 DW_MUTEX_UNLOCK;
1914 }
1915
1916 /*
1917 * Sets the spinbutton value.
1918 * Parameters:
1919 * handle: Handle to the spinbutton to be set.
1920 * position: Current value of the spinbutton.
1921 */
1922 void dw_spinbutton_set_pos(HWND handle, long position)
1923 {
1924 int _locked_by_me = FALSE;
1925
1926 DW_MUTEX_LOCK;
1927 gtk_spin_button_set_value(GTK_SPIN_BUTTON(handle), (gfloat)position);
1928 DW_MUTEX_UNLOCK;
1929 }
1930
1931 /*
1932 * Sets the spinbutton limits.
1933 * Parameters:
1934 * handle: Handle to the spinbutton to be set.
1935 * position: Current value of the spinbutton.
1936 * position: Current value of the spinbutton.
1937 */
1938 void dw_spinbutton_set_limits(HWND handle, long upper, long lower)
1939 {
1940 long curval;
1941 GtkAdjustment *adj;
1942 int _locked_by_me = FALSE;
1943
1944 curval = dw_spinbutton_query(handle);
1945 DW_MUTEX_LOCK;
1946 adj = (GtkAdjustment *)gtk_adjustment_new((gfloat)curval, (gfloat)lower, (gfloat)upper, 1.0, 5.0, 0.0);
1947 DW_MUTEX_UNLOCK;
1948 }
1949
1950 /*
1951 * Sets the entryfield character limit.
1952 * Parameters:
1953 * handle: Handle to the spinbutton to be set.
1954 * limit: Number of characters the entryfield will take.
1955 */
1956 void dw_entryfield_set_limit(HWND handle, ULONG limit)
1957 {
1958 /* TODO: can this be done after the fact? */
1959 }
1960
1961 /*
1962 * Returns the current value of the spinbutton.
1963 * Parameters:
1964 * handle: Handle to the spinbutton to be queried.
1965 */
1966 long dw_spinbutton_query(HWND handle)
1967 {
1968 long retval;
1969 int _locked_by_me = FALSE;
1970
1971 DW_MUTEX_LOCK;
1972 retval = (long)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(handle));
1973 DW_MUTEX_UNLOCK;
1974
1975 return retval;
1976 }
1977
1978 /*
1979 * Returns the state of the checkbox.
1980 * Parameters:
1981 * handle: Handle to the checkbox to be queried.
1982 */
1983 int dw_checkbox_query(HWND handle)
1984 {
1985 int retval;
1986 int _locked_by_me = FALSE;
1987
1988 DW_MUTEX_LOCK;
1989 retval = GTK_TOGGLE_BUTTON(handle)->active;
1990 DW_MUTEX_UNLOCK;
1991
1992 return retval;
1993 }
1994
1995 /*
1996 * Sets the state of the checkbox.
1997 * Parameters:
1998 * handle: Handle to the checkbox to be queried.
1999 * value: TRUE for checked, FALSE for unchecked.
2000 */
2001 void dw_checkbox_set(HWND handle, int value)
2002 {
2003 int _locked_by_me = FALSE;
2004
2005 DW_MUTEX_LOCK;
2006 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(handle), value);
2007 DW_MUTEX_UNLOCK;
2008 }
2009
2010 int _dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator, int extra)
2011 {
2012 GtkWidget *clist;
2013 char numbuf[10];
2014 int z;
2015 int _locked_by_me = FALSE;
2016
2017 DW_MUTEX_LOCK;
2018 clist = gtk_clist_new_with_titles(count, (gchar **)titles);
2019 if(!clist)
2020 {
2021 DW_MUTEX_UNLOCK;
2022 return FALSE;
2023 }
2024
2025 gtk_signal_connect(GTK_OBJECT(clist), "select_row", GTK_SIGNAL_FUNC(_select_row), NULL);
2026 gtk_signal_connect(GTK_OBJECT(clist), "unselect_row", GTK_SIGNAL_FUNC(_unselect_row), NULL);
2027
2028 gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE);
2029 gtk_container_add(GTK_CONTAINER(handle), clist);
2030 gtk_object_set_user_data(GTK_OBJECT(handle), (gpointer)clist);
2031 gtk_widget_show(clist);
2032 gtk_object_set_data(GTK_OBJECT(clist), "colcount", (gpointer)count);
2033
2034 if(extra)
2035 gtk_clist_set_column_width(GTK_CLIST(clist), 1, 120);
2036
2037 for(z=0;z<count;z++)
2038 {
2039 if(!extra || z > 1)
2040 gtk_clist_set_column_width(GTK_CLIST(clist), z, 50);
2041 sprintf(numbuf, "%d", z);
2042 gtk_object_set_data(GTK_OBJECT(clist), numbuf, (gpointer)flags[z]);
2043 }
2044
2045 DW_MUTEX_UNLOCK;
2046 return TRUE;
2047 }
2048
2049 /*
2050 * Sets up the container columns.
2051 * Parameters:
2052 * handle: Handle to the container to be configured.
2053 * flags: An array of unsigned longs with column flags.
2054 * titles: An array of strings with column text titles.
2055 * count: The number of columns (this should match the arrays).
2056 * separator: The column number that contains the main separator.
2057 * (this item may only be used in OS/2)
2058 */
2059 int dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator)
2060 {
2061 return _dw_container_setup(handle, flags, titles, count, separator, 0);
2062 }
2063
2064 /*
2065 * Sets up the filesystem columns, note: filesystem always has an icon/filename field.
2066 * Parameters:
2067 * handle: Handle to the container to be configured.
2068 * flags: An array of unsigned longs with column flags.
2069 * titles: An array of strings with column text titles.
2070 * count: The number of columns (this should match the arrays).
2071 */
2072 int dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count)
2073 {
2074 char **newtitles = malloc(sizeof(char *) * (count + 2));
2075 unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2));
2076
2077 newtitles[0] = "Icon";
2078 newtitles[1] = "Filename";
2079
2080 newflags[0] = DW_CFA_BITMAPORICON | DW_CFA_CENTER | DW_CFA_HORZSEPARATOR | DW_CFA_SEPARATOR;
2081 newflags[1] = DW_CFA_STRING | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR;
2082
2083 memcpy(&newtitles[2], titles, sizeof(char *) * count);
2084 memcpy(&newflags[2], flags, sizeof(unsigned long) * count);
2085
2086 _dw_container_setup(handle, newflags, newtitles, count + 2, 2, 1);
2087
2088 free(newtitles);
2089 free(newflags);
2090 return TRUE;
2091 }
2092
2093 /*
2094 * Obtains an icon from a module (or header in GTK).
2095 * Parameters:
2096 * module: Handle to module (DLL) in OS/2 and Windows.
2097 * id: A unsigned long id int the resources on OS/2 and
2098 * Windows, on GTK this is converted to a pointer
2099 * to an embedded XPM.
2100 */
2101 unsigned long dw_icon_load(unsigned long module, unsigned long id)
2102 {
2103 return id;
2104 }
2105
2106 /*
2107 * Frees a loaded resource in OS/2 and Windows.
2108 * Parameters:
2109 * handle: Handle to icon returned by dw_icon_load().
2110 */
2111 void dw_icon_free(unsigned long handle)
2112 {
2113 }
2114
2115 /*
2116 * Allocates memory used to populate a container.
2117 * Parameters:
2118 * handle: Handle to the container window (widget).
2119 * rowcount: The number of items to be populated.
2120 */
2121 void *dw_container_alloc(HWND handle, int rowcount)
2122 {
2123 int z, count = 0;
2124 GtkWidget *clist;
2125 char **blah;
2126 int _locked_by_me = FALSE;
2127
2128 DW_MUTEX_LOCK;
2129 clist = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
2130 if(!clist)
2131 {
2132 DW_MUTEX_UNLOCK;
2133 return NULL;
2134 }
2135
2136 count = (int)gtk_object_get_data(GTK_OBJECT(clist), "colcount");
2137
2138 if(!count)
2139 {
2140 DW_MUTEX_UNLOCK;
2141 return NULL;
2142 }
2143
2144 blah = malloc(sizeof(char *) * count);
2145 memset(blah, 0, sizeof(char *) * count);
2146
2147 gtk_clist_freeze(GTK_CLIST(clist));
2148 for(z=0;z<rowcount;z++)
2149 {
2150 gtk_clist_append(GTK_CLIST(clist), blah);
2151 }
2152 free(blah);
2153 DW_MUTEX_UNLOCK;
2154 return (void *)handle;
2155 }
2156
2157 /*
2158 * Sets an item in specified row and column to the given data.
2159 * Parameters:
2160 * handle: Handle to the container window (widget).
2161 * pointer: Pointer to the allocated memory in dw_container_alloc().
2162 * column: Zero based column of data being set.
2163 * row: Zero based row of data being set.
2164 * data: Pointer to the data to be added.
2165 */
2166 void dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data)
2167 {
2168 char numbuf[10], textbuffer[100];
2169 int flag = 0;
2170 GtkWidget *clist;
2171 int _locked_by_me = FALSE;
2172
2173 DW_MUTEX_LOCK;
2174 clist = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
2175 if(!clist)
2176 {
2177 DW_MUTEX_UNLOCK;
2178 return;
2179 }
2180
2181 sprintf(numbuf, "%d", column);
2182 flag = (int)gtk_object_get_data(GTK_OBJECT(clist), numbuf);
2183
2184 if(flag & DW_CFA_BITMAPORICON)
2185 {
2186 long hicon = *((long *)data);
2187 GdkBitmap *bitmap;
2188 GdkPixmap *pixmap = _find_pixmap(&bitmap, hicon, clist);
2189
2190 if(pixmap)
2191 gtk_clist_set_pixmap(GTK_CLIST(clist), row, column, pixmap, bitmap);
2192 }
2193 else if(flag & DW_CFA_STRING)
2194 {
2195 char *tmp = *((char **)data);
2196 gtk_clist_set_text(GTK_CLIST(clist), row, column, tmp);
2197 }
2198 else if(flag & DW_CFA_ULONG)
2199 {
2200 ULONG tmp = *((ULONG *)data);
2201
2202 sprintf(textbuffer, "%lu", tmp);
2203
2204 gtk_clist_set_text(GTK_CLIST(clist), row, column, textbuffer);
2205 }
2206 else if(flag & DW_CFA_DATE)
2207 {
2208 CDATE fdate = *((CDATE *)data);
2209
2210 sprintf(textbuffer, "%s %d, %d", monthlist[fdate.month], fdate.day, fdate.year);
2211 gtk_clist_set_text(GTK_CLIST(clist), row, column, textbuffer);
2212 }
2213 else if(flag & DW_CFA_TIME)
2214 {
2215 CTIME ftime = *((CTIME *)data);
2216
2217 if(ftime.hours > 12)
2218 sprintf(textbuffer, "%d:%s%dpm", ftime.hours - 12, (ftime.minutes < 10) ? "0" : "", ftime.minutes);
2219 else
2220 sprintf(textbuffer, "%d:%s%dam", ftime.hours ? ftime.hours : 12, (ftime.minutes < 10) ? "0" : "", ftime.minutes);
2221 gtk_clist_set_text(GTK_CLIST(clist), row, column, textbuffer);
2222 }
2223 DW_MUTEX_UNLOCK;
2224 }
2225
2226 /*
2227 * Sets an item in specified row and column to the given data.
2228 * Parameters:
2229 * handle: Handle to the container window (widget).
2230 * pointer: Pointer to the allocated memory in dw_container_alloc().
2231 * column: Zero based column of data being set.
2232 * row: Zero based row of data being set.
2233 * data: Pointer to the data to be added.
2234 */
2235 void dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon)
2236 {
2237 dw_container_set_item(handle, pointer, 0, row, (void *)&icon);
2238 dw_container_set_item(handle, pointer, 1, row, (void *)&filename);
2239 }
2240
2241 /*
2242 * Sets an item in specified row and column to the given data.
2243 * Parameters:
2244 * handle: Handle to the container window (widget).
2245 * pointer: Pointer to the allocated memory in dw_container_alloc().
2246 * column: Zero based column of data being set.
2247 * row: Zero based row of data being set.
2248 * data: Pointer to the data to be added.
2249 */
2250 void dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data)
2251 {
2252 dw_container_set_item(handle, pointer, column + 2, row, data);
2253 }
2254
2255 /*
2256 * Sets the title of a row in the container.
2257 * Parameters:
2258 * pointer: Pointer to the allocated memory in dw_container_alloc().
2259 * row: Zero based row of data being set.
2260 * title: String title of the item.
2261 */
2262 void dw_container_set_row_title(void *pointer, int row, char *title)
2263 {
2264 GtkWidget *clist;
2265 int _locked_by_me = FALSE;
2266
2267 DW_MUTEX_LOCK;
2268 clist = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(pointer));
2269
2270 if(clist)
2271 gtk_clist_set_row_data(GTK_CLIST(clist), row, (gpointer)title);
2272 DW_MUTEX_UNLOCK;
2273 }
2274
2275 /*
2276 * Sets the title of a row in the container.
2277 * Parameters:
2278 * handle: Handle to the container window (widget).
2279 * pointer: Pointer to the allocated memory in dw_container_alloc().
2280 * rowcount: The number of rows to be inserted.
2281 */
2282 void dw_container_insert(HWND handle, void *pointer, int rowcount)
2283 {
2284 GtkWidget *clist;
2285 int _locked_by_me = FALSE;
2286
2287 DW_MUTEX_LOCK;
2288 clist = gtk_object_get_user_data(GTK_OBJECT(handle));
2289
2290 if(clist && GTK_IS_CLIST(clist))
2291 gtk_clist_thaw(GTK_CLIST(clist));
2292 DW_MUTEX_UNLOCK;
2293 }
2294
2295 /*
2296 * Removes all rows from a container.
2297 * Parameters:
2298 * handle: Handle to the window (widget) to be cleared.
2299 */
2300 void dw_container_clear(HWND handle)
2301 {
2302 GtkWidget *clist;
2303 GList *list;
2304 int _locked_by_me = FALSE;
2305
2306 DW_MUTEX_LOCK;
2307 clist = (GtkWidget*)gtk_object_get_user_data(GTK_OBJECT(handle));
2308 if(clist && GTK_IS_CLIST(clist))
2309 {
2310 list = (GList *)gtk_object_get_data(GTK_OBJECT(clist), "selectlist");
2311 g_list_free(list);
2312 gtk_object_set_data(GTK_OBJECT(clist), "selectlist", NULL);
2313 gtk_clist_clear(GTK_CLIST(clist));
2314 }
2315 DW_MUTEX_UNLOCK;
2316 }
2317
2318 /*
2319 * Removes all rows from a container.
2320 * Parameters:
2321 * handle: Handle to the window (widget) to be cleared.
2322 */
2323 void dw_container_set_view(HWND handle, unsigned long flags, int iconwidth, int iconheight)
2324 {
2325 }
2326
2327 /*
2328 * Starts a new query of a container.
2329 * Parameters:
2330 * handle: Handle to the window (widget) to be queried.
2331 * flags: If this parameter is DW_CRA_SELECTED it will only
2332 * return items that are currently selected. Otherwise
2333 * it will return all records in the container.
2334 */
2335 char *dw_container_query_start(HWND handle, unsigned long flags)
2336 {
2337 GtkWidget *clist;
2338 GList *list;
2339 char *retval = NULL;
2340 int _locked_by_me = FALSE;
2341
2342 DW_MUTEX_LOCK;
2343 clist = (GtkWidget*)gtk_object_get_user_data(GTK_OBJECT(handle));
2344
2345 if(!clist)
2346 {
2347 DW_MUTEX_UNLOCK;
2348 return NULL;
2349 }
2350
2351 /* If there is an old query list, free it */
2352 list = (GList *)gtk_object_get_data(GTK_OBJECT(clist), "querylist");
2353 if(list)
2354 g_list_free(list);
2355
2356 /* Move the current selection list to the query list, and remove the
2357 * current selection list.
2358 */
2359 list = (GList *)gtk_object_get_data(GTK_OBJECT(clist), "selectlist");
2360 gtk_object_set_data(GTK_OBJECT(clist), "selectlist", NULL);
2361 gtk_object_set_data(GTK_OBJECT(clist), "querylist", (gpointer)list);
2362 gtk_clist_unselect_all(GTK_CLIST(clist));
2363
2364 if(list)
2365 {
2366 gtk_object_set_data(GTK_OBJECT(clist), "querypos", (gpointer)1);
2367 if(list->data)
2368 retval = list->data;
2369 else
2370 retval = "";
2371 }
2372 DW_MUTEX_UNLOCK;
2373 return retval;
2374 }
2375
2376 /*
2377 * Continues an existing query of a container.
2378 * Parameters:
2379 * handle: Handle to the window (widget) to be queried.
2380 * flags: If this parameter is DW_CRA_SELECTED it will only
2381 * return items that are currently selected. Otherwise
2382 * it will return all records in the container.
2383 */
2384 char *dw_container_query_next(HWND handle, unsigned long flags)
2385 {
2386 GtkWidget *clist;
2387 GList *list;
2388 char *retval = NULL;
2389 int _locked_by_me = FALSE;
2390
2391 DW_MUTEX_LOCK;
2392 clist = (GtkWidget*)gtk_object_get_user_data(GTK_OBJECT(handle));
2393
2394 if(!clist)
2395 {
2396 DW_MUTEX_UNLOCK;
2397 return NULL;
2398 }
2399
2400 list = (GList *)gtk_object_get_data(GTK_OBJECT(clist), "querylist");
2401
2402 if(list)
2403 {
2404 int counter = 0, pos = (int)gtk_object_get_data(GTK_OBJECT(clist), "querypos");
2405 gtk_object_set_data(GTK_OBJECT(clist), "querypos", (gpointer)pos+1);
2406
2407 while(list && counter < pos)
2408 {
2409 list = list->next;
2410 counter++;
2411 }
2412
2413 if(list && list->data)
2414 retval = list->data;
2415 else if(list && !list->data)
2416 retval = "";
2417 }
2418 DW_MUTEX_UNLOCK;
2419 return retval;
2420 }
2421
2422 /*
2423 * Creates a rendering context widget (window) to be packed.
2424 * Parameters:
2425 * id: An id to be used with dw_window_from_id.
2426 * Returns:
2427 * A handle to the widget or NULL on failure.
2428 */
2429 HWND dw_render_new(unsigned long id)
2430 {
2431 int _locked_by_me = FALSE;
2432 GtkWidget *tmp;
2433
2434 DW_MUTEX_LOCK;
2435 tmp = gtk_drawing_area_new();
2436 gtk_widget_set_events(tmp, GDK_EXPOSURE_MASK
2437 | GDK_LEAVE_NOTIFY_MASK
2438 | GDK_BUTTON_PRESS_MASK
2439 | GDK_POINTER_MOTION_MASK
2440 | GDK_POINTER_MOTION_HINT_MASK);
2441 gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
2442 gtk_widget_show(tmp);
2443 DW_MUTEX_UNLOCK;
2444 return tmp;
2445 }
2446
2447 /* Sets the current foreground drawing color.
2448 * Parameters:
2449 * red: red value.
2450 * green: green value.
2451 * blue: blue value.
2452 */
2453 void dw_color_foreground_set(unsigned long value)
2454 {
2455 int _locked_by_me = FALSE;
2456 GdkColor color = { 0, DW_RED_VALUE(value) << 8, DW_GREEN_VALUE(value) << 8, DW_BLUE_VALUE(value) << 8 };
2457
2458 DW_MUTEX_LOCK;
2459 gdk_color_alloc(_dw_cmap, &color);
2460 _foreground = color;
2461 DW_MUTEX_UNLOCK;
2462 }
2463
2464 /* Sets the current background drawing color.
2465 * Parameters:
2466 * red: red value.
2467 * green: green value.
2468 * blue: blue value.
2469 */
2470 void dw_color_background_set(unsigned long value)
2471 {
2472 int _locked_by_me = FALSE;
2473 GdkColor color = { 0, DW_RED_VALUE(value) << 8, DW_GREEN_VALUE(value) << 8, DW_BLUE_VALUE(value) << 8 };
2474
2475 DW_MUTEX_LOCK;
2476 gdk_color_alloc(_dw_cmap, &color);
2477 _background = color;
2478 DW_MUTEX_UNLOCK;
2479 }
2480
2481 GdkGC *_set_colors(GdkWindow *window)
2482 {
2483 GdkGC *gc;
2484 if(!window)
2485 return NULL;
2486 gc = gdk_gc_new(window);
2487 if(gc)
2488 {
2489 gdk_gc_set_foreground(gc, &_foreground);
2490 gdk_gc_set_background(gc, &_background);
2491 }
2492 return gc;
2493 }
2494
2495 /* Draw a point on a window (preferably a render window).
2496 * Parameters:
2497 * handle: Handle to the window.
2498 * pixmap: Handle to the pixmap. (choose only one of these)
2499 * x: X coordinate.
2500 * y: Y coordinate.
2501 */
2502 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
2503 {
2504 int _locked_by_me = FALSE;
2505 GdkGC *gc = NULL;
2506
2507 DW_MUTEX_LOCK;
2508 if(handle)
2509 gc = _set_colors(handle->window);
2510 else if(pixmap)
2511 gc = _set_colors(pixmap->pixmap);
2512 if(gc)
2513 {
2514 gdk_draw_point(handle ? handle->window : pixmap->pixmap, gc, x, y);
2515 gdk_gc_unref(gc);
2516 }
2517 DW_MUTEX_UNLOCK;
2518 }
2519
2520 /* Draw a line on a window (preferably a render window).
2521 * Parameters:
2522 * handle: Handle to the window.
2523 * pixmap: Handle to the pixmap. (choose only one of these)
2524 * x1: First X coordinate.
2525 * y1: First Y coordinate.
2526 * x2: Second X coordinate.
2527 * y2: Second Y coordinate.
2528 */
2529 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
2530 {
2531 int _locked_by_me = FALSE;
2532 GdkGC *gc = NULL;
2533
2534 DW_MUTEX_LOCK;
2535 if(handle)
2536 gc = _set_colors(handle->window);
2537 else if(pixmap)
2538 gc = _set_colors(pixmap->pixmap);
2539 if(gc)
2540 {
2541 gdk_draw_line(handle ? handle->window : pixmap->pixmap, gc, x1, y1, x2, y2);
2542 gdk_gc_unref(gc);
2543 }
2544 DW_MUTEX_UNLOCK;
2545 }
2546
2547 /* Draw a rectangle on a window (preferably a render window).
2548 * Parameters:
2549 * handle: Handle to the window.
2550 * pixmap: Handle to the pixmap. (choose only one of these)
2551 * x: X coordinate.
2552 * y: Y coordinate.
2553 * width: Width of rectangle.
2554 * height: Height of rectangle.
2555 */
2556 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height)
2557 {
2558 int _locked_by_me = FALSE;
2559 GdkGC *gc = NULL;
2560
2561 DW_MUTEX_LOCK;
2562 if(handle)
2563 gc = _set_colors(handle->window);
2564 else if(pixmap)
2565 gc = _set_colors(pixmap->pixmap);
2566 if(gc)
2567 {
2568 gdk_draw_rectangle(handle ? handle->window : pixmap->pixmap, gc, fill, x, y, width, height);
2569 gdk_gc_unref(gc);
2570 }
2571 DW_MUTEX_UNLOCK;
2572 }
2573
2574 /* Draw text on a window (preferably a render window).
2575 * Parameters:
2576 * handle: Handle to the window.
2577 * pixmap: Handle to the pixmap. (choose only one of these)
2578 * x: X coordinate.
2579 * y: Y coordinate.
2580 * text: Text to be displayed.
2581 */
2582 void dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text)
2583 {
2584 int _locked_by_me = FALSE;
2585 GdkGC *gc = NULL;
2586 GdkFont *font;
2587 char *fontname = "fixed";
2588
2589 DW_MUTEX_LOCK;
2590 if(handle)
2591 {
2592 fontname = (char *)gtk_object_get_data(GTK_OBJECT(handle), "fontname");
2593 gc = _set_colors(handle->window);
2594 }
2595 else if(pixmap)
2596 {
2597 fontname = (char *)gtk_object_get_data(GTK_OBJECT(pixmap->handle), "fontname");
2598 gc = _set_colors(pixmap->pixmap);
2599 }
2600 if(gc)
2601 {
2602 font = gdk_font_load(fontname);
2603 if(font)
2604 {
2605 gint ascent;
2606
2607 gdk_text_extents(font, text, strlen(text), NULL, NULL, NULL, &ascent, NULL);
2608 gdk_draw_text(handle ? handle->window : pixmap->pixmap, font, gc, x, y + ascent, text, strlen(text));
2609 gdk_gc_unref(gc);
2610 gdk_font_unref(font);
2611 }
2612 }
2613 DW_MUTEX_UNLOCK;
2614 }
2615
2616 /*
2617 * Creates a pixmap with given parameters.
2618 * Parameters:
2619 * handle: Window handle the pixmap is associated with.
2620 * width: Width of the pixmap in pixels.
2621 * height: Height of the pixmap in pixels.
2622 * depth: Color depth of the pixmap.
2623 * Returns:
2624 * A handle to a pixmap or NULL on failure.
2625 */
2626 HPIXMAP dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth)
2627 {
2628 int _locked_by_me = FALSE;
2629 HPIXMAP pixmap;
2630
2631 if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
2632 return NULL;
2633
2634 if (!depth)
2635 depth = 24;
2636
2637 pixmap->width = width; pixmap->height = height;
2638
2639
2640 DW_MUTEX_LOCK;
2641 pixmap->handle = handle;
2642 pixmap->pixmap = gdk_pixmap_new(handle->window, width, height, depth);
2643 DW_MUTEX_UNLOCK;
2644 return pixmap;
2645 }
2646
2647 /*
2648 * Creates a pixmap from internal resource graphic specified by id.
2649 * Parameters:
2650 * handle: Window handle the pixmap is associated with.
2651 * id: Resource ID associated with requested pixmap.
2652 * Returns:
2653 * A handle to a pixmap or NULL on failure.
2654 */
2655 HPIXMAP dw_pixmap_grab(HWND handle, ULONG id)
2656 {
2657 GdkBitmap *bitmap;
2658 HPIXMAP pixmap;
2659 int _locked_by_me = FALSE;
2660
2661 if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
2662 return NULL;
2663
2664
2665 DW_MUTEX_LOCK;
2666 pixmap->pixmap = _find_pixmap(&bitmap, id, handle);
2667 if(pixmap->pixmap)
2668 {
2669 GdkPixmapPrivate *pvt = (GdkPixmapPrivate *)pixmap->pixmap;
2670 pixmap->width = pvt->width; pixmap->height = pvt->height;
2671 }
2672 DW_MUTEX_UNLOCK;
2673 return pixmap;
2674 }
2675
2676 /* Call this after drawing to the screen to make sure
2677 * anything you have drawn is visible.
2678 */
2679 void dw_flush(void)
2680 {
2681 int _locked_by_me = FALSE;
2682
2683 DW_MUTEX_LOCK;
2684 gdk_flush();
2685 DW_MUTEX_UNLOCK;
2686 }
2687
2688 /*
2689 * Destroys an allocated pixmap.
2690 * Parameters:
2691 * pixmap: Handle to a pixmap returned by
2692 * dw_pixmap_new..
2693 */
2694 void dw_pixmap_destroy(HPIXMAP pixmap)
2695 {
2696 int _locked_by_me = FALSE;
2697
2698 DW_MUTEX_LOCK;
2699 gdk_pixmap_unref(pixmap->pixmap);
2700 free(pixmap);
2701 DW_MUTEX_UNLOCK;
2702 }
2703
2704 /*
2705 * Copies from one item to another.
2706 * Parameters:
2707 * dest: Destination window handle.
2708 * destp: Destination pixmap. (choose only one).
2709 * xdest: X coordinate of destination.
2710 * ydest: Y coordinate of destination.
2711 * width: Width of area to copy.
2712 * height: Height of area to copy.
2713 * src: Source window handle.
2714 * srcp: Source pixmap. (choose only one).
2715 * xsrc: X coordinate of source.
2716 * ysrc: Y coordinate of source.
2717 */
2718 void dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
2719 {
2720 int _locked_by_me = FALSE;
2721 GdkGC *gc = NULL;
2722
2723 if((!dest && !destp) || (!src && !srcp))
2724 return;
2725
2726 DW_MUTEX_LOCK;
2727 if(dest)
2728 gc = _set_colors(dest->window);
2729 else if(src)
2730 gc = _set_colors(src->window);
2731 else if(destp)
2732 gc = gdk_gc_new(destp->pixmap);
2733 else if(srcp)
2734 gc = gdk_gc_new(srcp->pixmap);
2735
2736 if(gc)
2737 {
2738 gdk_draw_pixmap(dest ? dest->window : destp->pixmap, gc, src ? src->window : srcp->pixmap, xsrc, ysrc, xdest, ydest, width, height);
2739 gdk_gc_unref(gc);
2740 }
2741 DW_MUTEX_UNLOCK;
2742 }
2743
2744 /*
2745 * Emits a beep.
2746 * Parameters:
2747 * freq: Frequency.
2748 * dur: Duration.
2749 */
2750 void dw_beep(int freq, int dur)
2751 {
2752 int _locked_by_me = FALSE;
2753
2754 DW_MUTEX_LOCK;
2755 gdk_beep();
2756 DW_MUTEX_UNLOCK;
2757 }
2758
2759 /*
2760 * Returns the handle to an unnamed mutex semaphore.
2761 */
2762 HMTX dw_mutex_new(void)
2763 {
2764 HMTX mutex;
2765
2766 pthread_mutex_init(&mutex, NULL);
2767 return mutex;
2768 }
2769
2770 /*
2771 * Closes a semaphore created by dw_mutex_new().
2772 * Parameters:
2773 * mutex: The handle to the mutex returned by dw_mutex_new().
2774 */
2775 void dw_mutex_close(HMTX mutex)
2776 {
2777 pthread_mutex_destroy(&mutex);
2778 }
2779
2780 /*
2781 * Tries to gain access to the semaphore, if it can't it blocks.
2782 * Parameters:
2783 * mutex: The handle to the mutex returned by dw_mutex_new().
2784 */
2785 void dw_mutex_lock(HMTX mutex)
2786 {
2787 pthread_mutex_lock(&mutex);
2788 }
2789
2790 /*
2791 * Reliquishes the access to the semaphore.
2792 * Parameters:
2793 * mutex: The handle to the mutex returned by dw_mutex_new().
2794 */
2795 void dw_mutex_unlock(HMTX mutex)
2796 {
2797 pthread_mutex_unlock(&mutex);
2798 }
2799
2800 /*
2801 * Returns the handle to an unnamed event semaphore.
2802 */
2803 HEV dw_event_new(void)
2804 {
2805 HEV eve = (HEV)malloc(sizeof(struct _dw_unix_event));
2806
2807 if(!eve)
2808 return NULL;
2809
2810 /* We need to be careful here, mutexes on Linux are
2811 * FAST by default but are error checking on other
2812 * systems such as FreeBSD and OS/2, perhaps others.
2813 */
2814 pthread_mutex_init (&(eve->mutex), NULL);
2815 pthread_mutex_lock (&(eve->mutex));
2816 pthread_cond_init (&(eve->event), NULL);
2817
2818 pthread_mutex_unlock (&(eve->mutex));
2819 eve->alive = 1;
2820 eve->posted = 0;
2821
2822 return eve;
2823 }
2824
2825 /*
2826 * Resets a semaphore created by dw_event_new().
2827 * Parameters:
2828 * eve: The handle to the event returned by dw_event_new().
2829 */
2830 int dw_event_reset (HEV eve)
2831 {
2832 if(!eve)
2833 return FALSE;
2834
2835 pthread_mutex_lock (&(eve->mutex));
2836 pthread_cond_broadcast (&(eve->event));
2837 pthread_cond_init (&(eve->event), NULL);
2838 eve->posted = 0;
2839 pthread_mutex_unlock (&(eve->mutex));
2840 return 0;
2841 }
2842
2843 /*
2844 * Posts a semaphore created by dw_event_new(). Causing all threads
2845 * waiting on this event in dw_event_wait to continue.
2846 * Parameters:
2847 * eve: The handle to the event returned by dw_event_new().
2848 */
2849 int dw_event_post (HEV eve)
2850 {
2851 if(!eve)
2852 return FALSE;
2853
2854 pthread_mutex_lock (&(eve->mutex));
2855 pthread_cond_broadcast (&(eve->event));
2856 eve->posted = 1;
2857 pthread_mutex_unlock (&(eve->mutex));
2858 return 0;
2859 }
2860
2861 /*
2862 * Waits on a semaphore created by dw_event_new(), until the
2863 * event gets posted or until the timeout expires.
2864 * Parameters:
2865 * eve: The handle to the event returned by dw_event_new().
2866 */
2867 int dw_event_wait(HEV eve, unsigned long timeout)
2868 {
2869 int rc;
2870 struct timeval now;
2871 struct timespec timeo;
2872
2873 if(!eve)
2874 return FALSE;
2875
2876 if(eve->posted)
2877 return 0;
2878
2879 pthread_mutex_lock (&(eve->mutex));
2880 gettimeofday(&now, 0);
2881 timeo.tv_sec = now.tv_sec + (timeout / 1000);
2882 timeo.tv_nsec = now.tv_usec * 1000;
2883 rc = pthread_cond_timedwait (&(eve->event), &(eve->mutex), &timeo);
2884 pthread_mutex_unlock (&(eve->mutex));
2885 if(!rc)
2886 return 1;
2887 if(rc == ETIMEDOUT)
2888 return -1;
2889 return 0;
2890 }
2891
2892 /*
2893 * Closes a semaphore created by dw_event_new().
2894 * Parameters:
2895 * eve: The handle to the event returned by dw_event_new().
2896 */
2897 int dw_event_close(HEV *eve)
2898 {
2899 if(!eve || !(*eve))
2900 return FALSE;
2901
2902 pthread_mutex_lock (&((*eve)->mutex));
2903 pthread_cond_destroy (&((*eve)->event));
2904 pthread_mutex_unlock (&((*eve)->mutex));
2905 pthread_mutex_destroy (&((*eve)->mutex));
2906 free(*eve);
2907 *eve = NULL;
2908
2909 return TRUE;
2910 }
2911
2912 /*
2913 * Creates a new thread with a starting point of func.
2914 * Parameters:
2915 * func: Function which will be run in the new thread.
2916 * data: Parameter(s) passed to the function.
2917 * stack: Stack size of new thread (OS/2 and Windows only).
2918 */
2919 DWTID dw_thread_new(void *func, void *data, int stack)
2920 {
2921 DWTID gtkthread;
2922
2923 pthread_create(&gtkthread, NULL, func, data);
2924 return gtkthread;
2925 }
2926
2927 /*
2928 * Ends execution of current thread immediately.
2929 */
2930 void dw_thread_end(void)
2931 {
2932 pthread_exit(NULL);
2933 }
2934
2935 /*
2936 * Cleanly terminates a DW session, should be signal handler safe.
2937 * Parameters:
2938 * exitcode: Exit code reported to the operating system.
2939 */
2940 void dw_exit(int exitcode)
2941 {
2942 exit(exitcode);
2943 }
2944
2945 /*
2946 * Pack windows (widgets) into a box from the end (or bottom).
2947 * Parameters:
2948 * box: Window handle of the box to be packed into.
2949 * item: Window handle of the item to be back.
2950 * width: Width in pixels of the item or -1 to be self determined.
2951 * height: Height in pixels of the item or -1 to be self determined.
2952 * hsize: TRUE if the window (widget) should expand horizontally to fill space given.
2953 * vsize: TRUE if the window (widget) should expand vertically to fill space given.
2954 * pad: Number of pixels of padding around the item.
2955 */
2956 void dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
2957 {
2958 int expand = (hsize == FALSE && vsize == FALSE) ? FALSE : TRUE;
2959 int _locked_by_me = FALSE;
2960
2961 if(!box)
2962 return;
2963
2964 DW_MUTEX_LOCK;
2965
2966 if(!item)
2967 {
2968 item = gtk_label_new("");
2969 gtk_widget_show(item);
2970 }
2971
2972 if(GTK_IS_BOX(box))
2973 {
2974 gtk_box_pack_end(GTK_BOX(box), item, expand, TRUE, pad);
2975 gtk_widget_set_usize(item, width, height);
2976 if(GTK_IS_RADIO_BUTTON(item))
2977 {
2978 GSList *group;
2979 GtkWidget *groupstart = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(box), "group");
2980
2981 if(groupstart)
2982 {
2983 group = gtk_radio_button_group(GTK_RADIO_BUTTON(groupstart));
2984 gtk_radio_button_set_group(GTK_RADIO_BUTTON(item), group);
2985 }
2986 else
2987 gtk_object_set_data(GTK_OBJECT(box), "group", (gpointer)item);
2988 }
2989 }
2990 else
2991 {
2992 GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
2993
2994 gtk_container_add(GTK_CONTAINER(box), vbox);
2995 gtk_box_pack_end(GTK_BOX(vbox), item, expand, TRUE, 0);
2996 gtk_widget_show(vbox);
2997
2998 gtk_widget_set_usize(item, width, height);
2999 gtk_object_set_user_data(GTK_OBJECT(box), vbox);
3000 }
3001 DW_MUTEX_UNLOCK;
3002 }
3003
3004 /*
3005 * Sets the size of a given window (widget).
3006 * Parameters:
3007 * handle: Window (widget) handle.
3008 * width: New width in pixels.
3009 * height: New height in pixels.
3010 */
3011 void dw_window_set_usize(HWND handle, unsigned long width, unsigned long height)
3012 {
3013 int _locked_by_me = FALSE;
3014
3015 DW_MUTEX_LOCK;
3016 if(GTK_IS_WINDOW(handle))
3017 _size_allocate(GTK_WINDOW(handle));
3018 #if 0
3019 gtk_window_set_default_size(GTK_WINDOW(handle), width, height);
3020 else
3021 #endif
3022 gtk_widget_set_usize(handle, width, height);
3023 DW_MUTEX_UNLOCK;
3024 }
3025
3026 /*
3027 * Returns the width of the screen.
3028 */
3029 int dw_screen_width(void)
3030 {
3031 int retval;
3032 int _locked_by_me = FALSE;
3033
3034 DW_MUTEX_LOCK;
3035 retval = gdk_screen_width();
3036 DW_MUTEX_UNLOCK;
3037 return retval;
3038 }
3039
3040 /*
3041 * Returns the height of the screen.
3042 */
3043 int dw_screen_height(void)
3044 {
3045 int retval;
3046 int _locked_by_me = FALSE;
3047
3048 DW_MUTEX_UNLOCK;
3049 retval = gdk_screen_height();
3050 DW_MUTEX_UNLOCK;
3051 return retval;
3052 }
3053
3054 /* This should return the current color depth */
3055 unsigned long dw_color_depth(void)
3056 {
3057 int retval;
3058 int _locked_by_me = FALSE;
3059
3060 DW_MUTEX_UNLOCK;
3061 retval = gdk_colormap_get_system_size();
3062 DW_MUTEX_UNLOCK;
3063 return retval;
3064 }
3065
3066 /*
3067 * Sets the position of a given window (widget).
3068 * Parameters:
3069 * handle: Window (widget) handle.
3070 * x: X location from the bottom left.
3071 * y: Y location from the bottom left.
3072 */
3073 void dw_window_set_pos(HWND handle, unsigned long x, unsigned long y)
3074 {
3075 int _locked_by_me = FALSE;
3076
3077 DW_MUTEX_LOCK;
3078 if(handle->window)
3079 gdk_window_move(handle->window, x, y);
3080 DW_MUTEX_UNLOCK;
3081 }
3082
3083 /*
3084 * Sets the position and size of a given window (widget).
3085 * Parameters:
3086 * handle: Window (widget) handle.
3087 * x: X location from the bottom left.
3088 * y: Y location from the bottom left.
3089 * width: Width of the widget.
3090 * height: Height of the widget.
3091 */
3092 void dw_window_set_pos_size(HWND handle, unsigned long x, unsigned long y, unsigned long width, unsigned long height)
3093 {
3094 int _locked_by_me = FALSE;
3095
3096 DW_MUTEX_LOCK;
3097 if(GTK_IS_WINDOW(handle))
3098 {
3099 _size_allocate(GTK_WINDOW(handle));
3100 gtk_widget_set_uposition(handle, x, y);
3101 gtk_window_set_default_size(GTK_WINDOW(handle), width, height);
3102 }
3103 else if(handle->window)
3104 {
3105 gdk_window_resize(handle->window, width, height);
3106 gdk_window_move(handle->window, x, y);
3107 }
3108 DW_MUTEX_UNLOCK;
3109 }
3110
3111 /*
3112 * Gets the position and size of a given window (widget).
3113 * Parameters:
3114 * handle: Window (widget) handle.
3115 * x: X location from the bottom left.
3116 * y: Y location from the bottom left.
3117 * width: Width of the widget.
3118 * height: Height of the widget.
3119 */
3120 void dw_window_get_pos_size(HWND handle, ULONG *x, ULONG *y, ULONG *width, ULONG *height)
3121 {
3122 int _locked_by_me = FALSE;
3123 gint gx, gy, gwidth, gheight, gdepth;
3124
3125 if(handle->window)
3126 {
3127 DW_MUTEX_LOCK;
3128 gdk_window_get_geometry(handle->window, &gx, &gy, &gwidth, &gheight, &gdepth);
3129 gdk_window_get_root_origin(handle->window, &gx, &gy);
3130 if(x)
3131 *x = gx;
3132 if(y)
3133 *y = gy;
3134 if(width)
3135 *width = gwidth;
3136 if(height)
3137 *height = gheight;
3138 DW_MUTEX_UNLOCK;
3139 }
3140 }
3141
3142 /*
3143 * Sets the style of a given window (widget).
3144 * Parameters:
3145 * handle: Window (widget) handle.
3146 * width: New width in pixels.
3147 * height: New height in pixels.
3148 */
3149 void dw_window_set_style(HWND handle, unsigned long style, unsigned long mask)
3150 {
3151 GtkWidget *handle2 = handle;
3152 int _locked_by_me = FALSE;
3153
3154 DW_MUTEX_LOCK;
3155 if(GTK_IS_SCROLLED_WINDOW(handle))
3156 {
3157 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3158 if(tmp)
3159 handle2 = tmp;
3160 }
3161 if(GTK_IS_CLIST(handle2))
3162 {
3163 if(style & DW_CCS_EXTENDSEL)
3164 gtk_clist_set_selection_mode(GTK_CLIST(handle2), GTK_SELECTION_MULTIPLE);
3165 if(style & DW_CCS_SINGLESEL)
3166 gtk_clist_set_selection_mode(GTK_CLIST(handle2), GTK_SELECTION_SINGLE);
3167 }
3168 DW_MUTEX_UNLOCK;
3169 }
3170
3171 /*
3172 * Adds a new page to specified notebook.
3173 * Parameters:
3174 * handle: Window (widget) handle.
3175 * flags: Any additional page creation flags.
3176 * front: If TRUE page is added at the beginning.
3177 */
3178 unsigned long dw_notebook_page_new(HWND handle, unsigned long flags, int front)
3179 {
3180 int z;
3181 int _locked_by_me = FALSE;
3182
3183 DW_MUTEX_LOCK;
3184 for(z=0;z<256;z++)
3185 if(!gtk_notebook_get_nth_page(GTK_NOTEBOOK(handle), z))
3186 {
3187 DW_MUTEX_UNLOCK;
3188 return z;
3189 }
3190
3191 DW_MUTEX_UNLOCK;
3192
3193 /* Hopefully this won't happen. */
3194 return 256;
3195 }
3196
3197 /*
3198 * Remove a page from a notebook.
3199 * Parameters:
3200 * handle: Handle to the notebook widget.
3201 * pageid: ID of the page to be destroyed.
3202 */
3203 void dw_notebook_page_destroy(HWND handle, unsigned int pageid)
3204 {
3205 int _locked_by_me = FALSE;
3206
3207 DW_MUTEX_LOCK;
3208 gtk_notebook_remove_page(GTK_NOTEBOOK(handle), pageid);
3209 DW_MUTEX_UNLOCK;
3210 }
3211
3212 /*
3213 * Queries the currently visible page ID.
3214 * Parameters:
3215 * handle: Handle to the notebook widget.
3216 */
3217 unsigned int dw_notebook_page_query(HWND handle)
3218 {
3219 int retval;
3220 int _locked_by_me = FALSE;
3221
3222 DW_MUTEX_LOCK;
3223 retval = gtk_notebook_get_current_page(GTK_NOTEBOOK(handle));
3224 DW_MUTEX_UNLOCK;
3225 return retval;
3226 }
3227
3228 /*
3229 * Sets the currently visibale page ID.
3230 * Parameters:
3231 * handle: Handle to the notebook widget.
3232 * pageid: ID of the page to be made visible.
3233 */
3234 void dw_notebook_page_set(HWND handle, unsigned int pageid)
3235 {
3236 int _locked_by_me = FALSE;
3237
3238 DW_MUTEX_LOCK;
3239 gtk_notebook_set_page(GTK_NOTEBOOK(handle), pageid);
3240 DW_MUTEX_UNLOCK;
3241 }
3242
3243
3244 /*
3245 * Sets the text on the specified notebook tab.
3246 * Parameters:
3247 * handle: Notebook handle.
3248 * pageid: Page ID of the tab to set.
3249 * text: Pointer to the text to set.
3250 */
3251 void dw_notebook_page_set_text(HWND handle, unsigned long pageid, char *text)
3252 {
3253 GtkWidget *child;
3254 int _locked_by_me = FALSE;
3255
3256 DW_MUTEX_LOCK;
3257 child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(handle), pageid);
3258 if(child)
3259 gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(handle), child, text);
3260 DW_MUTEX_UNLOCK;
3261 }
3262
3263 /*
3264 * Sets the text on the specified notebook tab status area.
3265 * Parameters:
3266 * handle: Notebook handle.
3267 * pageid: Page ID of the tab to set.
3268 * text: Pointer to the text to set.
3269 */
3270 void dw_notebook_page_set_status_text(HWND handle, unsigned long pageid, char *text)
3271 {
3272 /* TODO (if possible) */
3273 }
3274
3275 /*
3276 * Packs the specified box into the notebook page.
3277 * Parameters:
3278 * handle: Handle to the notebook to be packed.
3279 * pageid: Page ID in the notebook which is being packed.
3280 * page: Box handle to be packed.
3281 */
3282 void dw_notebook_pack(HWND handle, unsigned long pageid, HWND page)
3283 {
3284 GtkWidget *label;
3285 int _locked_by_me = FALSE;
3286
3287 DW_MUTEX_LOCK;
3288 label = gtk_label_new("");
3289
3290 gtk_notebook_append_page (GTK_NOTEBOOK(handle), page, label);
3291 DW_MUTEX_UNLOCK;
3292 }
3293
3294 /*
3295 * Appends the specified text to the listbox's (or combobox) entry list.
3296 * Parameters:
3297 * handle: Handle to the listbox to be appended to.
3298 * text: Text to append into listbox.
3299 */
3300 void dw_listbox_append(HWND handle, char *text)
3301 {
3302 GtkWidget *handle2 = handle;
3303 int _locked_by_me = FALSE;
3304
3305 DW_MUTEX_LOCK;
3306 if(GTK_IS_SCROLLED_WINDOW(handle))
3307 {
3308 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3309 if(tmp)
3310 handle2 = tmp;
3311 }
3312 if(GTK_IS_LIST(handle2))
3313 {
3314 GtkWidget *list_item;
3315 GList *tmp;
3316 char *font = (char *)gtk_object_get_data(GTK_OBJECT(handle), "font");
3317 unsigned long fore = (unsigned long)gtk_object_get_data(GTK_OBJECT(handle), "fore");
3318 unsigned long back = (unsigned long)gtk_object_get_data(GTK_OBJECT(handle), "back");
3319
3320 list_item=gtk_list_item_new_with_label(text);
3321
3322 if(font)
3323 _set_font(GTK_LIST_ITEM(list_item)->item.bin.child, font);
3324 if(fore && back)
3325 _set_color(GTK_LIST_ITEM(list_item)->item.bin.child, fore, back);
3326
3327 tmp = g_list_append(NULL, list_item);
3328 gtk_widget_show(list_item);
3329 gtk_list_append_items(GTK_LIST(handle2),tmp);
3330 }
3331 else if(GTK_IS_COMBO(handle2))
3332 {
3333 GList *tmp = (GList *)gtk_object_get_user_data(GTK_OBJECT(handle2));
3334 char *addtext = strdup(text);
3335
3336 if(addtext)
3337 {
3338 tmp = g_list_append(tmp, addtext);
3339 gtk_object_set_user_data(GTK_OBJECT(handle2), tmp);
3340 gtk_combo_set_popdown_strings(GTK_COMBO(handle2), tmp);
3341 }
3342 }
3343 DW_MUTEX_UNLOCK;
3344 }
3345
3346 /*
3347 * Clears the listbox's (or combobox) list of all entries.
3348 * Parameters:
3349 * handle: Handle to the listbox to be cleared.
3350 */
3351 void dw_listbox_clear(HWND handle)
3352 {
3353 GtkWidget *handle2 = handle;
3354 int _locked_by_me = FALSE;
3355
3356 DW_MUTEX_LOCK;
3357 if(GTK_IS_SCROLLED_WINDOW(handle))
3358 {
3359 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3360 if(tmp)
3361 handle2 = tmp;
3362 }
3363 if(GTK_IS_COMBO(handle2))
3364 {
3365 GList *list, *tmp = (GList *)gtk_object_get_user_data(GTK_OBJECT(handle2));
3366
3367 if(tmp)
3368 {
3369 list = tmp;
3370 while(list)
3371 {
3372 if(list->data)
3373 free(list->data);
3374 list=list->next;
3375 }
3376 g_list_free(tmp);
3377 }
3378 gtk_object_set_user_data(GTK_OBJECT(handle2), NULL);
3379 }
3380 else if(GTK_IS_LIST(handle2))
3381 {
3382 int count = dw_listbox_count(handle);
3383
3384 gtk_list_clear_items(GTK_LIST(handle2), 0, count - 1);
3385 }
3386 DW_MUTEX_UNLOCK;
3387 }
3388
3389 /*
3390 * Returns the listbox's item count.
3391 * Parameters:
3392 * handle: Handle to the listbox to be counted
3393 */
3394 int dw_listbox_count(HWND handle)
3395 {
3396 GtkWidget *handle2 = handle;
3397 int retval = 0;
3398 int _locked_by_me = FALSE;
3399
3400 DW_MUTEX_LOCK;
3401 if(GTK_IS_SCROLLED_WINDOW(handle))
3402 {
3403 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3404 if(tmp)
3405 handle2 = tmp;
3406 }
3407 else if(GTK_IS_COMBO(handle))
3408 {
3409 handle2 = GTK_COMBO(handle)->list;
3410 }
3411 if(GTK_IS_LIST(handle2))
3412 {
3413 GList *list = GTK_LIST(handle2)->children;
3414 while(list)
3415 {
3416 list = list->next;
3417 retval++;
3418 }
3419 }
3420 DW_MUTEX_UNLOCK;
3421 return retval;
3422 }
3423
3424 /*
3425 * Sets the topmost item in the viewport.
3426 * Parameters:
3427 * handle: Handle to the listbox to be cleared.
3428 * top: Index to the top item.
3429 */
3430 void dw_listbox_set_top(HWND handle, int top)
3431 {
3432 GtkWidget *handle2 = handle;
3433 int _locked_by_me = FALSE;
3434
3435 DW_MUTEX_LOCK;
3436 if(GTK_IS_SCROLLED_WINDOW(handle))
3437 {
3438 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3439 if(tmp)
3440 handle2 = tmp;
3441 }
3442 if(GTK_IS_LIST(handle2))
3443 {
3444 int count = dw_listbox_count(handle);
3445 GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(handle));
3446 float pos, ratio;
3447
3448 if(count)
3449 {
3450 ratio = (float)top/(float)count;
3451
3452 pos = (ratio * (float)(adj->upper - adj->lower)) + adj->lower;
3453
3454 gtk_adjustment_set_value(adj, pos);
3455 }
3456 }
3457 DW_MUTEX_UNLOCK;
3458 }
3459
3460 /*
3461 * Copies the given index item's text into buffer.
3462 * Parameters:
3463 * handle: Handle to the listbox to be queried.
3464 * index: Index into the list to be queried.
3465 * buffer: Buffer where text will be copied.
3466 * length: Length of the buffer (including NULL).
3467 */
3468 void dw_listbox_query_text(HWND handle, unsigned int index, char *buffer, unsigned int length)
3469 {
3470 GtkWidget *handle2 = handle;
3471 int _locked_by_me = FALSE;
3472
3473 DW_MUTEX_LOCK;
3474 if(GTK_IS_SCROLLED_WINDOW(handle))
3475 {
3476 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3477 if(tmp)
3478 handle2 = tmp;
3479 }
3480 else if(GTK_IS_COMBO(handle))
3481 {
3482 handle2 = GTK_COMBO(handle)->list;
3483 }
3484 if(GTK_IS_LIST(handle2))
3485 {
3486 int counter = 0;
3487 GList *list = GTK_LIST(handle2)->children;
3488
3489 while(list)
3490 {
3491 if(counter == index)
3492 {
3493 gchar *text = "";
3494
3495 if(GTK_IS_LIST_ITEM(list->data))
3496 {
3497 GtkListItem *li = GTK_LIST_ITEM(list->data);
3498
3499 if(GTK_IS_ITEM(&(li->item)))
3500 {
3501 GtkItem *i = &(li->item);
3502
3503 if(GTK_IS_BIN(&(i->bin)))
3504 {
3505 GtkBin *b = &(i->bin);
3506
3507 if(GTK_IS_LABEL(b->child))
3508 gtk_label_get(GTK_LABEL(b->child), &text);
3509 }
3510 }
3511 }
3512 else if(GTK_IS_COMBO(handle) && list->data)
3513 text = (gchar *)list->data;
3514
3515 strncpy(buffer, (char *)text, length);
3516 break;
3517 }
3518 list = list->next;
3519 counter++;
3520 }
3521 }
3522 DW_MUTEX_UNLOCK;
3523 }
3524
3525 /*
3526 * Sets the text of a given listbox entry.
3527 * Parameters:
3528 * handle: Handle to the listbox to be queried.
3529 * index: Index into the list to be queried.
3530 * buffer: Buffer where text will be copied.
3531 */
3532 void dw_listbox_set_text(HWND handle, unsigned int index, char *buffer)
3533 {
3534 GtkWidget *handle2 = handle;
3535 int _locked_by_me = FALSE;
3536
3537 DW_MUTEX_LOCK;
3538 if(GTK_IS_SCROLLED_WINDOW(handle))
3539 {
3540 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3541 if(tmp)
3542 handle2 = tmp;
3543 }
3544 else if(GTK_IS_COMBO(handle))
3545 {
3546 handle2 = GTK_COMBO(handle)->list;
3547 }
3548 if(GTK_IS_LIST(handle2))
3549 {
3550 int counter = 0;
3551 GList *list = GTK_LIST(handle2)->children;
3552
3553 while(list)
3554 {
3555 if(counter == index)
3556 {
3557
3558 if(GTK_IS_LIST_ITEM(list->data))
3559 {
3560 GtkListItem *li = GTK_LIST_ITEM(list->data);
3561
3562 if(GTK_IS_ITEM(&(li->item)))
3563 {
3564 GtkItem *i = &(li->item);
3565
3566 if(GTK_IS_BIN(&(i->bin)))
3567 {
3568 GtkBin *b = &(i->bin);
3569
3570 if(GTK_IS_LABEL(b->child))
3571 gtk_label_set_text(GTK_LABEL(b->child), buffer);
3572 }
3573 }
3574 }
3575 else if(GTK_IS_COMBO(handle))
3576 {
3577 if(list->data)
3578 g_free(list->data);
3579 list->data = g_strdup(buffer);
3580 }
3581 break;
3582 }
3583 list = list->next;
3584 counter++;
3585 }
3586 }
3587 DW_MUTEX_UNLOCK;
3588 }
3589
3590 /*
3591 * Returns the index to the item in the list currently selected.
3592 * Parameters:
3593 * handle: Handle to the listbox to be queried.
3594 */
3595 unsigned int dw_listbox_selected(HWND handle)
3596 {
3597 GtkWidget *handle2 = handle;
3598 int retval = DW_LIT_NONE;
3599 int _locked_by_me = FALSE;
3600
3601 DW_MUTEX_LOCK;
3602 if(GTK_IS_SCROLLED_WINDOW(handle))
3603 {
3604 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3605 if(tmp)
3606 handle2 = tmp;
3607 }
3608 else if(GTK_IS_COMBO(handle))
3609 {
3610 retval = (unsigned int)gtk_object_get_data(GTK_OBJECT(handle), "item");
3611 DW_MUTEX_UNLOCK;
3612 return retval;
3613 }
3614 if(GTK_IS_LIST(handle2))
3615 {
3616 int counter = 0;
3617 GList *list = GTK_LIST(handle2)->children;
3618 while(list)
3619 {
3620 if(list == GTK_LIST(handle2)->selection)
3621 {
3622 retval = counter;
3623 break;
3624 }
3625
3626 list = list->next;
3627 counter++;
3628 }
3629 }
3630 DW_MUTEX_UNLOCK;
3631 return retval;
3632 }
3633
3634 /*
3635 * Sets the selection state of a given index.
3636 * Parameters:
3637 * handle: Handle to the listbox to be set.
3638 * index: Item index.
3639 * state: TRUE if selected FALSE if unselected.
3640 */
3641 void dw_listbox_select(HWND handle, int index, int state)
3642 {
3643 GtkWidget *handle2 = handle;
3644 int _locked_by_me = FALSE;
3645
3646 DW_MUTEX_LOCK;
3647 if(GTK_IS_SCROLLED_WINDOW(handle))
3648 {
3649 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3650 if(tmp)
3651 handle2 = tmp;
3652 }
3653 else if(GTK_IS_COMBO(handle))
3654 {
3655 handle2 = GTK_COMBO(handle)->list;
3656 }
3657 if(GTK_IS_LIST(handle2))
3658 {
3659 if(state)
3660 gtk_list_select_item(GTK_LIST(handle2), index);
3661 else
3662 gtk_list_unselect_item(GTK_LIST(handle2), index);
3663 }
3664 DW_MUTEX_UNLOCK;
3665 }
3666
3667 /*
3668 * Deletes the item with given index from the list.
3669 * Parameters:
3670 * handle: Handle to the listbox to be set.
3671 * index: Item index.
3672 */
3673 void dw_listbox_delete(HWND handle, int index)
3674 {
3675 GtkWidget *handle2 = handle;
3676 int _locked_by_me = FALSE;
3677
3678 DW_MUTEX_LOCK;
3679 if(GTK_IS_SCROLLED_WINDOW(handle))
3680 {
3681 GtkWidget *tmp = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
3682 if(tmp)
3683 handle2 = tmp;
3684 }
3685 else if(GTK_IS_COMBO(handle))
3686 {
3687 handle2 = GTK_COMBO(handle)->list;
3688 }
3689 if(GTK_IS_LIST(handle2))
3690 gtk_list_clear_items(GTK_LIST(handle2), index, index);
3691 DW_MUTEX_UNLOCK;
3692 }
3693
3694
3695 /*
3696 * Pack a splitbar (sizer) into the specified box from the start.
3697 * Parameters:
3698 * box: Window handle of the box to be packed into.
3699 */
3700 void dw_box_pack_splitbar_start(HWND box)
3701 {
3702 /* TODO */
3703 }
3704
3705 /*
3706 * Pack a splitbar (sizer) into the specified box from the end.
3707 * Parameters:
3708 * box: Window handle of the box to be packed into.
3709 */
3710 void dw_box_pack_splitbar_end(HWND box)
3711 {
3712 /* TODO */
3713 }
3714
3715 /*
3716 * Pack windows (widgets) into a box from the start (or top).
3717 * Parameters:
3718 * box: Window handle of the box to be packed into.
3719 * item: Window handle of the item to be back.
3720 * width: Width in pixels of the item or -1 to be self determined.
3721 * height: Height in pixels of the item or -1 to be self determined.
3722 * hsize: TRUE if the window (widget) should expand horizontally to fill space given.
3723 * vsize: TRUE if the window (widget) should expand vertically to fill space given.
3724 * pad: Number of pixels of padding around the item.
3725 */
3726 void dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
3727 {
3728 int expand = (hsize == FALSE && vsize == FALSE) ? FALSE : TRUE;
3729 int _locked_by_me = FALSE;
3730
3731 if(!box)
3732 return;
3733
3734 DW_MUTEX_LOCK;
3735
3736 if(!item)
3737 {
3738 item = gtk_label_new("");
3739 gtk_widget_show(item);
3740 }
3741
3742 if(GTK_IS_BOX(box))
3743 {
3744 gtk_box_pack_start(GTK_BOX(box), item, expand, TRUE, pad);
3745 gtk_widget_set_usize(item, width, height);
3746 if(GTK_IS_RADIO_BUTTON(item))
3747 {
3748 GSList *group;
3749 GtkWidget *groupstart = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(box), "group");
3750
3751 if(groupstart)
3752 {
3753 group = gtk_radio_button_group(GTK_RADIO_BUTTON(groupstart));
3754 gtk_radio_button_set_group(GTK_RADIO_BUTTON(item), group);
3755 }
3756 else
3757 gtk_object_set_data(GTK_OBJECT(box), "group", (gpointer)item);
3758 }
3759 }
3760 else
3761 {
3762 GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
3763
3764 gtk_container_add(GTK_CONTAINER(box), vbox);
3765 gtk_box_pack_end(GTK_BOX(vbox), item, expand, TRUE, 0);
3766 gtk_widget_show(vbox);
3767
3768 gtk_widget_set_usize(item, width, height);
3769 gtk_object_set_user_data(GTK_OBJECT(box), vbox);
3770 }
3771 DW_MUTEX_UNLOCK;
3772 }
3773
3774 /*
3775 * Returns some information about the current operating environment.
3776 * Parameters:
3777 * env: Pointer to a DWEnv struct.
3778 */
3779 void dw_environment_query(DWEnv *env)
3780 {
3781 struct utsname name;
3782 char tempbuf[100];
3783 int len, z;
3784
3785 uname(&name);
3786 strcpy(env->osName, name.sysname);
3787 strcpy(tempbuf, name.release);
3788
3789 env->MajorBuild = env->MinorBuild = 0;
3790
3791 len = strlen(tempbuf);
3792
3793 for(z=1;z<len;z++)
3794 {
3795 if(tempbuf[z] == '.')
3796 {
3797 tempbuf[z] = '\0';
3798 env->MajorVersion = atoi(&tempbuf[z-1]);
3799 env->MinorVersion = atoi(&tempbuf[z+1]);
3800 return;
3801 }
3802 }
3803 env->MajorVersion = atoi(tempbuf);
3804 env->MinorVersion = 0;
3805 }
3806
3807 /* Internal function to handle the file OK press */
3808 void _gtk_file_ok(GtkWidget *widget, GtkWidget *window)
3809 {
3810 char *tmp;
3811
3812 tmp = gtk_file_selection_get_filename(GTK_FILE_SELECTION(window));
3813 if(tmp)
3814 _dw_browse_file = strdup(tmp);
3815 gtk_widget_destroy(GTK_WIDGET(window));
3816 if(pthread_self() == _dw_thread)
3817 gtk_main_quit();
3818 _dw_file_ready = 1;
3819 }
3820
3821 /* Internal function to handle the file Cancel press */
3822 void _gtk_file_cancel(GtkWidget *widget, GtkWidget *window)
3823 {
3824 gtk_widget_destroy(GTK_WIDGET(window));
3825 if(pthread_self() == _dw_thread)
3826 gtk_main_quit();
3827 _dw_file_ready = 1;
3828
3829 }
3830
3831 /*
3832 * Opens a file dialog and queries user selection.
3833 * Parameters:
3834 * title: Title bar text for dialog.
3835 * defpath: The default path of the open dialog.
3836 * ext: Default file extention.
3837 * flags: DW_FILE_OPEN or DW_FILE_SAVE.
3838 * Returns:
3839 * NULL on error. A malloced buffer containing
3840 * the file path on success.
3841 *
3842 */
3843 char *dw_file_browse(char *title, char *defpath, char *ext, int flags)
3844 {
3845 GtkWidget *filew;
3846 char *tmpvar;
3847 int _locked_by_me = FALSE;
3848
3849 DW_MUTEX_LOCK;
3850
3851 /* The DW mutex should be sufficient for
3852 * insuring no thread changes this unknowingly.
3853 */
3854 if(_dw_file_active)
3855 {
3856 DW_MUTEX_UNLOCK;
3857 return NULL;
3858 }
3859
3860 _dw_file_active = 1;
3861 _dw_file_ready = 0;
3862
3863 filew = gtk_file_selection_new(title);
3864
3865 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filew)->ok_button), "clicked", (GtkSignalFunc) _gtk_file_ok, filew);
3866 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filew)->cancel_button), "clicked", (GtkSignalFunc) _gtk_file_cancel, filew);
3867
3868 if(defpath)
3869 gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), defpath);
3870
3871 gtk_widget_show(filew);
3872
3873 DW_MUTEX_UNLOCK;
3874
3875 if(pthread_self() == _dw_thread)
3876 gtk_main();
3877 else
3878 {
3879 /* This should be an event semaphore */
3880 while(!_dw_file_ready)
3881 usleep(100);
3882 }
3883
3884 tmpvar = _dw_browse_file;
3885 _dw_browse_file = NULL;
3886 _dw_file_ready = _dw_file_active = 0;
3887
3888 return tmpvar;
3889 }
3890
3891
3892 /*
3893 * Execute and external program in a seperate session.
3894 * Parameters:
3895 * program: Program name with optional path.
3896 * type: Either DW_EXEC_CON or DW_EXEC_GUI.
3897 * params: An array of pointers to string arguements.
3898 * Returns:
3899 * -1 on error.
3900 */
3901 int dw_exec(char *program, int type, char **params)
3902 {
3903 int ret = -1;
3904
3905 if((ret = fork()) == 0)
3906 {
3907 int i;
3908
3909 for (i = 3; i < 256; i++)
3910 close(i);
3911 setsid();
3912 if(type == DW_EXEC_GUI)
3913 {
3914 execvp(program, params);
3915 }
3916 else if(type == DW_EXEC_CON)
3917 {
3918 char **tmpargs;
3919
3920 if(!params)
3921 {
3922 tmpargs = malloc(sizeof(char *));
3923 tmpargs[0] = NULL;
3924 }
3925 else
3926 {
3927 int z = 0;
3928
3929 while(params[z])
3930 {
3931 z++;
3932 }
3933 tmpargs = malloc(sizeof(char *)*(z+3));
3934 z=0;
3935 tmpargs[0] = "xterm";
3936 tmpargs[1] = "-e";
3937 while(params[z])
3938 {
3939 tmpargs[z+2] = params[z];
3940 z++;
3941 }
3942 tmpargs[z+2] = NULL;
3943 }
3944 execvp("xterm", tmpargs);
3945 free(tmpargs);
3946 }
3947 /* If we got here exec failed */
3948 _exit(-1);
3949 }
3950 return ret;
3951 }
3952
3953 /*
3954 * Loads a web browser pointed at the given URL.
3955 * Parameters:
3956 * url: Uniform resource locator.
3957 */
3958 int dw_browse(char *url)
3959 {
3960 /* Is there a way to find the webbrowser in Unix? */
3961 char *execargs[3], *browser = "netscape";
3962
3963 execargs[0] = browser;
3964 execargs[1] = url;
3965 execargs[2] = NULL;
3966
3967 return dw_exec(browser, DW_EXEC_GUI, execargs);
3968 }
3969
3970 /*
3971 * Returns a pointer to a static buffer which containes the
3972 * current user directory. Or the root directory (C:\ on
3973 * OS/2 and Windows).
3974 */
3975 char *dw_user_dir(void)
3976 {
3977 static char _user_dir[1024] = "";
3978
3979 if(!_user_dir[0])
3980 {
3981 char *home = getenv("HOME");
3982
3983 if(home)
3984 strcpy(_user_dir, home);
3985 else
3986 strcpy(_user_dir, "/");
3987 }
3988 return _user_dir;
3989 }
3990
3991 /*
3992 * Call a function from the window (widget)'s context.
3993 * Parameters:
3994 * handle: Window handle of the widget.
3995 * function: Function pointer to be called.
3996 * data: Pointer to the data to be passed to the function.
3997 */
3998 void dw_window_function(HWND handle, void *function, void *data)
3999 {
4000 /* TODO */
4001 }
4002
4003 #ifndef NO_SIGNALS
4004 /*
4005 * Add a callback to a window event.
4006 * Parameters:
4007 * window: Window handle of signal to be called back.
4008 * signame: A string pointer identifying which signal to be hooked.
4009 * sigfunc: The pointer to the function to be used as the callback.
4010 * data: User data to be passed to the handler function.
4011 */
4012 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
4013 {
4014 SignalHandler *work = malloc(sizeof(SignalHandler));
4015 void *thisfunc = _findsigfunc(signame);
4016 char *thisname = signame;
4017 HWND thiswindow = window;
4018 int _locked_by_me = FALSE;
4019
4020 DW_MUTEX_LOCK;
4021 if(GTK_IS_SCROLLED_WINDOW(thiswindow))
4022 {
4023 thiswindow = (HWND)gtk_object_get_user_data(GTK_OBJECT(window));
4024 }
4025
4026 if(GTK_IS_MENU_ITEM(thiswindow) && strcmp(signame, "clicked") == 0)
4027 {
4028 thisname = "activate";
4029 thisfunc = _findsigfunc(thisname);
4030 }
4031 else if(GTK_IS_CLIST(thiswindow) && strcmp(signame, "container-context") == 0)
4032 {
4033 thisname = "button_press_event";
4034 thisfunc = _findsigfunc("container-context");
4035 }
4036 else if(GTK_IS_CLIST(thiswindow) && strcmp(signame, "container-select") == 0)
4037 {
4038 thisname = "button_press_event";
4039 thisfunc = _findsigfunc("container-select");
4040 }
4041 else if(GTK_IS_COMBO(thiswindow) && strcmp(signame, "item-select") == 0)
4042 {
4043 thisname = "select_child";
4044 thiswindow = GTK_COMBO(thiswindow)->list;
4045 }
4046 else if(GTK_IS_LIST(thiswindow) && strcmp(signame, "item-select") == 0)
4047 {
4048 thisname = "select_child";
4049 }
4050
4051 if(!thisfunc || !thiswindow)
4052 {
4053 free(work);
4054 DW_MUTEX_UNLOCK;
4055 return;
4056 }
4057
4058 work->window = window;
4059 work->data = data;
4060 work->func = sigfunc;
4061
4062 gtk_signal_connect(GTK_OBJECT(thiswindow), thisname, GTK_SIGNAL_FUNC(thisfunc), work);
4063 DW_MUTEX_UNLOCK;
4064 }
4065
4066 /*
4067 * Removes callbacks for a given window with given name.
4068 * Parameters:
4069 * window: Window handle of callback to be removed.
4070 */
4071 void dw_signal_disconnect_by_name(HWND window, char *signame)
4072 {
4073 #if 0
4074 gtk_signal_disconnect_by_name(window, signame);
4075 #endif
4076 }
4077
4078 /*
4079 * Removes all callbacks for a given window.
4080 * Parameters:
4081 * window: Window handle of callback to be removed.
4082 */
4083 void dw_signal_disconnect_by_window(HWND window)
4084 {
4085 #if 0
4086 gtk_signal_disconnect_by_window(window);
4087 #endif
4088 }
4089
4090 /*
4091 * Removes all callbacks for a given window with specified data.
4092 * Parameters:
4093 * window: Window handle of callback to be removed.
4094 * data: Pointer to the data to be compared against.
4095 */
4096 void dw_signal_disconnect_by_data(HWND window, void *data)
4097 {
4098 dw_signal_disconnect_by_data(window, data);
4099 }
4100 #endif
4101
4102 #ifdef TEST
4103 HWND mainwindow,
4104 listbox,
4105 okbutton,
4106 cancelbutton,
4107 lbbox,
4108 stext,
4109 buttonbox,
4110 testwindow,
4111 testbox,
4112 testok,
4113 testcancel,
4114 testbox2,
4115 testok2,
4116 testcancel2,
4117 notebook;
4118 int count = 2;
4119
4120 int test_callback(HWND window, void *data)
4121 {
4122 dw_window_destroy((HWND)data);
4123 /* Return -1 to allow the default handlers to return. */
4124 count--;
4125 if(!count)
4126 exit(0);
4127 return -1;
4128 }
4129
4130 /*
4131 * Let's demonstrate the functionality of this library. :)
4132 */
4133 int main(void)
4134 {
4135 unsigned long flStyle = DW_FCF_SYSMENU | DW_FCF_TITLEBAR |
4136 DW_FCF_SHELLPOSITION | DW_FCF_TASKLIST | DW_FCF_DLGBORDER;
4137 int pageid;
4138
4139 dw_init(TRUE);
4140
4141 /* Try a little server dialog. :) */
4142 mainwindow = dw_window_new(DW_DESKTOP, "Server", flStyle | DW_FCF_SIZEBORDER | DW_FCF_MINMAX);
4143
4144 lbbox = dw_box_new(BOXVERT, 10);
4145
4146 dw_box_pack_start(mainwindow, lbbox, 0, 0, TRUE, TRUE, 0);
4147
4148 stext = dw_text_new("Choose a server:", 0);
4149
4150 dw_window_set_style(stext, DW_DT_VCENTER, DW_DT_VCENTER);
4151
4152 dw_box_pack_start(lbbox, stext, 130, 15, FALSE, FALSE, 10);
4153
4154 listbox = dw_listbox_new(100L, FALSE);
4155
4156 dw_box_pack_start(lbbox, listbox, 130, 200, TRUE, TRUE, 10);
4157
4158 buttonbox = dw_box_new(BOXHORZ, 0);
4159
4160 dw_box_pack_start(lbbox, buttonbox, 0, 0, TRUE, TRUE, 0);
4161
4162 okbutton = dw_button_new("Ok", 1001L);
4163
4164 dw_box_pack_start(buttonbox, okbutton, 50, 30, TRUE, TRUE, 5);
4165
4166 cancelbutton = dw_button_new("Cancel", 1002L);
4167
4168 dw_box_pack_start(buttonbox, cancelbutton, 50, 30, TRUE, TRUE, 5);
4169
4170 /* Set some nice fonts and colors */
4171 dw_window_set_color(lbbox, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
4172 dw_window_set_color(buttonbox, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
4173 dw_window_set_font(stext, "9.WarpSans");
4174 dw_window_set_color(stext, DW_CLR_BLACK, DW_CLR_PALEGRAY);
4175 dw_window_set_font(listbox, "9.WarpSans");
4176 dw_window_set_font(okbutton, "9.WarpSans");
4177 dw_window_set_font(cancelbutton, "9.WarpSans");
4178
4179 dw_window_show(mainwindow);
4180
4181 dw_window_set_usize(mainwindow, 170, 340);
4182
4183 /* Another small example */
4184 flStyle |= DW_FCF_MINMAX | DW_FCF_SIZEBORDER;
4185
4186 testwindow = dw_window_new(DW_DESKTOP, "Wow a test dialog! :) yay!", flStyle);
4187
4188 testbox = dw_box_new(BOXVERT, 0);
4189
4190 dw_box_pack_start(testwindow, testbox, 0, 0, TRUE, TRUE, 0);
4191
4192 notebook = dw_notebook_new(1010L, TRUE);
4193
4194 dw_box_pack_start(testbox, notebook, 100, 100, TRUE, TRUE, 0);
4195
4196 testbox = dw_box_new(BOXVERT, 10);
4197
4198 pageid = dw_notebook_page_new(notebook, 0L, FALSE);
4199
4200 dw_notebook_pack(notebook, pageid, testbox);
4201
4202 dw_notebook_page_set_text(notebook, pageid, "Test page");
4203 dw_notebook_page_set_status_text(notebook, pageid, "Test page");
4204
4205 testok = dw_button_new("Ok", 1003L);
4206
4207 dw_box_pack_start(testbox, testok, 60, 40, TRUE, TRUE, 10);
4208
4209 testcancel = dw_button_new("Cancel", 1004L);
4210
4211 dw_box_pack_start(testbox, testcancel, 60, 40, TRUE, TRUE, 10);
4212
4213 testbox2 = dw_box_new(BOXHORZ, 0);
4214
4215 dw_box_pack_start(testbox, testbox2, 0, 0, TRUE, TRUE, 0);
4216
4217 testok2 = dw_button_new("Ok", 1003L);
4218
4219 dw_box_pack_start(testbox2, testok2, 60, 40, TRUE, TRUE, 10);
4220
4221 dw_box_pack_splitbar_start(testbox2);
4222
4223 testcancel2 = dw_button_new("Cancel", 1004L);
4224
4225 dw_box_pack_start(testbox2, testcancel2, 60, 40, TRUE, TRUE, 10);
4226
4227 /* Set some nice fonts and colors */
4228 dw_window_set_color(testbox, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
4229 dw_window_set_color(testbox2, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
4230 dw_window_set_font(testok, "9.WarpSans");
4231 dw_window_set_font(testcancel, "9.WarpSans");
4232 dw_window_set_font(testok2, "9.WarpSans");
4233 dw_window_set_font(testcancel2, "9.WarpSans");
4234
4235 dw_window_show(testwindow);
4236
4237 /* Setup the function callbacks */
4238 dw_signal_connect(okbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)mainwindow);
4239 dw_signal_connect(cancelbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)mainwindow);
4240 dw_signal_connect(testok, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)testwindow);
4241 dw_signal_connect(testcancel, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)testwindow);
4242 dw_signal_connect(testok2, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)testwindow);
4243 dw_signal_connect(testcancel2, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)testwindow);
4244 dw_signal_connect(mainwindow, "delete_event", DW_SIGNAL_FUNC(test_callback), (void *)mainwindow);
4245 dw_signal_connect(testwindow, "delete_event", DW_SIGNAL_FUNC(test_callback), (void *)testwindow);
4246
4247 dw_main(0L, NULL);
4248
4249 return 0;
4250 }
4251 #endif