bug-gnubg
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-gnubg] Build option for gtk3


From: Jeremy Moore
Subject: [Bug-gnubg] Build option for gtk3
Date: Sun, 14 Aug 2016 14:29:24 +0300

Hi folks,

Another patch below for your consideration - this one adds an option
to build with gtk3 instead of gtk2. I've got it working for 2D boards
only. To make the gtk3 build use:

./configure --with-gtk3 --without-board3d

The main changes are around styles, sizing, and signals. I've created
shim macros in gtklocdefs.h to paper over some of the small API
changes, but resorted to ifdef-fery where new signals needed to be
connected up.

The big stumbling block is still the 3D code. As far as I could see,
there's no stable native API or 3rd party library available just yet.
I guess there's no real hurry anyways.

Regards,
Jeremy


Index: Makefile.am
===================================================================
RCS file: /sources/gnubg/gnubg/Makefile.am,v
retrieving revision 1.262
diff -u -r1.262 Makefile.am
--- Makefile.am 25 Jul 2016 21:37:11 -0000 1.262
+++ Makefile.am 14 Aug 2016 10:56:07 -0000
@@ -209,12 +209,12 @@
 ##files to be installed in the datadir
 #
 pkgdata_DATA = gnubg_ts0.bd gnubg.wd boards.xml \
- gnubg_os0.bd textures.txt gnubg.sql gnubg.gtkrc
+ gnubg_os0.bd textures.txt gnubg.sql gnubg.gtkrc gnubg.css

 #
 ##files to add to the tarball when 'make dist'
 #
-EXTRA_DIST = config.rpath  copying.awk gnubg.gtkrc credits.sh AUTHORS \
+EXTRA_DIST = config.rpath  copying.awk gnubg.gtkrc gnubg.css
credits.sh AUTHORS \
  $(BUILT_SOURCES) ABOUT-NLS boards.xml gnubg.sql autogen.sh \
  gnubg.weights textures.txt \
  external_y.h sgf_y.h commands.inc movefilters.inc
Index: configure.ac
===================================================================
RCS file: /sources/gnubg/gnubg/configure.ac,v
retrieving revision 1.67
diff -u -r1.67 configure.ac
--- configure.ac 25 Jul 2016 21:37:11 -0000 1.67
+++ configure.ac 14 Aug 2016 10:56:07 -0000
@@ -143,13 +143,22 @@
     if test "x$darwin" = "xyes"; then
         have_canberra="no"
     elif test "x$with_gtk" != "xno"; then
-        PKG_CHECK_MODULES(CANBERRA, [libcanberra-gtk],
have_canberra="yes", AC_MSG_WARN([no libcanberra-gtk support]))
+        if test "x$with_gtk3" = "xyes"; then
+            PKG_CHECK_MODULES(CANBERRA, [libcanberra-gtk3],
have_canberra="yes", AC_MSG_WARN([no libcanberra-gtk3 support]))
+        else
+            PKG_CHECK_MODULES(CANBERRA, [libcanberra-gtk],
have_canberra="yes", AC_MSG_WARN([no libcanberra-gtk support]))
+        fi
     fi
     PKG_CHECK_MODULES(GLU, [glu], have_glu="yes", AC_MSG_WARN([no glu
support]))
 fi

 if test "x$with_gtk" != "xno"; then
-    PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.6.0], have_gtk="yes" ,
AC_MSG_WARN([no gtk support]))
+    if test "x$with_gtk3" = "xyes"; then
+        PKG_CHECK_MODULES(GTK, [gtk+-3.0], have_gtk="yes",
AC_MSG_WARN([no gtk3 support]))
+    else
+        PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.6.0], have_gtk="yes",
AC_MSG_WARN([no gtk2 support]))
+    fi
+
     if test "x$with_board3d" != "xno"; then
         PKG_CHECK_MODULES(GTKGLEXT, [gtkglext-1.0 >= 1.0],
have_gtkglext="yes" , AC_MSG_WARN([no gtkglext support]))
     fi
@@ -311,6 +320,7 @@
 no_board3d="yes"
 no_gtkglext="yes"
 AC_ARG_WITH(gtk,[  --with-gtk              use GTK+ 2.0 (Default if found)])
+AC_ARG_WITH(gtk3,[  --with-gtk3             use GTK+ 3.0
(Experimental, disabled by default)])
 AC_ARG_WITH(board3d,[  --with-board3d          compile with 3D boards
(Default if found)])
 if test "$with_gtk" != "no" && test "x$have_gtk" = "xyes"; then
    AC_DEFINE(USE_GTK, 1, [Define if you want to use the gtk gui])
Index: gnubg.css
===================================================================
RCS file: gnubg.css
diff -N gnubg.css
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gnubg.css 14 Aug 2016 10:56:07 -0000
@@ -0,0 +1,106 @@
+/*
+ * Colour definitions for gtk3.
+ * Ported from the gtkrc file used for gtk2.
+ */
+
+/*
+ * Style for the move list (e.g. the hint window) for highlighting the actual
+ * move made.
+ */
+#gnubg-move-done:active {
+    color: red;
+}
+
+/*
+ * Style for the move list, used in detail view, sets font colour for stat line
+ */
+#gnubg-move-winlossfg:active {
+    color: gray;
+}
+
+/*
+ * Style for the uncompleted move (shown as you move pieces around)
+ */
+#gnubg-move-current:active {
+    color: red;
+}
+
+/*
+ * Styles for showing the graphical overview of the market windows.
+ *
+ * ACTIVE is used for showing the "double, take" window
+ * HOVER is used for showing the "double, pass" window
+ * SELECTED is used for showing the "too good" window
+ */
+#gnubg-doubling-window-graph:active {
+    background-color: green;
+}
+
+#gnubg-doubling-window-graph:hover {
+    background-color: red;
+}
+
+#gnubg-doubling-window-graph:selected {
+    background-color: blue;
+}
+
+/*
+ * Styles for moves in game list
+ */
+#gnubg-gamelist-chequer-blunder {
+    color: red;
+}
+
+#gnubg-gamelist-chequer-error {
+    color: blue;
+}
+
+#gnubg-gamelist-chequer-doubtful {
+    color: #11a011;
+}
+
+#gnubg-gamelist-cube-blunder {
+    background-color: yellow;
+}
+
+#gnubg-gamelist-cube-error {
+    background-color: #ff80ff;
+}
+
+#gnubg-gamelist-cube-doubtful {
+    background-color: silver;
+}
+
+#gnubg-gamelist-luck-bad {
+    font-style: italic;
+}
+
+#gnubg-gamelist-luck-good {
+    font-weight: bold;
+}
+
+/*
+ * Styles for match equity table
+ *
+ * The style for "met-matching-score" is used for highlighting the row
+ * and column that matches the current score. For example, if the score
+ * is 4-away,7-away the row for 4-away and the column for 7-away is
highlighted.
+ * The style for "met-the-score" is used to highlight the exact score, e.g.,
+ * in the example above, the entry at 4-away,7-away is highlighted.
+ */
+#gnubg-met-matching-score {
+    color: red;
+}
+
+#gnubg-met-the-score {
+    color: green;
+}
+
+/*
+ * Style for squares in the temperature map
+ */
+.gnubg-temp-map-quadrant {
+    border-width: 1px;
+    border-color: gray;
+    border-style: inset;
+}
Index: gtk-multiview.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtk-multiview.c,v
retrieving revision 1.16
diff -u -r1.16 gtk-multiview.c
--- gtk-multiview.c 22 Jul 2013 18:51:01 -0000 1.16
+++ gtk-multiview.c 14 Aug 2016 10:56:07 -0000
@@ -33,6 +33,12 @@

 static void
 gtk_multiview_size_request(GtkWidget * widget, GtkRequisition * requisition);
+#if GTK_CHECK_VERSION(3,0,0)
+static void
+gtk_multiview_get_preferred_width(GtkWidget * widget, gint *
minimal_width, gint * natural_width);
+static void
+gtk_multiview_get_preferred_height(GtkWidget * widget, gint *
minimal_height, gint * natural_height);
+#endif
 static void
 gtk_multiview_size_allocate(GtkWidget * widget, GtkAllocation * allocation);
 static void
@@ -67,7 +73,12 @@
     widget_class = (GtkWidgetClass *) klass;
     container_class = (GtkContainerClass *) klass;

+#if GTK_CHECK_VERSION(3,0,0)
+    widget_class->get_preferred_width = gtk_multiview_get_preferred_width;
+    widget_class->get_preferred_height = gtk_multiview_get_preferred_height;
+#else
     widget_class->size_request = gtk_multiview_size_request;
+#endif
     widget_class->size_allocate = gtk_multiview_size_allocate;
     widget_class->map = gtk_multiview_map;
     widget_class->unmap = gtk_multiview_unmap;
@@ -107,6 +118,24 @@
     }
 }

