changeset 195:b023d363fc09

Added scrollbar and timer support on OS/2 and GTK.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 20 Jan 2003 08:49:11 +0000
parents 37bee5b50bcb
children 3dc60d60007f
files dw.def dw.h dwtest.c gtk/dw.c os2/dw.c
diffstat 5 files changed, 420 insertions(+), 135 deletions(-) [+]
line wrap: on
line diff
--- a/dw.def	Sat Jan 18 19:15:18 2003 +0000
+++ b/dw.def	Mon Jan 20 08:49:11 2003 +0000
@@ -200,6 +200,9 @@
   dw_signal_disconnect_by_window         @361
   dw_signal_disconnect_by_data           @362
   dw_signal_disconnect_by_name           @363
+  
+  dw_timer_connect                       @365
+  dw_timer_disconnect                    @366
 
   dw_tree_new                            @370
   dw_tree_insert                         @371
@@ -229,3 +232,8 @@
   dw_module_symbol                       @421
   dw_module_close                        @422
 
+  dw_scrollbar_new                       @430
+  dw_scrollbar_query_pos                 @431
+  dw_scrollbar_set_pos                   @432
+  dw_scrollbar_set_range                 @433
+
--- a/dw.h	Sat Jan 18 19:15:18 2003 +0000
+++ b/dw.h	Mon Jan 20 08:49:11 2003 +0000
@@ -661,6 +661,7 @@
 HWND API dw_radiobutton_new(char *text, ULONG id);
 HWND API dw_percent_new(unsigned long id);
 HWND API dw_slider_new(int vertical, int increments, ULONG id);
+HWND API dw_scrollbar_new(int vertical, int increments, ULONG id);
 HWND API dw_checkbox_new(char *text, unsigned long id);
 HWND API dw_listbox_new(unsigned long id, int multi);
 void API dw_listbox_append(HWND handle, char *text);
@@ -677,6 +678,9 @@
 void API dw_percent_set_pos(HWND handle, unsigned int position);
 unsigned int API dw_slider_query_pos(HWND handle);
 void API dw_slider_set_pos(HWND handle, unsigned int position);
+unsigned int API dw_scrollbar_query_pos(HWND handle);
+void API dw_scrollbar_set_pos(HWND handle, unsigned int position);
+void API dw_scrollbar_set_range(HWND handle, unsigned int range);
 void API dw_window_set_pos(HWND handle, unsigned long x, unsigned long y);
 void API dw_window_set_usize(HWND handle, unsigned long width, unsigned long height);
 void API dw_window_set_pos_size(HWND handle, unsigned long x, unsigned long y, unsigned long width, unsigned long height);
@@ -809,11 +813,11 @@
 int API dw_module_load(char *name, HMOD *handle);
 int API dw_module_symbol(HMOD handle, char *name, void**func);
 int API dw_module_close(HMOD handle);
-#ifndef NO_SIGNALS
+int API dw_timer_connect(HWND window, int interval, void *sigfunc, void *data);
+void API dw_timer_disconnect(int id);
 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data);
 void API dw_signal_disconnect_by_window(HWND window);
 void API dw_signal_disconnect_by_data(HWND window, void *data);
 void API dw_signal_disconnect_by_name(HWND window, char *signame);
-#endif
 
 #endif
--- a/dwtest.c	Sat Jan 18 19:15:18 2003 +0000
+++ b/dwtest.c	Mon Jan 20 08:49:11 2003 +0000
@@ -8,128 +8,128 @@
 
 
 unsigned long flStyle = DW_FCF_SYSMENU | DW_FCF_TITLEBAR |
-   DW_FCF_SHELLPOSITION | DW_FCF_TASKLIST | DW_FCF_DLGBORDER;
+	DW_FCF_SHELLPOSITION | DW_FCF_TASKLIST | DW_FCF_DLGBORDER;
 
 HWND mainwindow,
      entryfield,
