#include <assert.h>
#include <stdlib.h>
#include <string.h>
+
#include <gtk/gtk.h>
#if !GTK_CHECK_VERSION(3,0,0)
#include <gdk/gdkkeysyms.h>
#endif
+
+#include "putty.h"
+#include "gtkfont.h"
+#include "gtkcompat.h"
+#include "tree234.h"
+
#ifndef NOT_X_WINDOWS
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif
-#include "putty.h"
-#include "gtkfont.h"
-#include "tree234.h"
-
/*
* Future work:
*
* - it would be nice to have a display of the current font name,
* and in particular whether it's client- or server-side,
* during the progress of the font selector.
- *
- * - it would be nice if we could move the processing of
- * underline and VT100 double width into this module, so that
- * instead of using the ghastly pixmap-stretching technique
- * everywhere we could tell the Pango backend to scale its
- * fonts to double size properly and at full resolution.
- * However, this requires me to learn how to make Pango stretch
- * text to an arbitrary aspect ratio (for double-width only
- * text, which perversely is harder than DW+DH), and right now
- * I haven't the energy.
*/
#if !GLIB_CHECK_VERSION(1,3,7)
static char *x11_guess_derived_font_name(XFontStruct *xfs, int bold, int wide)
{
- Display *disp = GDK_DISPLAY();
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
Atom fontprop = XInternAtom(disp, "FONT", False);
unsigned long ret;
if (XGetFontProperty(xfs, fontprop, &ret)) {
{
struct x11font *xfont;
XFontStruct *xfs;
- Display *disp = GDK_DISPLAY();
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
Atom charset_registry, charset_encoding, spacing;
unsigned long registry_ret, encoding_ret, spacing_ret;
int pubcs, realcs, sixteen_bit, variable;
static void x11font_destroy(unifont *font)
{
- Display *disp = GDK_DISPLAY();
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
struct x11font *xfont = (struct x11font *)font;
int i;
static void x11_alloc_subfont(struct x11font *xfont, int sfid)
{
- Display *disp = GDK_DISPLAY();
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
char *derived_name = x11_guess_derived_font_name
(xfont->fonts[0].xfs, sfid & 1, !!(sfid & 2));
xfont->fonts[sfid].xfs = XLoadQueryFont(disp, derived_name);
#if !GTK_CHECK_VERSION(2,0,0)
#define GDK_DRAWABLE_XID(d) GDK_WINDOW_XWINDOW(d) /* GTK1's name for this */
+#elif GTK_CHECK_VERSION(3,0,0)
+#define GDK_DRAWABLE_XID(d) GDK_WINDOW_XID(d) /* GTK3's name for this */
#endif
static int x11font_width_16(unifont_drawctx *ctx, x11font_individual *xfi,
#ifdef DRAW_TEXT_GDK
static void x11font_gdk_setup(unifont_drawctx *ctx, x11font_individual *xfi)
{
- XSetFont(GDK_DISPLAY(), GDK_GC_XGC(ctx->u.gdk.gc), xfi->xfs->fid);
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+ XSetFont(disp, GDK_GC_XGC(ctx->u.gdk.gc), xfi->xfs->fid);
}
static void x11font_gdk_draw_16(unifont_drawctx *ctx,
x11font_individual *xfi, int x, int y,
const void *vstring, int start, int length)
{
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
const XChar2b *string = (const XChar2b *)vstring;
- XDrawString16(GDK_DISPLAY(), GDK_DRAWABLE_XID(ctx->u.gdk.target),
+ XDrawString16(disp, GDK_DRAWABLE_XID(ctx->u.gdk.target),
GDK_GC_XGC(ctx->u.gdk.gc), x, y, string+start, length);
}
x11font_individual *xfi, int x, int y,
const void *vstring, int start, int length)
{
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
const char *string = (const char *)vstring;
- XDrawString(GDK_DISPLAY(), GDK_DRAWABLE_XID(ctx->u.gdk.target),
+ XDrawString(disp, GDK_DRAWABLE_XID(ctx->u.gdk.target),
GDK_GC_XGC(ctx->u.gdk.gc), x, y, string+start, length);
}
#endif
static void x11font_cairo_setup(unifont_drawctx *ctx, x11font_individual *xfi)
{
if (xfi->pixmap == None) {
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
XGCValues gcvals;
GdkWindow *widgetwin = gtk_widget_get_window(ctx->u.cairo.widget);
int widgetscr = GDK_SCREEN_XNUMBER(gdk_window_get_screen(widgetwin));
}
xfi->pixmap = XCreatePixmap
- (GDK_DISPLAY(),
+ (disp,
GDK_DRAWABLE_XID(gtk_widget_get_window(ctx->u.cairo.widget)),
xfi->pixwidth, xfi->pixheight, 1);
- gcvals.foreground = WhitePixel(GDK_DISPLAY(), widgetscr);
- gcvals.background = BlackPixel(GDK_DISPLAY(), widgetscr);
+ gcvals.foreground = WhitePixel(disp, widgetscr);
+ gcvals.background = BlackPixel(disp, widgetscr);
gcvals.font = xfi->xfs->fid;
- xfi->gc = XCreateGC(GDK_DISPLAY(), xfi->pixmap,
+ xfi->gc = XCreateGC(disp, xfi->pixmap,
GCForeground | GCBackground | GCFont, &gcvals);
}
}
XImage *image;
int x, y;
unsigned char *bitmap;
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
bitmap = snewn(xfi->allsize, unsigned char);
memset(bitmap, 0, xfi->allsize);
- image = XGetImage(GDK_DISPLAY(), xfi->pixmap, 0, 0,
+ image = XGetImage(disp, xfi->pixmap, 0, 0,
xfi->pixwidth, xfi->pixheight, AllPlanes, XYPixmap);
for (y = 0; y < xfi->pixheight; y++) {
for (x = 0; x < xfi->pixwidth; x++) {
* principle that Unicode characters come in contiguous blocks
* often used together */
int old_nglyphs = xfi->nglyphs;
- xfi->nglyphs = (glyphindex + 0xFF) & ~0xFF;
+ xfi->nglyphs = (glyphindex + 0x100) & ~0xFF;
xfi->glyphcache = sresize(xfi->glyphcache, xfi->nglyphs,
struct cairo_cached_glyph);
x11font_individual *xfi, int x, int y,
const void *vstring, int start, int length)
{
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
const XChar2b *string = (const XChar2b *)vstring + start;
int i;
for (i = 0; i < length; i++) {
(unsigned char)string[i].byte2);
if (glyphindex >= xfi->nglyphs ||
!xfi->glyphcache[glyphindex].surface) {
- XDrawImageString16(GDK_DISPLAY(), xfi->pixmap, xfi->gc,
+ XDrawImageString16(disp, xfi->pixmap, xfi->gc,
xfi->pixoriginx, xfi->pixoriginy,
string+i, 1);
x11font_cairo_cache_glyph(xfi, glyphindex);
x11font_individual *xfi, int x, int y,
const void *vstring, int start, int length)
{
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
const char *string = (const char *)vstring + start;
int i;
for (i = 0; i < length; i++) {
int glyphindex = (unsigned char)string[i];
if (glyphindex >= xfi->nglyphs ||
!xfi->glyphcache[glyphindex].surface) {
- XDrawImageString(GDK_DISPLAY(), xfi->pixmap, xfi->gc,
+ XDrawImageString(disp, xfi->pixmap, xfi->gc,
xfi->pixoriginx, xfi->pixoriginy,
string+i, 1);
x11font_cairo_cache_glyph(xfi, glyphindex);
static void x11font_enum_fonts(GtkWidget *widget,
fontsel_add_entry callback, void *callback_ctx)
{
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
char **fontnames;
char *tmp = NULL;
int nnames, i, max, tmpsize;
max = 32768;
while (1) {
- fontnames = XListFonts(GDK_DISPLAY(), "*", max, &nnames);
+ fontnames = XListFonts(disp, "*", max, &nnames);
if (nnames >= max) {
XFreeFontNames(fontnames);
max *= 2;
* selector treats them as worthwhile in their own right.
*/
XFontStruct *xfs;
- Display *disp = GDK_DISPLAY();
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
Atom fontprop, fontprop2;
unsigned long ret;
* Data passed in to unifont_create().
*/
int bold, shadowoffset, shadowalways;
+ /*
+ * Cache of character widths, indexed by Unicode code point. In
+ * pixels; -1 means we haven't asked Pango about this character
+ * before.
+ */
+ int *widthcache;
+ unsigned nwidthcache;
};
static const struct unifont_vtable pangofont_vtable = {
pfont->bold = bold;
pfont->shadowoffset = shadowoffset;
pfont->shadowalways = shadowalways;
+ pfont->widthcache = NULL;
+ pfont->nwidthcache = 0;
pango_font_metrics_unref(metrics);
{
struct pangofont *pfont = (struct pangofont *)font;
pango_font_description_free(pfont->desc);
+ sfree(pfont->widthcache);
g_object_unref(pfont->fset);
sfree(font);
}
+static int pangofont_char_width(PangoLayout *layout, struct pangofont *pfont,
+ wchar_t uchr, const char *utfchr, int utflen)
+{
+ /*
+ * Here we check whether a character has the same width as the
+ * character cell it'll be drawn in. Because profiling showed that
+ * pango_layout_get_pixel_extents() was a huge bottleneck when we
+ * were calling it every time we needed to know this, we instead
+ * call it only on characters we don't already know about, and
+ * cache the results.
+ */
+
+ if ((unsigned)uchr >= pfont->nwidthcache) {
+ unsigned newsize = ((int)uchr + 0x100) & ~0xFF;
+ pfont->widthcache = sresize(pfont->widthcache, newsize, int);
+ while (pfont->nwidthcache < newsize)
+ pfont->widthcache[pfont->nwidthcache++] = -1;
+ }
+
+ if (pfont->widthcache[uchr] < 0) {
+ PangoRectangle rect;
+ pango_layout_set_text(layout, utfchr, utflen);
+ pango_layout_get_pixel_extents(layout, NULL, &rect);
+ pfont->widthcache[uchr] = rect.width;
+ }
+
+ return pfont->widthcache[uchr];
+}
+
static int pangofont_has_glyph(unifont *font, wchar_t glyph)
{
/* Pango implements font fallback, so assume it has everything */
clen++;
n = 1;
- /*
- * If it's a right-to-left character, we must display it on
- * its own, to stop Pango helpfully re-reversing our already
- * reversed text.
- */
- if (!is_rtl(string[0])) {
-
+ if (is_rtl(string[0]) ||
+ pangofont_char_width(layout, pfont, string[n-1],
+ utfptr, clen) != cellwidth) {
/*
- * See if that character has the width we expect.
+ * If this character is a right-to-left one, or has an
+ * unusual width, then we must display it on its own.
*/
- pango_layout_set_text(layout, utfptr, clen);
- pango_layout_get_pixel_extents(layout, NULL, &rect);
-
- if (rect.width == cellwidth) {
- /*
- * Try extracting more characters, for as long as they
- * stay well-behaved.
- */
- while (clen < utflen) {
- int oldclen = clen;
- clen++; /* skip UTF-8 introducer byte */
- while (clen < utflen &&
- (unsigned char)utfptr[clen] >= 0x80 &&
- (unsigned char)utfptr[clen] < 0xC0)
- clen++;
- n++;
- pango_layout_set_text(layout, utfptr, clen);
- pango_layout_get_pixel_extents(layout, NULL, &rect);
- if (rect.width != n * cellwidth) {
- clen = oldclen;
- n--;
- break;
- }
+ } else {
+ /*
+ * Try to amalgamate a contiguous string of characters
+ * with the expected sensible width, for the common case
+ * in which we're using a monospaced font and everything
+ * works as expected.
+ */
+ while (clen < utflen) {
+ int oldclen = clen;
+ clen++; /* skip UTF-8 introducer byte */
+ while (clen < utflen &&
+ (unsigned char)utfptr[clen] >= 0x80 &&
+ (unsigned char)utfptr[clen] < 0xC0)
+ clen++;
+ n++;
+ if (pangofont_char_width(layout, pfont,
+ string[n-1], utfptr + oldclen,
+ clen - oldclen) != cellwidth) {
+ clen = oldclen;
+ n--;
+ break;
}
}
}
}
}
+/* ----------------------------------------------------------------------
+ * Utility routine used by the code below, and also gtkdlg.c.
+ */
+
+void get_label_text_dimensions(const char *text, int *width, int *height)
+{
+ /*
+ * Determine the dimensions of a piece of text in the standard
+ * font used in GTK interface elements like labels. We do this by
+ * instantiating an actual GtkLabel, and then querying its size.
+ *
+ * But GTK2 and GTK3 require us to query the size completely
+ * differently. I'm sure there ought to be an easier approach than
+ * the way I'm doing this in GTK3, too!
+ */
+ GtkWidget *label = gtk_label_new(text);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(label));
+ PangoRectangle logrect;
+ pango_layout_get_extents(layout, NULL, &logrect);
+ if (width)
+ *width = logrect.width / PANGO_SCALE;
+ if (height)
+ *height = logrect.height / PANGO_SCALE;
+#else
+ GtkRequisition req;
+ gtk_widget_size_request(label, &req);
+ if (width)
+ *width = req.width;
+ if (height)
+ *height = req.height;
+#endif
+
+ g_object_ref_sink(G_OBJECT(label));
+#if GTK_CHECK_VERSION(2,10,0)
+ g_object_unref(label);
+#endif
+}
+
#if GTK_CHECK_VERSION(2,0,0)
/* ----------------------------------------------------------------------
return 0;
}
+static void unifontsel_draw_preview_text(unifontsel_internal *fs);
+
static void unifontsel_deselect(unifontsel_internal *fs)
{
fs->selected = NULL;
gtk_list_store_clear(fs->size_model);
gtk_widget_set_sensitive(fs->u.ok_button, FALSE);
gtk_widget_set_sensitive(fs->size_entry, FALSE);
+ unifontsel_draw_preview_text(fs);
}
static void unifontsel_setup_familylist(unifontsel_internal *fs)
int currflags = -1;
fontinfo *info;
+ fs->inhibit_response = TRUE;
+
gtk_list_store_clear(fs->family_model);
listindex = 0;
*/
if (fs->selected && fs->selected->familyindex < 0)
unifontsel_deselect(fs);
+
+ fs->inhibit_response = FALSE;
}
static void unifontsel_setup_stylelist(unifontsel_internal *fs,
} else
font = NULL;
- if (font) {
#ifdef DRAW_TEXT_GDK
- if (dctx->type == DRAWTYPE_GDK) {
- gdk_gc_set_foreground(dctx->u.gdk.gc, &fs->preview_bg);
- gdk_draw_rectangle(dctx->u.gdk.target, dctx->u.gdk.gc, 1, 0, 0,
- fs->preview_width, fs->preview_height);
- gdk_gc_set_foreground(dctx->u.gdk.gc, &fs->preview_fg);
- }
+ if (dctx->type == DRAWTYPE_GDK) {
+ gdk_gc_set_foreground(dctx->u.gdk.gc, &fs->preview_bg);
+ gdk_draw_rectangle(dctx->u.gdk.target, dctx->u.gdk.gc, 1, 0, 0,
+ fs->preview_width, fs->preview_height);
+ gdk_gc_set_foreground(dctx->u.gdk.gc, &fs->preview_fg);
+ }
#endif
#ifdef DRAW_TEXT_CAIRO
- if (dctx->type == DRAWTYPE_CAIRO) {
- cairo_set_source_rgb(dctx->u.cairo.cr,
- fs->preview_bg.red / 65535.0,
- fs->preview_bg.green / 65535.0,
- fs->preview_bg.blue / 65535.0);
- cairo_paint(dctx->u.cairo.cr);
- cairo_set_source_rgb(dctx->u.cairo.cr,
- fs->preview_fg.red / 65535.0,
- fs->preview_fg.green / 65535.0,
- fs->preview_fg.blue / 65535.0);
- }
+ if (dctx->type == DRAWTYPE_CAIRO) {
+ cairo_set_source_rgb(dctx->u.cairo.cr,
+ fs->preview_bg.red / 65535.0,
+ fs->preview_bg.green / 65535.0,
+ fs->preview_bg.blue / 65535.0);
+ cairo_paint(dctx->u.cairo.cr);
+ cairo_set_source_rgb(dctx->u.cairo.cr,
+ fs->preview_fg.red / 65535.0,
+ fs->preview_fg.green / 65535.0,
+ fs->preview_fg.blue / 65535.0);
+ }
#endif
+ if (font) {
/*
* The pangram used here is rather carefully
* constructed: it contains a sequence of very narrow
{
int index;
int minval, maxval;
+ gboolean success;
GtkTreePath *treepath;
GtkTreeIter iter;
treepath);
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(fs->family_list),
treepath, NULL, FALSE, 0.0, 0.0);
- gtk_tree_model_get_iter(GTK_TREE_MODEL(fs->family_model), &iter, treepath);
+ success = gtk_tree_model_get_iter(GTK_TREE_MODEL(fs->family_model),
+ &iter, treepath);
+ assert(success);
gtk_tree_path_free(treepath);
/*
}
}
+#if GTK_CHECK_VERSION(3,0,0)
+static gint unifontsel_draw_area(GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+ unifontsel_internal *fs = (unifontsel_internal *)data;
+ unifont_drawctx dctx;
+
+ dctx.type = DRAWTYPE_CAIRO;
+ dctx.u.cairo.widget = widget;
+ dctx.u.cairo.cr = cr;
+ unifontsel_draw_preview_text_inner(&dctx, fs);
+
+ return TRUE;
+}
+#else
static gint unifontsel_expose_area(GtkWidget *widget, GdkEventExpose *event,
gpointer data)
{
return TRUE;
}
+#endif
static gint unifontsel_configure_area(GtkWidget *widget,
GdkEventConfigure *event, gpointer data)
fs->selected = NULL;
{
+ int width, height;
+
/*
* Invent some magic size constants.
*/
- GtkRequisition req;
- label = gtk_label_new("Quite Long Font Name (Foundry)");
- gtk_widget_size_request(label, &req);
- font_width = req.width;
- lists_height = 14 * req.height;
- preview_height = 5 * req.height;
- gtk_label_set_text(GTK_LABEL(label), "Italic Extra Condensed");
- gtk_widget_size_request(label, &req);
- style_width = req.width;
- gtk_label_set_text(GTK_LABEL(label), "48000");
- gtk_widget_size_request(label, &req);
- size_width = req.width;
- g_object_ref_sink(G_OBJECT(label));
-#if GTK_CHECK_VERSION(2,10,0)
- g_object_unref(label);
-#endif
+ get_label_text_dimensions("Quite Long Font Name (Foundry)",
+ &width, &height);
+ font_width = width;
+ lists_height = 14 * height;
+ preview_height = 5 * height;
+
+ get_label_text_dimensions("Italic Extra Condensed", &width, &height);
+ style_width = width;
+
+ get_label_text_dimensions("48000", &width, &height);
+ size_width = width;
}
/*
fs->u.window = GTK_WINDOW(gtk_dialog_new());
gtk_window_set_title(fs->u.window, wintitle);
fs->u.cancel_button = gtk_dialog_add_button
- (GTK_DIALOG(fs->u.window), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ (GTK_DIALOG(fs->u.window), STANDARD_CANCEL_LABEL, GTK_RESPONSE_CANCEL);
fs->u.ok_button = gtk_dialog_add_button
- (GTK_DIALOG(fs->u.window), GTK_STOCK_OK, GTK_RESPONSE_OK);
+ (GTK_DIALOG(fs->u.window), STANDARD_OK_LABEL, GTK_RESPONSE_OK);
gtk_widget_grab_default(fs->u.ok_button);
/*
* Now set up the internal fields, including in particular all
* the controls that actually allow the user to select fonts.
*/
+#if GTK_CHECK_VERSION(3,0,0)
+ table = gtk_grid_new();
+ gtk_grid_set_column_spacing(GTK_GRID(table), 8);
+#else
table = gtk_table_new(8, 3, FALSE);
- gtk_widget_show(table);
gtk_table_set_col_spacings(GTK_TABLE(table), 8);
+#endif
+ gtk_widget_show(table);
#if GTK_CHECK_VERSION(2,4,0)
/* GtkAlignment seems to be the simplest way to put padding round things */
w = gtk_alignment_new(0, 0, 1, 1);
label = gtk_label_new_with_mnemonic("_Font:");
gtk_widget_show(label);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
+ g_object_set(G_OBJECT(label), "hexpand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
+#endif
/*
* The Font list box displays only a string, but additionally
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
gtk_widget_set_size_request(scroll, font_width, lists_height);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), scroll, 0, 1, 1, 2);
+ g_object_set(G_OBJECT(scroll), "expand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), scroll, 0, 1, 1, 3, GTK_FILL,
GTK_EXPAND | GTK_FILL, 0, 0);
+#endif
fs->family_model = model;
fs->family_list = w;
label = gtk_label_new_with_mnemonic("_Style:");
gtk_widget_show(label);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), label, 1, 0, 1, 1);
+ g_object_set(G_OBJECT(label), "hexpand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
+#endif
/*
* The Style list box can contain insensitive elements
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
gtk_widget_set_size_request(scroll, style_width, lists_height);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), scroll, 1, 1, 1, 2);
+ g_object_set(G_OBJECT(scroll), "expand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), scroll, 1, 2, 1, 3, GTK_FILL,
GTK_EXPAND | GTK_FILL, 0, 0);
+#endif
fs->style_model = model;
fs->style_list = w;
label = gtk_label_new_with_mnemonic("Si_ze:");
gtk_widget_show(label);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), label, 2, 0, 1, 1);
+ g_object_set(G_OBJECT(label), "hexpand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0);
+#endif
/*
* The Size label attaches primarily to a text input box so
gtk_label_set_mnemonic_widget(GTK_LABEL(label), w);
gtk_widget_set_size_request(w, size_width, -1);
gtk_widget_show(w);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), w, 2, 1, 1, 1);
+ g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), w, 2, 3, 1, 2, GTK_FILL, 0, 0, 0);
+#endif
g_signal_connect(G_OBJECT(w), "changed", G_CALLBACK(size_entry_changed),
fs);
gtk_widget_show(scroll);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), scroll, 2, 2, 1, 1);
+ g_object_set(G_OBJECT(scroll), "expand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), scroll, 2, 3, 2, 3, GTK_FILL,
GTK_EXPAND | GTK_FILL, 0, 0);
+#endif
fs->size_model = model;
fs->size_list = w;
fs->preview_fg.pixel = fs->preview_bg.pixel = 0;
fs->preview_fg.red = fs->preview_fg.green = fs->preview_fg.blue = 0x0000;
fs->preview_bg.red = fs->preview_bg.green = fs->preview_bg.blue = 0xFFFF;
+#if !GTK_CHECK_VERSION(3,0,0)
gdk_colormap_alloc_color(gdk_colormap_get_system(), &fs->preview_fg,
FALSE, FALSE);
gdk_colormap_alloc_color(gdk_colormap_get_system(), &fs->preview_bg,
FALSE, FALSE);
+#endif
+#if GTK_CHECK_VERSION(3,0,0)
+ g_signal_connect(G_OBJECT(fs->preview_area), "draw",
+ G_CALLBACK(unifontsel_draw_area), fs);
+#else
g_signal_connect(G_OBJECT(fs->preview_area), "expose_event",
G_CALLBACK(unifontsel_expose_area), fs);
+#endif
g_signal_connect(G_OBJECT(fs->preview_area), "configure_event",
G_CALLBACK(unifontsel_configure_area), fs);
gtk_widget_set_size_request(fs->preview_area, 1, preview_height);
w = gtk_frame_new("Preview of font");
gtk_container_add(GTK_CONTAINER(w), ww);
gtk_widget_show(w);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), w, 0, 3, 3, 1);
+ g_object_set(G_OBJECT(w), "expand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), w, 0, 3, 3, 4,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 8);
+#endif
/*
* We only provide the checkboxes for client- and server-side
G_CALLBACK(unifontsel_button_toggled), fs);
gtk_widget_show(w);
fs->filter_buttons[fs->n_filter_buttons++] = w;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), w, 0, 4, 3, 1);
+ g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), w, 0, 3, 4, 5, GTK_FILL, 0, 0, 0);
+#endif
w = gtk_check_button_new_with_label("Show server-side fonts");
g_object_set_data(G_OBJECT(w), "user-data",
GINT_TO_POINTER(FONTFLAG_SERVERSIDE));
G_CALLBACK(unifontsel_button_toggled), fs);
gtk_widget_show(w);
fs->filter_buttons[fs->n_filter_buttons++] = w;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), w, 0, 5, 3, 1);
+ g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), w, 0, 3, 5, 6, GTK_FILL, 0, 0, 0);
+#endif
w = gtk_check_button_new_with_label("Show server-side font aliases");
g_object_set_data(G_OBJECT(w), "user-data",
GINT_TO_POINTER(FONTFLAG_SERVERALIAS));
G_CALLBACK(unifontsel_button_toggled), fs);
gtk_widget_show(w);
fs->filter_buttons[fs->n_filter_buttons++] = w;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), w, 0, 6, 3, 1);
+ g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), w, 0, 3, 6, 7, GTK_FILL, 0, 0, 0);
#endif
+#endif /* NOT_X_WINDOWS */
w = gtk_check_button_new_with_label("Show non-monospaced fonts");
g_object_set_data(G_OBJECT(w), "user-data",
GINT_TO_POINTER(FONTFLAG_NONMONOSPACED));
G_CALLBACK(unifontsel_button_toggled), fs);
gtk_widget_show(w);
fs->filter_buttons[fs->n_filter_buttons++] = w;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_grid_attach(GTK_GRID(table), w, 0, 7, 3, 1);
+ g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL);
+#else
gtk_table_attach(GTK_TABLE(table), w, 0, 3, 7, 8, GTK_FILL, 0, 0, 0);
+#endif
assert(fs->n_filter_buttons <= lenof(fs->filter_buttons));
fs->filter_flags = FONTFLAG_CLIENTSIDE | FONTFLAG_SERVERSIDE |