+#if GTK_CHECK_VERSION(3,0,0)
+static void
+gtk_multiview_get_preferred_width(GtkWidget * widget, gint *
minimal_width, gint * natural_width)
+{
+    GtkRequisition requisition;
+    gtk_multiview_size_request(widget, &requisition);
+    *minimal_width = *natural_width = requisition.width;
+}
+
+static void
+gtk_multiview_get_preferred_height(GtkWidget * widget, gint *
minimal_height, gint * natural_height)
+{
+    GtkRequisition requisition;
+    gtk_multiview_size_request(widget, &requisition);
+    *minimal_height = *natural_height = requisition.height;
+}
+#endif
+
 static void
 gtk_multiview_size_allocate(GtkWidget * widget, GtkAllocation * allocation)
 {
Index: gtkboard.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtkboard.c,v
retrieving revision 1.332
diff -u -r1.332 gtkboard.c
--- gtkboard.c 11 Jun 2016 15:46:31 -0000 1.332
+++ gtkboard.c 14 Aug 2016 10:56:08 -0000
@@ -297,6 +297,28 @@
     g_object_unref(pixbuf);
 }

+static void
+board_draw_area(cairo_t * cr, gint x, gint y, gint cx, gint cy, BoardData * bd)
+{
+    unsigned char *puch;
+
+    puch = malloc(cx * cy * 3);
+    RenderArea(bd, puch, x, y, cx, cy);
+    draw_rgb_image(cr, puch, x, y, cx, cy);
+    free(puch);
+}
+
+#if GTK_CHECK_VERSION(3,0,0)
+static gboolean
+board_draw(GtkWidget * drawing_area, cairo_t * cr, BoardData * bd)
+{
+    if (bd->rd->nSize == 0)
+        return TRUE;
+
+    board_draw_area(cr, 0, 0,
gtk_widget_get_allocated_width(drawing_area),
gtk_widget_get_allocated_height(drawing_area), bd);
+    return TRUE;
+}
+#else
 static gboolean
 board_expose(GtkWidget * drawing_area, GdkEventExpose * event, BoardData * bd)
 {
@@ -333,23 +355,22 @@
     if (cx <= 0 || cy <= 0)
         return TRUE;

-    puch = malloc(cx * cy * 3);
-
-    RenderArea(bd, puch, x, y, cx, cy);
-
     cr = gdk_cairo_create(gtk_widget_get_window(drawing_area));
-    draw_rgb_image(cr, puch, x, y, cx, cy);
+    board_draw_area(cr, x, y, cx, cy, bd);
     cairo_destroy(cr);

-    free(puch);
-
     return TRUE;
 }
+#endif

 extern void
 stop_board_expose(BoardData * bd)
 {
+#if GTK_CHECK_VERSION(3,0,0)
+    g_signal_handlers_disconnect_by_func(G_OBJECT(bd->drawing_area),
(gpointer)G_CALLBACK(board_draw), bd);
+#else
     g_signal_handlers_disconnect_by_func(G_OBJECT(bd->drawing_area),
(gpointer)G_CALLBACK(board_expose), bd);
+#endif
 }

 static void
@@ -985,22 +1006,22 @@
                      0, bd->ri.asRefract[bd->drag_colour > 0], 6 * s,
6 * s, 6 * s);

     {
-        GdkRegion *pr;
-        GdkRectangle r;
+        gtk_locdef_region *pr;
+        gtk_locdef_rectangle r;

         r.x = bd->x_drag - 3 * s;
         r.y = bd->y_drag - 3 * s;
         r.width = 6 * s;
         r.height = 6 * s;
-        pr = gdk_region_rectangle(&r);
+        pr = gtk_locdef_create_rectangle(&r);

         r.x = x - 3 * s;
         r.y = y - 3 * s;
-        gdk_region_union_with_rect(pr, &r);
+        gtk_locdef_union_rectangle(pr, &r);

         gdk_window_begin_paint_region(gtk_widget_get_window(bd->drawing_area),
pr);

-        gdk_region_destroy(pr);
+        gtk_locdef_region_destroy(pr);
     }

     cr = gdk_cairo_create(gtk_widget_get_window(bd->drawing_area));
@@ -3052,7 +3073,7 @@
                      auchChequers[i], CHEQUER_WIDTH * 3 * 4,
                      asRefract[i], CHEQUER_WIDTH * 3, CHEQUER_WIDTH *
3, CHEQUER_HEIGHT * 3);

-        cr = gdk_cairo_create(bd->appmKey[i]);
+        cr = gtk_locdef_cairo_create_from_surface(bd->appmKey[i]);
         draw_rgb_image(cr, auch, 0, 0, 20, 20);
         cairo_destroy(cr);
     }
@@ -3108,6 +3129,7 @@
     GtkAllocation child_allocation;
     GtkRequisition requisition;

+    GTK_WIDGET_CLASS(board_parent_class)->size_allocate(board, allocation);
     gtk_widget_set_allocation(board, allocation);

     /* position ID, match ID: just below toolbar */
@@ -3158,6 +3180,15 @@
     child_allocation.x = allocation->x + ((allocation->width -
child_allocation.width) >> 1);
     child_allocation.height = BOARD_HEIGHT * bd->rd->nSize;
     child_allocation.y = allocation->y + ((allocation->height -
BOARD_HEIGHT * bd->rd->nSize) >> 1);
+#if GTK_CHECK_VERSION(3,0,0)
+    {
+        gint min_width, min_height;
+        gtk_widget_get_preferred_width(bd->drawing_area, &min_width, NULL);
+        gtk_widget_get_preferred_height(bd->drawing_area, &min_height, NULL);
+        g_assert(child_allocation.width >= min_width);
+        g_assert(child_allocation.height >= min_height);
+    }
+#endif
     gtk_widget_size_allocate(bd->drawing_area, &child_allocation);

     /* allocation for dice area */
@@ -3213,6 +3244,24 @@
     pr->height += BOARD_HEIGHT + 2;
 }

+#if GTK_CHECK_VERSION(3,0,0)
+static void
+board_get_preferred_width(GtkWidget * widget, gint * minimal_width,
gint * natural_width)
+{
+    GtkRequisition requisition;
+    board_size_request (widget, &requisition);
+    *minimal_width = *natural_width = requisition.width;
+}
+
+static void
+board_get_preferred_height(GtkWidget * widget, gint * minimal_height,
gint * natural_height)
+{
+    GtkRequisition requisition;
+    board_size_request (widget, &requisition);
+    *minimal_height = *natural_height = requisition.height;
+}
+#endif
+
 static void
 board_realize(GtkWidget * board)
 {
@@ -3440,12 +3489,11 @@
 }

 static void
-DrawAlphaImage(GdkDrawable * pd, int x, int y, unsigned char
*puchSrc, int nStride, int cx, int cy)
+DrawAlphaImage(cairo_t * cr, int x, int y, unsigned char *puchSrc,
int nStride, int cx, int cy)
 {

     unsigned char *puch, *puchDest, *auch = g_alloca(cx * cy * 4);
     int ix, iy;
-    cairo_t *cr;
     GdkPixbuf *ppb;

     puchDest = auch;
@@ -3465,28 +3513,23 @@
         puch += nStride;
     }

-    cr = gdk_cairo_create(pd);
     ppb = gdk_pixbuf_new_from_data(auch, GDK_COLORSPACE_RGB, TRUE, 8,
cx, cy, cx * 4, NULL, NULL);
     gdk_cairo_set_source_pixbuf(cr, ppb, x, y);
     cairo_paint(cr);
     g_object_unref(G_OBJECT(ppb));
-    cairo_destroy(cr);
 }

 extern void
-DrawDie(GdkDrawable * pd, unsigned char *achDice[2], unsigned
+DrawDie(cairo_t * cr, unsigned char *achDice[2], unsigned
         char *achPip[2], const int s, int x, int y, int
         fColour, int n, int alpha)
 {

     int ix, iy, afPip[9];
-    cairo_t *cr;
     GdkPixbuf *pixbuf;

-    cr = gdk_cairo_create(pd);
-
     if (alpha)
-        DrawAlphaImage(pd, x, y, achDice[fColour], DIE_WIDTH * s * 4,
DIE_WIDTH * s, DIE_HEIGHT * s);
+        DrawAlphaImage(cr, x, y, achDice[fColour], DIE_WIDTH * s * 4,
DIE_WIDTH * s, DIE_HEIGHT * s);
     else
         draw_rgb_image(cr, achDice[fColour], x, y, DIE_WIDTH * s,
DIE_HEIGHT * s);

@@ -3507,24 +3550,37 @@
             }

     g_object_unref(pixbuf);
-    cairo_destroy(cr);
 }

 static gboolean
