tRestore GtkTable for GTK2 builds - 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 696618c1aea3a0e97fbb00051dfdaca143df93da
 (DIR) parent 716bcc4acfaee8c200ef0b2edf178f5ad3efd3ce
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Thu, 31 Dec 2020 17:58:22 -0800
       
       Restore GtkTable for GTK2 builds
       
       Provide an API similar to that of the 'real'
       GtkGrid, which we can implement using GtkTable
       when using GTK2. This should allow us to build
       for GTK3 using GtkGrid, or GTK2 using GtkTable,
       using the same codebase.
       
       Diffstat:
         M src/gtkport/gtkport.c               |      41 +++++++++++++++++++++++++++++++
         M src/gtkport/gtkport.h               |      53 ++++++++++++++++++++++---------
         M src/gui_client/gtk_client.c         |     117 +++++++++++++------------------
         M src/gui_client/newgamedia.c         |      24 ++++++++++--------------
         M src/gui_client/optdialog.c          |      90 +++++++++++++-------------------
       
       5 files changed, 172 insertions(+), 153 deletions(-)
       ---
 (DIR) diff --git a/src/gtkport/gtkport.c b/src/gtkport/gtkport.c
       t@@ -5494,6 +5494,47 @@ gchar *GtkGetFile(const GtkWidget *parent, const gchar *oldname,
          return ret;
        }
        
       +#if !CYGWIN && \
       +  (GTK_MAJOR_VERSION > 3 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 4))
       +/* GtkGrid does not take a size, unlike GtkTable */
       +GtkWidget *dp_gtk_grid_new(guint rows, guint cols, gboolean homogeneous)
       +{
       +  GtkWidget *grid = gtk_grid_new();
       +  if (homogeneous) {
       +    gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
       +    gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
       +  }
       +  return grid;
       +}
       +
       +void dp_gtk_grid_attach(GtkGrid *grid, GtkWidget *child,
       +                        gint left, gint top,
       +                        gint width, gint height, gboolean expand)
       +{
       +  gtk_grid_attach(grid, child, left, top, width, height);
       +  if (expand) {
       +    gtk_widget_set_hexpand(child, TRUE);
       +  }
       +}
       +#else
       +/* Implementation for older GTK or Win32, using GtkTable */
       +GtkWidget *dp_gtk_grid_new(guint rows, guint columns, gboolean homogeneous)
       +{
       +  GtkWidget *table = gtk_table_new(rows, columns, homogeneous);
       +  return table;
       +}
       +
       +void dp_gtk_grid_attach(GtkGrid *grid, GtkWidget *child,
       +                        gint left, gint top,
       +                        gint width, gint height, gboolean expand)
       +{
       +  gtk_table_attach(grid, child, left, left + width, top, top + height,
       +                   expand ? (GTK_EXPAND | GTK_FILL) : GTK_SHRINK,
       +                   expand ? (GTK_EXPAND | GTK_FILL) : GTK_SHRINK, 0, 0);
       +}
       +#endif
       +
       +
        #endif /* CYGWIN */
        
        #if CYGWIN
 (DIR) diff --git a/src/gtkport/gtkport.h b/src/gtkport/gtkport.h
       t@@ -381,8 +381,24 @@ void gtk_frame_set_shadow_type(GtkFrame *frame, GtkShadowType type);
        GtkWidget *gtk_text_new(GtkAdjustment *hadj, GtkAdjustment *vadj);
        GtkWidget *gtk_entry_new();
        void gtk_entry_set_visibility(GtkEntry *entry, gboolean visible);
       -GtkWidget *gtk_table_new(guint rows, guint cols, gboolean homogeneous);
       -void gtk_table_resize(GtkTable *table, guint rows, guint cols);
       +
       +/* GtkTable implementation */
       +GtkWidget *dp_gtk_table_new(guint rows, guint cols, gboolean homogeneous);
       +void dp_gtk_table_resize(GtkTable *table, guint rows, guint cols);
       +void dp_gtk_table_attach(GtkTable *table, GtkWidget *widget,
       +                         guint left_attach, guint right_attach,
       +                         guint top_attach, guint bottom_attach,
       +                         GtkAttachOptions xoptions, GtkAttachOptions yoptions,
       +                         guint xpadding, guint ypadding);
       +void dp_gtk_table_attach_defaults(GtkTable *table, GtkWidget *widget,
       +                                  guint left_attach, guint right_attach,
       +                                  guint top_attach, guint bottom_attach);
       +void dp_gtk_table_set_row_spacing(GtkTable *table, guint row, guint spacing);
       +void dp_gtk_table_set_col_spacing(GtkTable *table, guint column,
       +                                  guint spacing);
       +void dp_gtk_table_set_row_spacings(GtkTable *table, guint spacing);
       +void dp_gtk_table_set_col_spacings(GtkTable *table, guint spacing);
       +
        GSList *gtk_radio_button_get_group(GtkRadioButton *radio_button);
        void gtk_editable_insert_text(GtkEditable *editable, const gchar *new_text,
                                      gint new_text_length, gint *position);
       t@@ -401,19 +417,6 @@ void gtk_text_freeze(GtkText *text);
        void gtk_text_thaw(GtkText *text);
        GtkTextBuffer *gtk_text_view_get_buffer(GtkText *text);
        void gtk_text_buffer_create_tag(GtkTextBuffer *buffer, const gchar *name, ...);
       -void gtk_table_attach(GtkTable *table, GtkWidget *widget,
       -                      guint left_attach, guint right_attach,
       -                      guint top_attach, guint bottom_attach,
       -                      GtkAttachOptions xoptions, GtkAttachOptions yoptions,
       -                      guint xpadding, guint ypadding);
       -void gtk_table_attach_defaults(GtkTable *table, GtkWidget *widget,
       -                               guint left_attach, guint right_attach,
       -                               guint top_attach, guint bottom_attach);
       -void gtk_table_set_row_spacing(GtkTable *table, guint row, guint spacing);
       -void gtk_table_set_col_spacing(GtkTable *table, guint column,
       -                               guint spacing);
       -void gtk_table_set_row_spacings(GtkTable *table, guint spacing);
       -void gtk_table_set_col_spacings(GtkTable *table, guint spacing);
        void gtk_box_pack_start(GtkBox *box, GtkWidget *child, gboolean Expand,
                                gboolean Fill, gint Padding);
        void gtk_toggle_button_toggled(GtkToggleButton *toggle_button);
       t@@ -645,4 +648,24 @@ gchar *GtkGetFile(const GtkWidget *parent, const gchar *oldname,
        void DisplayHTML(GtkWidget *parent, const gchar *bin, const gchar *target);
        GtkWidget *gtk_scrolled_tree_view_new(GtkWidget **pack_widg);
        
       +/* GtkTable is used in GTK2 (and early GTK3) but GtkGrid is used in later
       + * GTK3 and GTK4. Provide an interface similar to GtkGrid that internally
       + * uses either GtkTable or GtkGrid. Use a dp_ prefix to avoid clashes with
       + * the real GtkTable */
       +#if CYGWIN || GTK_MAJOR_VERSION < 3 \
       +    || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 4)
       +#define GTK_GRID GTK_TABLE
       +typedef GtkTable GtkGrid;
       +#define gtk_grid_set_row_spacing(grid, spacing) gtk_table_set_row_spacings(grid, spacing)
       +#define gtk_grid_set_column_spacing(grid, spacing) gtk_table_set_col_spacings(grid, spacing)
       +#define dp_gtk_grid_resize(grid, rows, cols) gtk_table_resize(grid, rows, cols)
       +#else
       +#define dp_gtk_grid_resize(grid, rows, cols) {}
       +#endif
       +
       +GtkWidget *dp_gtk_grid_new(guint rows, guint columns, gboolean homogeneous);
       +void dp_gtk_grid_attach(GtkGrid *grid, GtkWidget *child,
       +                        gint left, gint top,
       +                        gint width, gint height, gboolean expand);
       +
        #endif /* __GTKPORT_H__ */
 (DIR) diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c
       t@@ -635,7 +635,7 @@ void PrepareHighScoreDialog(void)
                                       GTK_WINDOW(ClientData.window));
        
          HiScoreDialog.vbox = vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 7);
       -  HiScoreDialog.grid = grid = gtk_grid_new();
       +  HiScoreDialog.grid = grid = dp_gtk_grid_new(NUMHISCORE, 4, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 30);
        
       t@@ -685,8 +685,7 @@ void AddScoreToDialog(char *Data)
          }
          label = gtk_label_new(spl1[0]);
          gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
       -  gtk_grid_attach(GTK_GRID(HiScoreDialog.grid), label, 0, index, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(HiScoreDialog.grid), label, 0, index, 1, 1, TRUE);
          if (bold) {
            GdkColor color;
        
       t@@ -713,8 +712,7 @@ void AddScoreToDialog(char *Data)
          }
          label = gtk_label_new(spl2[0]);
          gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
       -  gtk_grid_attach(GTK_GRID(HiScoreDialog.grid), label, 1, index, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(HiScoreDialog.grid), label, 1, index, 1, 1, TRUE);
          if (bold) {
            gtk_widget_set_style(label, style);
          }
       t@@ -735,8 +733,8 @@ void AddScoreToDialog(char *Data)
          if (slen > 8 && spl2[1][slen - 1] == ')' && spl2[1][slen - 8] == '(') {
            label = gtk_label_new(&spl2[1][slen - 8]);
            gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
       -    gtk_grid_attach(GTK_GRID(HiScoreDialog.grid), label, 3, index, 1, 1);
       -    gtk_widget_set_hexpand(label, TRUE);
       +    dp_gtk_grid_attach(GTK_GRID(HiScoreDialog.grid), label, 3, index, 1, 1,
       +                       TRUE);
            if (bold) {
              gtk_widget_set_style(label, style);
            }
       t@@ -748,8 +746,7 @@ void AddScoreToDialog(char *Data)
          g_strchomp(spl2[1]);
          label = gtk_label_new(spl2[1]);
          gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
       -  gtk_grid_attach(GTK_GRID(HiScoreDialog.grid), label, 2, index, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(HiScoreDialog.grid), label, 2, index, 1, 1, TRUE);
          if (bold) {
            gtk_widget_set_style(label, style);
          }
       t@@ -923,13 +920,12 @@ static void CreateFightDialog(void)
        
          vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 7);
        
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(2, 4, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 7);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 10);
        
          hsep = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
       -  gtk_grid_attach(GTK_GRID(grid), hsep, 0, 1, 3, 1);
       -  gtk_widget_set_hexpand(hsep, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), hsep, 0, 1, 3, 1, TRUE);
          gtk_widget_show_all(grid);
          gtk_box_pack_start(GTK_BOX(vbox), grid, FALSE, FALSE, 0);
          g_object_set_data(G_OBJECT(dialog), "grid", grid);
       t@@ -1025,6 +1021,7 @@ static void UpdateCombatant(gchar *DefendName, int DefendBitches,
              g_array_set_size(combatants, i + 1);
              compt = &g_array_index(combatants, struct combatant, i);
        
       +      dp_gtk_grid_resize(GTK_GRID(grid), i + 2, 4);
              RowIndex = i + 1;
            }
          } else {
       t@@ -1063,16 +1060,18 @@ static void UpdateCombatant(gchar *DefendName, int DefendBitches,
            /* Display of the current player's name during combat */
            compt->name = gtk_label_new(DefendName[0] ? DefendName : _("You"));
        
       -    gtk_grid_attach(GTK_GRID(grid), compt->name, 0, RowIndex, 1, 1);
       +    dp_gtk_grid_attach(GTK_GRID(grid), compt->name, 0, RowIndex, 1, 1, FALSE);
            compt->bitches = gtk_label_new(DefendBitches >= 0 ? BitchText : "");
       -    gtk_grid_attach(GTK_GRID(grid), compt->bitches, 1, RowIndex, 1, 1);
       +    dp_gtk_grid_attach(GTK_GRID(grid), compt->bitches, 1, RowIndex, 1, 1,
       +                       FALSE);
            compt->healthprog = gtk_progress_bar_new();
            gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(compt->healthprog),
                                          ProgPercent);
       -    gtk_grid_attach(GTK_GRID(grid), compt->healthprog, 2, RowIndex, 1, 1);
       -    gtk_widget_set_hexpand(compt->healthprog, TRUE);
       +    dp_gtk_grid_attach(GTK_GRID(grid), compt->healthprog, 2, RowIndex, 1, 1,
       +                       TRUE);
            compt->healthlabel = gtk_label_new(HealthText);
       -    gtk_grid_attach(GTK_GRID(grid), compt->healthlabel, 3, RowIndex, 1, 1);
       +    dp_gtk_grid_attach(GTK_GRID(grid), compt->healthlabel, 3, RowIndex, 1, 1,
       +                       FALSE);
            gtk_widget_show(compt->name);
            gtk_widget_show(compt->bitches);
            gtk_widget_show(compt->healthprog);
       t@@ -1495,9 +1494,7 @@ void Jet(GtkWidget *parent)
            row++;
          }
        
       -  grid = gtk_grid_new();
       -  gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
       -  gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
       +  grid = dp_gtk_grid_new(row, col, TRUE);
        
          for (i = 0; i < NumLocation; i++) {
            if (i < 9) {
       t@@ -1534,7 +1531,7 @@ void Jet(GtkWidget *parent)
            g_object_set_data(G_OBJECT(button), "dialog", dialog);
            g_signal_connect(G_OBJECT(button), "clicked",
                             G_CALLBACK(JetCallback), GINT_TO_POINTER(i));
       -    gtk_grid_attach(GTK_GRID(grid), button, col, row, 1, 1);
       +    dp_gtk_grid_attach(GTK_GRID(grid), button, col, row, 1, 1, TRUE);
          }
          gtk_box_pack_start(GTK_BOX(vbox), grid, TRUE, TRUE, 0);
        
       t@@ -2089,77 +2086,61 @@ GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status)
        {
          GtkWidget *grid, *label;
        
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(3, 6, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 3);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 3);
          gtk_container_set_border_width(GTK_CONTAINER(grid), 3);
        
          label = Status->Location = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 2, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 2, 1, TRUE);
        
          label = Status->Date = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 2, 0, 2, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 2, 0, 2, 1, TRUE);
        
          /* Available space label in GTK+ client status display */
          label = Status->SpaceName = gtk_label_new(_("Space"));
        
       -  gtk_grid_attach(GTK_GRID(grid), label, 4, 0, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 4, 0, 1, 1, TRUE);
          label = Status->SpaceValue = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 5, 0, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 5, 0, 1, 1, TRUE);
        
          /* Player's cash label in GTK+ client status display */
          label = Status->CashName = gtk_label_new(_("Cash"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1, TRUE);
        
          label = Status->CashValue = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 1, 1, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 1, 1, 1, 1, TRUE);
        
          /* Player's debt label in GTK+ client status display */
          label = Status->DebtName = gtk_label_new(_("Debt"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 2, 1, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 2, 1, 1, 1, TRUE);
        
          label = Status->DebtValue = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 3, 1, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 3, 1, 1, 1, TRUE);
        
          /* Player's bank balance label in GTK+ client status display */
          label = Status->BankName = gtk_label_new(_("Bank"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 4, 1, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 4, 1, 1, 1, TRUE);
        
          label = Status->BankValue = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 5, 1, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 5, 1, 1, 1, TRUE);
        
          label = Status->GunsName = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1, TRUE);
          label = Status->GunsValue = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 1, 2, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 1, 2, 1, 1, TRUE);
        
          label = Status->BitchesName = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 2, 2, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 2, 2, 1, 1, TRUE);
          label = Status->BitchesValue = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 3, 2, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 3, 2, 1, 1, TRUE);
        
          /* Player's health label in GTK+ client status display */
          label = Status->HealthName = gtk_label_new(_("Health"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 4, 2, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 4, 2, 1, 1, TRUE);
        
          label = Status->HealthValue = gtk_label_new(NULL);
       -  gtk_grid_attach(GTK_GRID(grid), label, 5, 2, 1, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 5, 2, 1, 1, TRUE);
          return grid;
        }
        
       t@@ -2456,7 +2437,7 @@ void display_intro(GtkWidget *widget, gpointer data)
          gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
          g_free(VersionStr);
        
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(rows, cols, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 3);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 3);
          for (i = 0; i < rows; i++) {
       t@@ -2468,8 +2449,7 @@ void display_intro(GtkWidget *widget, gpointer data)
                  } else {
                    label = gtk_label_new(table_data[i][j]);
                  }
       -          gtk_grid_attach(GTK_GRID(grid), label, j, i, 1, 1);
       -          gtk_widget_set_hexpand(label, TRUE);
       +          dp_gtk_grid_attach(GTK_GRID(grid), label, j, i, 1, 1, TRUE);
                }
              }
            }
       t@@ -2607,15 +2587,14 @@ void TransferDialog(gboolean Debt)
                                       GTK_WINDOW(ClientData.window));
        
          vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 7);
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(4, 3, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 4);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 4);
        
          /* Display of player's cash in bank or loan shark dialog */
          dpg_string_printf(text, _("Cash: %P"), ClientData.Play->Cash);
          label = gtk_label_new(text->str);
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 3, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 3, 1, TRUE);
        
          if (Debt) {
            /* Display of player's debt in loan shark dialog */
       t@@ -2625,24 +2604,23 @@ void TransferDialog(gboolean Debt)
            dpg_string_printf(text, _("Bank: %P"), ClientData.Play->Bank);
          }
          label = gtk_label_new(text->str);
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 3, 1);
       -  gtk_widget_set_hexpand(label, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 3, 1, TRUE);
        
          g_object_set_data(G_OBJECT(dialog), "debt", GINT_TO_POINTER(Debt));
          if (Debt) {
            /* Prompt for paying back a loan */
            label = gtk_label_new(_("Pay back:"));
       -    gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 2);
       +    dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 2, FALSE);
          } else {
            /* Radio button selected if you want to pay money into the bank */
            radio = gtk_radio_button_new_with_label(NULL, _("Deposit"));
            g_object_set_data(G_OBJECT(dialog), "deposit", radio);
            group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
       -    gtk_grid_attach(GTK_GRID(grid), radio, 0, 2, 1, 1);
       +    dp_gtk_grid_attach(GTK_GRID(grid), radio, 0, 2, 1, 1, FALSE);
        
            /* Radio button selected if you want to withdraw money from the bank */
            radio = gtk_radio_button_new_with_label(group, _("Withdraw"));
       -    gtk_grid_attach(GTK_GRID(grid), radio, 0, 3, 1, 1);
       +    dp_gtk_grid_attach(GTK_GRID(grid), radio, 0, 3, 1, 1, FALSE);
          }
          label = gtk_label_new(Currency.Symbol);
          entry = gtk_entry_new();
       t@@ -2650,14 +2628,13 @@ void TransferDialog(gboolean Debt)
          g_object_set_data(G_OBJECT(dialog), "entry", entry);
          g_signal_connect(G_OBJECT(entry), "activate",
                           G_CALLBACK(TransferOK), dialog);
       -  gtk_widget_set_hexpand(entry, TRUE);
        
          if (Currency.Prefix) {
       -    gtk_grid_attach(GTK_GRID(grid), label, 1, 2, 1, 2);
       -    gtk_grid_attach(GTK_GRID(grid), entry, 2, 2, 1, 2);
       +    dp_gtk_grid_attach(GTK_GRID(grid), label, 1, 2, 1, 2, FALSE);
       +    dp_gtk_grid_attach(GTK_GRID(grid), entry, 2, 2, 1, 2, TRUE);
          } else {
       -    gtk_grid_attach(GTK_GRID(grid), label, 2, 2, 1, 2);
       -    gtk_grid_attach(GTK_GRID(grid), entry, 1, 2, 1, 2);
       +    dp_gtk_grid_attach(GTK_GRID(grid), label, 2, 2, 1, 2, FALSE);
       +    dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 2, 1, 2, TRUE);
          }
        
          gtk_box_pack_start(GTK_BOX(vbox), grid, TRUE, TRUE, 0);
 (DIR) diff --git a/src/gui_client/newgamedia.c b/src/gui_client/newgamedia.c
       t@@ -550,14 +550,14 @@ void NewGameDialog(Player *play)
        #ifdef NETWORKING
          vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 7);
          gtk_container_set_border_width(GTK_CONTAINER(vbox2), 8);
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(2, 2, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 4);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 4);
        
          /* Prompt for hostname to connect to in GTK+ new game dialog */
          label = gtk_label_new(_("Host name"));
        
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1, FALSE);
          entry = stgam.hostname = gtk_entry_new();
        
          ServerEntry = "localhost";
       t@@ -572,16 +572,14 @@ void NewGameDialog(Player *play)
            ServerEntry = ServerName;
        
          gtk_entry_set_text(GTK_ENTRY(entry), ServerEntry);
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 0, 1, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 0, 1, 1, TRUE);
          label = gtk_label_new(_("Port"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1, FALSE);
          entry = stgam.port = gtk_entry_new();
          text = g_strdup_printf("%d", Port);
          gtk_entry_set_text(GTK_ENTRY(entry), text);
          g_free(text);
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 1, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 1, 1, TRUE);
        
          gtk_box_pack_start(GTK_BOX(vbox2), grid, FALSE, FALSE, 0);
        
       t@@ -742,20 +740,19 @@ static void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data)
        
          vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 7);
        
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(2, 2, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 10);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
        
          label = gtk_label_new("User name:");
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1, FALSE);
        
          entry = gtk_entry_new();
          g_object_set_data(G_OBJECT(window), "username", (gpointer)entry);
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 0, 1, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 0, 1, 1, TRUE);
        
          label = gtk_label_new("Password:");
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1, FALSE);
        
          entry = gtk_entry_new();
          g_object_set_data(G_OBJECT(window), "password", (gpointer)entry);
       t@@ -765,8 +762,7 @@ static void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data)
          gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
        #endif
        
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 1, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 1, 1, TRUE);
        
          gtk_box_pack_start(GTK_BOX(vbox), grid, TRUE, TRUE, 0);
        
 (DIR) diff --git a/src/gui_client/optdialog.c b/src/gui_client/optdialog.c
       t@@ -284,14 +284,13 @@ static void AddStructConfig(GtkWidget *grid, int row, gchar *structname,
            GtkWidget *check;
        
            check = gtk_check_button_new_with_label(_(member->label));
       -    gtk_grid_attach(GTK_GRID(grid), check, 0, row, 2, 1);
       -    gtk_widget_set_hexpand(check, TRUE);
       +    dp_gtk_grid_attach(GTK_GRID(grid), check, 0, row, 2, 1, TRUE);
            AddConfigWidget(check, ind);
          } else {
            GtkWidget *label, *entry;
        
            label = gtk_label_new(_(member->label));
       -    gtk_grid_attach(GTK_GRID(grid), label, 0, row, 1, 1);
       +    dp_gtk_grid_attach(GTK_GRID(grid), label, 0, row, 1, 1, FALSE);
            if (gvar->IntVal && gvar->MaxVal > gvar->MinVal) {
              GtkAdjustment *spin_adj = (GtkAdjustment *)
                  gtk_adjustment_new(gvar->MinVal, gvar->MinVal, gvar->MaxVal,
       t@@ -300,8 +299,7 @@ static void AddStructConfig(GtkWidget *grid, int row, gchar *structname,
            } else {
              entry = gtk_entry_new();
            }
       -    gtk_grid_attach(GTK_GRID(grid), entry, 1, row, 1, 1);
       -    gtk_widget_set_hexpand(entry, TRUE);
       +    dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, row, 1, 1, TRUE);
            AddConfigWidget(entry, ind);
          }
        }
       t@@ -762,7 +760,7 @@ static GtkWidget *CreateList(gchar *structname, struct ConfigMembers *members)
          gtk_box_pack_start(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
          gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
        
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(nummembers + 1, 2, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
        
       t@@ -857,64 +855,55 @@ void OptDialog(GtkWidget *widget, gpointer data)
        
          notebook = gtk_notebook_new();
        
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(8, 3, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
        
          check = NewConfigCheck("Sanitized", _("Remove drug references"));
       -  gtk_grid_attach(GTK_GRID(grid), check, 0, 0, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), check, 0, 0, 1, 1, FALSE);
        
          check = gtk_check_button_new_with_label(_("Unicode config file"));
          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), IsConfigFileUTF8());
       -  gtk_grid_attach(GTK_GRID(grid), check, 1, 0, 2, 1);
       -  gtk_widget_set_hexpand(check, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), check, 1, 0, 2, 1, TRUE);
          g_object_set_data(G_OBJECT(dialog), "unicode_check", check);
        
          label = gtk_label_new(_("Game length (turns)"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1, FALSE);
          entry = NewConfigEntry("NumTurns");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 2, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 2, 1, TRUE);
        
          label = gtk_label_new(_("Starting cash"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1, FALSE);
          entry = NewConfigEntry("StartCash");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 2, 2, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 2, 2, 1, TRUE);
        
          label = gtk_label_new(_("Starting debt"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 3, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 3, 1, 1, FALSE);
          entry = NewConfigEntry("StartDebt");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 3, 2, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 3, 2, 1, TRUE);
        
          label = gtk_label_new(_("Currency symbol"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 4, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 4, 1, 1, FALSE);
          entry = NewConfigEntry("Currency.Symbol");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 4, 1, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 4, 1, 1, TRUE);
          check = NewConfigCheck("Currency.Prefix", _("Symbol prefixes prices"));
       -  gtk_grid_attach(GTK_GRID(grid), check, 2, 4, 1, 1);
       -  gtk_widget_set_hexpand(check, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), check, 2, 4, 1, 1, TRUE);
        
          label = gtk_label_new(_("Name of one bitch"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 5, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 5, 1, 1, FALSE);
          entry = NewConfigEntry("Names.Bitch");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 5, 2, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 5, 2, 1, TRUE);
        
          label = gtk_label_new(_("Name of several bitches"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 6, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 6, 1, 1, FALSE);
          entry = NewConfigEntry("Names.Bitches");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 6, 2, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 6, 2, 1, TRUE);
        
        #ifndef CYGWIN
          label = gtk_label_new(_("Web browser"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 7, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 7, 1, 1, FALSE);
          entry = NewConfigEntry("WebBrowser");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 7, 2, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 7, 2, 1, TRUE);
        #endif
        
          gtk_container_set_border_width(GTK_CONTAINER(grid), 7);
       t@@ -936,20 +925,18 @@ void OptDialog(GtkWidget *widget, gpointer data)
          hsep = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
          gtk_box_pack_start(GTK_BOX(vbox2), hsep, FALSE, FALSE, 0);
        
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(2, 2, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
          label = gtk_label_new(_("Expensive string 1"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1, FALSE);
          entry = NewConfigEntry("Drugs.ExpensiveStr1");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 0, 1, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 0, 1, 1, TRUE);
        
          label = gtk_label_new(_("Expensive string 2"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1, FALSE);
          entry = NewConfigEntry("Drugs.ExpensiveStr2");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 1, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 1, 1, TRUE);
          gtk_box_pack_start(GTK_BOX(vbox2), grid, FALSE, FALSE, 0);
        
          label = gtk_label_new(_("Drugs"));
       t@@ -966,38 +953,33 @@ void OptDialog(GtkWidget *widget, gpointer data)
          gtk_notebook_append_page(GTK_NOTEBOOK(notebook), hbox, label);
        
        #ifdef NETWORKING
       -  grid = gtk_grid_new();
       +  grid = dp_gtk_grid_new(6, 4, FALSE);
          gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
          gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
        
          check = NewConfigCheck("MetaServer.Active",
                                 _("Server reports to metaserver"));
       -  gtk_grid_attach(GTK_GRID(grid), check, 0, 0, 2, 1);
       -  gtk_widget_set_hexpand(check, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), check, 0, 0, 2, 1, TRUE);
        
        #ifdef CYGWIN
          check = NewConfigCheck("MinToSysTray", _("Minimize to System Tray"));
       -  gtk_grid_attach(GTK_GRID(grid), check, 2, 0, 2, 1);
       -  gtk_widget_set_hexpand(check, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), check, 2, 0, 2, 1, TRUE);
        #endif
        
          label = gtk_label_new(_("Metaserver URL"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1, FALSE);
          entry = NewConfigEntry("MetaServer.URL");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 3, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 1, 3, 1, TRUE);
        
          label = gtk_label_new(_("Comment"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 4, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 4, 1, 1, FALSE);
          entry = NewConfigEntry("MetaServer.Comment");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 4, 3, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 4, 3, 1, TRUE);
        
          label = gtk_label_new(_("MOTD (welcome message)"));
       -  gtk_grid_attach(GTK_GRID(grid), label, 0, 5, 1, 1);
       +  dp_gtk_grid_attach(GTK_GRID(grid), label, 0, 5, 1, 1, FALSE);
          entry = NewConfigEntry("ServerMOTD");
       -  gtk_grid_attach(GTK_GRID(grid), entry, 1, 5, 3, 1);
       -  gtk_widget_set_hexpand(entry, TRUE);
       +  dp_gtk_grid_attach(GTK_GRID(grid), entry, 1, 5, 3, 1, TRUE);
        
          gtk_container_set_border_width(GTK_CONTAINER(grid), 7);
          label = gtk_label_new(_("Server"));