tUpdates to GTK+ library for Win32; Win32 client now functional - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 4fbf221d8daa964b0f74d5eda5fe51b35ed5df2e
 (DIR) parent 787438c63e3be440e14161b651b55e13ab135353
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Mon, 11 Dec 2000 12:57:43 +0000
       
       Updates to GTK+ library for Win32; Win32 client now functional
       
       
       Diffstat:
         M src/gtk.c                           |     529 ++++++++++++++++++++++++++-----
         M src/gtk.h                           |      60 ++++++++++++++++++++++++++++++-
         M src/gtk_client.c                    |      94 +++++++++++++++++--------------
         M src/gtk_client.h                    |       4 ++++
         M src/win32_client.c                  |      12 ++++++------
       
       5 files changed, 572 insertions(+), 127 deletions(-)
       ---
 (DIR) diff --git a/src/gtk.c b/src/gtk.c
       t@@ -87,6 +87,7 @@ static void gtk_box_show_all(GtkWidget *widget,gboolean hWndOnly);
        static void gtk_table_show_all(GtkWidget *widget,gboolean hWndOnly);
        static void gtk_widget_show_all_full(GtkWidget *widget,gboolean hWndOnly);
        static void gtk_widget_show_full(GtkWidget *widget,gboolean recurse);
       +static void gtk_widget_update(GtkWidget *widget,gboolean ForceResize);
        static void gtk_container_hide_all(GtkWidget *widget,gboolean hWndOnly);
        static void gtk_box_hide_all(GtkWidget *widget,gboolean hWndOnly);
        static void gtk_table_hide_all(GtkWidget *widget,gboolean hWndOnly);
       t@@ -146,6 +147,16 @@ static void gtk_hpaned_size_request(GtkWidget *widget,
                                            GtkRequisition *requisition);
        static void gtk_vpaned_set_size(GtkWidget *widget,GtkAllocation *allocation);
        static void gtk_hpaned_set_size(GtkWidget *widget,GtkAllocation *allocation);
       +static void gtk_option_menu_size_request(GtkWidget *widget,
       +                                         GtkRequisition *requisition);
       +static void gtk_option_menu_set_size(GtkWidget *widget,
       +                                     GtkAllocation *allocation);
       +static void gtk_option_menu_realize(GtkWidget *widget);
       +static void gtk_clist_update_selection(GtkWidget *widget);
       +static void gtk_button_set_text(GtkButton *button,gchar *text);
       +static void gtk_menu_item_set_text(GtkMenuItem *menuitem,gchar *text);
       +static void gtk_editable_create(GtkWidget *widget);
       +static void gtk_option_menu_update_selection(GtkWidget *widget);
        
        typedef struct _GdkInput GdkInput;
        
       t@@ -232,6 +243,7 @@ static GtkClass GtkMenuBarClass = {
        
        static GtkSignalType GtkMenuItemSignals[] = {
           { "realize",gtk_marshal_VOID__VOID,gtk_menu_item_realize },
       +   { "set_text",gtk_marshal_VOID__GPOIN,gtk_menu_item_set_text },
           { "activate",gtk_marshal_VOID__VOID,NULL },
           { "enable",gtk_marshal_VOID__VOID,gtk_menu_item_enable },
           { "disable",gtk_marshal_VOID__VOID,gtk_menu_item_disable },
       t@@ -251,8 +263,13 @@ static GtkClass GtkMenuClass = {
           "menu",&GtkMenuShellClass,sizeof(GtkMenu),GtkMenuSignals
        };
        
       +static GtkSignalType GtkEditableSignals[] = {
       +   { "create",gtk_marshal_VOID__VOID,gtk_editable_create },
       +   { "",NULL,NULL }
       +};
       +
        static GtkClass GtkEditableClass = {
       -   "editable",&GtkWidgetClass,sizeof(GtkEditable),NULL
       +   "editable",&GtkWidgetClass,sizeof(GtkEditable),GtkEditableSignals
        };
        
        static GtkSignalType GtkEntrySignals[] = {
       t@@ -292,6 +309,7 @@ static GtkClass GtkTextClass = {
        static GtkSignalType GtkLabelSignals[] = {
           { "size_request",gtk_marshal_VOID__GPOIN,gtk_label_size_request },
           { "set_size",gtk_marshal_VOID__GPOIN,gtk_label_set_size },
       +   { "set_text",gtk_marshal_VOID__GPOIN,gtk_label_set_text },
           { "realize",gtk_marshal_VOID__VOID,gtk_label_realize },
           { "destroy",gtk_marshal_VOID__VOID,gtk_label_destroy },
           { "",NULL,NULL }
       t@@ -303,6 +321,7 @@ static GtkClass GtkLabelClass = {
        
        static GtkSignalType GtkButtonSignals[] = {
           { "size_request",gtk_marshal_VOID__GPOIN,gtk_button_size_request },
       +   { "set_text",gtk_marshal_VOID__GPOIN,gtk_button_set_text },
           { "realize",gtk_marshal_VOID__VOID,gtk_button_realize },
           { "destroy",gtk_marshal_VOID__VOID,gtk_button_destroy },
           { "clicked",gtk_marshal_VOID__VOID,NULL },
       t@@ -313,6 +332,17 @@ static GtkClass GtkButtonClass = {
           "button",&GtkWidgetClass,sizeof(GtkButton),GtkButtonSignals
        };
        
       +static GtkSignalType GtkOptionMenuSignals[] = {
       +   { "size_request",gtk_marshal_VOID__GPOIN,gtk_option_menu_size_request },
       +   { "set_size",gtk_marshal_VOID__GPOIN,gtk_option_menu_set_size },
       +   { "realize",gtk_marshal_VOID__VOID,gtk_option_menu_realize },
       +   { "",NULL,NULL }
       +};
       +
       +static GtkClass GtkOptionMenuClass = {
       +   "optionmenu",&GtkButtonClass,sizeof(GtkOptionMenu),GtkOptionMenuSignals
       +};
       +
        static GtkSignalType GtkToggleButtonSignals[] = {
           { "toggled",gtk_marshal_VOID__VOID,NULL },
           { "",NULL,NULL }
       t@@ -357,8 +387,8 @@ static GtkClass GtkContainerClass = {
        };
        
        static GtkSignalType GtkPanedSignals[] = {
       -   { "show_all",gtk_marshal_VOID__VOID,gtk_paned_show_all },
       -   { "hide_all",gtk_marshal_VOID__VOID,gtk_paned_hide_all },
       +   { "show_all",gtk_marshal_VOID__BOOL,gtk_paned_show_all },
       +   { "hide_all",gtk_marshal_VOID__BOOL,gtk_paned_hide_all },
           { "",NULL,NULL }
        };
        static GtkClass GtkPanedClass = {
       t@@ -431,6 +461,7 @@ static GtkSignalType GtkCListSignals[] = {
           { "size_request",gtk_marshal_VOID__GPOIN,gtk_clist_size_request },
           { "set_size",gtk_marshal_VOID__GPOIN,gtk_clist_set_size },
           { "realize",gtk_marshal_VOID__VOID,gtk_clist_realize },
       +   { "click-column",gtk_marshal_VOID__GPOIN,NULL },
           { "show",gtk_marshal_VOID__VOID,gtk_clist_show },
           { "hide",gtk_marshal_VOID__VOID,gtk_clist_hide },
           { "",NULL,NULL }
       t@@ -570,6 +601,7 @@ LRESULT CALLBACK GtkSepProc(HWND hwnd,UINT msg,UINT wParam,LONG lParam) {
        
        LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,UINT wParam,LONG lParam) {
           GtkWidget *window,*widget;
       +   GtkClass *klass;
           RECT rect;
           GtkAllocation alloc;
           gboolean signal_return;
       t@@ -590,13 +622,19 @@ LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,UINT wParam,LONG lParam) {
                 gtk_widget_set_size(window,&alloc);
                 break;
              case WM_COMMAND:
       -         if (lParam && HIWORD(wParam)==BN_CLICKED) {
       -            gtk_signal_emit(GTK_OBJECT(GetWindowLong((HWND)lParam,
       -                                       GWL_USERDATA)),"clicked");
       +         widget=GTK_WIDGET(GetWindowLong((HWND)lParam,GWL_USERDATA));
       +         if (widget) klass=GTK_OBJECT(widget)->klass; else klass=NULL;
       +
       +         if (lParam && klass==&GtkCListClass && HIWORD(wParam)==LBN_SELCHANGE) {
       +            gtk_clist_update_selection(widget);
       +         } else if (lParam && klass==&GtkOptionMenuClass &&
       +                    HIWORD(wParam)==CBN_SELENDOK) {
       +            gtk_option_menu_update_selection(widget);
       +         } else if (lParam && HIWORD(wParam)==BN_CLICKED) {
       +            gtk_signal_emit(GTK_OBJECT(widget),"clicked");
                 } else if (HIWORD(wParam)==0) {
       -            widget=gtk_window_get_menu_ID(
       -                      GTK_WINDOW(GetWindowLong(hwnd,GWL_USERDATA)),
       -                      LOWORD(wParam));
       +            window=GTK_WIDGET(GetWindowLong(hwnd,GWL_USERDATA));
       +            widget=gtk_window_get_menu_ID(GTK_WINDOW(window),LOWORD(wParam));
                    if (widget) gtk_signal_emit(GTK_OBJECT(widget),"activate");
                 } else return TRUE;
                 break;
       t@@ -682,15 +720,40 @@ void win32_init(HINSTANCE hInstance,HINSTANCE hPrevInstance) {
           InitCommonControls();
        }
        
       +void gtk_widget_update(GtkWidget *widget,gboolean ForceResize) {
       +   GtkRequisition req;
       +   GtkWidget *window;
       +   GtkAllocation alloc;
       +
       +   if (!GTK_WIDGET_REALIZED(widget)) return;
       +
       +   gtk_widget_size_request(widget,&req);
       +   window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW);
       +   if (window) {
       +      alloc.x=alloc.y=0;
       +      alloc.width=window->requisition.width;
       +      alloc.height=window->requisition.height;
       +      if (alloc.width < window->allocation.width) {
       +         alloc.width=window->allocation.width;
       +      }
       +      if (alloc.height < window->allocation.height) {
       +         alloc.height=window->allocation.height;
       +      }
       +      if (alloc.width!=window->allocation.width ||
       +          alloc.height!=window->allocation.height || ForceResize) {
       +         gtk_widget_set_size(window,&alloc);
       +      }
       +   }
       +}
       +
        void gtk_widget_show(GtkWidget *widget) {
           gtk_widget_show_full(widget,TRUE);
        }
        
        void gtk_widget_show_full(GtkWidget *widget,gboolean recurse) {
           GtkAllocation alloc;
       -   GtkRequisition req;
       -   GtkWidget *window;
        
       +   if (GTK_WIDGET_VISIBLE(widget)) return;
           GTK_WIDGET_SET_FLAGS(widget,GTK_VISIBLE);
           if (recurse) gtk_widget_show_all_full(widget,TRUE);
           else gtk_signal_emit(GTK_OBJECT(widget),"show");
       t@@ -705,21 +768,8 @@ void gtk_widget_show_full(GtkWidget *widget,gboolean recurse) {
              ShowWindow(widget->hWnd,SW_SHOWNORMAL);
              UpdateWindow(widget->hWnd);
           } else if (GTK_WIDGET_REALIZED(widget)) {
       -      gtk_widget_size_request(widget,&req);
       +      gtk_widget_update(widget,TRUE);
              if (!recurse) ShowWindow(widget->hWnd,SW_SHOWNORMAL);
       -      window=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW);
       -      if (window) {
       -         alloc.x=alloc.y=0;
       -         alloc.width=window->requisition.width;
       -         alloc.height=window->requisition.height;
       -         if (alloc.width < window->allocation.width) {
       -            alloc.width=window->allocation.width;
       -         }
       -         if (alloc.height < window->allocation.height) {
       -            alloc.height=window->allocation.height;
       -         }
       -         gtk_widget_set_size(window,&alloc);
       -      }
           }
        }
        
       t@@ -732,6 +782,8 @@ void gtk_widget_hide_full(GtkWidget *widget,gboolean recurse) {
           GtkRequisition req;
           GtkWidget *window;
        
       +   if (!GTK_WIDGET_VISIBLE(widget)) return;
       +
           if (recurse) gtk_widget_hide_all_full(widget,TRUE);
           else {
              gtk_signal_emit(GTK_OBJECT(widget),"hide");
       t@@ -763,6 +815,7 @@ void gtk_widget_realize(GtkWidget *widget) {
           gtk_signal_emit(GTK_OBJECT(widget),"realize",&req);
           if (widget->hWnd) SetWindowLong(widget->hWnd,GWL_USERDATA,(LONG)widget);
           GTK_WIDGET_SET_FLAGS(widget,GTK_REALIZED);
       +   gtk_widget_set_sensitive(widget,GTK_WIDGET_SENSITIVE(widget));
           gtk_widget_size_request(widget,&req);
        }
        
       t@@ -794,8 +847,11 @@ void gtk_widget_size_request(GtkWidget *widget,GtkRequisition *requisition) {
           if (GTK_WIDGET_VISIBLE(widget)) {
              gtk_signal_emit(GTK_OBJECT(widget),"size_request",requisition);
           }
       -   memcpy(&widget->requisition,requisition,sizeof(GtkRequisition));
       -   if (widget->parent) gtk_widget_size_request(widget->parent,&req);
       +   if (requisition->width != widget->requisition.width ||
       +       requisition->height != widget->requisition.height) {
       +      memcpy(&widget->requisition,requisition,sizeof(GtkRequisition));
       +      if (widget->parent) gtk_widget_size_request(widget->parent,&req);
       +   }
        }
        
        void gtk_widget_set_size(GtkWidget *widget,GtkAllocation *allocation) {
       t@@ -915,12 +971,25 @@ void gtk_window_size_request(GtkWidget *widget,GtkRequisition *requisition) {
        void gtk_window_set_size(GtkWidget *widget,GtkAllocation *allocation) {
           GtkAllocation child_alloc;
           GtkWindow *window=GTK_WINDOW(widget);
       +   RECT rect;
       +
       +   GetWindowRect(GetDesktopWindow(),&rect);
       +
           if (allocation->width < window->default_width) {
              allocation->width=window->default_width;
           }
           if (allocation->height < window->default_height) {
              allocation->height=window->default_height;
           }
       +
       +   if (widget->parent) {
       +      allocation->x = rect.left+(rect.right-rect.left-allocation->width)/2;
       +      allocation->y = rect.top+(rect.bottom-rect.top-allocation->height)/2;
       +      if (allocation->x < 0) allocation->x = 0;
       +      if (allocation->y < 0) allocation->y = 0;
       +      if (widget->hWnd) SetWindowPos(widget->hWnd,HWND_TOP,allocation->x,
       +                                     allocation->y,0,0,SWP_NOSIZE|SWP_NOZORDER);
       +   }
           child_alloc.x=child_alloc.y=0;
           child_alloc.width=allocation->width-GetSystemMetrics(SM_CXSIZEFRAME)*2;
           child_alloc.height=allocation->height-GetSystemMetrics(SM_CYSIZEFRAME)*2
       t@@ -1076,13 +1145,9 @@ GtkWidget *gtk_radio_button_new_with_label(GSList *group,const gchar *label) {
        
        GtkWidget *gtk_label_new(const gchar *text) {
           GtkLabel *label;
       -   gint i;
        
           label=GTK_LABEL(GtkNewObject(&GtkLabelClass));
       -   label->text = g_strdup(text);
       -   for (i=0;i<strlen(label->text);i++) {
       -      if (label->text[i]=='_') label->text[i]='&';
       -   }
       +   gtk_label_set_text(label,text);
        
           return GTK_WIDGET(label);
        }
       t@@ -1153,55 +1218,84 @@ GSList *gtk_radio_button_group(GtkRadioButton *radio_button) {
           return radio_button->group;
        }
        
       +static void gtk_editable_sync_text(GtkEditable *editable) {
       +   HWND hWnd;
       +   gint textlen;
       +   gchar *buffer;
       +
       +   hWnd=GTK_WIDGET(editable)->hWnd;
       +   if (!hWnd) return;
       +
       +   textlen=SendMessage(hWnd,WM_GETTEXTLENGTH,0,0);
       +   buffer=g_new(gchar,textlen+1);
       +   SendMessage(hWnd,WM_GETTEXT,(WPARAM)(textlen+1),(LPARAM)buffer);
       +   g_string_assign(editable->text,buffer);
       +   g_free(buffer);
       +}
       +
        void gtk_editable_insert_text(GtkEditable *editable,const gchar *new_text,
                                      gint new_text_length,gint *position) {
           GtkWidget *widget=GTK_WIDGET(editable);
           HWND hWnd;
       -   if (!GTK_WIDGET_REALIZED(widget)) return;
       +   gint i,textlen;
       +
       +   gtk_editable_sync_text(editable);
       +   g_string_insert(editable->text,*position,new_text);
       +   for (i=*position;i<*position+strlen(new_text);i++) {
       +      if (editable->text->str[i]=='\r' &&
       +          editable->text->str[i+1]=='\n') {
       +         i++;
       +      } else if (editable->text->str[i]=='\n') {
       +         g_string_insert_c(editable->text,i,'\r');
       +         i++;
       +         (*position)++;
       +      }
       +   }
       +
           hWnd=widget->hWnd;
       -   SendMessage(hWnd,EM_SETSEL,(WPARAM)-1,(LPARAM)*position);
       -   SendMessage(hWnd,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)new_text);
       -   *position+=strlen(new_text);
       +   if (hWnd) {
       +      SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)editable->text->str);
       +      *position+=strlen(new_text);
       +      gtk_editable_set_position(editable,*position);
       +   }
        }
        
        void gtk_editable_delete_text(GtkEditable *editable,
                                      gint start_pos,gint end_pos) {
           GtkWidget *widget=GTK_WIDGET(editable);
           HWND hWnd;
       -   if (!GTK_WIDGET_REALIZED(widget)) return;
       +
       +   gtk_editable_sync_text(editable);
       +   if (end_pos < 0 || end_pos >= editable->text->len)
       +      end_pos=editable->text->len;
       +   g_string_erase(editable->text,start_pos,end_pos-start_pos);
       +
           hWnd=widget->hWnd;
       -   SendMessage(hWnd,EM_SETSEL,(WPARAM)start_pos,(LPARAM)end_pos);
       -   SendMessage(hWnd,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)"");
       +   if (hWnd) {
       +      SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)editable->text->str);
       +   }
        }
        
        gchar *gtk_editable_get_chars(GtkEditable *editable,
                                      gint start_pos,gint end_pos) {
       -   GtkWidget *widget=GTK_WIDGET(editable);
       -   HWND hWnd;
       -   LRESULT textlen;
       -   gchar *buffer,*retbuf;
       +   gchar *retbuf;
           gint copylen;
       -   if (!GTK_WIDGET_REALIZED(widget)) return NULL;
       -   hWnd=widget->hWnd;
       -   textlen=SendMessage(hWnd,WM_GETTEXTLENGTH,0,0);
       -   buffer=g_new(gchar,textlen+1);
       -   SendMessage(hWnd,WM_GETTEXT,(WPARAM)(textlen+1),(LPARAM)buffer);
       -   if (start_pos==0 && end_pos<0) return buffer;
       -   else {
       -      copylen=end_pos-start_pos;
       -      retbuf=g_new(gchar,copylen+1);
       -      memcpy(retbuf,&buffer[start_pos],copylen+1);
       -      g_free(buffer);
       -      return retbuf;
       -   }
       +   gtk_editable_sync_text(editable);
       +   if (end_pos < 0 || end_pos >= editable->text->len)
       +      end_pos=editable->text->len;
       +   copylen=end_pos-start_pos+1;
       +   retbuf=g_new(gchar,copylen);
       +   memcpy(retbuf,&editable->text->str[start_pos],copylen);
       +   retbuf[copylen]='\0';
       +   return retbuf;
        }
        
        void gtk_editable_set_editable(GtkEditable *editable,gboolean is_editable) {
           GtkWidget *widget=GTK_WIDGET(editable);
           HWND hWnd;
       -   if (!GTK_WIDGET_REALIZED(widget)) return;
       +   editable->is_editable=is_editable;
           hWnd=widget->hWnd;
       -   SendMessage(hWnd,EM_SETREADONLY,(WPARAM)(!is_editable),(LPARAM)0);
       +   if (hWnd) SendMessage(hWnd,EM_SETREADONLY,(WPARAM)(!is_editable),(LPARAM)0);
        }
        
        void gtk_editable_set_position(GtkEditable *editable,gint position) {
       t@@ -1210,6 +1304,8 @@ void gtk_editable_set_position(GtkEditable *editable,gint position) {
           if (!GTK_WIDGET_REALIZED(widget)) return;
           hWnd=widget->hWnd;
           SendMessage(hWnd,EM_SETSEL,(WPARAM)-1,(LPARAM)position);
       +   SendMessage(hWnd,EM_SCROLLCARET,0,0);
       +   SendMessage(hWnd,EM_LINESCROLL,0,(LPARAM)1000);
        }
        
        gint gtk_editable_get_position(GtkEditable *editable) {
       t@@ -1223,13 +1319,7 @@ gint gtk_editable_get_position(GtkEditable *editable) {
        }
        
        guint gtk_text_get_length(GtkText *text) {
       -   GtkWidget *widget=GTK_WIDGET(text);
       -   HWND hWnd;
       -   LRESULT textlen;
       -   if (!GTK_WIDGET_REALIZED(widget)) return 0;
       -   hWnd=widget->hWnd;
       -   textlen=SendMessage(hWnd,WM_GETTEXTLENGTH,0,0);
       -   return (guint)textlen;
       +   return GTK_EDITABLE(text)->text->len;
        }
        
        void gtk_box_pack_start(GtkBox *box,GtkWidget *child,gboolean Expand,
       t@@ -1450,7 +1540,7 @@ void gtk_window_realize(GtkWidget *widget) {
           widget->hWnd = CreateWindow("mainwin",win->title,
                             win->type == GTK_WINDOW_TOPLEVEL ?
                                WS_OVERLAPPEDWINDOW|CS_HREDRAW|CS_VREDRAW|WS_SIZEBOX :
       -                        WS_CAPTION|CS_HREDRAW|CS_VREDRAW,
       +                        WS_CAPTION|WS_SYSMENU|CS_HREDRAW|CS_VREDRAW,
                             CW_USEDEFAULT,0,
                             widget->allocation.width,widget->allocation.height,
                             Parent,NULL,hInst,NULL);
       t@@ -1509,16 +1599,25 @@ void gtk_entry_realize(GtkWidget *widget) {
                                    widget->allocation.width,widget->allocation.height,
                                    Parent,NULL,hInst,NULL);
           gtk_set_default_font(widget->hWnd);
       +   gtk_editable_set_editable(GTK_EDITABLE(widget),
       +                             GTK_EDITABLE(widget)->is_editable);
       +   SendMessage(widget->hWnd,WM_SETTEXT,0,
       +               (LPARAM)GTK_EDITABLE(widget)->text->str);
        }
        
        void gtk_text_realize(GtkWidget *widget) {
           HWND Parent;
           Parent=gtk_get_parent_hwnd(widget);
           widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",
       -                            WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|
       -                            ES_MULTILINE|ES_WANTRETURN|WS_VSCROLL,
       +                            WS_CHILD|WS_TABSTOP|
       +                            ES_MULTILINE|ES_WANTRETURN|WS_VSCROLL|
       +                            (GTK_TEXT(widget)->word_wrap ? 0 : ES_AUTOHSCROLL),
                                    0,0,0,0,Parent,NULL,hInst,NULL);
           gtk_set_default_font(widget->hWnd);
       +   gtk_editable_set_editable(GTK_EDITABLE(widget),
       +                             GTK_EDITABLE(widget)->is_editable);
       +   SendMessage(widget->hWnd,WM_SETTEXT,0,
       +               (LPARAM)GTK_EDITABLE(widget)->text->str);
        }
        
        void gtk_frame_realize(GtkWidget *widget) {
       t@@ -1641,7 +1740,8 @@ void gtk_clist_realize(GtkWidget *widget) {
        /* g_print("Header %p, size %d\n",header,wp.cy);*/
           widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,"LISTBOX","",
                                         WS_CHILD|WS_TABSTOP|LBS_DISABLENOSCROLL|
       -                                 WS_VSCROLL|LBS_USETABSTOPS|LBS_OWNERDRAWFIXED,
       +                                 WS_VSCROLL|LBS_USETABSTOPS|
       +                                 LBS_OWNERDRAWFIXED|LBS_NOTIFY,
                                         0,0,0,0,Parent,NULL,hInst,NULL);
           gtk_set_default_font(widget->hWnd);
        
       t@@ -1719,6 +1819,8 @@ gint gtk_clist_insert(GtkCList *clist,gint row,gchar *text[]) {
           GtkCListRow *new_row;
           gint i;
        
       +   if (row<0) row=g_slist_length(clist->rows);
       +
           new_row=g_new0(GtkCListRow,1);
           new_row->text=g_new0(gchar *,clist->ncols);
           for (i=0;i<clist->ncols;i++) {
       t@@ -1747,6 +1849,14 @@ GtkWidget *gtk_clist_new_with_titles(gint columns,gchar *titles[]) {
           return widget;
        }
        
       +GtkWidget *gtk_scrolled_clist_new_with_titles(gint columns,gchar *titles[],
       +                                              GtkWidget **pack_widg) {
       +   GtkWidget *widget;
       +   widget=gtk_clist_new_with_titles(columns,titles);
       +   *pack_widg=widget;
       +   return widget;
       +}
       +
        gint gtk_clist_append(GtkCList *clist,gchar *text[]) {
           return gtk_clist_insert(clist,-1,text);
        }
       t@@ -1776,6 +1886,18 @@ void gtk_clist_column_titles_passive(GtkCList *clist) {
           }
        }
        
       +void gtk_clist_column_title_active(GtkCList *clist,gint column) {
       +   if (column>=0 && column<clist->ncols)
       +      clist->cols[column].button_passive=FALSE;
       +}
       +
       +void gtk_clist_column_titles_active(GtkCList *clist) {
       +   gint i;
       +   for (i=0;i<clist->ncols;i++) {
       +      gtk_clist_column_title_active(clist,i);
       +   }
       +}
       +
        void gtk_clist_set_column_width(GtkCList *clist,gint column,gint width) {
           HWND hWnd;
           if (column<0 || column>=clist->ncols) return;
       t@@ -2205,7 +2327,7 @@ void gtk_main() {
              for (list=WindowList;list && !MsgDone;list=g_slist_next(list)) {
                 if ((MsgDone=IsDialogMessage((HWND)list->data,&msg))==TRUE) break;
              }
       -      if (!MsgDone && GTK_OBJECT(widget)->klass==&GtkWindowClass) {
       +      if (!MsgDone && widget && GTK_OBJECT(widget)->klass==&GtkWindowClass) {
                 hAccel=GTK_WINDOW(widget)->hAccel;
                 if (hAccel) MsgDone=TranslateAccelerator(widget->hWnd,hAccel,&msg);
              }
       t@@ -2662,6 +2784,10 @@ void gtk_menu_realize(GtkWidget *widget) {
           gtk_menu_shell_realize(widget);
        }
        
       +void gtk_menu_set_active(GtkMenu *menu,guint index) {
       +   menu->active=index;
       +}
       +
        void gtk_menu_shell_realize(GtkWidget *widget) {
           GSList *children;
           GtkMenuShell *menu=GTK_MENU_SHELL(widget);
       t@@ -2894,7 +3020,7 @@ GtkWidget *gtk_spin_button_new(GtkAdjustment *adjustment,gfloat climb_rate,
           GtkSpinButton *spin;
        
           spin=GTK_SPIN_BUTTON(GtkNewObject(&GtkSpinButtonClass));
       -   spin->adj=adjustment;
       +   gtk_spin_button_set_adjustment(spin,adjustment);
        
           return GTK_WIDGET(spin);
        }
       t@@ -2923,6 +3049,37 @@ void gtk_spin_button_set_size(GtkWidget *widget,
           }
        }
        
       +gint gtk_spin_button_get_value_as_int(GtkSpinButton *spin_button) {
       +   HWND hWnd;
       +   LRESULT lres;
       +   hWnd=spin_button->updown;
       +   if (hWnd) {
       +      lres=SendMessage(hWnd,UDM_GETPOS,0,0);
       +      if (HIWORD(lres) != 0) return 0;
       +      else return (gint)LOWORD(lres);
       +   } else return (gint)spin_button->adj->value;
       +}
       +
       +void gtk_spin_button_set_value(GtkSpinButton *spin_button,gfloat value) {
       +   HWND hWnd;
       +   spin_button->adj->value=value;
       +   hWnd=spin_button->updown;
       +   if (hWnd) SendMessage(hWnd,UDM_SETPOS,0,(LPARAM)MAKELONG((short)value,0));
       +}
       +
       +void gtk_spin_button_set_adjustment(GtkSpinButton *spin_button,
       +                                    GtkAdjustment *adjustment) {
       +   HWND hWnd;
       +   spin_button->adj=adjustment;
       +   hWnd=spin_button->updown;
       +   if (hWnd) {
       +      SendMessage(hWnd,UDM_SETRANGE,0,
       +          (LPARAM)MAKELONG((short)adjustment->upper,(short)adjustment->lower));
       +      SendMessage(hWnd,UDM_SETPOS,0,
       +          (LPARAM)MAKELONG((short)adjustment->value,0));
       +   }
       +}
       +
        void gtk_spin_button_realize(GtkWidget *widget) {
           GtkSpinButton *spin=GTK_SPIN_BUTTON(widget);
           HWND Parent;
       t@@ -2932,10 +3089,9 @@ void gtk_spin_button_realize(GtkWidget *widget) {
           Parent=gtk_get_parent_hwnd(widget->parent);
           spin->updown=CreateUpDownControl(WS_CHILD|WS_BORDER|
                                UDS_SETBUDDYINT|UDS_NOTHOUSANDS|UDS_ARROWKEYS,
       -                        0,0,0,0,Parent,0,hInst,widget->hWnd,
       -                        (int)spin->adj->upper,(int)spin->adj->lower,
       -                        (int)spin->adj->value);
       +                        0,0,0,0,Parent,0,hInst,widget->hWnd,20,10,15);
           gtk_set_default_font(spin->updown);
       +   gtk_spin_button_set_adjustment(spin,spin->adj);
        }
        
        void gtk_spin_button_destroy(GtkWidget *widget) {
       t@@ -3045,13 +3201,15 @@ void gtk_entry_set_text(GtkEntry *entry,const gchar *text) {
        guint SetAccelerator(GtkWidget *labelparent,gchar *Text,
                             GtkWidget *sendto,gchar *signal,
                             GtkAccelGroup *accel_group) {
       +   gtk_signal_emit(GTK_OBJECT(labelparent),"set_text",Text);
           return 0;
        }
        
        void gtk_widget_add_accelerator(GtkWidget *widget,
                                        const gchar *accel_signal,
                                        GtkAccelGroup *accel_group,
       -                                guint accel_key,guint accel_mods) {
       +                                guint accel_key,guint accel_mods,
       +                                GtkAccelFlags accel_flags) {
        }
        
        void gtk_widget_remove_accelerator(GtkWidget *widget,
       t@@ -3173,8 +3331,6 @@ void gtk_hpaned_set_size(GtkWidget *widget,GtkAllocation *allocation) {
           child_alloc.height=allocation->height;
           child_alloc.width=allocation->width/numchildren;
           for (i=0;i<2;i++) if (paned->children[i].widget) {
       -/*    g_print("Setting size of child to %d,%d at %d,%d\n",
       -  child_alloc.width,child_alloc.height,child_alloc.x,child_alloc.y);*/
              gtk_widget_set_size(paned->children[i].widget,&child_alloc);
              child_alloc.x+=allocation->width/numchildren;
           }
       t@@ -3185,6 +3341,7 @@ void gtk_text_set_editable(GtkText *text,gboolean is_editable) {
        }
        
        void gtk_text_set_word_wrap(GtkText *text,gboolean word_wrap) {
       +   text->word_wrap=word_wrap;
        }
        
        void gtk_text_freeze(GtkText *text) {
       t@@ -3203,4 +3360,222 @@ void gtk_clist_thaw(GtkCList *clist) {
        }
        
        void gtk_clist_clear(GtkCList *clist) {
       +   GtkCListRow *row;
       +   GSList *list;
       +   gint i;
       +   HWND hWnd;
       +
       +   for (list=clist->rows;list;list=g_slist_next(list)) {
       +      row=(GtkCListRow *)list->data;
       +      for (i=0;i<clist->ncols;i++) {
       +         g_free(row->text[i]);
       +      }
       +      g_free(row);
       +   }
       +   g_slist_free(clist->rows);
       +   clist->rows=NULL;
       +
       +   hWnd=GTK_WIDGET(clist)->hWnd;
       +   if (hWnd) {
       +      SendMessage(hWnd,LB_RESETCONTENT,0,0);
       +   }
       +}
       +
       +GtkWidget *gtk_option_menu_new() {
       +   GtkOptionMenu *option_menu;
       +   option_menu=GTK_OPTION_MENU(GtkNewObject(&GtkOptionMenuClass));
       +   return GTK_WIDGET(option_menu);
       +}
       +
       +GtkWidget *gtk_option_menu_get_menu(GtkOptionMenu *option_menu) {
       +   return option_menu->menu;
       +}
       +
       +void gtk_option_menu_set_menu(GtkOptionMenu *option_menu,GtkWidget *menu) {
       +   GSList *list;
       +   GtkMenuItem *menu_item;
       +   HWND hWnd;
       +
       +   if (!menu) return;
       +   option_menu->menu=menu;
       +   hWnd=GTK_WIDGET(option_menu)->hWnd;
       +
       +   if (hWnd) {
       +      SendMessage(hWnd,CB_RESETCONTENT,0,0);
       +      for (list=GTK_MENU_SHELL(menu)->children;list;list=g_slist_next(list)) {
       +         menu_item=GTK_MENU_ITEM(list->data);
       +         if (menu_item && menu_item->text)
       +            SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM)menu_item->text);
       +      }
       +      SendMessage(hWnd,CB_SETCURSEL,(WPARAM)GTK_MENU(menu)->active,0);
       +   }
       +}
       +
       +void gtk_option_menu_set_history(GtkOptionMenu *option_menu,guint index) {
       +   GtkWidget *menu;
       +   menu=gtk_option_menu_get_menu(option_menu);
       +   if (menu) gtk_menu_set_active(GTK_MENU(menu),index);
       +}
       +
       +void gtk_option_menu_size_request(GtkWidget *widget,
       +                                  GtkRequisition *requisition) {
       +   SIZE size;
       +
       +   if (GetTextSize(widget->hWnd,"Sample text",&size)) {
       +      requisition->width = size.cx+40;
       +      requisition->height = size.cy+4;
       +   }
       +}
       +
       +void gtk_option_menu_set_size(GtkWidget *widget,GtkAllocation *allocation) {
       +   allocation->height *= 6;
       +}
       +
       +void gtk_option_menu_realize(GtkWidget *widget) {
       +   HWND Parent;
       +   GtkOptionMenu *option_menu=GTK_OPTION_MENU(widget);
       +
       +   Parent=gtk_get_parent_hwnd(widget);
       +   widget->hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,"COMBOBOX","",
       +                                 WS_CHILD|WS_TABSTOP|WS_VSCROLL|
       +                                 CBS_HASSTRINGS|CBS_DROPDOWNLIST,
       +                                 0,0,0,0,Parent,NULL,hInst,NULL);
       +   gtk_set_default_font(widget->hWnd);
       +   gtk_option_menu_set_menu(option_menu,option_menu->menu);
       +}
       +
       +void gtk_label_set_text(GtkLabel *label,const gchar *str) {
       +   gint i;
       +   HWND hWnd;
       +   g_free(label->text);
       +   label->text = g_strdup(str ? str : "");
       +   for (i=0;i<strlen(label->text);i++) {
       +      if (label->text[i]=='_') label->text[i]='&';
       +   }
       +   hWnd=GTK_WIDGET(label)->hWnd;
       +   if (hWnd) {
       +      gtk_widget_update(GTK_WIDGET(label),FALSE);
       +      SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)label->text);
       +   }
       +}
       +
       +void gtk_button_set_text(GtkButton *button,gchar *text) {
       +   gint i;
       +   HWND hWnd;
       +   g_free(button->text);
       +   button->text = g_strdup(text ? text : "");
       +   for (i=0;i<strlen(button->text);i++) {
       +      if (button->text[i]=='_') button->text[i]='&';
       +   }
       +   hWnd=GTK_WIDGET(button)->hWnd;
       +   if (hWnd) {
       +      gtk_widget_update(GTK_WIDGET(button),FALSE);
       +      SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)button->text);
       +   }
       +}
       +
       +static void gtk_menu_item_set_text(GtkMenuItem *menuitem,gchar *text) {
       +   gint i;
       +   g_free(menuitem->text);
       +   menuitem->text = g_strdup(text ? text : "");
       +   for (i=0;i<strlen(menuitem->text);i++) {
       +      if (menuitem->text[i]=='_') menuitem->text[i]='&';
       +   }
       +}
       +
       +guint gtk_label_parse_uline(GtkLabel *label,const gchar *str) {
       +   gint i;
       +   gtk_label_set_text(label,str);
       +   if (str) for (i=0;i<strlen(str);i++) {
       +      if (str[i]=='_') return str[i+1];
       +   }
       +   return 0;
       +}
       +
       +void gtk_clist_set_row_data(GtkCList *clist,gint row,gpointer data) {
       +   GtkCListRow *list_row;
       +   if (row>=0 && row<g_slist_length(clist->rows)) {
       +      list_row=(GtkCListRow *)g_slist_nth_data(clist->rows,row);
       +      if (list_row) list_row->data=data;
       +   }
       +}
       +
       +gpointer gtk_clist_get_row_data(GtkCList *clist,gint row) {
       +   GtkCListRow *list_row;
       +   if (row>=0 && row<g_slist_length(clist->rows)) {
       +      list_row=(GtkCListRow *)g_slist_nth_data(clist->rows,row);
       +      if (list_row) return list_row->data;
       +   }
       +   return NULL;
       +}
       +
       +void gtk_clist_set_auto_sort(GtkCList *clist,gboolean auto_sort) {
       +   clist->auto_sort=auto_sort;
       +}
       +
       +void gtk_clist_columns_autosize(GtkCList *clist) {
       +}
       +
       +void gtk_text_set_point(GtkText *text,guint index) {
       +   gtk_editable_set_position(GTK_EDITABLE(text),index);
       +}
       +
       +void gtk_widget_set_usize(GtkWidget *widget,gint width,gint height) {
       +}
       +
       +void gtk_clist_select_row(GtkCList *clist,gint row,gint column) {
       +}
       +
       +GtkVisibility gtk_clist_row_is_visible(GtkCList *clist,gint row) {
       +   return GTK_VISIBILITY_FULL;
       +}
       +
       +void gtk_clist_moveto(GtkCList *clist,gint row,gint column,
       +                      gfloat row_align,gfloat col_align) {
       +}
       +
       +void gtk_clist_set_compare_func(GtkCList *clist,GtkCListCompareFunc cmp_func) {
       +}
       +
       +void gtk_clist_set_column_auto_resize(GtkCList *clist,gint column,
       +                                      gboolean auto_resize) {
       +   if (clist && column>=0 && column<clist->ncols) {
       +      clist->cols[column].auto_resize=auto_resize;
       +   }
       +}
       +
       +void gtk_clist_update_selection(GtkWidget *widget) {
       +   GtkCList *clist=GTK_CLIST(widget);
       +   gint i;
       +   g_list_free(clist->selection);
       +   clist->selection=NULL;
       +   if (widget->hWnd==NULL) return;
       +   for (i=0;i<g_slist_length(clist->rows);i++) {
       +      if (SendMessage(widget->hWnd,LB_GETSEL,(WPARAM)i,0) > 0) {
       +         clist->selection=g_list_append(clist->selection,GINT_TO_POINTER(i));
       +      }
       +   }
       +}
       +
       +void gtk_editable_create(GtkWidget *widget) {
       +   GtkEditable *editable=GTK_EDITABLE(widget);
       +   gtk_widget_create(widget);
       +   editable->is_editable=TRUE;
       +   editable->text=g_string_new("");
       +}
       +
       +void gtk_option_menu_update_selection(GtkWidget *widget) {
       +   LRESULT lres;
       +   GtkMenuShell *menu;
       +   GtkWidget *menu_item;
       +
       +   if (widget->hWnd==NULL) return;
       +   lres=SendMessage(widget->hWnd,CB_GETCURSEL,0,0);
       +   if (lres==CB_ERR) return;
       +
       +   menu=GTK_MENU_SHELL(gtk_option_menu_get_menu(GTK_OPTION_MENU(widget)));
       +   if (menu) {
       +      menu_item=GTK_WIDGET(g_slist_nth_data(menu->children,lres));
       +      if (menu_item) gtk_signal_emit(GTK_OBJECT(menu_item),"activate");
       +   }
        }
 (DIR) diff --git a/src/gtk.h b/src/gtk.h
       t@@ -10,6 +10,17 @@ typedef enum {
        } GtkWindowType;
        
        typedef enum {
       +   GTK_ACCEL_VISIBLE        = 1 << 0,
       +   GTK_ACCEL_SIGNAL_VISIBLE = 1 << 1
       +} GtkAccelFlags;
       +
       +typedef enum {
       +   GTK_VISIBILITY_NONE,
       +   GTK_VISIBILITY_PARTIAL,
       +   GTK_VISIBILITY_FULL
       +} GtkVisibility;
       +
       +typedef enum {
           GTK_EXPAND = 1 << 0,
           GTK_SHRINK = 1 << 1,
           GTK_FILL   = 1 << 2
       t@@ -68,6 +79,7 @@ typedef struct _GtkPanedChild GtkPanedChild;
        typedef struct _GtkPaned GtkPaned;
        typedef struct _GtkVPaned GtkVPaned;
        typedef struct _GtkHPaned GtkHPaned;
       +typedef struct _GtkOptionMenu GtkOptionMenu;
        
        struct _GtkAccelGroup {
           GSList *accel;
       t@@ -144,6 +156,7 @@ struct _GtkMenuShell {
        
        struct _GtkMenu {
           GtkMenuShell menushell;
       +   guint active;
        };
        
        struct _GtkMenuBar {
       t@@ -158,6 +171,8 @@ typedef struct _GtkSpinButton GtkSpinButton;
        
        struct _GtkEditable {
           GtkWidget widget;
       +   GString *text;
       +   gint is_editable : 1;
        };
        
        struct _GtkEntry {
       t@@ -172,6 +187,7 @@ struct _GtkSpinButton {
        
        struct _GtkText {
           GtkEditable editable;
       +   gint word_wrap : 1;
        };
        
        typedef struct _GtkLabel GtkLabel;
       t@@ -222,6 +238,9 @@ typedef struct _GtkCListColumn GtkCListColumn;
        typedef struct _GtkItemFactoryEntry GtkItemFactoryEntry;
        typedef struct _GtkItemFactory GtkItemFactory;
        
       +typedef gint (*GtkCListCompareFunc)(GtkCList *clist,gconstpointer ptr1,
       +                                    gconstpointer ptr2);
       +
        struct _GtkItemFactoryEntry {
           gchar *path;
           gchar *accelerator;
       t@@ -289,7 +308,9 @@ struct _GtkCList {
           gint16 header_size;
           GSList *rows;
           GtkCListColumn *cols;
       +   GList *selection;
           GtkSelectionMode mode;
       +   gint auto_sort : 1;
        };
        
        typedef struct _GtkBin GtkBin;
       t@@ -316,6 +337,12 @@ struct _GtkButton {
           gchar *text;
        };
        
       +struct _GtkOptionMenu {
       +   GtkButton button;
       +   GtkWidget *menu;
       +   guint selection;
       +};
       +
        struct _GtkToggleButton {
           GtkButton button;
           gboolean toggled;
       t@@ -386,6 +413,7 @@ struct _GtkTableRowCol {
        #define GTK_TEXT(obj) ((GtkText *)(obj))
        #define GTK_WINDOW(obj) ((GtkWindow *)(obj))
        #define GTK_BUTTON(obj) ((GtkButton *)(obj))
       +#define GTK_OPTION_MENU(obj) ((GtkOptionMenu *)(obj))
        #define GTK_TOGGLE_BUTTON(obj) ((GtkToggleButton *)(obj))
        #define GTK_RADIO_BUTTON(obj) ((GtkRadioButton *)(obj))
        #define GTK_CHECK_BUTTON(obj) ((GtkCheckButton *)(obj))
       t@@ -409,6 +437,7 @@ typedef int GdkEvent;
        
        void gtk_widget_show(GtkWidget *widget);
        void gtk_widget_show_all(GtkWidget *widget);
       +void gtk_widget_hide_all(GtkWidget *widget);
        void gtk_widget_hide(GtkWidget *widget);
        void gtk_widget_destroy(GtkWidget *widget);
        void gtk_widget_realize(GtkWidget *widget);
       t@@ -449,12 +478,16 @@ GtkWidget *gtk_item_factory_get_widget(GtkItemFactory *ifactory,
                                               const gchar *path);
        GtkWidget *gtk_clist_new(gint columns);
        GtkWidget *gtk_clist_new_with_titles(gint columns,gchar *titles[]);
       +GtkWidget *gtk_scrolled_clist_new_with_titles(gint columns,gchar *titles[],
       +                                              GtkWidget **pack_widg);
        gint gtk_clist_append(GtkCList *clist,gchar *text[]);
        void gtk_clist_set_column_title(GtkCList *clist,gint column,const gchar *title);
        gint gtk_clist_insert(GtkCList *clist,gint row,gchar *text[]);
        void gtk_clist_set_column_width(GtkCList *clist,gint column,gint width);
        void gtk_clist_column_title_passive(GtkCList *clist,gint column);
        void gtk_clist_column_titles_passive(GtkCList *clist);
       +void gtk_clist_column_title_active(GtkCList *clist,gint column);
       +void gtk_clist_column_titles_active(GtkCList *clist);
        void gtk_clist_set_selection_mode(GtkCList *clist,GtkSelectionMode mode);
        void gtk_clist_sort(GtkCList *clist);
        void gtk_clist_freeze(GtkCList *clist);
       t@@ -515,6 +548,7 @@ void gtk_menu_append(GtkMenu *menu,GtkWidget *child);
        void gtk_menu_prepend(GtkMenu *menu,GtkWidget *child);
        GtkWidget *gtk_menu_item_new_with_label(const gchar *label);
        void gtk_menu_item_set_submenu(GtkMenuItem *menu_item,GtkWidget *submenu);
       +void gtk_menu_set_active(GtkMenu *menu,guint index);
        GtkWidget *gtk_notebook_new();
        void gtk_notebook_append_page(GtkNotebook *notebook,GtkWidget *child,
                                      GtkWidget *tab_label);
       t@@ -546,7 +580,8 @@ void gtk_entry_set_text(GtkEntry *entry,const gchar *text);
        void gtk_widget_add_accelerator(GtkWidget *widget,
                                        const gchar *accel_signal,
                                        GtkAccelGroup *accel_group,
       -                                guint accel_key,guint accel_mods);
       +                                guint accel_key,guint accel_mods,
       +                                GtkAccelFlags accel_flags);
        void gtk_widget_remove_accelerator(GtkWidget *widget,
                                           GtkAccelGroup *accel_group,
                                           guint accel_key,guint accel_mods);
       t@@ -567,5 +602,28 @@ void gtk_paned_pack2(GtkPaned *paned,GtkWidget *child,gboolean resize,
        #define gtk_container_border_width gtk_container_set_border_width
        #define gtk_hbutton_box_new() gtk_hbox_new(TRUE,5)
        #define gtk_vbutton_box_new() gtk_vbox_new(TRUE,5)
       +GtkWidget *gtk_option_menu_new();
       +GtkWidget *gtk_option_menu_get_menu(GtkOptionMenu *option_menu);
       +void gtk_option_menu_set_menu(GtkOptionMenu *option_menu,GtkWidget *menu);
       +void gtk_option_menu_set_history(GtkOptionMenu *option_menu,guint index);
       +void gtk_label_set_text(GtkLabel *label,const gchar *str);
       +guint gtk_label_parse_uline(GtkLabel *label,const gchar *str);
       +void gtk_clist_set_row_data(GtkCList *clist,gint row,gpointer data);
       +gpointer gtk_clist_get_row_data(GtkCList *clist,gint row);
       +void gtk_clist_set_auto_sort(GtkCList *clist,gboolean auto_sort);
       +void gtk_clist_columns_autosize(GtkCList *clist);
       +void gtk_text_set_point(GtkText *text,guint index);
       +void gtk_widget_set_usize(GtkWidget *widget,gint width,gint height);
       +void gtk_clist_select_row(GtkCList *clist,gint row,gint column);
       +GtkVisibility gtk_clist_row_is_visible(GtkCList *clist,gint row);
       +void gtk_clist_moveto(GtkCList *clist,gint row,gint column,
       +                      gfloat row_align,gfloat col_align);
       +void gtk_clist_set_compare_func(GtkCList *clist,GtkCListCompareFunc cmp_func);
       +void gtk_clist_set_column_auto_resize(GtkCList *clist,gint column,
       +                                      gboolean auto_resize);
       +gint gtk_spin_button_get_value_as_int(GtkSpinButton *spin_button);
       +void gtk_spin_button_set_value(GtkSpinButton *spin_button,gfloat value);
       +void gtk_spin_button_set_adjustment(GtkSpinButton *spin_button,
       +                                    GtkAdjustment *adjustment);
        
        #endif
 (DIR) diff --git a/src/gtk_client.c b/src/gtk_client.c
       t@@ -125,10 +125,8 @@ static void Jet();
        static void DealDrugs(GtkWidget *widget,gpointer data);
        static void DealGuns(GtkWidget *widget,gpointer data);
        static void QuestionDialog(char *Data,Player *From);
       -#ifndef CYGWIN
       -static gint MessageBox(GtkWidget *parent,const gchar *Text,
       -                       const gchar *Title,gint Options);
       -#endif
       +static gint GtkMessageBox(GtkWidget *parent,const gchar *Text,
       +                          const gchar *Title,gint Options);
        static void TransferDialog(gboolean Debt);
        static void ListPlayers(GtkWidget *widget,gpointer data);
        static void TalkToAll(GtkWidget *widget,gpointer data);
       t@@ -180,9 +178,9 @@ static gchar *MenuTranslate(const gchar *path,gpointer func_data) {
        
        static void LogMessage(const gchar *log_domain,GLogLevelFlags log_level,
                               const gchar *message,gpointer user_data) {
       -   MessageBox(NULL,message,
       -              log_level&G_LOG_LEVEL_WARNING ? _("Warning") : _("Message"),
       -              MB_OK);
       +   GtkMessageBox(NULL,message,
       +                 log_level&G_LOG_LEVEL_WARNING ? _("Warning") : _("Message"),
       +                 MB_OK);
        }
        
        #ifndef CYGWIN
       t@@ -201,8 +199,8 @@ static guint SetAccelerator(GtkWidget *labelparent,gchar *Text,
        
        void QuitGame(GtkWidget *widget,gpointer data) {
           if (!InGame ||
       -       MessageBox(ClientData.window,_("Abandon current game?"),_("Quit Game"),
       -                  MB_YESNO)==IDYES) {
       +      GtkMessageBox(ClientData.window,_("Abandon current game?"),
       +                    _("Quit Game"),MB_YESNO)==IDYES) {
              gtk_main_quit();
           }
        }
       t@@ -212,15 +210,15 @@ void DestroyGtk(GtkWidget *widget,gpointer data) {
        }
        
        gint MainDelete(GtkWidget *widget,GdkEvent *event,gpointer data) {
       -   return (InGame && MessageBox(ClientData.window,_("Abandon current game?"),
       -                                _("Quit Game"),MB_YESNO)==IDNO);
       +   return (InGame && GtkMessageBox(ClientData.window,_("Abandon current game?"),
       +                                   _("Quit Game"),MB_YESNO)==IDNO);
        }
        
        
        void NewGame(GtkWidget *widget,gpointer data) {
           if (InGame) {
       -      if (MessageBox(ClientData.window,_("Abandon current game?"),
       -                     _("Start new game"),MB_YESNO)==IDYES) EndGame();
       +      if (GtkMessageBox(ClientData.window,_("Abandon current game?"),
       +                        _("Start new game"),MB_YESNO)==IDYES) EndGame();
              else return;
           }
           NewGameDialog();
       t@@ -549,6 +547,19 @@ static GtkWidget *gtk_scrolled_text_new(GtkAdjustment *hadj,GtkAdjustment *vadj,
           *pack_widg=hbox;
           return text;
        }
       +
       +static GtkWidget *gtk_scrolled_clist_new_with_titles(gint columns,
       +                                                     gchar *titles[],
       +                                                     GtkWidget **pack_widg) {
       +   GtkWidget *scrollwin,*clist;
       +   clist=gtk_clist_new_with_titles(5,server_titles);
       +   scrollwin=gtk_scrolled_window_new(NULL,NULL);
       +   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
       +                                  GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
       +   gtk_container_add(GTK_CONTAINER(scrollwin),clist);
       +   *pack_widg=scrollwin;
       +   return clist;
       +}
        #endif
        
        static GtkWidget *AddFightButton(gchar *Text,GtkAccelGroup *accel_group,
       t@@ -1156,24 +1167,24 @@ void DealGuns(GtkWidget *widget,gpointer data) {
        
           if (data!=BT_BUY && TotalGunsCarried(ClientData.Play)==0) {
              dpg_string_sprintf(text,_("You don't have any %tde!"),Names.Guns);
       -      MessageBox(dialog,text->str,Title,MB_OK);
       +      GtkMessageBox(dialog,text->str,Title,MB_OK);
           } else if (data==BT_BUY && TotalGunsCarried(ClientData.Play) >=
                                      ClientData.Play->Bitches.Carried+2) { 
              dpg_string_sprintf(text,
                                 _("You'll need more %tde to carry any more %tde!"),
                                 Names.Bitches,Names.Guns);
       -      MessageBox(dialog,text->str,Title,MB_OK);
       +      GtkMessageBox(dialog,text->str,Title,MB_OK);
           } else if (data==BT_BUY && Gun[GunInd].Space > ClientData.Play->CoatSize) {
              dpg_string_sprintf(text,
                                 _("You don't have enough space to carry that %tde!"),
                                 Names.Gun);
       -      MessageBox(dialog,text->str,Title,MB_OK);
       +      GtkMessageBox(dialog,text->str,Title,MB_OK);
           } else if (data==BT_BUY && Gun[GunInd].Price > ClientData.Play->Cash) {
              dpg_string_sprintf(text,_("You don't have enough cash to buy that %tde!"),
                                 Names.Gun);
       -      MessageBox(dialog,text->str,Title,MB_OK);
       +      GtkMessageBox(dialog,text->str,Title,MB_OK);
           } else if (data==BT_SELL && ClientData.Play->Guns[GunInd].Carried == 0) {
       -      MessageBox(dialog,_("You don't have any to sell!"),Title,MB_OK);
       +      GtkMessageBox(dialog,_("You don't have any to sell!"),Title,MB_OK);
           } else {
              g_string_sprintf(text,"gun^%d^%d",GunInd,data==BT_BUY ? 1 : -1);
              SendClientMessage(ClientData.Play,C_NONE,C_BUYOBJECT,NULL,text->str);
       t@@ -1402,7 +1413,7 @@ void SetJetButtonTitle(GtkAccelGroup *accel_group) {
        }
        
        #ifdef CYGWIN
       -char GtkLoop(HINST hInstance,HINST hPrevInstance) {
       +char GtkLoop(HINSTANCE hInstance,HINSTANCE hPrevInstance) {
        #else
        char GtkLoop(int *argc,char **argv[],char ReturnOnFail) {
        #endif
       t@@ -1466,16 +1477,12 @@ char GtkLoop(int *argc,char **argv[],char ReturnOnFail) {
        
           vpaned=gtk_vpaned_new();
        
       -   hbox=gtk_hbox_new(FALSE,0);
           adj=(GtkAdjustment *)gtk_adjustment_new(0.0,0.0,100.0,1.0,10.0,10.0);
       -   text=ClientData.messages=gtk_text_new(NULL,adj);
       +   text=ClientData.messages=gtk_scrolled_text_new(NULL,adj,&hbox);
           gtk_widget_set_usize(text,100,80);
           gtk_text_set_point(GTK_TEXT(text),0);
           gtk_text_set_editable(GTK_TEXT(text),FALSE);
           gtk_text_set_word_wrap(GTK_TEXT(text),TRUE);
       -   gtk_box_pack_start(GTK_BOX(hbox),text,TRUE,TRUE,0);
       -   vscroll=gtk_vscrollbar_new(adj);
       -   gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,FALSE,0);
           gtk_paned_pack1(GTK_PANED(vpaned),hbox,TRUE,TRUE);
        
           hbox=gtk_hbox_new(FALSE,7);
       t@@ -1838,13 +1845,12 @@ void NewGameDialog() {
        
           vbox2=gtk_vbox_new(FALSE,7);
           gtk_container_set_border_width(GTK_CONTAINER(vbox2),4);
       -   scrollwin=gtk_scrolled_window_new(NULL,NULL);
       -   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
       -                                  GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
       -   clist=widgets.metaserv=gtk_clist_new_with_titles(5,server_titles);
       +
       +   clist=widgets.metaserv=gtk_scrolled_clist_new_with_titles(5,server_titles,
       +                                                             &scrollwin);
           gtk_clist_column_titles_passive(GTK_CLIST(clist));
           gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_SINGLE);
       -   gtk_container_add(GTK_CONTAINER(scrollwin),clist);
       +
           gtk_box_pack_start(GTK_BOX(vbox2),scrollwin,TRUE,TRUE,0);
        
           hbbox=gtk_hbutton_box_new();
       t@@ -1883,11 +1889,11 @@ void NewGameDialog() {
        }
        
        #ifndef CYGWIN
       -static void DestroyMessageBox(GtkWidget *widget,gpointer data) {
       +static void DestroyGtkMessageBox(GtkWidget *widget,gpointer data) {
           gtk_main_quit();
        }
        
       -static void MessageBoxCallback(GtkWidget *widget,gpointer data) {
       +static void GtkMessageBoxCallback(GtkWidget *widget,gpointer data) {
           gint *retval;
           GtkWidget *dialog;
           dialog=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW);
       t@@ -1896,8 +1902,8 @@ static void MessageBoxCallback(GtkWidget *widget,gpointer data) {
           gtk_widget_destroy(dialog);
        }
        
       -gint MessageBox(GtkWidget *parent,const gchar *Text,
       -                const gchar *Title,gint Options) {
       +gint GtkMessageBox(GtkWidget *parent,const gchar *Text,
       +                   const gchar *Title,gint Options) {
           GtkWidget *dialog,*button,*label,*vbox,*hbbox,*hsep;
           GtkAccelGroup *accel_group;
           gint i;
       t@@ -1913,7 +1919,7 @@ gint MessageBox(GtkWidget *parent,const gchar *Text,
           if (parent) gtk_window_set_transient_for(GTK_WINDOW(dialog),
                                                    GTK_WINDOW(parent));
           gtk_signal_connect(GTK_OBJECT(dialog),"destroy",
       -                      GTK_SIGNAL_FUNC(DestroyMessageBox),NULL);
       +                      GTK_SIGNAL_FUNC(DestroyGtkMessageBox),NULL);
           if (Title) gtk_window_set_title(GTK_WINDOW(dialog),Title);
        
           vbox=gtk_vbox_new(FALSE,7);
       t@@ -1936,7 +1942,7 @@ gint MessageBox(GtkWidget *parent,const gchar *Text,
                               "clicked",accel_group);
                 gtk_object_set_data(GTK_OBJECT(button),"retval",&retval);
                 gtk_signal_connect(GTK_OBJECT(button),"clicked",
       -                            GTK_SIGNAL_FUNC(MessageBoxCallback),
       +                            GTK_SIGNAL_FUNC(GtkMessageBoxCallback),
                                    GINT_TO_POINTER(1<<i));
                 gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0);
              }
       t@@ -1947,6 +1953,12 @@ gint MessageBox(GtkWidget *parent,const gchar *Text,
           gtk_main();
           return retval;
        }
       +#else
       +gint GtkMessageBox(GtkWidget *parent,const gchar *Text,
       +                   const gchar *Title,gint Options) {
       +   return MessageBox(parent && parent->hWnd ? parent->hWnd : NULL,
       +                     Text,Title,Options);
       +}
        #endif
        
        static void SendDoneMessage(GtkWidget *widget,gpointer data) {
       t@@ -1982,13 +1994,13 @@ static void TransferOK(GtkWidget *widget,GtkWidget *dialog) {
                 money=-money;
              }
              if (-money>ClientData.Play->Bank) {
       -         MessageBox(dialog,_("There isn't that much money in the bank..."),
       +         GtkMessageBox(dialog,_("There isn't that much money in the bank..."),
                            "Bank",MB_OK);
                 return;
              }
           }
           if (money>ClientData.Play->Cash) {
       -      MessageBox(dialog,_("You don't have that much money!"),
       +      GtkMessageBox(dialog,_("You don't have that much money!"),
                         Debt ? "Pay loan" : "Bank",MB_OK);
              return;
           }
       t@@ -2369,7 +2381,7 @@ void SackBitch(GtkWidget *widget,gpointer data) {
           text=dpg_strdup_printf(_("Are you sure? (Any %tde or %tde carried\n"
                                  "by this %tde may be lost!)"),Names.Guns,
                                  Names.Drugs,Names.Bitch);
       -   if (MessageBox(ClientData.window,text,title,MB_YESNO)==IDYES) {
       +   if (GtkMessageBox(ClientData.window,text,title,MB_YESNO)==IDYES) {
              SendClientMessage(ClientData.Play,C_NONE,C_SACKBITCH,NULL,NULL);
           }
           g_free(text); g_free(title);
       t@@ -2407,16 +2419,12 @@ void CreateInventory(GtkWidget *hbox,gchar *Objects,GtkAccelGroup *accel_group,
           for (i=mini;i<2;i++) {
              gtk_container_set_border_width(GTK_CONTAINER(frame[i]),5);
        
       -      scrollwin=gtk_scrolled_window_new(NULL,NULL);
       -      gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
       -                                     GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
       -      clist=gtk_clist_new_with_titles(2,titles[i]);
       +      clist=gtk_scrolled_clist_new_with_titles(2,titles[i],&scrollwin);
              gtk_clist_set_column_auto_resize(GTK_CLIST(clist),0,TRUE);
              gtk_clist_set_column_auto_resize(GTK_CLIST(clist),1,TRUE);
              gtk_clist_column_titles_passive(GTK_CLIST(clist));
              gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_SINGLE);
              gtk_clist_set_auto_sort(GTK_CLIST(clist),FALSE);
       -      gtk_container_add(GTK_CONTAINER(scrollwin),clist);
              gtk_container_add(GTK_CONTAINER(frame[i]),scrollwin);
              if (i==0) widgets->HereList=clist; else widgets->CarriedList=clist;
           }
 (DIR) diff --git a/src/gtk_client.h b/src/gtk_client.h
       t@@ -26,6 +26,10 @@
        #include <config.h>
        #endif
        
       +#ifdef CYGWIN
       +char GtkLoop(HINSTANCE hInstance,HINSTANCE hPrevInstance);
       +#else
        char GtkLoop(int *argc,char **argv[],char ReturnOnFail);
       +#endif
        
        #endif
 (DIR) diff --git a/src/win32_client.c b/src/win32_client.c
       t@@ -1734,7 +1734,7 @@ int APIENTRY Win32Loop(HINSTANCE hInstance,HINSTANCE hPrevInstance,
           split=g_strsplit(lpszCmdParam," ",0);
           argc=0;
           while (split[argc]) argc++;
       -   g_set_print_handler(Win32PrintFunc);
       +// g_set_print_handler(Win32PrintFunc);
           HandleCmdLine(argc,split);
           g_strfreev(split);
           if (WantVersion || WantHelp) {
       t@@ -1790,14 +1790,14 @@ int APIENTRY Win32Loop(HINSTANCE hInstance,HINSTANCE hPrevInstance,
                 }
                 StopNetworking();
                 return msg.wParam;
       -      }
        #elif GUI_CLIENT
       -      GtkLoop(hInstance,hPrevInstance);
       +         GtkLoop(hInstance,hPrevInstance);
        #else
       -      g_print("No windowed client available - rebuild the binary passing the\n"
       -              "--enable-win32-client option to configure, or use the curses\n"
       -              "client (if available) instead!\n");
       +         g_print("No windowed client available - rebuild the binary passing\n"
       +                 "the --enable-win32-client option to configure, or use the\n"
       +                 "curses client (if available) instead!\n");
        #endif
       +      }
              StopNetworking();
           }
           if (PidFile) g_free(PidFile);