-dice_expose(GtkWidget * dice, GdkEventExpose * UNUSED(event), BoardData * bd)
+dice_draw(GtkWidget * dice, cairo_t * cr, BoardData * bd)
 {

     if (bd->rd->nSize == 0 || bd->diceShown == DICE_NOT_SHOWN)
         return TRUE;

-    DrawDie(gtk_widget_get_window(dice), bd->ri.achDice, bd->ri.achPip,
+    DrawDie(cr, bd->ri.achDice, bd->ri.achPip,
             bd->rd->nSize, 0, 0, bd->turn > 0, bd->diceRoll[0], TRUE);
-    DrawDie(gtk_widget_get_window(dice), bd->ri.achDice, bd->ri.achPip,
+    DrawDie(cr, bd->ri.achDice, bd->ri.achPip,
             bd->rd->nSize, (DIE_WIDTH + 1) * bd->rd->nSize, 0,
bd->turn > 0, bd->diceRoll[1], TRUE);

     return TRUE;
 }

+#if ! GTK_CHECK_VERSION(3,0,0)
+static gboolean
+dice_expose(GtkWidget * dice, GdkEventExpose * UNUSED(event), BoardData * bd)
+{
+    cairo_t *cr;
+
+    cr = gdk_cairo_create(gtk_widget_get_window(dice));
+    dice_draw(dice, cr, bd);
+    cairo_destroy(cr);
+
+    return TRUE;
+}
+#endif
+
 static gboolean
 dice_press(GtkWidget * UNUSED(dice), GdkEvent * UNUSED(event),
BoardData * UNUSED(bd))
 {
@@ -3549,14 +3605,12 @@

     GtkWidget *pw = gtk_event_box_new(), *pwImage;
     BoardData *bd = board->board_data;
-    GdkPixmap *ppm;
     char sz[128];

     gtk_event_box_set_visible_window(GTK_EVENT_BOX(pw), FALSE);
-    ppm = bd->appmKey[iPlayer] =
-        gdk_pixmap_new(NULL, 20, 20,
gdk_visual_get_depth(gtk_widget_get_visual(GTK_WIDGET(board))));
+    bd->appmKey[iPlayer] =
gtk_locdef_surface_create(GTK_WIDGET(board), 20, 20);

-    pwImage = gtk_image_new_from_pixmap(ppm, NULL);
+    pwImage = gtk_locdef_image_new_from_surface(bd->appmKey[iPlayer]);

     gtk_container_add(GTK_CONTAINER(pw), pwImage);

@@ -3813,12 +3867,20 @@
     gtk_widget_set_size_request(bd->dice_area, 2 * DIE_WIDTH + 1, DIE_HEIGHT);
     gtk_widget_add_events(GTK_WIDGET(bd->dice_area),
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_STRUCTURE_MASK);

+#if GTK_CHECK_VERSION(3,0,0)
+    g_signal_connect(G_OBJECT(bd->drawing_area), "draw",
G_CALLBACK(board_draw), bd);
+#else
     g_signal_connect(G_OBJECT(bd->drawing_area), "expose_event",
G_CALLBACK(board_expose), bd);
+#endif
     g_signal_connect(G_OBJECT(bd->drawing_area),
"button_press_event", G_CALLBACK(board_button_press), bd);
     g_signal_connect(G_OBJECT(bd->drawing_area),
"button_release_event", G_CALLBACK(board_button_release), bd);
     g_signal_connect(G_OBJECT(bd->drawing_area),
"motion_notify_event", G_CALLBACK(board_motion_notify), bd);

+#if GTK_CHECK_VERSION(3,0,0)
+    g_signal_connect(G_OBJECT(bd->dice_area), "draw",
G_CALLBACK(dice_draw), bd);
+#else
     g_signal_connect(G_OBJECT(bd->dice_area), "expose_event",
G_CALLBACK(dice_expose), bd);
+#endif
     g_signal_connect(G_OBJECT(bd->dice_area), "button_press_event",
G_CALLBACK(dice_press), bd);

     g_signal_connect(G_OBJECT(bd->amatch), "value-changed",
G_CALLBACK(score_changed), bd);
@@ -3836,7 +3898,12 @@
     g_assert(parent_class);

     ((GtkWidgetClass *) c)->size_allocate = board_size_allocate;
+#if GTK_CHECK_VERSION(3,0,0)
+    ((GtkWidgetClass *) c)->get_preferred_width = board_get_preferred_width;
+    ((GtkWidgetClass *) c)->get_preferred_height = board_get_preferred_height;
+#else
     ((GtkWidgetClass *) c)->size_request = board_size_request;
+#endif
     ((GtkWidgetClass *) c)->realize = board_realize;
     ((GtkWidgetClass *) c)->show_all = board_show_all;
 }
@@ -3844,7 +3911,7 @@

 #define N_CUBES_IN_WIDGET 8
 static gboolean
-cube_widget_expose(GtkWidget * cube, GdkEventExpose * UNUSED(event),
BoardData * bd)
+cube_widget_draw(GtkWidget * cube, cairo_t * cr, BoardData * bd)
 {

     int n, nValue;
@@ -3852,7 +3919,6 @@
     int setSize = bd->rd->nSize;
     int cubeStride = setSize * CUBE_WIDTH * 4;
     int cubeFaceStride = setSize * CUBE_LABEL_WIDTH * 3;
-    cairo_t *cr;

     n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cube), "user_data"));
     if ((nValue = n % N_CUBES_IN_WIDGET - 1) == -1)
@@ -3867,14 +3933,26 @@
                        cubeFaceStride,
                        0, CUBE_LABEL_HEIGHT * setSize * nValue,
                        CUBE_LABEL_WIDTH * setSize, CUBE_LABEL_HEIGHT
* setSize, 2 - n / N_CUBES_IN_WIDGET);
-    DrawAlphaImage(gtk_widget_get_window(cube), 0, 0,
+    DrawAlphaImage(cr, 0, 0,
                    TTachCube, cubeStride, CUBE_WIDTH * setSize,
CUBE_HEIGHT * setSize);
-    cr = gdk_cairo_create(gtk_widget_get_window(cube));
     draw_rgb_image(cr, puch, setSize, setSize, CUBE_LABEL_WIDTH *
setSize, CUBE_LABEL_HEIGHT * setSize);
+
+    return TRUE;
+}
+
+#if ! GTK_CHECK_VERSION(3,0,0)
+static gboolean
+cube_widget_expose(GtkWidget * cube, GdkEventExpose * UNUSED(event),
BoardData * bd)
+{
+    cairo_t *cr;
+
+    cr = gdk_cairo_create(gtk_widget_get_window(cube));
+    cube_widget_draw(cube, cr, bd);
     cairo_destroy(cr);

     return TRUE;
 }
+#endif

 static gboolean
 cube_widget_press(GtkWidget * cube, GdkEvent * UNUSED(event),
BoardData * UNUSED(bd))
@@ -3898,7 +3976,7 @@
 }

 extern void
-DestroySetCube(GtkObject * UNUSED(po), GtkWidget * pw)
+DestroySetCube(GObject * UNUSED(po), GtkWidget * pw)
 {
     free(TTachCubeFaces);
     free(TTachCube);
@@ -3936,7 +4014,11 @@
             g_object_set_data(G_OBJECT(pwCube), "user_data",
GINT_TO_POINTER((y * N_CUBES_IN_WIDGET + x)));
             gtk_widget_set_size_request(pwCube, CUBE_WIDTH * setSize,
CUBE_HEIGHT * setSize);
             gtk_widget_add_events(pwCube, GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK | GDK_STRUCTURE_MASK);
+#if GTK_CHECK_VERSION(3,0,0)
+            g_signal_connect(G_OBJECT(pwCube), "draw",
G_CALLBACK(cube_widget_draw), bd);
+#else
             g_signal_connect(G_OBJECT(pwCube), "expose_event",
G_CALLBACK(cube_widget_expose), bd);
+#endif
             g_signal_connect(G_OBJECT(pwCube), "button_press_event",
G_CALLBACK(cube_widget_press), bd);
             gtk_table_attach_defaults(GTK_TABLE(pw), pwCube, x, x +
1, y, y + 1);
         }
@@ -3951,15 +4033,15 @@


 static gboolean
