# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1611971600 0 # Node ID bb0690c044132e3614b636bc97ada6dbf5e1237c # Parent 63bb97e94cd399a5987a4f743a1645194d28cffc GTK4: First buildable version... although tons still left to do. No thread safety at all, only single threaded apps... no menus. Signal handlers are a complete mess.... but progress. diff -r 63bb97e94cd3 -r bb0690c04413 dw.h --- a/dw.h Fri Jan 29 13:18:47 2021 +0000 +++ b/dw.h Sat Jan 30 01:53:20 2021 +0000 @@ -1249,7 +1249,11 @@ /* Key Modifiers */ #define KC_CTRL GDK_CONTROL_MASK #define KC_SHIFT GDK_SHIFT_MASK +#if GTK_MAJOR_VERSION > 3 +#define KC_ALT GDK_ALT_MASK +#else #define KC_ALT GDK_MOD1_MASK +#endif typedef GtkWidget *HWND; #ifndef _ENVRNMNT_H diff -r 63bb97e94cd3 -r bb0690c04413 gtk4/dw.c --- a/gtk4/dw.c Fri Jan 29 13:18:47 2021 +0000 +++ b/gtk4/dw.c Sat Jan 30 01:53:20 2021 +0000 @@ -1286,6 +1286,7 @@ int response; va_list args; char outbuf[1025] = {0}; + DWDialog *tmp = dw_dialog_new(NULL); va_start(args, format); vsnprintf(outbuf, 1024, format, args); @@ -1311,7 +1312,9 @@ gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", outbuf); if(flags & DW_MB_YESNOCANCEL) gtk_dialog_add_button(GTK_DIALOG(dialog), "Cancel", GTK_RESPONSE_CANCEL); - response = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_show(GTK_WIDGET(dialog)); + /* TODO: Implement signal handlers so this will return */ + response = DW_POINTER_TO_INT(dw_dialog_wait(tmp)); if(GTK_IS_WINDOW(dialog)) gtk_window_destroy(GTK_WINDOW(dialog)); switch(response) @@ -1665,6 +1668,7 @@ char *font = currfont ? strdup(currfont) : NULL; char *name = font ? strchr(font, '.') : NULL; char *retfont = NULL; + DWDialog *tmp = dw_dialog_new(NULL); /* Detect Dynamic Windows style font name... * Format: ##.Fontname @@ -1687,7 +1691,8 @@ gtk_widget_show(GTK_WIDGET(fd)); - if(gtk_dialog_run(GTK_DIALOG(fd)) == GTK_RESPONSE_OK) + /* TODO: Connect signal handlers so this actually returns */ + if(DW_POINTER_TO_INT(dw_dialog_wait(tmp)) == GTK_RESPONSE_OK) { char *fontname = gtk_font_chooser_get_font(fd); if(fontname && (retfont = strdup(fontname))) @@ -1716,7 +1721,8 @@ g_free(fontname); } } - g_object_unref(G_OBJECT(fd)); + if(GTK_IS_WINDOW(fd)) + gtk_window_destroy(GTK_WINDOW(fd)); return retfont; } @@ -2153,11 +2159,13 @@ */ HMENUI dw_menu_new(unsigned long id) { - HMENUI tmp; - + HMENUI tmp = NULL; + +#if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ tmp = gtk_menu_new(); gtk_widget_show(tmp); g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); +#endif return tmp; } @@ -2170,8 +2178,9 @@ */ HMENUI dw_menubar_new(HWND location) { + HMENUI tmp = 0; +#if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ GtkWidget *box; - HMENUI tmp = 0; if(GTK_IS_WINDOW(location) && (box = (GtkWidget *)g_object_get_data(G_OBJECT(location), "_dw_grid"))) @@ -2188,6 +2197,7 @@ g_object_set_data(G_OBJECT(tmp), "_dw_window", (gpointer)location); gtk_grid_attach(GTK_GRID(box), tmp, 0, 0, 1, 1); } +#endif return tmp; } @@ -2198,6 +2208,7 @@ */ void dw_menu_destroy(HMENUI *menu) { +#if 0 /* TODO: Implement this with GMenuModel and GtkPopoverMenu */ if(menu && *menu) { GtkWidget *window; @@ -2211,29 +2222,7 @@ g_object_unref(G_OBJECT(*menu)); *menu = NULL; } -} - -char _removetilde(char *dest, const char *src) -{ - int z, cur=0; - char accel = '\0'; - - for(z=0;zimage); @@ -5541,13 +5475,18 @@ cairo_stroke(cr); if(clip) cairo_region_destroy(clip); + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 /* If we are using a drawing context... * we don't own the cairo context so don't destroy it. */ if(dc) gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); else - cairo_destroy(cr); +#else + if(!dc) +#endif + cairo_destroy(cr); } } @@ -5568,13 +5507,16 @@ if(handle) { - GdkWindow *window = gtk_widget_get_window(handle); + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 + GdkWindow *window = gtk_widget_get_window(handle); /* Safety check for non-existant windows */ if(!window || !GDK_IS_WINDOW(window)) return; clip = gdk_window_get_clip_region(window); dc = gdk_window_begin_draw_frame(window, clip); cr = gdk_drawing_context_get_cairo_context(dc); +#endif } else if(pixmap) cr = cairo_create(pixmap->image); @@ -5589,13 +5531,18 @@ cairo_stroke(cr); if(clip) cairo_region_destroy(clip); - /* If we are using a drawing context... + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 + /* If we are using a drawing context... * we don't own the cairo context so don't destroy it. */ if(dc) gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); else - cairo_destroy(cr); +#else + if(!dc) +#endif + cairo_destroy(cr); } } @@ -5617,6 +5564,8 @@ if(handle) { + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 GdkWindow *window = gtk_widget_get_window(handle); /* Safety check for non-existant windows */ if(!window || !GDK_IS_WINDOW(window)) @@ -5624,6 +5573,7 @@ clip = gdk_window_get_clip_region(window); dc = gdk_window_begin_draw_frame(window, clip); cr = gdk_drawing_context_get_cairo_context(dc); +#endif } else if(pixmap) cr = cairo_create(pixmap->image); @@ -5646,13 +5596,18 @@ cairo_stroke(cr); if(clip) cairo_region_destroy(clip); + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 /* If we are using a drawing context... * we don't own the cairo context so don't destroy it. */ if(dc) gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); else - cairo_destroy(cr); +#else + if(!dc) +#endif + cairo_destroy(cr); } } @@ -5674,6 +5629,8 @@ if(handle) { + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 GdkWindow *window = gtk_widget_get_window(handle); /* Safety check for non-existant windows */ if(!window || !GDK_IS_WINDOW(window)) @@ -5681,6 +5638,7 @@ clip = gdk_window_get_clip_region(window); dc = gdk_window_begin_draw_frame(window, clip); cr = gdk_drawing_context_get_cairo_context(dc); +#endif } else if(pixmap) cr = cairo_create(pixmap->image); @@ -5702,13 +5660,18 @@ cairo_stroke(cr); if(clip) cairo_region_destroy(clip); + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 /* If we are using a drawing context... * we don't own the cairo context so don't destroy it. */ if(dc) gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); else - cairo_destroy(cr); +#else + if(!dc) +#endif + cairo_destroy(cr); } } @@ -5733,6 +5696,8 @@ if(handle) { + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 GdkWindow *window = gtk_widget_get_window(handle); /* Safety check for non-existant windows */ if(!window || !GDK_IS_WINDOW(window)) @@ -5740,6 +5705,7 @@ clip = gdk_window_get_clip_region(window); dc = gdk_window_begin_draw_frame(window, clip); cr = gdk_drawing_context_get_cairo_context(dc); +#endif } else if(pixmap) cr = cairo_create(pixmap->image); @@ -5773,13 +5739,18 @@ cairo_stroke(cr); if(clip) cairo_region_destroy(clip); + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 /* If we are using a drawing context... * we don't own the cairo context so don't destroy it. */ if(dc) gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); else - cairo_destroy(cr); +#else + if(!dc) +#endif + cairo_destroy(cr); } } @@ -5804,6 +5775,8 @@ if(handle) { + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 GdkWindow *window = gtk_widget_get_window(handle); /* Safety check for non-existant windows */ if(!window || !GDK_IS_WINDOW(window)) @@ -5813,6 +5786,7 @@ cr = gdk_drawing_context_get_cairo_context(dc); if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname"))) fontname = tmpname; +#endif } else if(pixmap) { @@ -5868,13 +5842,18 @@ } if(clip) cairo_region_destroy(clip); + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 /* If we are using a drawing context... * we don't own the cairo context so don't destroy it. */ if(dc) gdk_window_end_draw_frame(gtk_widget_get_window(handle), dc); else - cairo_destroy(cr); +#else + if(!dc) +#endif + cairo_destroy(cr); } } @@ -5915,7 +5894,7 @@ font = pango_font_description_from_string(fontname ? fontname : "monospace 10"); if(font) { - PangoContext *context = gdk_pango_context_get(); + PangoContext *context = pango_context_new(); if(context) { @@ -5940,8 +5919,8 @@ } pango_font_description_free(font); } - if ( free_fontname ) - free( fontname ); + if(free_fontname) + free(fontname); } /* @@ -6199,6 +6178,8 @@ if(dest) { + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 GdkWindow *window = gtk_widget_get_window(dest); /* Safety check for non-existant windows */ if(!window || !GDK_IS_WINDOW(window)) @@ -6206,6 +6187,7 @@ clip = gdk_window_get_clip_region(window); dc = gdk_window_begin_draw_frame(window, clip); cr = gdk_drawing_context_get_cairo_context(dc); +#endif } else if(destp) cr = cairo_create(destp->image); @@ -6222,7 +6204,10 @@ } if(src) + ; +#ifdef GTK3 gdk_cairo_set_source_window (cr, gtk_widget_get_window(src), (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); +#endif else if(srcp) cairo_set_source_surface (cr, srcp->image, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); @@ -6230,12 +6215,17 @@ cairo_fill(cr); if(clip) cairo_region_destroy(clip); + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ +#if GTK3 /* If we are using a drawing context... * we don't own the cairo context so don't destroy it. */ if(dc) gdk_window_end_draw_frame(gtk_widget_get_window(dest), dc); else +#else + if(!dc) +#endif cairo_destroy(cr); retval = DW_ERROR_NONE; } @@ -7143,8 +7133,8 @@ } else { - gtk_widget_get_preferred_height(GTK_WIDGET(widget), NULL, thisheight); - gtk_widget_get_preferred_width(GTK_WIDGET(widget), NULL, thiswidth); + gtk_widget_measure(GTK_WIDGET(widget), GTK_ORIENTATION_HORIZONTAL, -1, thiswidth, NULL, NULL, NULL); + gtk_widget_measure(GTK_WIDGET(widget), GTK_ORIENTATION_VERTICAL, -1, thisheight, NULL, NULL, NULL); *thisheight += 20; *thiswidth += 20; @@ -7163,7 +7153,6 @@ /* Internal box packing function called by the other 3 functions */ void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname) { - int warn = FALSE; GtkWidget *tmp, *tmpitem, *image = NULL; if(!box) @@ -7190,13 +7179,17 @@ { item = gtk_label_new(""); g_object_set_data(G_OBJECT(item), "_dw_padding", GINT_TO_POINTER(1)); - gtk_widget_show_all(item); + gtk_widget_show(item); } /* Due to GTK3 minimum size limitations, if we are packing a widget * with an image, we need to scale the image down to fit the packed size. */ else if((image = g_object_get_data(G_OBJECT(item), "_dw_bitmap"))) { + /* TODO: Figure out how to do this in GTK4 since gtk_image_get_pixbif() is gone... + * Might need to save the pixbuf in the window data manually. + */ +#if GTK3 GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image)); if(pixbuf) @@ -7213,6 +7206,7 @@ pixbuf = gdk_pixbuf_scale_simple(pixbuf, pwidth > width ? width : pwidth, pheight > height ? height : pheight, GDK_INTERP_BILINEAR); gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); } +#endif } /* Check if the item to be packed is a special box */ @@ -7231,25 +7225,11 @@ */ if(GTK_IS_GRID(item) || (tmpitem && GTK_IS_GRID(tmpitem))) { - GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_eventbox"); - /* NOTE: I left in the ability to pack boxes with a size, * this eliminates that by forcing the size to 0. */ height = width = 0; - - if(eventbox) - { - int boxpad = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "_dw_boxpad")); - gtk_container_add(GTK_CONTAINER(eventbox), item); - gtk_container_set_border_width(GTK_CONTAINER(eventbox), boxpad); - item = eventbox; - } - } - else - { - /* Only show warning if item is not a box */ - warn = TRUE; + /* TODO: Might need to add "_dw_boxpad" to item here */ } /* Do some sanity bounds checking */ @@ -7308,16 +7288,12 @@ else gtk_widget_set_size_request(item, width, height); } - if(GTK_IS_RADIO_BUTTON(item)) - { - GSList *group; - GtkWidget *groupstart = (GtkWidget *)g_object_get_data(G_OBJECT(box), "_dw_group"); + if(GTK_IS_TOGGLE_BUTTON(item)) + { + GtkToggleButton *groupstart = (GtkToggleButton *)g_object_get_data(G_OBJECT(box), "_dw_group"); if(groupstart) - { - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(groupstart)); - gtk_radio_button_set_group(GTK_RADIO_BUTTON(item), group); - } + gtk_toggle_button_set_group(GTK_TOGGLE_BUTTON(item), groupstart); else g_object_set_data(G_OBJECT(box), "_dw_group", (gpointer)item); } @@ -7328,14 +7304,6 @@ g_object_set_data(G_OBJECT(item), "_dw_refed", NULL); } } - - if(warn) - { - if ( width == 0 && hsize == FALSE ) - dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); - if ( height == 0 && vsize == FALSE ) - dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); - } } /* @@ -7448,7 +7416,7 @@ g_object_set_data(G_OBJECT(item), "_dw_refed", GINT_TO_POINTER(1)); } /* Remove the widget from the box */ - gtk_container_remove(GTK_CONTAINER(box), item); + gtk_grid_remove(GTK_GRID(box), item); if(boxtype == DW_VERT) gtk_grid_remove_row(GTK_GRID(box), index); else @@ -7524,9 +7492,9 @@ return; if(GTK_IS_WINDOW(handle)) - gtk_window_set_default_size(handle, width, height); + gtk_window_set_default_size(GTK_WINDOW(handle), width, height); else - gtk_widget_set_size_request(handle, width, height); + gtk_widget_set_size_request(GTK_WIDGET(handle), width, height); } /* @@ -7551,10 +7519,10 @@ } else { - if(width) - gtk_widget_get_preferred_width(handle, NULL, width); + if(width) + gtk_widget_measure(GTK_WIDGET(handle), GTK_ORIENTATION_HORIZONTAL, -1, width, NULL, NULL, NULL); if(height) - gtk_widget_get_preferred_height(handle, NULL, height); + gtk_widget_measure(GTK_WIDGET(handle), GTK_ORIENTATION_VERTICAL, -1, height, NULL, NULL, NULL); } } @@ -7565,7 +7533,9 @@ if(display) { - GdkMonitor *monitor = gdk_display_get_primary_monitor(display); + /* TODO: Verify this is the correct way to do this */ + GListModel *monitors = gdk_display_get_monitors(display); + GdkMonitor *monitor = GDK_MONITOR(g_list_model_get_object(monitors, 0)); if(monitor) { @@ -7592,7 +7562,9 @@ if(display) { - GdkMonitor *monitor = gdk_display_get_primary_monitor(display); + /* TODO: Verify this is the correct way to do this */ + GListModel *monitors = gdk_display_get_monitors(display); + GdkMonitor *monitor = GDK_MONITOR(g_list_model_get_object(monitors, 0)); if(monitor) { @@ -7615,8 +7587,8 @@ /* This should return the current color depth */ unsigned long dw_color_depth_get(void) { - GdkVisual *vis = gdk_screen_get_system_visual(gdk_screen_get_default()); - return gdk_visual_get_depth(vis); + /* TODO: Make this work on GTK4... with no GdkVisual */ + return 32; } /* @@ -7642,127 +7614,9 @@ */ void dw_window_set_pos(HWND handle, long x, long y) { + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ if(!handle) return; - - { - GdkWindow *window = NULL; - - if(GTK_IS_WINDOW(handle)) - { - GdkWindow *window = gtk_widget_get_window(handle); - int horz = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_grav_horz")); - int vert = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_grav_vert")); - int cx = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_frame_width")); - int cy = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_frame_height")); - int newx = x, newy = y, width = 0, height = 0; - - /* If the window is mapped */ - if(window && gtk_widget_get_mapped(handle)) - { - /* If we need the width or height... */ - if(horz || vert) - { - GdkRectangle frame; - int count = 0; - - /* Get the frame size */ - gdk_window_get_frame_extents(window, &frame); - - /* FIXME: Sometimes we get returned an invalid 200x200 - * result... so if we get this... try the call a second - * time and hope for a better result. - */ - while((frame.width == 200 || frame.width == (200 + cx)) && - (frame.height == 200 || frame.height == (200 + cy)) && count < 10) - { - _dw_msleep(1); - count++; - gdk_window_get_frame_extents(window, &frame); - } - width = frame.width; - height = frame.height; - } - } - else - { - /* Check if we have cached frame size values */ - if(!(cx | cy)) - { - /* If not try to ask the window manager for the estimated size... - * and finally if all else fails, guess. - */ - _dw_get_frame_extents(handle, &cy, &cx); - /* Cache values for later use */ - g_object_set_data(G_OBJECT(handle), "_dw_frame_width", GINT_TO_POINTER(cx)); - g_object_set_data(G_OBJECT(handle), "_dw_frame_height", GINT_TO_POINTER(cy)); - } - /* Save the positions for when it is shown */ - g_object_set_data(G_OBJECT(handle), "_dw_x", GINT_TO_POINTER(x)); - g_object_set_data(G_OBJECT(handle), "_dw_y", GINT_TO_POINTER(y)); - g_object_set_data(G_OBJECT(handle), "_dw_pos", GINT_TO_POINTER(1)); - /* Check to see if there is a pending size request too */ - width = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_width")); - height = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(handle), "_dw_height")); - if(!width || !height) - { - /* Ask what GTK is planning on suggesting for the window size */ - gtk_window_get_size(GTK_WINDOW(handle), !width ? &width : NULL, !height ? &height : NULL); - } - /* Add the frame size to it */ - width += cx; - height += cy; - } - /* Do any gravity calculations */ - if(horz || vert) - { - /* Handle horizontal center gravity */ - if((horz & 0xf) == DW_GRAV_CENTER) - newx += ((_dw_screen_width() / 2) - (width / 2)); - /* Handle right gravity */ - else if((horz & 0xf) == DW_GRAV_RIGHT) - newx = _dw_screen_width() - width - x; - /* Handle vertical center gravity */ - if((vert & 0xf) == DW_GRAV_CENTER) - newy += ((_dw_screen_height() / 2) - (height / 2)); - else if((vert & 0xf) == DW_GRAV_BOTTOM) - newy = _dw_screen_height() - height - y; - - /* Adjust the values to avoid Gnome bar if requested */ - if((horz | vert) & DW_GRAV_OBSTACLES) - { - GdkRectangle rect = { 0, 0, 0, 0 }; - GdkDisplay *display = gdk_display_get_default(); - - if(display) - { - GdkMonitor *monitor = gdk_display_get_primary_monitor(display); - - if(monitor) - gdk_monitor_get_workarea(monitor, &rect); - } - if(horz & DW_GRAV_OBSTACLES) - { - if((horz & 0xf) == DW_GRAV_LEFT) - newx += rect.x; - else if((horz & 0xf) == DW_GRAV_RIGHT) - newx -= _dw_screen_width() - (rect.x + rect.width); - } - if(vert & DW_GRAV_OBSTACLES) - { - if((vert & 0xf) == DW_GRAV_TOP) - newy += rect.y; - else if((vert & 0xf) == DW_GRAV_BOTTOM) - newy -= _dw_screen_height() - (rect.y + rect.height); - } - } - } - /* Finally move the window into place */ - gtk_window_move(GTK_WINDOW(handle), newx, newy); - } - else if((window = gtk_widget_get_window(handle))) - gdk_window_move(window, x, y); - } } /* @@ -7791,46 +7645,18 @@ */ void dw_window_get_pos_size(HWND handle, long *x, long *y, ULONG *width, ULONG *height) { - gint gx = 0, gy = 0, gwidth = 0, gheight = 0; - - { - GdkWindow *window; - - /* Can only query if the window is realized */ - if(handle && (window = gtk_widget_get_window(handle))) - { - /* If it is a toplevel window */ - if(GTK_IS_WINDOW(handle)) - { - if(gtk_widget_get_mapped(handle)) - { - GdkRectangle frame; - - /* Calculate the border rectangle */ - gdk_window_get_frame_extents(window, &frame); - gx = frame.x; - gy = frame.y; - gwidth = frame.width; - gheight = frame.height; - } - } - else - { - /* Get an individual widget coordinates */ - gdk_window_get_geometry(window, &gx, &gy, &gwidth, &gheight); - gdk_window_get_root_origin(window, &gx, &gy); - } - } - } - /* Fill in the requested fields */ + /* TODO: Figure out how to do this in GTK4 with no GdkWindow */ + if(!handle || !GTK_IS_WIDGET(handle)) + return; + + if(width) + *width = (ULONG)gtk_widget_get_width(GTK_WIDGET(handle)); + if(height) + *height = (ULONG)gtk_widget_get_height(GTK_WIDGET(handle)); if(x) - *x = gx; + *x = 0; if(y) - *y = gy; - if(width) - *width = gwidth; - if(height) - *height = gheight; + *y = 0; } /* @@ -7860,17 +7686,14 @@ { if(mask & DW_BS_NOBORDER) { + /* TODO: Figure out how to do this in GTK4 with no Shadow or Relief */ if(style & DW_BS_NOBORDER) - { - gtk_button_set_relief((GtkButton *)handle, GTK_RELIEF_NONE); - } + ; else - { - gtk_button_set_relief((GtkButton *)handle, GTK_RELIEF_NORMAL); - } + ; } } - if ( GTK_IS_LABEL(handle2) ) + if(GTK_IS_LABEL(handle2)) { gfloat x=DW_LEFT, y=DW_CENTER; /* horizontal... */ @@ -7889,10 +7712,12 @@ y = DW_BOTTOM; gtk_label_set_xalign(GTK_LABEL(handle2), x); gtk_label_set_yalign(GTK_LABEL(handle2), y); - if ( style & DW_DT_WORDBREAK ) - gtk_label_set_line_wrap( GTK_LABEL(handle), TRUE ); - } - if ( GTK_IS_CHECK_MENU_ITEM(handle2) && (mask & (DW_MIS_CHECKED | DW_MIS_UNCHECKED)) ) + if(style & DW_DT_WORDBREAK) + gtk_label_set_wrap(GTK_LABEL(handle), TRUE); + } + /* TODO: Convert to GMenuModel */ +#if GTK3 + if(GTK_IS_CHECK_MENU_ITEM(handle2) && (mask & (DW_MIS_CHECKED | DW_MIS_UNCHECKED)) { int check = 0; @@ -7904,15 +7729,16 @@ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(handle2), check); _dw_ignore_click = 0; } - if ( (GTK_IS_CHECK_MENU_ITEM(handle2) || GTK_IS_MENU_ITEM(handle2)) && (mask & (DW_MIS_ENABLED | DW_MIS_DISABLED) )) + if((GTK_IS_CHECK_MENU_ITEM(handle2) || GTK_IS_MENU_ITEM(handle2)) && (mask & (DW_MIS_ENABLED | DW_MIS_DISABLED))) { _dw_ignore_click = 1; if ( style & DW_MIS_ENABLED ) - gtk_widget_set_sensitive( handle2, TRUE ); + gtk_widget_set_sensitive(handle2, TRUE); else - gtk_widget_set_sensitive( handle2, FALSE ); + gtk_widget_set_sensitive(handle2, FALSE); _dw_ignore_click = 0; } +#endif } /* @@ -8113,7 +7939,8 @@ if(GTK_IS_GRID(page)) { pad = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(page), "_dw_boxpad")); - gtk_container_set_border_width(GTK_CONTAINER(page), pad); + /* TODO: Add padding to page with no GtkContainer in GTK4 */ + pad = pad; } if(realpage != -1) @@ -8695,8 +8522,12 @@ float *percent = malloc(sizeof(float)); tmp = gtk_paned_new(type == DW_HORZ ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL); - gtk_paned_pack1(GTK_PANED(tmp), topleft, TRUE, FALSE); - gtk_paned_pack2(GTK_PANED(tmp), bottomright, TRUE, FALSE); + gtk_paned_set_start_child(GTK_PANED(tmp), topleft); + gtk_paned_set_resize_start_child(GTK_PANED(tmp), TRUE); + gtk_paned_set_shrink_start_child(GTK_PANED(tmp), FALSE); + gtk_paned_set_end_child(GTK_PANED(tmp), bottomright); + gtk_paned_set_resize_end_child(GTK_PANED(tmp), TRUE); + gtk_paned_set_shrink_end_child(GTK_PANED(tmp), FALSE); g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); *percent = 50.0; g_object_set_data(G_OBJECT(tmp), "_dw_percent", (gpointer)percent); @@ -8754,21 +8585,18 @@ */ HWND dw_calendar_new(unsigned long id) { - GtkWidget *tmp; - GtkCalendarDisplayOptions flags; - time_t now; - struct tm *tmdata; - - tmp = gtk_calendar_new(); + GtkWidget *tmp = gtk_calendar_new(); + GTimeZone *tz = g_time_zone_new_local(); + GDateTime *now = g_date_time_new_now(tz); + gtk_widget_show(tmp); g_object_set_data(G_OBJECT(tmp), "_dw_id", GINT_TO_POINTER(id)); /* select today */ - flags = GTK_CALENDAR_SHOW_HEADING|GTK_CALENDAR_SHOW_DAY_NAMES; - gtk_calendar_set_display_options( GTK_CALENDAR(tmp), flags ); - now = time( NULL ); - tmdata = localtime( & now ); - gtk_calendar_select_month( GTK_CALENDAR(tmp), tmdata->tm_mon, 1900+tmdata->tm_year ); - gtk_calendar_select_day( GTK_CALENDAR(tmp), tmdata->tm_mday ); + gtk_calendar_set_show_day_names(GTK_CALENDAR(tmp), TRUE); + gtk_calendar_set_show_heading(GTK_CALENDAR(tmp), TRUE); + gtk_calendar_select_day(GTK_CALENDAR(tmp), now); + g_date_time_unref(now); + g_time_zone_unref(tz); return tmp; } @@ -8782,8 +8610,11 @@ { if(GTK_IS_CALENDAR(handle)) { - gtk_calendar_select_month(GTK_CALENDAR(handle),month-1,year); - gtk_calendar_select_day(GTK_CALENDAR(handle), day); + GTimeZone *tz = g_time_zone_new_local(); + GDateTime *datetime = g_date_time_new(tz, year, month, day, 0, 0, 0); + gtk_calendar_select_day(GTK_CALENDAR(handle), datetime); + g_date_time_unref(datetime); + g_time_zone_unref(tz); } } @@ -8796,8 +8627,13 @@ { if(GTK_IS_CALENDAR(handle)) { - gtk_calendar_get_date(GTK_CALENDAR(handle),year,month,day); - *month = *month + 1; + GDateTime *datetime = gtk_calendar_get_date(GTK_CALENDAR(handle)); + if(year) + *year = g_date_time_get_year(datetime); + if(month) + *month = g_date_time_get_month(datetime); + if(day) + *day = g_date_time_get_day_of_month(datetime); } } @@ -8982,7 +8818,7 @@ gchar *button; char *filename = NULL; char buf[1000]; - char mypath[PATH_MAX+1]; + DWDialog *tmp = dw_dialog_new(NULL); switch (flags ) { @@ -9011,10 +8847,7 @@ button, GTK_RESPONSE_ACCEPT, NULL); - if ( flags == DW_FILE_SAVE ) - gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER( filew ), TRUE ); - - if ( ext ) + if(ext) { filter1 = gtk_file_filter_new(); sprintf( buf, "*.%s", ext ); @@ -9028,74 +8861,31 @@ gtk_file_chooser_add_filter( GTK_FILE_CHOOSER( filew ), filter2 ); } - if ( defpath ) - { - struct stat buf; - - if ( g_path_is_absolute( defpath ) || !realpath(defpath, mypath)) - { - strcpy( mypath, defpath ); - } + if(defpath) + { + GFile *path = g_file_new_for_path(defpath); /* See if the path exists */ - if(stat(mypath, &buf) == 0) + if(path) { /* If the path is a directory... set the current folder */ - if(buf.st_mode & S_IFDIR) - gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( filew ), mypath ); - else if(flags == DW_FILE_SAVE) /* Otherwise set the filename */ - gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( filew ), mypath ); - else if(flags == DW_FILE_OPEN) - gtk_file_chooser_select_filename( GTK_FILE_CHOOSER( filew), mypath ); - } - else if(flags == DW_FILE_SAVE) - { - if(strchr(mypath, '/')) - { - unsigned long x = strlen(mypath) - 1; - - /* Trim off the filename */ - while(x > 0 && mypath[x] != '/') - { - x--; - } - if(mypath[x] == '/') - { - char *file = NULL; - char temp[PATH_MAX+1]; - - /* Save the original path in temp */ - strcpy(temp, mypath); - mypath[x] = 0; - - /* Check to make sure the trimmed piece is a directory */ - if(realpath(mypath, temp) && stat(temp, &buf) == 0) - { - if(buf.st_mode & S_IFDIR) - { - /* We now have it split */ - file = &mypath[x+1]; - } - } - - /* Select folder... */ - gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(filew), temp ); - /* ... and file separately */ - if(file) - gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER(filew), file ); - } - } - } - } - - if ( gtk_dialog_run( GTK_DIALOG( filew ) ) == GTK_RESPONSE_ACCEPT ) - { - filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( filew ) ); - /*g_free (filename);*/ - } - - if(GTK_IS_WIDGET(filew)) - g_object_unref(G_OBJECT(filew)); + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filew), path, NULL); + gtk_file_chooser_set_file(GTK_FILE_CHOOSER(filew), path, NULL); + + g_object_unref(G_OBJECT(path)); + } + } + + /* TODO: Connect signal handlers so this actually returns */ + if(DW_POINTER_TO_INT(dw_dialog_wait(tmp)) == GTK_RESPONSE_ACCEPT) + { + GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(filew)); + filename = g_file_get_path(file); + g_object_unref(G_OBJECT(file)); + } + + if(GTK_IS_WINDOW(filew)) + gtk_window_destroy(GTK_WINDOW(filew)); return filename; } @@ -9169,29 +8959,8 @@ int dw_browse(const char *url) { /* If possible load the URL/URI using gvfs... */ -#if GTK_CHECK_VERSION(3,22,0) - if(gtk_show_uri_on_window(NULL, url, GDK_CURRENT_TIME, NULL)) -#else - if(gtk_show_uri(gdk_screen_get_default(), url, GDK_CURRENT_TIME, NULL)) -#endif - { - return DW_ERROR_NONE; - } - else - { - /* Otherwise just fall back to executing firefox... - * or the browser defined by the DW_BROWSER variable. - */ - char *execargs[3], *browser = "firefox", *tmp; - - tmp = getenv( "DW_BROWSER" ); - if(tmp) browser = tmp; - execargs[0] = browser; - execargs[1] = (char *)url; - execargs[2] = NULL; - - return dw_exec(browser, DW_EXEC_GUI, execargs); - } + gtk_show_uri(NULL, url, GDK_CURRENT_TIME); + return DW_ERROR_NONE; } #ifdef USE_WEBKIT @@ -9362,11 +9131,14 @@ */ char *dw_clipboard_get_text() { - GtkClipboard *clipboard_object; + GdkDisplay *display = gdk_display_get_default(); + GdkClipboard *clipboard_object; char *ret = NULL; - if((clipboard_object = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ))) - { + if((clipboard_object = gdk_display_get_clipboard(display))) + { + /* TODO: Finish conversion to GdkClipboard */ +#if GTK3 gchar *clipboard_contents; if((clipboard_contents = gtk_clipboard_wait_for_text( clipboard_object ))) @@ -9374,6 +9146,7 @@ ret = strdup((char *)clipboard_contents); g_free(clipboard_contents); } +#endif } return ret; } @@ -9385,11 +9158,15 @@ */ void dw_clipboard_set_text(const char *str, int len) { - GtkClipboard *clipboard_object; - - if((clipboard_object = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ))) - { + GdkDisplay *display = gdk_display_get_default(); + GdkClipboard *clipboard_object; + + if((clipboard_object = gdk_display_get_clipboard(display))) + { + /* TODO: Finish conversion to GdkClipboard */ +#if GTK3 gtk_clipboard_set_text( clipboard_object, str, len ); +#endif } } @@ -9758,11 +9535,14 @@ { thisname = "draw"; } + /* TODO: Convert to GMenuModel */ +#if GTK3 else if (GTK_IS_MENU_ITEM(thiswindow) && strcmp(signame, DW_SIGNAL_CLICKED) == 0) { thisname = "activate"; thisfunc = _findsigfunc(thisname); } +#endif else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_CONTEXT) == 0) { sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc, discfunc); @@ -9824,7 +9604,7 @@ { thisname = "focus-in-event"; if (GTK_IS_COMBO_BOX(thiswindow)) - thiswindow = gtk_bin_get_child(GTK_BIN(thiswindow)); + thiswindow = gtk_combo_box_get_child(GTK_COMBO_BOX(thiswindow)); } #ifdef USE_WEBKIT else if (WEBKIT_IS_WEB_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_HTML_CHANGED) == 0)