mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Basic support for running under GDK Wayland back end.
GTK 3 PuTTY/pterm has always assumed that if it was compiled with _support_ for talking to the raw X11 layer underneath GTK and GDK, then it was entitled to expect that raw X11 layer to exist at all times, i.e. that GDK_DISPLAY_XDISPLAY would return a meaningful X display that it could do useful things with. So if you ran it over the GDK Wayland backend, it would immediately segfault. Modern GTK applications need to cope with multiple GDK backends at run time. It's fine for GTK PuTTY to _contain_ the code to find and use underlying X11 primitives like the display and the X window id, but it should be prepared to find that it's running on Wayland (or something else again!) so those functions don't return anything useful - in which case it should degrade gracefully to the subset of functionality that can be accessed through backend-independent GTK calls. Accordingly, I've centralised the use of GDK_DISPLAY_XDISPLAY into a support function get_x_display() in gtkmisc.c, which starts by checking that there actually is one first. All previous direct uses of GDK_*_XDISPLAY now go via that function, and check the result for NULL afterwards. (To save faffing about calling that function too many times, I'm also caching the display pointer in more places, and passing it as an extra argument to various subfunctions, mostly in gtkfont.c.) Similarly, the get_windowid() function that retrieves the window id to put in the environment of pterm's child process has to be prepared for there not to be a window id. This isn't a complete fix for all Wayland-related problems. The other one I'm currently aware of is that the default font is "server:fixed", which is a bad default now that it won't be available on all backends. And I expect that further problems will show up with more testing. But it's a start.
This commit is contained in:
parent
5788226460
commit
7fee4e9b43
@ -177,6 +177,10 @@
|
|||||||
|
|
||||||
#endif /* 2.24 */
|
#endif /* 2.24 */
|
||||||
|
|
||||||
|
#if !GTK_CHECK_VERSION(3,0,0)
|
||||||
|
#define GDK_IS_X11_WINDOW(window) (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if GTK_CHECK_VERSION(3,0,0)
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
#define STANDARD_OK_LABEL "_OK"
|
#define STANDARD_OK_LABEL "_OK"
|
||||||
#define STANDARD_OPEN_LABEL "_Open"
|
#define STANDARD_OPEN_LABEL "_Open"
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include "x11misc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TESTMODE
|
#ifdef TESTMODE
|
||||||
@ -1776,9 +1777,12 @@ static void filefont_clicked(GtkButton *button, gpointer data)
|
|||||||
GdkFont *font = gdk_font_load(fontname);
|
GdkFont *font = gdk_font_load(fontname);
|
||||||
if (font) {
|
if (font) {
|
||||||
XFontStruct *xfs = GDK_FONT_XFONT(font);
|
XFontStruct *xfs = GDK_FONT_XFONT(font);
|
||||||
Display *disp = GDK_FONT_XDISPLAY(font);
|
Display *disp = get_x11_display();
|
||||||
Atom fontprop = XInternAtom(disp, "FONT", False);
|
Atom fontprop = XInternAtom(disp, "FONT", False);
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
|
|
||||||
|
assert(disp); /* this is GTK1! */
|
||||||
|
|
||||||
gdk_font_ref(font);
|
gdk_font_ref(font);
|
||||||
if (XGetFontProperty(xfs, fontprop, &ret)) {
|
if (XGetFontProperty(xfs, fontprop, &ret)) {
|
||||||
char *name = XGetAtomName(disp, (Atom)ret);
|
char *name = XGetAtomName(disp, (Atom)ret);
|
||||||
|
103
unix/gtkfont.c
103
unix/gtkfont.c
@ -31,6 +31,7 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include "x11misc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -177,6 +178,11 @@ typedef struct x11font_individual {
|
|||||||
|
|
||||||
struct x11font {
|
struct x11font {
|
||||||
struct unifont u;
|
struct unifont u;
|
||||||
|
/*
|
||||||
|
* Copy of the X display handle, so we don't have to keep
|
||||||
|
* extracting it from GDK.
|
||||||
|
*/
|
||||||
|
Display *disp;
|
||||||
/*
|
/*
|
||||||
* Individual physical X fonts. We store a number of these, for
|
* Individual physical X fonts. We store a number of these, for
|
||||||
* automatically guessed bold and wide variants.
|
* automatically guessed bold and wide variants.
|
||||||
@ -308,9 +314,9 @@ static char *xlfd_recompose(const struct xlfd_decomposed *dec)
|
|||||||
#undef ARG_INT
|
#undef ARG_INT
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *x11_guess_derived_font_name(XFontStruct *xfs, int bold, int wide)
|
static char *x11_guess_derived_font_name(Display *disp, XFontStruct *xfs,
|
||||||
|
int bold, int wide)
|
||||||
{
|
{
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
||||||
Atom fontprop = XInternAtom(disp, "FONT", False);
|
Atom fontprop = XInternAtom(disp, "FONT", False);
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
if (XGetFontProperty(xfs, fontprop, &ret)) {
|
if (XGetFontProperty(xfs, fontprop, &ret)) {
|
||||||
@ -428,12 +434,15 @@ static unifont *x11font_create(GtkWidget *widget, const char *name,
|
|||||||
{
|
{
|
||||||
struct x11font *xfont;
|
struct x11font *xfont;
|
||||||
XFontStruct *xfs;
|
XFontStruct *xfs;
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
Display *disp;
|
||||||
Atom charset_registry, charset_encoding, spacing;
|
Atom charset_registry, charset_encoding, spacing;
|
||||||
unsigned long registry_ret, encoding_ret, spacing_ret;
|
unsigned long registry_ret, encoding_ret, spacing_ret;
|
||||||
int pubcs, realcs, sixteen_bit, variable;
|
int pubcs, realcs, sixteen_bit, variable;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if ((disp = get_x11_display()) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
xfs = XLoadQueryFont(disp, name);
|
xfs = XLoadQueryFont(disp, name);
|
||||||
if (!xfs)
|
if (!xfs)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -508,6 +517,7 @@ static unifont *x11font_create(GtkWidget *widget, const char *name,
|
|||||||
#else
|
#else
|
||||||
#error No drawtype available at all
|
#error No drawtype available at all
|
||||||
#endif
|
#endif
|
||||||
|
xfont->disp = disp;
|
||||||
xfont->real_charset = realcs;
|
xfont->real_charset = realcs;
|
||||||
xfont->sixteen_bit = sixteen_bit;
|
xfont->sixteen_bit = sixteen_bit;
|
||||||
xfont->variable = variable;
|
xfont->variable = variable;
|
||||||
@ -534,8 +544,8 @@ static unifont *x11font_create(GtkWidget *widget, const char *name,
|
|||||||
|
|
||||||
static void x11font_destroy(unifont *font)
|
static void x11font_destroy(unifont *font)
|
||||||
{
|
{
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
||||||
struct x11font *xfont = (struct x11font *)font;
|
struct x11font *xfont = (struct x11font *)font;
|
||||||
|
Display *disp = xfont->disp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < lenof(xfont->fonts); i++) {
|
for (i = 0; i < lenof(xfont->fonts); i++) {
|
||||||
@ -561,9 +571,9 @@ static void x11font_destroy(unifont *font)
|
|||||||
|
|
||||||
static void x11_alloc_subfont(struct x11font *xfont, int sfid)
|
static void x11_alloc_subfont(struct x11font *xfont, int sfid)
|
||||||
{
|
{
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
Display *disp = xfont->disp;
|
||||||
char *derived_name = x11_guess_derived_font_name
|
char *derived_name = x11_guess_derived_font_name
|
||||||
(xfont->fonts[0].xfs, sfid & 1, !!(sfid & 2));
|
(disp, xfont->fonts[0].xfs, sfid & 1, !!(sfid & 2));
|
||||||
xfont->fonts[sfid].xfs = XLoadQueryFont(disp, derived_name);
|
xfont->fonts[sfid].xfs = XLoadQueryFont(disp, derived_name);
|
||||||
xfont->fonts[sfid].allocated = TRUE;
|
xfont->fonts[sfid].allocated = TRUE;
|
||||||
sfree(derived_name);
|
sfree(derived_name);
|
||||||
@ -618,27 +628,25 @@ static int x11font_width_8(unifont_drawctx *ctx, x11font_individual *xfi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DRAW_TEXT_GDK
|
#ifdef DRAW_TEXT_GDK
|
||||||
static void x11font_gdk_setup(unifont_drawctx *ctx, x11font_individual *xfi)
|
static void x11font_gdk_setup(unifont_drawctx *ctx, x11font_individual *xfi,
|
||||||
|
Display *disp)
|
||||||
{
|
{
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
||||||
XSetFont(disp, GDK_GC_XGC(ctx->u.gdk.gc), xfi->xfs->fid);
|
XSetFont(disp, GDK_GC_XGC(ctx->u.gdk.gc), xfi->xfs->fid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x11font_gdk_draw_16(unifont_drawctx *ctx,
|
static void x11font_gdk_draw_16(unifont_drawctx *ctx, x11font_individual *xfi,
|
||||||
x11font_individual *xfi, int x, int y,
|
Display *disp, int x, int y,
|
||||||
const void *vstring, int start, int length)
|
const void *vstring, int start, int length)
|
||||||
{
|
{
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
||||||
const XChar2b *string = (const XChar2b *)vstring;
|
const XChar2b *string = (const XChar2b *)vstring;
|
||||||
XDrawString16(disp, 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);
|
GDK_GC_XGC(ctx->u.gdk.gc), x, y, string+start, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x11font_gdk_draw_8(unifont_drawctx *ctx,
|
static void x11font_gdk_draw_8(unifont_drawctx *ctx, x11font_individual *xfi,
|
||||||
x11font_individual *xfi, int x, int y,
|
Display *disp, int x, int y,
|
||||||
const void *vstring, int start, int length)
|
const void *vstring, int start, int length)
|
||||||
{
|
{
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
||||||
const char *string = (const char *)vstring;
|
const char *string = (const char *)vstring;
|
||||||
XDrawString(disp, 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);
|
GDK_GC_XGC(ctx->u.gdk.gc), x, y, string+start, length);
|
||||||
@ -646,10 +654,10 @@ static void x11font_gdk_draw_8(unifont_drawctx *ctx,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DRAW_TEXT_CAIRO
|
#ifdef DRAW_TEXT_CAIRO
|
||||||
static void x11font_cairo_setup(unifont_drawctx *ctx, x11font_individual *xfi)
|
static void x11font_cairo_setup(
|
||||||
|
unifont_drawctx *ctx, x11font_individual *xfi, Display *disp)
|
||||||
{
|
{
|
||||||
if (xfi->pixmap == None) {
|
if (xfi->pixmap == None) {
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
||||||
XGCValues gcvals;
|
XGCValues gcvals;
|
||||||
GdkWindow *widgetwin = gtk_widget_get_window(ctx->u.cairo.widget);
|
GdkWindow *widgetwin = gtk_widget_get_window(ctx->u.cairo.widget);
|
||||||
int widgetscr = GDK_SCREEN_XNUMBER(gdk_window_get_screen(widgetwin));
|
int widgetscr = GDK_SCREEN_XNUMBER(gdk_window_get_screen(widgetwin));
|
||||||
@ -693,12 +701,12 @@ static void x11font_cairo_setup(unifont_drawctx *ctx, x11font_individual *xfi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x11font_cairo_cache_glyph(x11font_individual *xfi, int glyphindex)
|
static void x11font_cairo_cache_glyph(
|
||||||
|
Display *disp, x11font_individual *xfi, int glyphindex)
|
||||||
{
|
{
|
||||||
XImage *image;
|
XImage *image;
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned char *bitmap;
|
unsigned char *bitmap;
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
||||||
const XCharStruct *xcs = x11_char_struct(xfi->xfs, glyphindex >> 8,
|
const XCharStruct *xcs = x11_char_struct(xfi->xfs, glyphindex >> 8,
|
||||||
glyphindex & 0xFF);
|
glyphindex & 0xFF);
|
||||||
|
|
||||||
@ -752,11 +760,10 @@ static void x11font_cairo_draw_glyph(unifont_drawctx *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x11font_cairo_draw_16(unifont_drawctx *ctx,
|
static void x11font_cairo_draw_16(
|
||||||
x11font_individual *xfi, int x, int y,
|
unifont_drawctx *ctx, x11font_individual *xfi, Display *disp,
|
||||||
const void *vstring, int start, int length)
|
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;
|
const XChar2b *string = (const XChar2b *)vstring + start;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
@ -768,7 +775,7 @@ static void x11font_cairo_draw_16(unifont_drawctx *ctx,
|
|||||||
XDrawImageString16(disp, xfi->pixmap, xfi->gc,
|
XDrawImageString16(disp, xfi->pixmap, xfi->gc,
|
||||||
xfi->pixoriginx, xfi->pixoriginy,
|
xfi->pixoriginx, xfi->pixoriginy,
|
||||||
string+i, 1);
|
string+i, 1);
|
||||||
x11font_cairo_cache_glyph(xfi, glyphindex);
|
x11font_cairo_cache_glyph(disp, xfi, glyphindex);
|
||||||
}
|
}
|
||||||
x11font_cairo_draw_glyph(ctx, xfi, x, y, glyphindex);
|
x11font_cairo_draw_glyph(ctx, xfi, x, y, glyphindex);
|
||||||
x += XTextWidth16(xfi->xfs, string+i, 1);
|
x += XTextWidth16(xfi->xfs, string+i, 1);
|
||||||
@ -776,11 +783,10 @@ static void x11font_cairo_draw_16(unifont_drawctx *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x11font_cairo_draw_8(unifont_drawctx *ctx,
|
static void x11font_cairo_draw_8(
|
||||||
x11font_individual *xfi, int x, int y,
|
unifont_drawctx *ctx, x11font_individual *xfi, Display *disp,
|
||||||
const void *vstring, int start, int length)
|
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;
|
const char *string = (const char *)vstring + start;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
@ -791,7 +797,7 @@ static void x11font_cairo_draw_8(unifont_drawctx *ctx,
|
|||||||
XDrawImageString(disp, xfi->pixmap, xfi->gc,
|
XDrawImageString(disp, xfi->pixmap, xfi->gc,
|
||||||
xfi->pixoriginx, xfi->pixoriginy,
|
xfi->pixoriginx, xfi->pixoriginy,
|
||||||
string+i, 1);
|
string+i, 1);
|
||||||
x11font_cairo_cache_glyph(xfi, glyphindex);
|
x11font_cairo_cache_glyph(disp, xfi, glyphindex);
|
||||||
}
|
}
|
||||||
x11font_cairo_draw_glyph(ctx, xfi, x, y, glyphindex);
|
x11font_cairo_draw_glyph(ctx, xfi, x, y, glyphindex);
|
||||||
x += XTextWidth(xfi->xfs, string+i, 1);
|
x += XTextWidth(xfi->xfs, string+i, 1);
|
||||||
@ -803,9 +809,10 @@ static void x11font_cairo_draw_8(unifont_drawctx *ctx,
|
|||||||
struct x11font_drawfuncs {
|
struct x11font_drawfuncs {
|
||||||
int (*width)(unifont_drawctx *ctx, x11font_individual *xfi,
|
int (*width)(unifont_drawctx *ctx, x11font_individual *xfi,
|
||||||
const void *vstring, int start, int length);
|
const void *vstring, int start, int length);
|
||||||
void (*setup)(unifont_drawctx *ctx, x11font_individual *xfi);
|
void (*setup)(unifont_drawctx *ctx, x11font_individual *xfi,
|
||||||
void (*draw)(unifont_drawctx *ctx, x11font_individual *xfi, int x, int y,
|
Display *disp);
|
||||||
const void *vstring, int start, int length);
|
void (*draw)(unifont_drawctx *ctx, x11font_individual *xfi, Display *disp,
|
||||||
|
int x, int y, const void *vstring, int start, int length);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -843,12 +850,11 @@ static const struct x11font_drawfuncs x11font_drawfuncs[2*DRAWTYPE_NTYPES] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void x11font_really_draw_text(const struct x11font_drawfuncs *dfns,
|
static void x11font_really_draw_text(
|
||||||
unifont_drawctx *ctx,
|
const struct x11font_drawfuncs *dfns, unifont_drawctx *ctx,
|
||||||
x11font_individual *xfi, int x, int y,
|
x11font_individual *xfi, Display *disp,
|
||||||
const void *string, int nchars,
|
int x, int y, const void *string, int nchars,
|
||||||
int shadowoffset,
|
int shadowoffset, int fontvariable, int cellwidth)
|
||||||
int fontvariable, int cellwidth)
|
|
||||||
{
|
{
|
||||||
int start = 0, step, nsteps, centre;
|
int start = 0, step, nsteps, centre;
|
||||||
|
|
||||||
@ -869,16 +875,17 @@ static void x11font_really_draw_text(const struct x11font_drawfuncs *dfns,
|
|||||||
centre = FALSE;
|
centre = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dfns->setup(ctx, xfi);
|
dfns->setup(ctx, xfi, disp);
|
||||||
|
|
||||||
while (nsteps-- > 0) {
|
while (nsteps-- > 0) {
|
||||||
int X = x;
|
int X = x;
|
||||||
if (centre)
|
if (centre)
|
||||||
X += (cellwidth - dfns->width(ctx, xfi, string, start, step)) / 2;
|
X += (cellwidth - dfns->width(ctx, xfi, string, start, step)) / 2;
|
||||||
|
|
||||||
dfns->draw(ctx, xfi, X, y, string, start, step);
|
dfns->draw(ctx, xfi, disp, X, y, string, start, step);
|
||||||
if (shadowoffset)
|
if (shadowoffset)
|
||||||
dfns->draw(ctx, xfi, X + shadowoffset, y, string, start, step);
|
dfns->draw(ctx, xfi, disp, X + shadowoffset, y,
|
||||||
|
string, start, step);
|
||||||
|
|
||||||
x += cellwidth;
|
x += cellwidth;
|
||||||
start += step;
|
start += step;
|
||||||
@ -935,7 +942,7 @@ static void x11font_draw_text(unifont_drawctx *ctx, unifont *font,
|
|||||||
}
|
}
|
||||||
|
|
||||||
x11font_really_draw_text(x11font_drawfuncs + index + 1, ctx,
|
x11font_really_draw_text(x11font_drawfuncs + index + 1, ctx,
|
||||||
&xfont->fonts[sfid], x, y,
|
&xfont->fonts[sfid], xfont->disp, x, y,
|
||||||
xcs, len, shadowoffset,
|
xcs, len, shadowoffset,
|
||||||
xfont->variable, cellwidth * mult);
|
xfont->variable, cellwidth * mult);
|
||||||
sfree(xcs);
|
sfree(xcs);
|
||||||
@ -948,7 +955,7 @@ static void x11font_draw_text(unifont_drawctx *ctx, unifont *font,
|
|||||||
int sblen = wc_to_mb(xfont->real_charset, 0, string, len,
|
int sblen = wc_to_mb(xfont->real_charset, 0, string, len,
|
||||||
sbstring, len+1, ".", NULL, NULL);
|
sbstring, len+1, ".", NULL, NULL);
|
||||||
x11font_really_draw_text(x11font_drawfuncs + index + 0, ctx,
|
x11font_really_draw_text(x11font_drawfuncs + index + 0, ctx,
|
||||||
&xfont->fonts[sfid], x, y,
|
&xfont->fonts[sfid], xfont->disp, x, y,
|
||||||
sbstring, sblen, shadowoffset,
|
sbstring, sblen, shadowoffset,
|
||||||
xfont->variable, cellwidth * mult);
|
xfont->variable, cellwidth * mult);
|
||||||
sfree(sbstring);
|
sfree(sbstring);
|
||||||
@ -972,11 +979,14 @@ static void x11font_draw_combining(unifont_drawctx *ctx, unifont *font,
|
|||||||
static void x11font_enum_fonts(GtkWidget *widget,
|
static void x11font_enum_fonts(GtkWidget *widget,
|
||||||
fontsel_add_entry callback, void *callback_ctx)
|
fontsel_add_entry callback, void *callback_ctx)
|
||||||
{
|
{
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
Display *disp;
|
||||||
char **fontnames;
|
char **fontnames;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
int nnames, i, max, tmpsize;
|
int nnames, i, max, tmpsize;
|
||||||
|
|
||||||
|
if ((disp = get_x11_display()) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
max = 32768;
|
max = 32768;
|
||||||
while (1) {
|
while (1) {
|
||||||
fontnames = XListFonts(disp, "*", max, &nnames);
|
fontnames = XListFonts(disp, "*", max, &nnames);
|
||||||
@ -1145,10 +1155,13 @@ static char *x11font_canonify_fontname(GtkWidget *widget, const char *name,
|
|||||||
* selector treats them as worthwhile in their own right.
|
* selector treats them as worthwhile in their own right.
|
||||||
*/
|
*/
|
||||||
XFontStruct *xfs;
|
XFontStruct *xfs;
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
Display *disp;
|
||||||
Atom fontprop, fontprop2;
|
Atom fontprop, fontprop2;
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
|
|
||||||
|
if ((disp = get_x11_display()) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
xfs = XLoadQueryFont(disp, name);
|
xfs = XLoadQueryFont(disp, name);
|
||||||
|
|
||||||
if (!xfs)
|
if (!xfs)
|
||||||
@ -1191,7 +1204,7 @@ static char *x11font_scale_fontname(GtkWidget *widget, const char *name,
|
|||||||
static char *x11font_size_increment(unifont *font, int increment)
|
static char *x11font_size_increment(unifont *font, int increment)
|
||||||
{
|
{
|
||||||
struct x11font *xfont = (struct x11font *)font;
|
struct x11font *xfont = (struct x11font *)font;
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
Display *disp = xfont->disp;
|
||||||
Atom fontprop = XInternAtom(disp, "FONT", False);
|
Atom fontprop = XInternAtom(disp, "FONT", False);
|
||||||
char *returned_name = NULL;
|
char *returned_name = NULL;
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include "x11misc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char *progname, **gtkargvstart;
|
static char *progname, **gtkargvstart;
|
||||||
@ -54,8 +55,10 @@ static const char *app_name = "pterm";
|
|||||||
char *x_get_default(const char *key)
|
char *x_get_default(const char *key)
|
||||||
{
|
{
|
||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
return XGetDefault(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
|
Display *disp;
|
||||||
app_name, key);
|
if ((disp = get_x11_display()) == NULL)
|
||||||
|
return NULL;
|
||||||
|
return XGetDefault(disp, app_name, key);
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
#include "putty.h"
|
#include "putty.h"
|
||||||
#include "gtkcompat.h"
|
#include "gtkcompat.h"
|
||||||
|
|
||||||
|
#ifndef NOT_X_WINDOWS
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void get_label_text_dimensions(const char *text, int *width, int *height)
|
void get_label_text_dimensions(const char *text, int *width, int *height)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -206,3 +211,14 @@ char *buildinfo_gtk_version(void)
|
|||||||
return dupprintf("%d.%d.%d",
|
return dupprintf("%d.%d.%d",
|
||||||
GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
|
GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NOT_X_WINDOWS
|
||||||
|
Display *get_x11_display(void)
|
||||||
|
{
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
if (!GDK_IS_X11_DISPLAY(gdk_display_get_default()))
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
return GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
107
unix/gtkwin.c
107
unix/gtkwin.c
@ -97,6 +97,9 @@ struct gui_data {
|
|||||||
GtkWidget *menu, *specialsmenu, *specialsitem1, *specialsitem2,
|
GtkWidget *menu, *specialsmenu, *specialsitem1, *specialsitem2,
|
||||||
*restartitem;
|
*restartitem;
|
||||||
GtkWidget *sessionsmenu;
|
GtkWidget *sessionsmenu;
|
||||||
|
#ifndef NOT_X_WINDOWS
|
||||||
|
Display *disp;
|
||||||
|
#endif
|
||||||
#ifndef NO_BACKING_PIXMAPS
|
#ifndef NO_BACKING_PIXMAPS
|
||||||
/*
|
/*
|
||||||
* Server-side pixmap which we use to cache the terminal window's
|
* Server-side pixmap which we use to cache the terminal window's
|
||||||
@ -2854,31 +2857,36 @@ void frontend_request_paste(void *frontend, int clipboard)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Store the data in a cut-buffer. */
|
/* Store the data in a cut-buffer. */
|
||||||
static void store_cutbuffer(char * ptr, int len)
|
static void store_cutbuffer(struct gui_data *inst, char *ptr, int len)
|
||||||
{
|
{
|
||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
if (inst->disp) {
|
||||||
/* ICCCM says we must rotate the buffers before storing to buffer 0. */
|
/* ICCCM says we must rotate the buffers before storing to buffer 0. */
|
||||||
XRotateBuffers(disp, 1);
|
XRotateBuffers(inst->disp, 1);
|
||||||
XStoreBytes(disp, ptr, len);
|
XStoreBytes(inst->disp, ptr, len);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve data from a cut-buffer.
|
/* Retrieve data from a cut-buffer.
|
||||||
* Returned data needs to be freed with XFree().
|
* Returned data needs to be freed with XFree().
|
||||||
*/
|
*/
|
||||||
static char *retrieve_cutbuffer(int *nbytes)
|
static char *retrieve_cutbuffer(struct gui_data *inst, int *nbytes)
|
||||||
{
|
{
|
||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
char *ptr;
|
||||||
char * ptr;
|
if (!inst->disp) {
|
||||||
ptr = XFetchBytes(disp, nbytes);
|
*nbytes = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ptr = XFetchBytes(inst->disp, nbytes);
|
||||||
if (*nbytes <= 0 && ptr != 0) {
|
if (*nbytes <= 0 && ptr != 0) {
|
||||||
XFree(ptr);
|
XFree(ptr);
|
||||||
ptr = 0;
|
ptr = 0;
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
#else
|
#else
|
||||||
|
*nbytes = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2907,7 +2915,6 @@ void write_clip(void *frontend, int clipboard,
|
|||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
XTextProperty tp;
|
XTextProperty tp;
|
||||||
char *list[1];
|
char *list[1];
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
state->pasteout_data_utf8 = snewn(len*6, char);
|
state->pasteout_data_utf8 = snewn(len*6, char);
|
||||||
@ -2931,8 +2938,8 @@ void write_clip(void *frontend, int clipboard,
|
|||||||
*/
|
*/
|
||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
list[0] = state->pasteout_data_utf8;
|
list[0] = state->pasteout_data_utf8;
|
||||||
if (Xutf8TextListToTextProperty(disp, list, 1,
|
if (inst->disp && Xutf8TextListToTextProperty(
|
||||||
XCompoundTextStyle, &tp) == 0) {
|
inst->disp, list, 1, XCompoundTextStyle, &tp) == 0) {
|
||||||
state->pasteout_data_ctext = snewn(tp.nitems+1, char);
|
state->pasteout_data_ctext = snewn(tp.nitems+1, char);
|
||||||
memcpy(state->pasteout_data_ctext, tp.value, tp.nitems);
|
memcpy(state->pasteout_data_ctext, tp.value, tp.nitems);
|
||||||
state->pasteout_data_ctext_len = tp.nitems;
|
state->pasteout_data_ctext_len = tp.nitems;
|
||||||
@ -2966,7 +2973,7 @@ void write_clip(void *frontend, int clipboard,
|
|||||||
|
|
||||||
/* The legacy X cut buffers go with PRIMARY, not any other clipboard */
|
/* The legacy X cut buffers go with PRIMARY, not any other clipboard */
|
||||||
if (state->atom == GDK_SELECTION_PRIMARY)
|
if (state->atom == GDK_SELECTION_PRIMARY)
|
||||||
store_cutbuffer(state->pasteout_data, state->pasteout_data_len);
|
store_cutbuffer(inst, state->pasteout_data, state->pasteout_data_len);
|
||||||
|
|
||||||
if (gtk_selection_owner_set(inst->area, state->atom,
|
if (gtk_selection_owner_set(inst->area, state->atom,
|
||||||
inst->input_event_time)) {
|
inst->input_event_time)) {
|
||||||
@ -3131,7 +3138,7 @@ static void selection_received(GtkWidget *widget, GtkSelectionData *seldata,
|
|||||||
*/
|
*/
|
||||||
if (seldata_length <= 0) {
|
if (seldata_length <= 0) {
|
||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
text = retrieve_cutbuffer(&length);
|
text = retrieve_cutbuffer(inst, &length);
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
return;
|
return;
|
||||||
/* Xterm is rumoured to expect Latin-1, though I havn't checked the
|
/* Xterm is rumoured to expect Latin-1, though I havn't checked the
|
||||||
@ -3149,13 +3156,13 @@ static void selection_received(GtkWidget *widget, GtkSelectionData *seldata,
|
|||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
XTextProperty tp;
|
XTextProperty tp;
|
||||||
int ret, count;
|
int ret, count;
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
|
||||||
|
|
||||||
tp.value = (unsigned char *)seldata_data;
|
tp.value = (unsigned char *)seldata_data;
|
||||||
tp.encoding = (Atom) seldata_type;
|
tp.encoding = (Atom) seldata_type;
|
||||||
tp.format = gtk_selection_data_get_format(seldata);
|
tp.format = gtk_selection_data_get_format(seldata);
|
||||||
tp.nitems = seldata_length;
|
tp.nitems = seldata_length;
|
||||||
ret = Xutf8TextPropertyToTextList(disp, &tp, &list, &count);
|
ret = inst->disp == NULL ? -1 :
|
||||||
|
Xutf8TextPropertyToTextList(inst->disp, &tp, &list, &count);
|
||||||
if (ret == 0 && count == 1) {
|
if (ret == 0 && count == 1) {
|
||||||
text = list[0];
|
text = list[0];
|
||||||
length = strlen(list[0]);
|
length = strlen(list[0]);
|
||||||
@ -3220,32 +3227,33 @@ void init_clipboard(struct gui_data *inst)
|
|||||||
* Ensure that all the cut buffers exist - according to the ICCCM,
|
* Ensure that all the cut buffers exist - according to the ICCCM,
|
||||||
* we must do this before we start using cut buffers.
|
* we must do this before we start using cut buffers.
|
||||||
*/
|
*/
|
||||||
unsigned char empty[] = "";
|
if (inst->disp) {
|
||||||
Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
unsigned char empty[] = "";
|
||||||
x11_ignore_error(disp, BadMatch);
|
x11_ignore_error(inst->disp, BadMatch);
|
||||||
XChangeProperty(disp, GDK_ROOT_WINDOW(),
|
XChangeProperty(inst->disp, GDK_ROOT_WINDOW(), XA_CUT_BUFFER0,
|
||||||
XA_CUT_BUFFER0, XA_STRING, 8, PropModeAppend, empty, 0);
|
XA_STRING, 8, PropModeAppend, empty, 0);
|
||||||
x11_ignore_error(disp, BadMatch);
|
x11_ignore_error(inst->disp, BadMatch);
|
||||||
XChangeProperty(disp, GDK_ROOT_WINDOW(),
|
XChangeProperty(inst->disp, GDK_ROOT_WINDOW(), XA_CUT_BUFFER1,
|
||||||
XA_CUT_BUFFER1, XA_STRING, 8, PropModeAppend, empty, 0);
|
XA_STRING, 8, PropModeAppend, empty, 0);
|
||||||
x11_ignore_error(disp, BadMatch);
|
x11_ignore_error(inst->disp, BadMatch);
|
||||||
XChangeProperty(disp, GDK_ROOT_WINDOW(),
|
XChangeProperty(inst->disp, GDK_ROOT_WINDOW(), XA_CUT_BUFFER2,
|
||||||
XA_CUT_BUFFER2, XA_STRING, 8, PropModeAppend, empty, 0);
|
XA_STRING, 8, PropModeAppend, empty, 0);
|
||||||
x11_ignore_error(disp, BadMatch);
|
x11_ignore_error(inst->disp, BadMatch);
|
||||||
XChangeProperty(disp, GDK_ROOT_WINDOW(),
|
XChangeProperty(inst->disp, GDK_ROOT_WINDOW(), XA_CUT_BUFFER3,
|
||||||
XA_CUT_BUFFER3, XA_STRING, 8, PropModeAppend, empty, 0);
|
XA_STRING, 8, PropModeAppend, empty, 0);
|
||||||
x11_ignore_error(disp, BadMatch);
|
x11_ignore_error(inst->disp, BadMatch);
|
||||||
XChangeProperty(disp, GDK_ROOT_WINDOW(),
|
XChangeProperty(inst->disp, GDK_ROOT_WINDOW(), XA_CUT_BUFFER4,
|
||||||
XA_CUT_BUFFER4, XA_STRING, 8, PropModeAppend, empty, 0);
|
XA_STRING, 8, PropModeAppend, empty, 0);
|
||||||
x11_ignore_error(disp, BadMatch);
|
x11_ignore_error(inst->disp, BadMatch);
|
||||||
XChangeProperty(disp, GDK_ROOT_WINDOW(),
|
XChangeProperty(inst->disp, GDK_ROOT_WINDOW(), XA_CUT_BUFFER5,
|
||||||
XA_CUT_BUFFER5, XA_STRING, 8, PropModeAppend, empty, 0);
|
XA_STRING, 8, PropModeAppend, empty, 0);
|
||||||
x11_ignore_error(disp, BadMatch);
|
x11_ignore_error(inst->disp, BadMatch);
|
||||||
XChangeProperty(disp, GDK_ROOT_WINDOW(),
|
XChangeProperty(inst->disp, GDK_ROOT_WINDOW(), XA_CUT_BUFFER6,
|
||||||
XA_CUT_BUFFER6, XA_STRING, 8, PropModeAppend, empty, 0);
|
XA_STRING, 8, PropModeAppend, empty, 0);
|
||||||
x11_ignore_error(disp, BadMatch);
|
x11_ignore_error(inst->disp, BadMatch);
|
||||||
XChangeProperty(disp, GDK_ROOT_WINDOW(),
|
XChangeProperty(inst->disp, GDK_ROOT_WINDOW(), XA_CUT_BUFFER7,
|
||||||
XA_CUT_BUFFER7, XA_STRING, 8, PropModeAppend, empty, 0);
|
XA_STRING, 8, PropModeAppend, empty, 0);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inst->clipstates[CLIP_PRIMARY].atom = GDK_SELECTION_PRIMARY;
|
inst->clipstates[CLIP_PRIMARY].atom = GDK_SELECTION_PRIMARY;
|
||||||
@ -4060,10 +4068,14 @@ const char *get_x_display(void *frontend)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
long get_windowid(void *frontend)
|
int get_windowid(void *frontend, long *id)
|
||||||
{
|
{
|
||||||
struct gui_data *inst = (struct gui_data *)frontend;
|
struct gui_data *inst = (struct gui_data *)frontend;
|
||||||
return (long)GDK_WINDOW_XID(gtk_widget_get_window(inst->area));
|
GdkWindow *window = gtk_widget_get_window(inst->area);
|
||||||
|
if (!GDK_IS_X11_WINDOW(window))
|
||||||
|
return FALSE;
|
||||||
|
*id = GDK_WINDOW_XID(window);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -4992,6 +5004,7 @@ void new_session_window(Conf *conf, const char *geometry_string)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NOT_X_WINDOWS
|
#ifndef NOT_X_WINDOWS
|
||||||
|
inst->disp = get_x11_display();
|
||||||
if (geometry_string) {
|
if (geometry_string) {
|
||||||
int flags, x, y;
|
int flags, x, y;
|
||||||
unsigned int w, h;
|
unsigned int w, h;
|
||||||
@ -5046,13 +5059,11 @@ void new_session_window(Conf *conf, const char *geometry_string)
|
|||||||
GdkWindow *gdkwin;
|
GdkWindow *gdkwin;
|
||||||
gtk_widget_realize(GTK_WIDGET(inst->window));
|
gtk_widget_realize(GTK_WIDGET(inst->window));
|
||||||
gdkwin = gtk_widget_get_window(GTK_WIDGET(inst->window));
|
gdkwin = gtk_widget_get_window(GTK_WIDGET(inst->window));
|
||||||
if (gdk_window_ensure_native(gdkwin)) {
|
if (inst->disp && gdk_window_ensure_native(gdkwin)) {
|
||||||
Display *disp =
|
|
||||||
GDK_DISPLAY_XDISPLAY(gdk_window_get_display(gdkwin));
|
|
||||||
XClassHint *xch = XAllocClassHint();
|
XClassHint *xch = XAllocClassHint();
|
||||||
xch->res_name = (char *)winclass;
|
xch->res_name = (char *)winclass;
|
||||||
xch->res_class = (char *)winclass;
|
xch->res_class = (char *)winclass;
|
||||||
XSetClassHint(disp, GDK_WINDOW_XID(gdkwin), xch);
|
XSetClassHint(inst->disp, GDK_WINDOW_XID(gdkwin), xch);
|
||||||
XFree(xch);
|
XFree(xch);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -195,7 +195,7 @@ void app_menu_action(void *frontend, enum MenuAction);
|
|||||||
/* Things pty.c needs from pterm.c */
|
/* Things pty.c needs from pterm.c */
|
||||||
const char *get_x_display(void *frontend);
|
const char *get_x_display(void *frontend);
|
||||||
int font_dimension(void *frontend, int which);/* 0 for width, 1 for height */
|
int font_dimension(void *frontend, int which);/* 0 for width, 1 for height */
|
||||||
long get_windowid(void *frontend);
|
int get_windowid(void *frontend, long *id);
|
||||||
|
|
||||||
/* Things gtkdlg.c needs from pterm.c */
|
/* Things gtkdlg.c needs from pterm.c */
|
||||||
#ifdef MAY_REFER_TO_GTK_IN_HEADERS
|
#ifdef MAY_REFER_TO_GTK_IN_HEADERS
|
||||||
|
@ -742,6 +742,7 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
|
|||||||
int slavefd;
|
int slavefd;
|
||||||
pid_t pid, pgrp;
|
pid_t pid, pgrp;
|
||||||
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
||||||
|
int got_windowid;
|
||||||
long windowid;
|
long windowid;
|
||||||
#endif
|
#endif
|
||||||
Pty pty;
|
Pty pty;
|
||||||
@ -794,7 +795,7 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
||||||
windowid = get_windowid(pty->frontend);
|
got_windowid = get_windowid(pty->frontend, &windowid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -909,7 +910,7 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
||||||
{
|
if (got_windowid) {
|
||||||
char *windowid_env_var = dupprintf("WINDOWID=%ld", windowid);
|
char *windowid_env_var = dupprintf("WINDOWID=%ld", windowid);
|
||||||
putenv(windowid_env_var);
|
putenv(windowid_env_var);
|
||||||
/* We mustn't free windowid_env_var, as putenv links it into the
|
/* We mustn't free windowid_env_var, as putenv links it into the
|
||||||
|
@ -12,4 +12,9 @@
|
|||||||
*/
|
*/
|
||||||
void x11_ignore_error(Display *disp, unsigned char errcode);
|
void x11_ignore_error(Display *disp, unsigned char errcode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gtkmisc.c
|
||||||
|
*/
|
||||||
|
Display *get_x11_display(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user