-setdice_widget_expose(GtkWidget * dice, GdkEventExpose *
UNUSED(event), SetDiceData * sdd)
+setdice_widget_draw(GtkWidget * dice, cairo_t * cr, SetDiceData * sdd)
 {
     int setSize = sdd->bd->rd->nSize;
     int n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dice), "user_data"));

     if (sdd->mdt == MT_FIRSTMOVE && (n % 6 == n / 6)) {
-        DrawDie(gtk_widget_get_window(dice), &sdd->TTachGrayDice,
&sdd->TTachGrayPip, setSize,
+        DrawDie(cr, &sdd->TTachGrayDice, &sdd->TTachGrayPip, setSize,
                 0, 0, 0, n % 6 + 1, FALSE);
-        DrawDie(gtk_widget_get_window(dice), &sdd->TTachGrayDice,
&sdd->TTachGrayPip, setSize,
+        DrawDie(cr, &sdd->TTachGrayDice, &sdd->TTachGrayPip, setSize,
                 DIE_WIDTH * setSize, 0, 0, n / 6 + 1, FALSE);
     } else {
         int col1, col2;
@@ -3971,14 +4053,26 @@
         } else
             col1 = col2 = ((n % 6) <= n / 6);

-        DrawDie(gtk_widget_get_window(dice), sdd->TTachDice,
sdd->TTachPip, setSize,
+        DrawDie(cr, sdd->TTachDice, sdd->TTachPip, setSize,
                 0, 0, col1, n % 6 + 1, FALSE);
-        DrawDie(gtk_widget_get_window(dice), sdd->TTachDice,
sdd->TTachPip, setSize,
+        DrawDie(cr, sdd->TTachDice, sdd->TTachPip, setSize,
                 DIE_WIDTH * setSize, 0, col2, n / 6 + 1, FALSE);
     }
     return TRUE;
 }

+#if ! GTK_CHECK_VERSION(3,0,0)
+static gboolean
+setdice_widget_expose(GtkWidget * dice, GdkEventExpose *
UNUSED(event), SetDiceData * sdd)
+{
+    cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(dice));
+    setdice_widget_draw(dice, cr, sdd);
+    cairo_destroy(cr);
+
+    return TRUE;
+}
+#endif
+
 static gboolean
 dice_widget_press(GtkWidget * dice, GdkEvent * UNUSED(event),
BoardData * UNUSED(bd))
 {
@@ -4106,7 +4200,11 @@
             g_object_set_data(G_OBJECT(pwDice), "user_data",
GINT_TO_POINTER((y * 6 + x)));
             gtk_widget_set_size_request(pwDice, 2 * DIE_WIDTH *
setSize, DIE_HEIGHT * setSize);
             gtk_widget_add_events(pwDice, GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK | GDK_STRUCTURE_MASK);
+#if GTK_CHECK_VERSION(3,0,0)
+            g_signal_connect(G_OBJECT(pwDice), "draw",
G_CALLBACK(setdice_widget_draw), sdd);
+#else
             g_signal_connect(G_OBJECT(pwDice), "expose_event",
G_CALLBACK(setdice_widget_expose), sdd);
+#endif
             g_signal_connect(G_OBJECT(pwDice), "button_press_event",
G_CALLBACK(dice_widget_press), bd);
             gtk_table_attach_defaults(GTK_TABLE(pw), pwDice, x, x +
1, y, y + 1);
         }
Index: gtkboard.h
===================================================================
RCS file: /sources/gnubg/gnubg/gtkboard.h,v
retrieving revision 1.104
diff -u -r1.104 gtkboard.h
--- gtkboard.h 11 Jun 2016 15:46:31 -0000 1.104
+++ gtkboard.h 14 Aug 2016 10:56:08 -0000
@@ -28,6 +28,7 @@
 #include "gtkpanels.h"
 #include "common.h"
 #include "render.h"
+#include "gtklocdefs.h"

 #if defined(USE_BOARD3D)
 #include "types3d.h"
@@ -72,7 +73,7 @@
     GtkWidget *pipcountlabel0, *pipcountlabel1;
     GtkWidget *pwvboxcnt;

-    GdkPixmap *appmKey[2];
+    gtk_locdef_surface *appmKey[2];

     gboolean playing, computer_turn;
     gint drag_point, drag_colour, x_drag, y_drag, x_dice[2],
y_dice[2], drag_button, click_time, cube_use;      /* roll showing on
the off-board dice */
@@ -140,7 +141,7 @@
 extern GType board_get_type(void);
 extern GtkWidget *board_new(renderdata * prd);
 extern GtkWidget *board_cube_widget(Board * board);
-extern void DestroySetCube(GtkObject * po, GtkWidget * pw);
+extern void DestroySetCube(GObject * po, GtkWidget * pw);
 extern void Copy3dDiceColour(renderdata * prd);
 typedef enum { MT_STANDARD, MT_FIRSTMOVE, MT_EDIT } manualDiceType;
 extern GtkWidget *board_dice_widget(Board * board, manualDiceType mdt);
@@ -172,7 +173,7 @@
 extern void RollDice2d(BoardData * bd);
 extern void DestroyPanel(gnubgwindow window);
 extern void
-DrawDie(GdkDrawable * pd,
+DrawDie(cairo_t * cr,
         unsigned char *achDice[2], unsigned char *achPip[2],
         const int s, int x, int y, int fColour, int n, int alpha);

Index: gtkgame.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtkgame.c,v
retrieving revision 1.901
diff -u -r1.901 gtkgame.c
--- gtkgame.c 26 Jun 2016 18:53:49 -0000 1.901
+++ gtkgame.c 14 Aug 2016 10:56:08 -0000
@@ -1288,6 +1288,7 @@
         gtk_widget_hide(pwGameBox);
         gtk_paned_set_position(GTK_PANED(hpaned), allocation.width -
panelSize);

+#if ! GTK_CHECK_VERSION(3,0,0)
         {                       /* Hack to sort out widget positions
- may be removed if works in later version of gtk */
             GtkAllocation temp = allocation;
             temp.height++;
@@ -1295,6 +1296,7 @@
             temp.height--;
             gtk_widget_size_allocate(pwMain, &temp);
         }
+#endif
     } else {
         /* Need to hide these, as handle box seems to be buggy and
gets confused */
         gtk_widget_hide(gtk_widget_get_parent(pwMenuBar));
@@ -3709,7 +3711,7 @@
                                    TRUE);
     gtk_window_add_accel_group(GTK_WINDOW(pwMain), pagMain);
 #endif
-    gtk_box_pack_start(GTK_BOX(pwVbox), pwHandle =
gtk_handle_box_new(), FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(pwVbox), pwHandle =
gtk_locdef_handle_box_new(), FALSE, FALSE, 0);
 #if defined(USE_GTKUIMANAGER)
     pwMenuBar = gtk_ui_manager_get_widget(puim, "/MainMenu");
     gtk_container_add(GTK_CONTAINER(pwHandle), pwMenuBar);
@@ -3718,7 +3720,7 @@
     gtk_container_add(GTK_CONTAINER(pwHandle), pwMenuBar =
gtk_item_factory_get_widget(pif, "<main>"));
 #endif

-    gtk_box_pack_start(GTK_BOX(pwVbox), pwHandle =
gtk_handle_box_new(), FALSE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(pwVbox), pwHandle =
gtk_locdef_handle_box_new(), FALSE, TRUE, 0);
     gtk_container_add(GTK_CONTAINER(pwHandle), pwToolbar = ToolbarNew());

     gtk_box_pack_start(GTK_BOX(pwVbox), pwGameBox =
gtk_hbox_new(FALSE, 0), TRUE, TRUE, 0);
@@ -3807,7 +3809,9 @@
     gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pwProgress), " ");

     g_signal_connect(G_OBJECT(pwMain), "configure_event",
G_CALLBACK(configure_event), NULL);
+#if ! GTK_CHECK_VERSION(3,0,0)
     g_signal_connect(G_OBJECT(pwMain), "size-request",
G_CALLBACK(MainSize), NULL);
+#endif
     g_signal_connect(G_OBJECT(pwMain), "delete_event",
G_CALLBACK(main_delete), NULL);
     g_signal_connect(G_OBJECT(pwMain), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
 }
@@ -3849,6 +3853,24 @@
 #endif
 }