-    okbutton,
-    cancelbutton,
-    lbbox,
-    notebookbox,
-    notebookbox1,
-    notebookbox2,
-    notebook,
-    stext,
-    pagebox,
-    textbox1, textbox2,
-    buttonbox;
+     okbutton,
+     cancelbutton,
+     lbbox,
+     notebookbox,
+     notebookbox1,
+     notebookbox2,
+     notebook,
+     stext,
+     pagebox,
+     textbox1, textbox2,
+     buttonbox;
 
 int DWSIGNAL exit_callback(HWND window, void *data)
 {
-   dw_window_destroy((HWND)data);
-   exit(0);
-   return -1;
+	dw_window_destroy((HWND)data);
+	exit(0);
+	return -1;
 }
 
 int DWSIGNAL test_callback(HWND window, void *data)
 {
-   dw_window_destroy((HWND)data);
-   exit(0);
-   return -1;
+	dw_window_destroy((HWND)data);
+	exit(0);
+	return -1;
 }
 
 int DWSIGNAL browse_callback(HWND window, void *data)
 {
-   dw_file_browse("test string", NULL, "c", DW_FILE_OPEN );
-   return 0;
+	dw_file_browse("test string", NULL, "c", DW_FILE_OPEN );
+	return 0;
 }
 
 void archive_add(void)
 {
-   HWND browsebutton, browsebox;
+	HWND browsebutton, browsebox;
 
-   lbbox = dw_box_new(BOXVERT, 10);
+	lbbox = dw_box_new(BOXVERT, 10);
 
-   dw_box_pack_start(notebookbox1, lbbox, 150, 70, TRUE, TRUE, 0);
+	dw_box_pack_start(notebookbox1, lbbox, 150, 70, TRUE, TRUE, 0);
 
-    /* Archive Name */
-   stext = dw_text_new("Archive Name", 0);
+	/* Archive Name */
+	stext = dw_text_new("Archive Name", 0);
 
-   dw_window_set_style(stext, DW_DT_VCENTER, DW_DT_VCENTER);
+	dw_window_set_style(stext, DW_DT_VCENTER, DW_DT_VCENTER);
 
-   dw_box_pack_start(lbbox, stext, 130, 15, TRUE, TRUE, 2);
+	dw_box_pack_start(lbbox, stext, 130, 15, TRUE, TRUE, 2);
 
-   browsebox = dw_box_new(BOXHORZ, 0);
+	browsebox = dw_box_new(BOXHORZ, 0);
 
-   dw_box_pack_start(lbbox, browsebox, 0, 0, TRUE, TRUE, 0);
+	dw_box_pack_start(lbbox, browsebox, 0, 0, TRUE, TRUE, 0);
 
-   entryfield = dw_entryfield_new("", 100L);
+	entryfield = dw_entryfield_new("", 100L);
 
-   dw_box_pack_start(browsebox, entryfield, 100, 15, TRUE, TRUE, 4);
+	dw_box_pack_start(browsebox, entryfield, 100, 15, TRUE, TRUE, 4);
 
-   browsebutton = dw_button_new("Browse", 1001L);
+	browsebutton = dw_button_new("Browse", 1001L);
 
-   dw_box_pack_start(browsebox, browsebutton, 30, 15, TRUE, TRUE, 0);
+	dw_box_pack_start(browsebox, browsebutton, 30, 15, TRUE, TRUE, 0);
 
-   dw_window_set_color(browsebox, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
-   dw_window_set_font(browsebutton, "9.WarpSans");
-   dw_window_set_font(stext, "9.WarpSans");
-   dw_window_set_color(stext, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-   dw_window_set_font(entryfield, "9.WarpSans");
+	dw_window_set_color(browsebox, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
+	dw_window_set_font(browsebutton, "9.WarpSans");
+	dw_window_set_font(stext, "9.WarpSans");
+	dw_window_set_color(stext, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+	dw_window_set_font(entryfield, "9.WarpSans");
 
-    /* Archive Description */
-   stext = dw_text_new("Archive Description", 0);
+	/* Archive Description */
+	stext = dw_text_new("Archive Description", 0);
 
-   dw_window_set_style(stext, DW_DT_VCENTER, DW_DT_VCENTER);
+	dw_window_set_style(stext, DW_DT_VCENTER, DW_DT_VCENTER);
 
-   dw_box_pack_start(lbbox, stext, 130, 15, TRUE, TRUE, 4);
+	dw_box_pack_start(lbbox, stext, 130, 15, TRUE, TRUE, 4);
 
-   entryfield = dw_entryfield_new("", 100L);
+	entryfield = dw_entryfield_new("", 100L);
 
-   dw_box_pack_start(lbbox, entryfield, 130, 15, TRUE, TRUE, 4);
+	dw_box_pack_start(lbbox, entryfield, 130, 15, TRUE, TRUE, 4);
 
-   dw_window_set_font(stext, "9.WarpSans");
-   dw_window_set_color(stext, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-   dw_window_set_font(entryfield, "9.WarpSans");
+	dw_window_set_font(stext, "9.WarpSans");
+	dw_window_set_color(stext, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+	dw_window_set_font(entryfield, "9.WarpSans");
 
-    /* Comments */
-   stext = dw_text_new("Comments", 0);
+	/* Comments */
+	stext = dw_text_new("Comments", 0);
 
-   dw_window_set_style(stext, DW_DT_VCENTER, DW_DT_VCENTER);
+	dw_window_set_style(stext, DW_DT_VCENTER, DW_DT_VCENTER);
 
-   dw_box_pack_start(lbbox, stext, 130, 15, TRUE, TRUE, 4);
+	dw_box_pack_start(lbbox, stext, 130, 15, TRUE, TRUE, 4);
 
-   entryfield = dw_entryfield_new("", 100L);
+	entryfield = dw_entryfield_new("", 100L);
 
-   dw_box_pack_start(lbbox, entryfield, 130, 15, TRUE, TRUE, 4);
+	dw_box_pack_start(lbbox, entryfield, 130, 15, TRUE, TRUE, 4);
 
-   dw_window_set_font(stext, "9.WarpSans");
-   dw_window_set_color(stext, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-   dw_window_set_font(entryfield, "9.WarpSans");
+	dw_window_set_font(stext, "9.WarpSans");
+	dw_window_set_color(stext, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+	dw_window_set_font(entryfield, "9.WarpSans");
 
-    /* Buttons */
-   buttonbox = dw_box_new(BOXHORZ, 10);
+	/* Buttons */
+	buttonbox = dw_box_new(BOXHORZ, 10);
 
-   dw_box_pack_start(lbbox, buttonbox, 0, 0, TRUE, TRUE, 0);
+	dw_box_pack_start(lbbox, buttonbox, 0, 0, TRUE, TRUE, 0);
 
-   okbutton = dw_button_new("Ok", 1001L);
+	okbutton = dw_button_new("Ok", 1001L);
 
-   dw_box_pack_start(buttonbox, okbutton, 130, 30, TRUE, TRUE, 2);
+	dw_box_pack_start(buttonbox, okbutton, 130, 30, TRUE, TRUE, 2);
 
-   cancelbutton = dw_button_new("Cancel", 1002L);
+	cancelbutton = dw_button_new("Cancel", 1002L);
 
-   dw_box_pack_start(buttonbox, cancelbutton, 130, 30, TRUE, TRUE, 2);
+	dw_box_pack_start(buttonbox, cancelbutton, 130, 30, TRUE, TRUE, 2);
 
-   /* Set some nice fonts and colors */
-   dw_window_set_color(lbbox, DW_CLR_DARKCYAN, DW_CLR_PALEGRAY);
-   dw_window_set_color(buttonbox, DW_CLR_DARKCYAN, DW_CLR_PALEGRAY);
-   dw_window_set_color(okbutton, DW_CLR_PALEGRAY, DW_CLR_DARKCYAN);
-   dw_window_set_font(okbutton, "9.WarpSans");
-   dw_window_set_font(cancelbutton, "9.WarpSans");
+	/* Set some nice fonts and colors */
+	dw_window_set_color(lbbox, DW_CLR_DARKCYAN, DW_CLR_PALEGRAY);
+	dw_window_set_color(buttonbox, DW_CLR_DARKCYAN, DW_CLR_PALEGRAY);
+	dw_window_set_color(okbutton, DW_CLR_PALEGRAY, DW_CLR_DARKCYAN);
+	dw_window_set_font(okbutton, "9.WarpSans");
+	dw_window_set_font(cancelbutton, "9.WarpSans");
 
-   dw_signal_connect(browsebutton, "clicked", DW_SIGNAL_FUNC(browse_callback), (void *)notebookbox1);
-   dw_signal_connect(okbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)notebookbox1);
-   dw_signal_connect(cancelbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)notebookbox1);
+	dw_signal_connect(browsebutton, "clicked", DW_SIGNAL_FUNC(browse_callback), (void *)notebookbox1);
+	dw_signal_connect(okbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)notebookbox1);
+	dw_signal_connect(cancelbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)notebookbox1);
 }
 
 
@@ -140,52 +140,61 @@
 /* This gets called when a part of the graph needs to be repainted. */
 int DWSIGNAL text_expose(HWND hwnd, DWExpose *exp, void *data)
 {
-   HPIXMAP hpm = (HPIXMAP)data;
+	HPIXMAP hpm = (HPIXMAP)data;
 
-   dw_pixmap_bitblt(hwnd, NULL, 0, 0, font_width*width1, font_height*rows, NULL, hpm, 0, 0 );
-   dw_flush();
-   return TRUE;
+	dw_pixmap_bitblt(hwnd, NULL, 0, 0, font_width*width1, font_height*rows, NULL, hpm, 0, 0 );
+	dw_flush();
+	return TRUE;
 }
 
 void text_add(void)
 {
-   int i,y,depth = dw_color_depth();
-   char buf[10];
-   HPIXMAP text1pm,text2pm;
+	int i,y,depth = dw_color_depth();
+	char buf[10];
+	HPIXMAP text1pm,text2pm;
 
-   pagebox = dw_box_new(BOXVERT, 5);
-   dw_box_pack_start( notebookbox2, pagebox, 1, 1, TRUE, TRUE, 0);
+	pagebox = dw_box_new(BOXVERT, 5);
+	dw_box_pack_start( notebookbox2, pagebox, 1, 1, TRUE, TRUE, 0);
+
+	textbox1 = dw_render_new( 100 );
+	dw_box_pack_start( pagebox, textbox1, font_width*width1, font_height*rows, TRUE, TRUE, 4);
+	dw_window_set_font(textbox1, "9.WarpSans");
 
-   textbox1 = dw_render_new( 100 );
-   dw_box_pack_start( pagebox, textbox1, font_width*width1, font_height*rows, TRUE, TRUE, 4);
-   dw_window_set_font(textbox1, "9.WarpSans");
+	textbox2 = dw_render_new( 101 );
+	dw_box_pack_start( pagebox, textbox2, font_width*width2, font_height*rows, TRUE, TRUE, 4);
+	dw_window_set_font(textbox2, "9.WarpSans");
 
-   textbox2 = dw_render_new( 101 );
-   dw_box_pack_start( pagebox, textbox2, font_width*width2, font_height*rows, TRUE, TRUE, 4);
-   dw_window_set_font(textbox2, "9.WarpSans");
+	text1pm = dw_pixmap_new( textbox1, font_width*width1, font_height*rows, depth );
+	text2pm = dw_pixmap_new( textbox2, font_width*width2, font_height*rows, depth );
 
-   text1pm = dw_pixmap_new( textbox1, font_width*width1, font_height*rows, depth );
-   text2pm = dw_pixmap_new( textbox2, font_width*width2, font_height*rows, depth );
+	dw_color_foreground_set(DW_CLR_WHITE);
+	dw_draw_rect(0, text1pm, TRUE, 0, 0, font_width*width1, font_height*rows);
+	dw_draw_rect(0, text2pm, TRUE, 0, 0, font_width*width2, font_height*rows);
 
-   dw_color_foreground_set(DW_CLR_WHITE);
-   dw_draw_rect(0, text1pm, TRUE, 0, 0, font_width*width1, font_height*rows);
-   dw_draw_rect(0, text2pm, TRUE, 0, 0, font_width*width2, font_height*rows);
+	dw_font_text_extents( NULL, text1pm, "O", &font_width, &font_height );
+	dw_messagebox("DWTest", "Width: %d Height: %d\n", font_width, font_height);
 
-   dw_font_text_extents( NULL, text1pm, "O", &font_width, &font_height );
-   dw_messagebox("DWTest", "Width: %d Height: %d\n", font_width, font_height);
+	dw_color_background_set( DW_CLR_WHITE );
+	for ( i = 0;i < 100; i++)
+	{
+		y = i*font_height;
 
-   dw_color_background_set( DW_CLR_WHITE );
-   for ( i = 0;i < 100; i++)
-   {
-      y = i*font_height;
+		dw_color_foreground_set( DW_CLR_BLACK );
+		sprintf( buf, "%6.6d", i );
+		dw_draw_text( NULL, text1pm, 0, y, buf);
+		dw_draw_text( NULL, text2pm, 0, y, buf);
+	}
+	dw_signal_connect(textbox1, "expose_event", DW_SIGNAL_FUNC(text_expose), text1pm);
+	dw_signal_connect(textbox2, "expose_event", DW_SIGNAL_FUNC(text_expose), text2pm);
+}
 
-      dw_color_foreground_set( DW_CLR_BLACK );
-      sprintf( buf, "%6.6d", i );
-      dw_draw_text( NULL, text1pm, 0, y, buf);
-      dw_draw_text( NULL, text2pm, 0, y, buf);
-   }
-   dw_signal_connect(textbox1, "expose_event", DW_SIGNAL_FUNC(text_expose), text1pm);
-   dw_signal_connect(textbox2, "expose_event", DW_SIGNAL_FUNC(text_expose), text2pm);
+/* Beep every second */
+int DWSIGNAL timer_callback(void *data)
+{
+	dw_beep(200, 200);
+
+	/* Return TRUE so we get called again */
+	return TRUE;
 }
 
 /*
@@ -193,39 +202,39 @@
  */
 int main(int argc, char *argv[])
 {
-    ULONG notebookpage1;
+	ULONG notebookpage1;
 	ULONG notebookpage2;
+	int timerid;
 
-   dw_init(TRUE, argc, argv);
-
-   mainwindow = dw_window_new( HWND_DESKTOP, "dwindows test", flStyle | DW_FCF_SIZEBORDER | DW_FCF_MINMAX );
+	dw_init(TRUE, argc, argv);
 
-   notebookbox = dw_box_new( BOXVERT, 5 );
-   dw_box_pack_start( mainwindow, notebookbox, 1, 1, TRUE, TRUE, 0);
+	mainwindow = dw_window_new( HWND_DESKTOP, "dwindows test", flStyle | DW_FCF_SIZEBORDER | DW_FCF_MINMAX );
 
-   notebook = dw_notebook_new( 1, TRUE );
-   dw_box_pack_start( notebookbox, notebook, 100, 100, TRUE, TRUE, 0);
-   dw_window_set_font( notebook, "8.WarpSans");
+	notebookbox = dw_box_new( BOXVERT, 5 );
+	dw_box_pack_start( mainwindow, notebookbox, 1, 1, TRUE, TRUE, 0);
+
+	notebook = dw_notebook_new( 1, TRUE );
+	dw_box_pack_start( notebookbox, notebook, 100, 100, TRUE, TRUE, 0);
+	dw_window_set_font( notebook, "8.WarpSans");
 
-   notebookbox1 = dw_box_new( BOXVERT, 5 );
-   notebookpage1 = dw_notebook_page_new( notebook, 0, TRUE );
-   dw_notebook_pack( notebook, notebookpage1, notebookbox1 );
-   fprintf( stderr, "page1: %ld\n", notebookpage1 );
-   dw_notebook_page_set_text( notebook, notebookpage1, "first page");
-   archive_add();
+	notebookbox1 = dw_box_new( BOXVERT, 5 );
+	notebookpage1 = dw_notebook_page_new( notebook, 0, TRUE );
+	dw_notebook_pack( notebook, notebookpage1, notebookbox1 );
+	dw_notebook_page_set_text( notebook, notebookpage1, "first page");
+	archive_add();
 
-   notebookbox2 = dw_box_new( BOXVERT, 5 );
-   notebookpage2 = dw_notebook_page_new( notebook, 1, FALSE );
-   dw_notebook_pack( notebook, notebookpage2, notebookbox2 );
-   fprintf( stderr, "page2: %ld\n",notebookpage2);
-   dw_notebook_page_set_text( notebook, notebookpage2, "second page");
-   text_add();
+	notebookbox2 = dw_box_new( BOXVERT, 5 );
+	notebookpage2 = dw_notebook_page_new( notebook, 1, FALSE );
+	dw_notebook_pack( notebook, notebookpage2, notebookbox2 );
+	dw_notebook_page_set_text( notebook, notebookpage2, "second page");
+	text_add();
 
-   dw_signal_connect(mainwindow, "delete_event", DW_SIGNAL_FUNC(exit_callback), (void *)mainwindow);
-   dw_window_set_usize(mainwindow, 640, 480);
-   dw_window_show(mainwindow);
+	dw_signal_connect(mainwindow, "delete_event", DW_SIGNAL_FUNC(exit_callback), (void *)mainwindow);
+	timerid = dw_timer_connect(mainwindow, 1000, DW_SIGNAL_FUNC(timer_callback), 0);
+	dw_window_set_usize(mainwindow, 640, 480);
+	dw_window_show(mainwindow);
 
-   dw_main();
+	dw_main();
 
-   return 0;
+	return 0;
 }
--- a/gtk/dw.c	Sat Jan 18 19:15:18 2003 +0000
+++ b/gtk/dw.c	Mon Jan 20 08:49:11 2003 +0000
@@ -2370,6 +2370,33 @@
 }
 
 /*
+ * Create a new scrollbar window (widget) to be packed.
+ * Parameters:
+ *       vertical: TRUE or FALSE if scrollbar is vertical.
+ *       increments: Number of increments available.
+ *       id: An ID to be used with WinWindowFromID() or 0L.
+ */
+HWND dw_scrollbar_new(int vertical, int increments, ULONG id)
+{
+	GtkWidget *tmp;
+	GtkAdjustment *adjustment;
+	int _locked_by_me = FALSE;
+
+	DW_MUTEX_LOCK;
+	adjustment = (GtkAdjustment *)gtk_adjustment_new(0, 0, (gfloat)increments, 1, 1, 1);
+	if(vertical)
+		tmp = gtk_vscrollbar_new(adjustment);
+	else
+		tmp = gtk_hscrollbar_new(adjustment);
+	GTK_WIDGET_UNSET_FLAGS(tmp, GTK_CAN_FOCUS);
+	gtk_widget_show(tmp);
+	gtk_object_set_data(GTK_OBJECT(tmp), "adjustment", (gpointer)adjustment);
+	gtk_object_set_data(GTK_OBJECT(adjustment), "scrollbar", (gpointer)tmp);
+	gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
+	DW_MUTEX_UNLOCK;
+	return tmp;
+
+/*
  * Create a new percent bar window (widget) to be packed.
  * Parameters:
  *       id: An ID to be used with WinWindowFromID() or 0L.
@@ -3194,6 +3221,63 @@
 }
 
 /*
+ * Returns the position of the scrollbar.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be queried.
+ */
+unsigned int dw_scrollbar_query_pos(HWND handle)
+{
+	int val = 0, _locked_by_me = FALSE;
+	GtkAdjustment *adjustment;
+
+	if(!handle)
+		return 0;
+
+	DW_MUTEX_LOCK;
+	adjustment = (GtkAdjustment *)gtk_object_get_data(GTK_OBJECT(handle), "adjustment");
+	if(adjustment)
+	{
+		int max = _round_value(adjustment->upper) - 1;
+		int thisval = _round_value(adjustment->value);
+
+		if(GTK_IS_VSCROLLBAR(handle))
+			val = max - thisval;
+        else
+			val = thisval;
+	}
+	DW_MUTEX_UNLOCK;
+	return val;
+}
+
+/*
+ * Sets the scrollbar position.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be set.
+ *          position: Position of the scrollbar withing the range.
+ */
+void dw_scrollbar_set_pos(HWND handle, unsigned int position)
+{
+	int _locked_by_me = FALSE;
+	GtkAdjustment *adjustment;
+
+	if(!handle)
+		return;
+
+	DW_MUTEX_LOCK;
+	adjustment = (GtkAdjustment *)gtk_object_get_data(GTK_OBJECT(handle), "adjustment");
+	if(adjustment)
+	{
+		int max = _round_value(adjustment->upper) - 1;
+
+		if(GTK_IS_VSCROLLBAR(handle))
+			gtk_adjustment_set_value(adjustment, (gfloat)(max - position));
+        else
+			gtk_adjustment_set_value(adjustment, (gfloat)position);
+	}
+	DW_MUTEX_UNLOCK;
+}
+
+/*
  * Sets the spinbutton value.
  * Parameters:
  *          handle: Handle to the spinbutton to be set.
@@ -6952,6 +7036,46 @@
 }
 
 /*
+ * Add a callback to a timer event.
+ * Parameters:
+ *       window: Window handle which owns this timer.
+ *       interval: Milliseconds to delay between calls.
+ *       sigfunc: The pointer to the function to be used as the callback.
+ *       data: User data to be passed to the handler function.
+ * Returns:
+ *       Timer ID for use with dw_timer_disconnect(), 0 on error.
+ */
+int API dw_timer_connect(HWND window, int interval, void *sigfunc, void *data)
+{
+	int tag, _locked_by_me = FALSE;
+	char buf[100];
+
+	if(!window)
+		return 0;
+
+	DW_MUTEX_LOCK;
+	tag = gtk_timeout_add(interval, (GtkFunction)sigfunc, data);
+	sprintf(buf, "_dw_timer%d", tag);
+	gtk_object_set_data(GTK_OBJECT(window), buf, (gpointer)tag);
+	DW_MUTEX_UNLOCK;
+	return tag;
+}
+
+/*
+ * Removes timer callback.
+ * Parameters:
+ *       id: Timer ID returned by dw_timer_connect().
+ */
+void API dw_timer_disconnect(int id)
+{
+	int _locked_by_me = FALSE;
+
+	DW_MUTEX_LOCK;
+	gtk_timeout_remove(id);
+	DW_MUTEX_UNLOCK;
+}
+
+/*
  * Add a callback to a window event.
  * Parameters:
  *       window: Window handle of signal to be called back.
--- a/os2/dw.c	Sat Jan 18 19:15:18 2003 +0000
+++ b/os2/dw.c	Mon Jan 20 08:49:11 2003 +0000
@@ -58,6 +58,7 @@
 	struct _sighandler	*next;
 	ULONG message;
 	HWND window;
+	int id;
 	void *signalfunction;
 	void *data;
 
@@ -95,7 +96,7 @@
 
 /* This function adds a signal handler callback into the linked list.
  */
-void _new_signal(ULONG message, HWND window, void *signalfunction, void *data)
+void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
 {
 	SignalHandler *new = malloc(sizeof(SignalHandler));
 
@@ -104,6 +105,7 @@
 
 	new->message = message;
 	new->window = window;
+	new->id = id;
 	new->signalfunction = signalfunction;
 	new->data = data;
 	new->next = NULL;
@@ -1890,6 +1892,18 @@
 					}
 				}
 				break;
+			case WM_TIMER:
+				{
+					int (* API timerfunc)(void *) = (int (* API)(void *))tmp->signalfunction;
+					if(tmp->id == (int)mp1)
+					{
+						if(!timerfunc(tmp->data))
+							dw_timer_disconnect(tmp->id);
+						tmp = NULL;
+					}
+					result = 0;
+				}
+				break;
 			case WM_SIZE:
 				{
 					int (* API sizefunc)(HWND, int, int, void *) = (int (* API)(HWND, int, int, void *))tmp->signalfunction;
@@ -4262,6 +4276,31 @@
 }
 
 /*
+ * Create a new scrollbar window (widget) to be packed.
+ * Parameters:
+ *       vertical: TRUE or FALSE if scrollbar is vertical.
+ *       increments: Number of increments available.
+ *       id: An ID to be used with WinWindowFromID() or 0L.
+ */
+HWND API dw_scrollbar_new(int vertical, int increments, ULONG id)
+{
+	HWND tmp;
+
+	tmp = WinCreateWindow(HWND_OBJECT,
+						  WC_SCROLLBAR,
+						  "",
+						  WS_VISIBLE | SBS_AUTOTRACK |
+						  (vertical ? SBS_VERT : SBS_HORZ),
+						  0,0,2000,1000,
+						  NULLHANDLE,
+						  HWND_TOP,
+						  id,
+						  NULL,
+						  NULL);
+	return tmp;
+}
+
+/*
  * Create a new percent bar window (widget) to be packed.
  * Parameters:
  *       id: An ID to be used with WinWindowFromID() or 0L.
@@ -5209,6 +5248,40 @@
 }
 
 /*
+ * Returns the position of the scrollbar.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be queried.
+ */
+unsigned int API dw_scrollbar_query_pos(HWND handle)
+{
+	return (unsigned int)WinSendMsg(handle, SBM_QUERYPOS, 0, 0);
+}
+
+/*
+ * Sets the scrollbar position.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be set.
+ *          position: Position of the scrollbar withing the range.
+ */
+void API dw_scrollbar_set_pos(HWND handle, unsigned int position)
+{
+	dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position);
+	WinSendMsg(handle, SBM_SETPOS, (MPARAM)position, 0);
+}
+
+/*
+ * Sets the scrollbar range.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be set.
+ *          range: Maximum range value.
+ */
+void API dw_scrollbar_set_range(HWND handle, unsigned int range)
+{
+	unsigned int pos = (unsigned int)dw_window_get_data(handle, "_dw_scrollbar_value");
+	WinSendMsg(handle, SBM_SETSCROLLBAR, (MPARAM)pos, MPFROM2SHORT(0, (unsigned short)range));
+}
+
+/*
  * Sets the spinbutton value.
  * Parameters:
  *          handle: Handle to the spinbutton to be set.
@@ -7563,6 +7636,72 @@
 }
 
 /*
+ * Add a callback to a timer event.
+ * Parameters:
+ *       window: Window handle which owns this timer.
+ *       interval: Milliseconds to delay between calls.
+ *       sigfunc: The pointer to the function to be used as the callback.
+ *       data: User data to be passed to the handler function.
+ * Returns:
+ *       Timer ID for use with dw_timer_disconnect(), 0 on error.
+ */
+int API dw_timer_connect(HWND window, int interval, void *sigfunc, void *data)
+{
+	static int timerid = 0;
+
+	if(window && sigfunc)
+	{
+		timerid++;
+
+		if(timerid >= TID_USERMAX)
+			timerid = 1;
+
+		_new_signal(WM_TIMER, window, timerid, sigfunc, data);
+		return WinStartTimer(dwhab, window, timerid, interval);
+	}
+	return 0;
+}
+
+/*
+ * Removes timer callback.
+ * Parameters:
+ *       id: Timer ID returned by dw_timer_connect().
+ */
+void API dw_timer_disconnect(int id)
+{
+	SignalHandler *prev = NULL, *tmp = Root;
+
+	/* 0 is an invalid timer ID */
+	if(!id)
+		return;
+
+	while(tmp)
+	{
+		if(tmp->id == id)
+		{
+			WinStopTimer(dwhab, tmp->window, id);
+			if(prev)
+			{
+				prev->next = tmp->next;
+				free(tmp);
+				tmp = prev->next;
+			}
+			else
+			{
+				Root = tmp->next;
+				free(tmp);
+				tmp = Root;
+			}
+		}
+		else
+		{
+			prev = tmp;
+			tmp = tmp->next;
+		}
+	}
+}
+
+/*
  * Add a callback to a window event.
  * Parameters:
  *       window: Window handle of signal to be called back.
@@ -7592,7 +7731,7 @@
 	if(window && signame && sigfunc)
 	{
 		if((message = _findsigmessage(signame)) != 0)
-			_new_signal(message, window, sigfunc, data);
+			_new_signal(message, window, 0, sigfunc, data);
 	}
 }
 
@@ -7703,3 +7842,4 @@
 	}
 }
 
+