+static void
+ApplyDefaultCss(void)
+{
+    GtkCssProvider *cssProvider;
+    char *cssPath;
+
+    cssProvider = gtk_css_provider_new();
+    cssPath = BuildFilename("gnubg.css");
+    gtk_css_provider_load_from_path(cssProvider, cssPath, NULL);
+    
gtk_style_context_add_provider_for_screen(gtk_window_get_screen(GTK_WINDOW(pwMain)),
+                                              GTK_STYLE_PROVIDER(cssProvider),
+
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+    g_free(cssPath);
+    if (cssProvider)
+        g_object_unref(G_OBJECT(cssProvider));
+}
+
 extern void
 InitGTK(int *argc, char ***argv)
 {
@@ -3889,6 +3911,7 @@
     gnubg_set_default_icon();

     CreateMainWindow();
+    ApplyDefaultCss();

     /*Create string for handling messages from output* functions */
     output_str = g_string_new(NULL);
@@ -7139,7 +7162,7 @@
 }

 static gboolean
-CalibrationCancel(GtkObject * UNUSED(po), gpointer UNUSED(p))
+CalibrationCancel(GObject * UNUSED(po), gpointer UNUSED(p))
 {

     fInterrupt = TRUE;
Index: gtkgamelist.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtkgamelist.c,v
retrieving revision 1.46
diff -u -r1.46 gtkgamelist.c
--- gtkgamelist.c 13 Jul 2016 19:55:48 -0000 1.46
+++ gtkgamelist.c 14 Aug 2016 10:56:08 -0000
@@ -34,6 +34,7 @@
 #include "drawboard.h"
 #include "positionid.h"
 #include "gtkgame.h"
+#include "util.h"
 #if defined(USE_BOARD3D)
 #include "fun3d.h"
 #endif
@@ -88,6 +89,9 @@
     listOLD *pl;

     gtk_tree_view_get_cursor(tree_view, &path, &column);
+    if (!path)
+        return;
+
     pPlayer = g_object_get_data(G_OBJECT(column), "player");
     if (!pPlayer) {
         gtk_tree_path_free(path);
@@ -259,13 +263,46 @@
     g_object_unref(style);
 }

+static void
+CreateStyles(GtkWidget * widget, gpointer UNUSED(p))
+{
+    GtkStyle *ps;
+
+    gtk_widget_ensure_style(pwGameList);
+    GetStyleFromRCFile(&ps, "gnubg", gtk_widget_get_style(pwGameList));
+    ps->base[GTK_STATE_SELECTED] =
+        ps->base[GTK_STATE_ACTIVE] =
+        ps->base[GTK_STATE_NORMAL] =
gtk_widget_get_style(pwGameList)->base[GTK_STATE_NORMAL];
+    ps->fg[GTK_STATE_SELECTED] =
+        ps->fg[GTK_STATE_ACTIVE] = ps->fg[GTK_STATE_NORMAL] =
gtk_widget_get_style(pwGameList)->fg[GTK_STATE_NORMAL];
+    gtk_widget_set_style(pwGameList, ps);
+
+    psGameList = gtk_style_copy(ps);
+    psGameList->bg[GTK_STATE_SELECTED] =
psGameList->bg[GTK_STATE_NORMAL] = ps->base[GTK_STATE_NORMAL];
+
+    psCurrent = gtk_style_copy(psGameList);
+    psCurrent->bg[GTK_STATE_SELECTED] = psCurrent->bg[GTK_STATE_NORMAL] =
+        psCurrent->base[GTK_STATE_SELECTED] =
psCurrent->base[GTK_STATE_NORMAL] = psGameList->fg[GTK_STATE_NORMAL];
+    psCurrent->fg[GTK_STATE_SELECTED] =
psCurrent->fg[GTK_STATE_NORMAL] = psGameList->bg[GTK_STATE_NORMAL];
+
+    GetStyleFromRCFile(&psCubeErrors[SKILL_VERYBAD],
"gamelist-cube-blunder", psGameList);
+    GetStyleFromRCFile(&psCubeErrors[SKILL_BAD],
"gamelist-cube-error", psGameList);
+    GetStyleFromRCFile(&psCubeErrors[SKILL_DOUBTFUL],
"gamelist-cube-doubtful", psGameList);
+
+    GetStyleFromRCFile(&psChequerErrors[SKILL_VERYBAD],
"gamelist-chequer-blunder", psGameList);
+    GetStyleFromRCFile(&psChequerErrors[SKILL_BAD],
"gamelist-chequer-error", psGameList);
+    GetStyleFromRCFile(&psChequerErrors[SKILL_DOUBTFUL],
"gamelist-chequer-doubtful", psGameList);
+
+    GetStyleFromRCFile(&psLucky[LUCK_VERYBAD], "gamelist-luck-bad",
psGameList);
+    GetStyleFromRCFile(&psLucky[LUCK_VERYGOOD], "gamelist-luck-good",
psGameList);
+}
+
 extern GtkWidget *
 GL_Create(void)
 {
     static int player[] = {0, 1};
     GtkTreeViewColumn *column;
     GtkCellRenderer *renderer;
-    GtkStyle *ps;
     gint nMaxWidth;
     PangoRectangle logical_rect;
     PangoLayout *layout;
@@ -300,34 +337,6 @@

     GL_SetNames();

-    gtk_widget_ensure_style(pwGameList);
-    GetStyleFromRCFile(&ps, "gnubg", gtk_widget_get_style(pwGameList));
-    ps->base[GTK_STATE_SELECTED] =
-        ps->base[GTK_STATE_ACTIVE] =
-        ps->base[GTK_STATE_NORMAL] =
gtk_widget_get_style(pwGameList)->base[GTK_STATE_NORMAL];
-    ps->fg[GTK_STATE_SELECTED] =
-        ps->fg[GTK_STATE_ACTIVE] = ps->fg[GTK_STATE_NORMAL] =
gtk_widget_get_style(pwGameList)->fg[GTK_STATE_NORMAL];
-    gtk_widget_set_style(pwGameList, ps);
-
-    psGameList = gtk_style_copy(ps);
-    psGameList->bg[GTK_STATE_SELECTED] =
psGameList->bg[GTK_STATE_NORMAL] = ps->base[GTK_STATE_NORMAL];
-
-    psCurrent = gtk_style_copy(psGameList);
-    psCurrent->bg[GTK_STATE_SELECTED] = psCurrent->bg[GTK_STATE_NORMAL] =
-        psCurrent->base[GTK_STATE_SELECTED] =
psCurrent->base[GTK_STATE_NORMAL] = psGameList->fg[GTK_STATE_NORMAL];
-    psCurrent->fg[GTK_STATE_SELECTED] =
psCurrent->fg[GTK_STATE_NORMAL] = psGameList->bg[GTK_STATE_NORMAL];
-
-    GetStyleFromRCFile(&psCubeErrors[SKILL_VERYBAD],
"gamelist-cube-blunder", psGameList);
-    GetStyleFromRCFile(&psCubeErrors[SKILL_BAD],
"gamelist-cube-error", psGameList);
-    GetStyleFromRCFile(&psCubeErrors[SKILL_DOUBTFUL],
"gamelist-cube-doubtful", psGameList);
-
-    GetStyleFromRCFile(&psChequerErrors[SKILL_VERYBAD],
"gamelist-chequer-blunder", psGameList);
-    GetStyleFromRCFile(&psChequerErrors[SKILL_BAD],
"gamelist-chequer-error", psGameList);
-    GetStyleFromRCFile(&psChequerErrors[SKILL_DOUBTFUL],
"gamelist-chequer-doubtful", psGameList);
-
-    GetStyleFromRCFile(&psLucky[LUCK_VERYBAD], "gamelist-luck-bad",
psGameList);
-    GetStyleFromRCFile(&psLucky[LUCK_VERYGOOD], "gamelist-luck-good",
psGameList);
-
     layout = gtk_widget_create_pango_layout(pwGameList, "99");
     pango_layout_get_pixel_extents(layout, NULL, &logical_rect);
     g_object_unref(layout);
@@ -342,6 +351,12 @@
     
gtk_tree_view_column_set_fixed_width(gtk_tree_view_get_column(GTK_TREE_VIEW(pwGameList),
2), nMaxWidth - 22);

     g_signal_connect(G_OBJECT(pwGameList), "cursor-changed",
G_CALLBACK(GameListSelectRow), NULL);
+#if GTK_CHECK_VERSION(3,0,0)
+    /* Set up styles after the widget's base GtkStyleContext has been
created */
+    g_signal_connect(G_OBJECT(pwGameList), "style-updated",
G_CALLBACK(CreateStyles), NULL);
+#else
+    CreateStyles(pwGameList, NULL);
+#endif

     return pwGameList;
 }
@@ -542,9 +557,9 @@
             } while (iterValid && !lastRow && !apmr[fPlayer]);

             if (!iterValid) {
-                int *moveNum = gtk_tree_path_get_indices(path);
+                int *moveIndex = gtk_tree_path_get_indices(path);
                 gtk_list_store_append(plsGameList, &iter);
-                gtk_list_store_set(plsGameList, &iter,
GL_COL_MOVE_NUMBER, *moveNum, -1);
+                gtk_list_store_set(plsGameList, &iter,
GL_COL_MOVE_NUMBER, *moveIndex + 1, -1);
             }
         }
     }
Index: gtklocdefs.h
===================================================================
RCS file: /sources/gnubg/gnubg/gtklocdefs.h,v
retrieving revision 1.14
diff -u -r1.14 gtklocdefs.h
--- gtklocdefs.h 30 Apr 2016 14:12:38 -0000 1.14
+++ gtklocdefs.h 14 Aug 2016 10:56:08 -0000
@@ -30,6 +30,52 @@
 #if (USE_GTK)
 #include <gtk/gtk.h>

+#if GTK_CHECK_VERSION(3,0,0)
+typedef cairo_region_t gtk_locdef_region;
+typedef cairo_rectangle_int_t gtk_locdef_rectangle;
+typedef cairo_surface_t gtk_locdef_surface;
+typedef const GdkRectangle gtk_locdef_cell_area;
+#define gtk_locdef_surface_create(widget, width, height)
cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height)
+#define gtk_locdef_image_new_from_surface(s) gtk_image_new_from_surface(s)
+#define gtk_locdef_cairo_create_from_surface(s) cairo_create(s)
+#define gtk_locdef_create_rectangle(r) cairo_region_create_rectangle(r)
+#define gtk_locdef_union_rectangle(pr, r) cairo_region_union_rectangle(pr, r)
+#define gtk_locdef_region_destroy(pr) cairo_region_destroy(pr)
+#define gtk_locdef_handle_box_new() gtk_vbox_new(FALSE, 0)
+#define gtk_locdef_paint_vline(style, window, cr, state_type, area,
widget, detail, y1, y2, x) \
+    gtk_paint_vline(style, cr, state_type, widget, detail, y1, y2, x)
+#define gtk_locdef_paint_layout(style, window, cr, state_type,
use_text, area, widget, detail, x, y, layout) \
+    gtk_paint_layout (style, cr, state_type, use_text, widget,
detail, x, y, layout)
+#define gtk_locdef_paint_box(style, window, cr, state_type,
shadow_type, area, widget, detail, x, y, width, height) \
+    gtk_paint_box(style, cr, state_type, shadow_type, widget, detail,
x, y, width, height)
+#define gdk_colormap_alloc_color(cm, c, w, bm)
+#define gtk_statusbar_set_has_resize_grip(pw, grip)
+#define USE_GTKUIMANAGER 1
+
+#else // GTK2
+typedef GdkRegion gtk_locdef_region;
+typedef GdkRectangle gtk_locdef_rectangle;
+typedef GdkPixmap gtk_locdef_surface;
+typedef GdkRectangle gtk_locdef_cell_area;
+typedef void *GtkCssProvider;
+#define gtk_locdef_surface_create(widget, width, height)
gdk_pixmap_new(NULL, width, height,
gdk_visual_get_depth(gtk_widget_get_visual(widget)))
+#define gtk_locdef_image_new_from_surface(s) gtk_image_new_from_pixmap(s, NULL)
+#define gtk_locdef_cairo_create_from_surface(s) gdk_cairo_create(s)
+#define gtk_locdef_create_rectangle(r) gdk_region_rectangle(r)
+#define gtk_locdef_union_rectangle(pr, r) gdk_region_union_with_rect(pr, r)
+#define gtk_locdef_region_destroy(pr) gdk_region_destroy(pr)
+#define gtk_locdef_handle_box_new() gtk_handle_box_new()
+#define gtk_locdef_paint_vline(style, window, cr, state_type, area,
widget, detail, y1, y2, x) \
+    gtk_paint_vline(style, window, state_type, area, widget, detail, y1, y2, x)
+#define gtk_locdef_paint_layout(style, window, cr, state_type,
use_text, area, widget, detail, x, y, layout) \
+    gtk_paint_layout (style, window, state_type, use_text, area,
widget, detail, x, y, layout)
+#define gtk_locdef_paint_box(style, window, cr, state_type,
shadow_type, area, widget, detail, x, y, width, height) \
+    gtk_paint_box(style, window, state_type, shadow_type, area,
widget, detail, x, y, width, height)
+#define gtk_css_provider_new() NULL
+#define gtk_css_provider_load_from_path(pr, path, err)
+#define gtk_style_context_add_provider_for_screen(scr, pr, pri)
+#endif
+
 #if ! GTK_CHECK_VERSION(2,24,0)
 #define gtk_combo_box_text_new_with_entry gtk_combo_box_entry_new_text
 #define gtk_combo_box_text_new gtk_combo_box_new_text
Index: gtkmovelistctrl.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtkmovelistctrl.c,v
retrieving revision 1.27
diff -u -r1.27 gtkmovelistctrl.c
--- gtkmovelistctrl.c 11 Jun 2016 15:46:31 -0000 1.27
+++ gtkmovelistctrl.c 14 Aug 2016 10:56:08 -0000
@@ -40,15 +40,25 @@
 /* These functions are the heart of our custom cell renderer: */
 static void custom_cell_renderer_movelist_get_size(GtkCellRenderer * cell,
                                                    GtkWidget * widget,
-                                                   GdkRectangle * cell_area,
+
gtk_locdef_cell_area * cell_area,
                                                    gint * x_offset,
gint * y_offset, gint * width, gint * height);

 static void custom_cell_renderer_movelist_render(GtkCellRenderer * cell,
-                                                 GdkWindow * window,
+                                                 cairo_t * cr,
                                                  GtkWidget * widget,
-                                                 GdkRectangle *
background_area,
-                                                 GdkRectangle * cell_area,
-                                                 GdkRectangle *
expose_area, GtkCellRendererState flags);
+                                                 const GdkRectangle *
background_area,
+                                                 const GdkRectangle *
cell_area,
+                                                 GtkCellRendererState flags);
+
+#if ! GTK_CHECK_VERSION(3,0,0)
+static void custom_cell_renderer_movelist_render_window(GtkCellRenderer * cell,
+                                                        GdkWindow * window,
+                                                        GtkWidget * widget,
+                                                        GdkRectangle
* background_area,
+                                                        GdkRectangle
* cell_area,
+                                                        GdkRectangle
* expose_area, GtkCellRendererState flags);
+#endif
+
 static gpointer parent_class;

 /***************************************************************************
@@ -136,7 +146,11 @@
     /* Override the two crucial functions that are the heart
      *   of a cell renderer in the parent class */
     cell_class->get_size = custom_cell_renderer_movelist_get_size;
+#if GTK_CHECK_VERSION(3,0,0)
     cell_class->render = custom_cell_renderer_movelist_render;
+#else
+    cell_class->render = custom_cell_renderer_movelist_render_window;
+#endif

     /* Install our very own properties */
     g_object_class_install_property(object_class, 1,
@@ -236,7 +250,7 @@
 static void
 custom_cell_renderer_movelist_get_size(GtkCellRenderer * cell,
                                        GtkWidget * widget,
-                                       GdkRectangle * cell_area,
+                                       gtk_locdef_cell_area * cell_area,
                                        gint * x_offset, gint *
y_offset, gint * width, gint * height)
 {
     gint calc_width;
@@ -344,14 +358,14 @@

 static void
 custom_cell_renderer_movelist_render(GtkCellRenderer * cell,
-                                     GdkWindow * window,
+                                     cairo_t * cr,
                                      GtkWidget * widget,
-                                     GdkRectangle * background_area,
-                                     GdkRectangle * cell_area,
GdkRectangle * expose_area, GtkCellRendererState flags)
+                                     const GdkRectangle * background_area,
+                                     const GdkRectangle * cell_area,
+                                     GtkCellRendererState flags)
 {
     CustomCellRendererMovelist *cellprogress =
CUSTOM_CELL_RENDERER_MOVELIST(cell);
     PangoLayout *layout = gtk_widget_create_pango_layout(widget, NULL);
-    cairo_t *cr;
     hintdata *phd = g_object_get_data(G_OBJECT(widget), "hintdata");
     int i, x, y, selected;
     char buf[100];
@@ -365,12 +379,6 @@
     /*lint --e(641) */
     selected = (flags & GTK_CELL_RENDERER_SELECTED) &&
gtk_widget_has_focus(widget);

-    cr = gdk_cairo_create(window);
-    if (expose_area) {
-        cairo_rectangle(cr, expose_area->x, expose_area->y,
expose_area->width, expose_area->height);
-        cairo_clip(cr);
-    }
-
     if (phd->piHighlight && cellprogress->rank - 1 == *phd->piHighlight)
         pFontCol = &psHighlight->fg[GTK_STATE_SELECTED];
     else
@@ -492,5 +500,26 @@
     }

     g_object_unref(layout);
+}
+
+#if ! GTK_CHECK_VERSION(3,0,0)
+static void
+custom_cell_renderer_movelist_render_window(GtkCellRenderer * cell,
+                                            GdkWindow * window,
+                                            GtkWidget * widget,
+                                            GdkRectangle * background_area,
+                                            GdkRectangle * cell_area,
+                                            GdkRectangle *
expose_area, GtkCellRendererState flags)
+{
+    cairo_t *cr;
+
+    cr = gdk_cairo_create(window);
+    if (expose_area) {
+        cairo_rectangle(cr, expose_area->x, expose_area->y,
expose_area->width, expose_area->height);
+        cairo_clip(cr);
+    }
+
+    custom_cell_renderer_movelist_render(cell, cr, widget,
background_area, cell_area, flags);
     cairo_destroy(cr);
 }
+#endif
Index: gtkpanels.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtkpanels.c,v
retrieving revision 1.81
diff -u -r1.81 gtkpanels.c
--- gtkpanels.c 11 Jun 2016 15:46:31 -0000 1.81
+++ gtkpanels.c 14 Aug 2016 10:56:08 -0000
@@ -810,6 +810,7 @@
     gtk_container_add(GTK_CONTAINER(pvbox), psw);
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(psw),
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);

+    gtk_widget_set_size_request(psw, -1, 150);
     gtk_container_add(GTK_CONTAINER(psw), GL_Create());

     if (!woPanel[WINDOW_GAME].docked) {
Index: gtktempmap.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtktempmap.c,v
retrieving revision 1.55
diff -u -r1.55 gtktempmap.c
--- gtktempmap.c 11 Jun 2016 15:46:31 -0000 1.55
+++ gtktempmap.c 14 Aug 2016 10:56:08 -0000
@@ -187,6 +187,11 @@
 {

     GtkStyle *ps = gtk_style_copy(gtk_widget_get_style(pw));
+    double *gbval;
+
+    gbval = g_malloc(sizeof(*gbval));
+    *gbval = 1.0 - r;
+    g_object_set_data_full(G_OBJECT(pw), "gbval", gbval, g_free);

     ps->bg[GTK_STATE_NORMAL].red = 0xFFFF;
     ps->bg[GTK_STATE_NORMAL].blue = ps->bg[GTK_STATE_NORMAL].green =
(guint16) ((1.0f - r) * 0xFFFF);
@@ -302,8 +307,8 @@
     gtk_label_set_text(GTK_LABEL(ptmw->apwGauge[!ptmw->fInvert]),
GetEquityString(rMax, &ci, ptmw->fInvert));
 }

-static void
-ExposeQuadrant(GtkWidget * pw, GdkEventExpose * UNUSED(pev),
tempmapwidget * ptmw)
+static gboolean
+DrawQuadrant(GtkWidget * pw, cairo_t * cr, tempmapwidget * ptmw)
 {
     int *pi = (int *) g_object_get_data(G_OBJECT(pw), "user_data");
     int i = 0;
@@ -319,10 +324,26 @@
     GtkAllocation allocation;
     gtk_widget_get_allocation(pw, &allocation);

+#if GTK_CHECK_VERSION(3,0,0)
+    {
+        double *gbval = g_object_get_data(G_OBJECT(pw), "gbval");
+        guint width, height;
+
+        width = gtk_widget_get_allocated_width(pw);
+        height = gtk_widget_get_allocated_height(pw);
+
+        cairo_rectangle(cr, 0, 0, width, height);
+        cairo_set_source_rgb(cr, 1.0, *gbval, *gbval);
+        cairo_fill(cr);
+
+        gtk_render_frame(gtk_widget_get_style_context(pw), cr, 0, 0,
width, height);
+    }
+#else
     gtk_paint_box(gtk_widget_get_style(pw),
gtk_widget_get_window(pw), GTK_STATE_NORMAL,
                   GTK_SHADOW_IN, NULL, NULL, NULL, 0, 0,
allocation.width, allocation.height);
+#endif
     if (pi == NULL)
-        return;
+        return TRUE;

     if (*pi >= 0) {
         i = (*pi % 100) / 6;
@@ -361,7 +382,7 @@

     if (str->len == 0) {
         g_string_free(str, TRUE);
-        return;
+        return TRUE;
     }

     pch = str->str;
@@ -381,8 +402,8 @@
         if (tmp)
             *tmp = 0;
         pango_layout_set_text(layout, pch, -1);
-        gtk_paint_layout(gtk_widget_get_style(pw), gtk_widget_get_window(pw),
-                         GTK_STATE_NORMAL, TRUE, NULL, pw, NULL, 2,
(int) y, layout);
+        gtk_locdef_paint_layout(gtk_widget_get_style(pw),
gtk_widget_get_window(pw), cr,
+                                GTK_STATE_NORMAL, TRUE, NULL, pw,
NULL, 2, (int) y, layout);
         if (tmp) {
              pch = tmp + 1;
              y += (allocation.height - 4) / 5.0f;
@@ -391,10 +412,22 @@

     g_object_unref(layout);
     g_string_free(str, TRUE);
+
+    return TRUE;
 }

+#if ! GTK_CHECK_VERSION(3,0,0)
 static void
-ExposeDie(GtkWidget * pw, GdkEventExpose * pev, tempmapwidget * ptmw)
+ExposeQuadrant(GtkWidget * pw, GdkEventExpose * UNUSED(pev),
tempmapwidget * ptmw)
+{
+    cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(pw));
+    DrawQuadrant(pw, cr, ptmw);
+    cairo_destroy(cr);
+}
+#endif
+
+static void
+ExposeDieArea(GtkWidget * pw, cairo_t * cr, gint area_x, gint area_y,
gint area_width, gint area_height, tempmapwidget * ptmw)
 {
     int *pi = (int *) g_object_get_data(G_OBJECT(pw), "user_data");
     int x, y;
@@ -433,11 +466,32 @@
     x = (allocation.width - ptmw->nSizeDie * 7) / 2;
     y = (allocation.height - ptmw->nSizeDie * 7) / 2;

-    gdk_window_clear_area(gtk_widget_get_window(pw), pev->area.x,
pev->area.y, pev->area.width, pev->area.height);
-    DrawDie(gtk_widget_get_window(pw), ptmw->achDice, ptmw->achPips,
ptmw->nSizeDie,
+    cairo_save(cr);
+    cairo_rectangle(cr, area_x, area_y, area_width, area_height);
+    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
+    cairo_fill(cr);
+    cairo_restore(cr);
+    DrawDie(cr, ptmw->achDice, ptmw->achPips, ptmw->nSizeDie,
             x, y, ptmw->atm[0].pms->fMove, *pi + 1, FALSE);
 }

+#if GTK_CHECK_VERSION(3,0,0)
+static gboolean
+ExposeDie(GtkWidget * pw, cairo_t * cr, tempmapwidget * ptmw)
+{
+    ExposeDieArea(pw, cr, 3, 3, gtk_widget_get_allocated_width(pw) -
6, gtk_widget_get_allocated_height(pw) - 6, ptmw);
+    return TRUE;
+}
+#else
+static void
+ExposeDie(GtkWidget * pw, GdkEventExpose * pev, tempmapwidget * ptmw)
+{
+    cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(pw));
+    ExposeDieArea(pw, cr, pev->area.x, pev->area.y, pev->area.width,
pev->area.height, ptmw);
+    cairo_destroy(cr);
+}
+#endif
+
 static void
 TempMapPlyToggled(GtkWidget * pw, tempmapwidget * ptmw)
 {
@@ -601,7 +655,12 @@


g_object_set_data_full(G_OBJECT(ptm->aapwDA[i][j]), "user_data", pi,
g_free);

+#if GTK_CHECK_VERSION(3,0,0)
+
gtk_style_context_add_class(gtk_widget_get_style_context(ptm->aapwDA[i][j]),
"gnubg-temp-map-quadrant");
+                    g_signal_connect(G_OBJECT(ptm->aapwDA[i][j]),
"draw", G_CALLBACK(DrawQuadrant), ptmw);
+#else
                     g_signal_connect(G_OBJECT(ptm->aapwDA[i][j]),
"expose_event", G_CALLBACK(ExposeQuadrant), ptmw);
+#endif

                 }

@@ -617,7 +676,11 @@

                 g_object_set_data_full(G_OBJECT(pw), "user_data", pi, g_free);

+#if GTK_CHECK_VERSION(3,0,0)
+                g_signal_connect(G_OBJECT(pw), "draw",
G_CALLBACK(ExposeDie), ptmw);
+#else
                 g_signal_connect(G_OBJECT(pw), "expose_event",
G_CALLBACK(ExposeDie), ptmw);
+#endif
                 /* die */

                 pw = gtk_drawing_area_new();
@@ -630,7 +693,11 @@

                 g_object_set_data_full(G_OBJECT(pw), "user_data", pi, g_free);

+#if GTK_CHECK_VERSION(3,0,0)
+                g_signal_connect(G_OBJECT(pw), "draw",
G_CALLBACK(ExposeDie), ptmw);
+#else
                 g_signal_connect(G_OBJECT(pw), "expose_event",
G_CALLBACK(ExposeDie), ptmw);
+#endif

             }

@@ -651,7 +718,12 @@

             g_object_set_data_full(G_OBJECT(ptm->pwAverage),
"user_data", pi, g_free);

+#if GTK_CHECK_VERSION(3,0,0)
+            
gtk_style_context_add_class(gtk_widget_get_style_context(ptm->pwAverage),
"gnubg-temp-map-quadrant");
+            g_signal_connect(G_OBJECT(ptm->pwAverage), "draw",
G_CALLBACK(DrawQuadrant), ptmw);
+#else
             g_signal_connect(G_OBJECT(ptm->pwAverage),
"expose_event", G_CALLBACK(ExposeQuadrant), ptmw);
+#endif

         }

@@ -673,7 +745,12 @@

         g_object_set_data(G_OBJECT(pw), "user_data", NULL);

+#if GTK_CHECK_VERSION(3,0,0)
+        gtk_style_context_add_class(gtk_widget_get_style_context(pw),
"gnubg-temp-map-quadrant");
+        g_signal_connect(G_OBJECT(pw), "draw", G_CALLBACK(DrawQuadrant), NULL);
+#else
         g_signal_connect(G_OBJECT(pw), "expose_event",
G_CALLBACK(ExposeQuadrant), NULL);
+#endif

         UpdateStyle(pw, 1.0f * i / 15.0f);

Index: gtktheory.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtktheory.c,v
retrieving revision 1.62
diff -u -r1.62 gtktheory.c
--- gtktheory.c 11 May 2016 21:33:08 -0000 1.62
+++ gtktheory.c 14 Aug 2016 10:56:08 -0000
@@ -463,8 +463,8 @@

 }

-static void
-GraphExpose(GtkWidget * pwGraph, GdkEventExpose * UNUSED(pev),
theorywidget * ptw)
+static gboolean
+GraphDraw(GtkWidget * pwGraph, cairo_t * cr, theorywidget * ptw)
 {

     GtkAllocation allocation;
@@ -489,8 +489,8 @@
     iPlayer = pwGraph == ptw->apwGraph[1];

     for (i = 0; i <= 20; i++) {
-        gtk_paint_vline(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph), GTK_STATE_NORMAL,
-                        NULL, pwGraph, "tick", y - 1, i & 3 ? y - 3 :
y - 5, x + cx * i / 20);
+        gtk_locdef_paint_vline(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph), cr, GTK_STATE_NORMAL,
+                               NULL, pwGraph, "tick", y - 1, i & 3 ?
y - 3 : y - 5, x + cx * i / 20);

         if (!(i & 3)) {
             int width;
@@ -498,9 +498,9 @@
             sprintf(sz, "%d", i * 5);
             pango_layout_set_text(layout, sz, -1);
             pango_layout_get_pixel_size(layout, &width, &height);
-            gtk_paint_layout(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph),
-                             GTK_STATE_NORMAL, TRUE, NULL, pwGraph, "label",
-                             x + cx * i / 20 - width / 2 /* FIXME */
, y - height - 1, layout);
+            gtk_locdef_paint_layout(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph), cr,
+                                    GTK_STATE_NORMAL, TRUE, NULL,
pwGraph, "label",
+                                    x + cx * i / 20 - width / 2 /*
FIXME */ , y - height - 1, layout);
         }
     }
     g_object_unref(layout);
@@ -508,23 +508,34 @@
     for (i = 0; i < 3; i++)
         ax[i] = (int) (x + cx * ptw->aar[iPlayer][i]);

-    gtk_paint_box(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph), GTK_STATE_NORMAL,
-                  GTK_SHADOW_IN, NULL, pwGraph, "doubling-window", x,
12, cx, cy);
+    gtk_locdef_paint_box(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph), cr, GTK_STATE_NORMAL,
+                         GTK_SHADOW_IN, NULL, pwGraph,
"doubling-window", x, 12, cx, cy);

     /* FIXME it's horrible to abuse the "state" parameters like this */
     if (ptw->aar[iPlayer][1] > ptw->aar[iPlayer][0])
-        gtk_paint_box(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph),
-                      GTK_STATE_ACTIVE, GTK_SHADOW_OUT, NULL,
pwGraph, "take", ax[0], 13, ax[1] - ax[0], cy - 2);
+        gtk_locdef_paint_box(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph), cr,
+                             GTK_STATE_ACTIVE, GTK_SHADOW_OUT, NULL,
pwGraph, "take", ax[0], 13, ax[1] - ax[0], cy - 2);

     if (ptw->aar[iPlayer][2] > ptw->aar[iPlayer][1])
-        gtk_paint_box(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph),
-                      GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, NULL,
pwGraph, "drop", ax[1], 13, ax[2] - ax[1], cy - 2);
+        gtk_locdef_paint_box(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph), cr,
+                             GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
NULL, pwGraph, "drop", ax[1], 13, ax[2] - ax[1], cy - 2);

     if (ptw->aar[iPlayer][2] < 1.0)
-        gtk_paint_box(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph),
-                      GTK_STATE_SELECTED, GTK_SHADOW_OUT, NULL,
pwGraph, "too-good", ax[2], 13, x + cx - ax[2], cy - 2);
+        gtk_locdef_paint_box(gtk_widget_get_style(pwGraph),
gtk_widget_get_window(pwGraph), cr,
+                             GTK_STATE_SELECTED, GTK_SHADOW_OUT,
NULL, pwGraph, "too-good", ax[2], 13, x + cx - ax[2], cy - 2);
 }

+#if ! GTK_CHECK_VERSION(3,0,0)
+static void
+GraphExpose(GtkWidget * pwGraph, GdkEventExpose * UNUSED(pev),
theorywidget * ptw)
+{
+    cairo_t *cr;
+
+    cr = gdk_cairo_create(gtk_widget_get_window(pwGraph));
+    GraphDraw(pwGraph, cr, ptw);
+    cairo_destroy(cr);
+}
+#endif

 static void
 PlyClicked(GtkWidget * pw, theorywidget * ptw)
@@ -832,7 +843,11 @@
         gtk_widget_set_name(ptw->apwGraph[i], "gnubg-doubling-window-graph");
         gtk_container_set_border_width(GTK_CONTAINER(pwAlign), 4);
         gtk_widget_set_size_request(ptw->apwGraph[i], -1, 48);
+#if GTK_CHECK_VERSION(3,0,0)
+        g_signal_connect(G_OBJECT(ptw->apwGraph[i]), "draw",
G_CALLBACK(GraphDraw), ptw);
+#else
         g_signal_connect(G_OBJECT(ptw->apwGraph[i]), "expose_event",
G_CALLBACK(GraphExpose), ptw);
+#endif
     }

     /* gammon prices */
Index: gtktoolbar.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtktoolbar.c,v
retrieving revision 1.74
diff -u -r1.74 gtktoolbar.c
--- gtktoolbar.c 14 Oct 2015 22:30:27 -0000 1.74
+++ gtktoolbar.c 14 Aug 2016 10:56:08 -0000
@@ -368,6 +368,7 @@

     pwToolbar = gtk_ui_manager_get_widget(puim, "/MainToolBar");
     g_object_set_data_full(G_OBJECT(pwToolbar), "toolbarwidget", ptw, g_free);
+    gtk_toolbar_set_style(GTK_TOOLBAR(pwToolbar), GTK_TOOLBAR_BOTH);

     ptw->pwNew = gtk_ui_manager_get_widget(puim, "/MainToolBar/New");
     gtk_tool_item_set_homogeneous(GTK_TOOL_ITEM(ptw->pwNew), TRUE);
Index: gtkwindows.c
===================================================================
RCS file: /sources/gnubg/gnubg/gtkwindows.c,v
retrieving revision 1.53
diff -u -r1.53 gtkwindows.c
--- gtkwindows.c 7 Sep 2014 19:24:06 -0000 1.53
+++ gtkwindows.c 14 Aug 2016 10:56:08 -0000
@@ -174,7 +174,7 @@
     gtk_window_add_accel_group(GTK_WINDOW(pwDialog), pag);

     pwHbox = gtk_hbox_new(FALSE, 0);
-    
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(pwDialog))),
pwHbox);
+    
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(pwDialog))),
pwHbox, TRUE, TRUE, 0);

     if (dt != DT_CUSTOM) {
         pwPixmap = gtk_image_new_from_stock(aszStockItem[dt],
GTK_ICON_SIZE_DIALOG);
@@ -199,7 +199,7 @@
         gtk_dialog_set_default_response(GTK_DIALOG(pwDialog),
OkButton ? GTK_RESPONSE_OK : GTK_RESPONSE_CLOSE);

         if (!fQuestion)
-            gtk_widget_add_accelerator(DialogArea(pwDialog, DA_OK),
"clicked", pag, GDK_Escape, 0, 0);
+            gtk_widget_add_accelerator(DialogArea(pwDialog, DA_OK),
"clicked", pag, GDK_KEY_Escape, 0, 0);
     }

     if (fQuestion)
Index: progress.c
===================================================================
RCS file: /sources/gnubg/gnubg/progress.c,v
retrieving revision 1.75
diff -u -r1.75 progress.c
--- progress.c 25 Jan 2016 21:45:09 -0000 1.75
+++ progress.c 14 Aug 2016 10:56:08 -0000
@@ -636,7 +636,7 @@
 }

 static void
-RolloutCancel(GtkObject * UNUSED(po), rolloutprogress * prp)
+RolloutCancel(GObject * UNUSED(po), rolloutprogress * prp)
 {
     pwGrab = pwOldGrab;
     prp->pwRolloutDialog = NULL;
@@ -647,7 +647,7 @@
 }

 static void
-RolloutStop(GtkObject * UNUSED(po), rolloutprogress * prp)
+RolloutStop(GObject * UNUSED(po), rolloutprogress * prp)
 {
     fInterrupt = TRUE;
     prp->stopped = -1;
@@ -655,7 +655,7 @@


 static void
-RolloutStopAll(GtkObject * UNUSED(po), rolloutprogress * prp)
+RolloutStopAll(GObject * UNUSED(po), rolloutprogress * prp)
 {
     fInterrupt = TRUE;
     prp->stopped = -2;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]