1 /* Copyright (C) 2000-2012 by George Williams */
2 /*
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are met:
5 
6  * Redistributions of source code must retain the above copyright notice, this
7  * list of conditions and the following disclaimer.
8 
9  * Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12 
13  * The name of the author may not be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15 
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /* There are two configurable option here that the configure script can't
29     figure out:
30 
31 	_WACOM_DRV_BROKEN
32 on my system the XFree driver for the WACOM tablet sends no events. I don't
33 understand the driver, so I'm not able to attempt fixing it. However thanks
34 to John E. Joganic wacdump program I do know what the event stream on
35 	/dev/input/event0
36 looks like, and I shall attempt to simulate driver behavior from that
37 
38 So set macro this in your makefile if you have problems too, and then
39 change the protection on /dev/input/event0 so that it is world readable
40 
41 (there is now a working XFree driver for wacom, but you have to get it from
42 John, it's not part of standard XFree yet).
43 
44 	_COMPOSITE_BROKEN
45 on XFree with the composite extension active, scrolling windows with docket
46 palletes may result in parts of the palettes duplicated outside their dock
47 rectangles.
48 
49 Defining this macro forces redisplay of the entire window area, which is
50 slightly slower, but should make no significant difference on a machine
51 capable of using composite.
52 */
53 
54 #ifndef FONTFORGE_XDRAW_H
55 #define FONTFORGE_XDRAW_H
56 
57 #include <fontforge-config.h>
58 
59 #ifndef FONTFORGE_CAN_USE_GDK
60 
61 #include "gdrawP.h"
62 
63 #ifndef X_DISPLAY_MISSING
64 # include <X11/X.h>
65 # include <X11/Xlib.h>
66 # include <X11/Xutil.h>
67 # ifndef _NO_XINPUT
68 #  include <X11/extensions/XI.h>
69 #  include <X11/extensions/XInput.h>
70 # endif
71 # ifndef _NO_XKB
72 #   include <X11/XKBlib.h>
73 /*# include <X11/extensions/XKBgeom.h>*/
74 # endif
75 # ifndef _NO_LIBCAIRO
76 #  include <cairo/cairo-xlib.h>
77 #  include <cairo/cairo.h>
78 # endif
79 #  define GTimer GTimer_GTK
80 #  include <X11/Xft/Xft.h>
81 #  include <ft2build.h>
82 #  include <pango/pango.h>
83 #  undef GTimer
84 #endif
85 
86 #ifdef HAVE_PTHREAD_H
87 # include <pthread.h>
88 #endif
89 
90 typedef struct gcstate {
91     void *gc;
92     Color fore_col;		/* desired */
93     Color back_col;		/* desired */
94     GRect clip;
95     unsigned int bitmap_col: 1;			/* fore_col is mapped for bitmap */
96     int16 dash_len, skip_len;
97     int16 line_width;
98     int16 dash_offset;
99     int16 ts;
100     int32 ts_xoff, ts_yoff;
101     struct font_data *cur_font;
102 } GCState;
103 
104 #ifndef X_DISPLAY_MISSING
105 struct gxinput_context {
106     GWindow w;
107     enum gic_style style;
108     XIC ic;
109     struct gxinput_context *next;
110     XPoint ploc;
111     XPoint sloc;
112 };
113 
114 typedef struct gxwindow /* :GWindow */ {
115     GGC *ggc;
116     struct gxdisplay *display;
117     int (*eh)(GWindow,GEvent *);
118     GRect pos;				/* Filled in when Resize events happen */
119     struct gxwindow *parent;
120     void *user_data;
121     void *widget_data;
122     Window w;
123     unsigned int is_visible: 1;		/* Filled in when MapNotify events happen */
124     unsigned int is_pixmap: 1;
125     unsigned int is_toplevel: 1;
126     unsigned int visible_request: 1;
127     unsigned int is_dying: 1;
128     unsigned int is_popup: 1;
129     unsigned int disable_expose_requests: 1;
130     unsigned int usecairo: 1;		/* use a cairo context */
131     unsigned int is_dlg: 1;
132     unsigned int not_restricted: 1;
133     unsigned int was_positioned: 1;
134 	/* is_bitmap can be found in the bitmap_col field of the ggc */
135     unsigned int restrict_input_to_me: 1;/* for dialogs, no input outside of dlg */
136     unsigned int redirect_chars_to_me: 1;/* ditto, we get any input outside of us */
137     unsigned int istransient: 1;	/* has transient for hint set */
138     unsigned int isverytransient: 1;
139     GWindow redirect_from;		/* only redirect input from this window and its children */
140     GCursor cursor;
141     Window parentissimus;
142     struct gxinput_context *gic, *all;
143     PangoLayout  *pango_layout;
144 #ifndef _NO_LIBCAIRO
145     cairo_t *cc;
146     cairo_surface_t *cs;
147     struct gcstate cairo_state;
148 #endif
149     XftDraw *xft_w;
150     Window transient_owner;
151 } *GXWindow;
152 
153 struct colstate {
154     int16 red_shift, green_shift, blue_shift;
155     int32 red_bits_mask, green_bits_mask, blue_bits_mask;
156     int16 red_bits_shift, green_bits_shift, blue_bits_shift;
157     int32 alpha_bits;
158     RevCMap *rev;
159     unsigned int is_grey: 1;
160 };
161 
162 struct gatoms {
163     Atom wm_del_window;
164     Atom wm_protocols;
165     Atom drag_and_drop;
166 };
167 
168 /* Input states:
169     normal => input goes to the expected window
170     restricted => input only goes to one window (and its children)
171     redirected => characters from any window go to one window
172     targetted_redirect => characters from one special window (and its children) go to another window
173 */
174 enum inputtype { it_normal, it_restricted, it_redirected, it_targetted };
175 struct inputRedirect {
176     enum inputtype it;
177     GWindow cur_dlg;		/* This one always gets input */
178     GWindow inactive;		/* This one gives its input to the dlg */
179     struct inputRedirect *prev;
180 };
181 
182 struct button_state {
183     Time release_time;
184     Window release_w;
185     int16 release_x, release_y;
186     int16 release_button;
187     int16 cur_click;
188     int16 double_time;		/* max milliseconds between release & click */
189     int16 double_wiggle;	/* max pixel wiggle allowed between release&click */
190 };
191 
192 struct seldata {
193     int32 typeatom;
194     int32 cnt;
195     int32 unitsize;
196     void *data;
197     void *(*gendata)(void *,int32 *len);
198     /* Either the data are stored here, or we use this function to generate them on the fly */
199     void (*freedata)(void *);
200     struct seldata *next;
201 };
202 
203 struct gxselinfo {
204     int32 sel_atom;		/* Either XA_PRIMARY or CLIPBOARD */
205     GXWindow owner;
206     Time timestamp;
207     struct seldata *datalist;
208 };
209 
210 struct gxseltypes {
211     Time timestamp;		/* for last request for selection types */
212     int cnt;			/* number of types return */
213     Atom *types;		/* array of selection types */
214 };
215 
216 struct things_to_do {
217     void (*func)(void *);
218     void *data;
219     struct things_to_do *next;
220 };
221 
222 struct xthreaddata {
223 # ifdef HAVE_PTHREAD_H
224     pthread_mutex_t sync_mutex;		/* controls access to the rest of this structure */
225     struct things_to_do *things_to_do;
226 # endif
227     int sync_sock, send_sock;		/* socket on which to send sync events to thread displaying screen */
228 };
229 
230 struct gimageglobals {
231     XImage *img, *mask;
232     int16 *red_dith, *green_dith, *blue_dith;
233     int32 iwidth, iheight;
234 };
235 
236 struct atomdata { char *atomname; int32 xatom; };
237 
238 struct inputdevices {
239     char *name;
240     int devid;
241 # ifndef _NO_XINPUT
242     XDevice *dev;
243 # else
244     int *dev;
245 # endif
246     int event_types[5];	/* mousemove, mousedown, mouseup, char, charup */
247 };
248 
249 struct xkb {
250     int opcode, event, error;
251 };
252 
253 typedef struct gxdisplay /* : GDisplay */ {
254     struct displayfuncs *funcs;
255     struct font_state *fontstate;
256     int16 res;
257     GXWindow groot;
258     Color def_background, def_foreground;
259     uint16 mykey_state;
260     uint16 mykey_keysym;
261     uint16 mykey_mask;
262     unsigned int mykeybuild: 1;
263     unsigned int default_visual: 1;
264     unsigned int do_dithering: 1;
265     unsigned int focusfollowsmouse: 1;
266     unsigned int top_offsets_set: 1;
267     unsigned int wm_breaks_raiseabove: 1;
268     unsigned int wm_raiseabove_tested: 1;
269     unsigned int endian_mismatch: 1;
270     unsigned int macosx_cmd: 1;		/* if set then map state=0x20 to control */
271     unsigned int twobmouse_win: 1;	/* if set then map state=0x40 to mouse button 2 */
272     unsigned int devicesinit: 1;	/* the devices structure has been initialized. Else call XListInputDevices */
273     unsigned int expecting_core_event: 1;/* when we move an input extension device we generally get two events, one for the device, one later for the core device. eat the core event */
274     unsigned int has_xkb: 1;		/* we were able to initialize the XKB extension */
275     unsigned int supports_alpha_images: 1;
276     unsigned int supports_alpha_windows: 1;
277     int err_flag;
278     char * err_report;
279     struct gcstate gcstate[2];			/* 0 is state for normal images, 1 for bitmap (pixmaps) */
280     Display *display;
281     Window root;
282     Window virtualRoot;				/* Some window managers create a "virtual root" that is bigger than the real root and all decoration windows live in it */
283     int16 screen;
284     int16 depth;
285     int16 pixel_size;				/* 32bit displays usually have a 24bit depth */
286     int16 bitmap_pad;				/* 8bit displays sometimes pad on 32bit boundaries */
287     Visual *visual;
288     Colormap cmap;
289     struct colstate cs;
290     struct gatoms atoms;
291     struct button_state bs;
292     XComposeStatus buildingkeys;
293     struct inputRedirect *input;
294     struct gimageglobals gg;
295     Pixmap grey_stipple;
296     Pixmap fence_stipple;
297     int32 mycontext;
298     int16 top_window_count;
299     GTimer *timers;
300     Time last_event_time;
301     struct gxselinfo selinfo[sn_max];
302     int amax, alen;
303     struct atomdata *atomdata;
304     struct gxseltypes seltypes;
305     int32 SelNotifyTimeout;		/* In seconds (time to give up on requests for selections) */
306     struct {
307 	Window w;
308 	GWindow gw;
309 	int x,y;
310 	int rx,ry;
311     } last_dd;
312     struct xthreaddata xthread;
313     int16 off_x, off_y;			/* The difference between where I asked */
314     					/*  to put a top level window, and where */
315 			                /*  it ended up */
316     GWindow grab_window;		/* For reasons I don't understand the */
317 	/* X Server seems to deliver events to my windows even when the pointer*/
318 	/* is grabbed by another window. If the pointer is outside of any of my*/
319 	/* windows then the event goes to my grab window, but if it's in one of*/
320 	/* my other windows, then that window gets it and is mightily confused*/
321 	/* So this field lets us do it right. when the pointer is grabbed the */
322 	/* events go to the grab window. It seems so simple... */
323     int16 desired_depth, desired_vc, desired_cm;
324     int16 xres;				/* What X Thinks the resolution is */
325     XIM im;				/* Input method for current locale */
326     XFontSet def_im_fontset;
327     struct inputdevices *inputdevices;
328     int n_inputdevices;
329 # ifdef _WACOM_DRV_BROKEN
330     struct wacom_state *wacom_state;
331     int wacom_fd;
332 # endif
333     GXWindow default_icon;
334     struct xkb xkb;
335     PangoFontMap *pango_fontmap;
336     PangoContext *pango_context;
337 # if !defined(_NO_LIBCAIRO)
338     PangoFontMap *pangoc_fontmap;
339     PangoContext *pangoc_context;
340 # endif
341 # if defined(__MINGW32__) || __CygWin
342     int32  mousemove_last_x;
343     int32  mousemove_last_y;
344 #endif
345     Window last_nontransient_window;
346 } GXDisplay;
347 
348 # define Pixel32(gdisp,col) ( Pixel16(gdisp,col) | (gdisp)->cs.alpha_bits )
349 # define Pixel24(gdisp,col) ( ((((col)>>16)&0xff)<<(gdisp)->cs.red_shift) | ((((col)>>8)&0xff)<<(gdisp)->cs.green_shift) | (((col)&0xff)<<(gdisp)->cs.blue_shift) )
350 # define Pixel16(gdisp,col) ( ((((col)>>(gdisp)->cs.red_bits_shift)&(gdisp)->cs.red_bits_mask)<<(gdisp)->cs.red_shift) | ((((col)>>(gdisp)->cs.green_bits_shift)&(gdisp)->cs.green_bits_mask)<<(gdisp)->cs.green_shift) | (((col>>(gdisp)->cs.blue_bits_shift)&(gdisp)->cs.blue_bits_mask)<<(gdisp)->cs.blue_shift) )
351 # define FixEndian16(col)	((((col)&0xff)<<8) | ((col>>8)&0xff))
352 # define FixEndian32(col)	((((col)&0xff)<<24) | ((col&0xff00)<<8) | ((col>>8)&0xff00))
353 
354 #else /* No X */
355 
356 # define gxwindow gwindow
357 # define gxdisplay gdisplay
358 typedef struct gwindow *GXWindow;
359 typedef struct gdisplay GXDisplay;
360 
361 #endif
362 
363 extern int _GXDraw_WindowOrParentsDying(GXWindow gw);
364 extern void _GXCDraw_NewWindow(GXWindow nw);
365 extern void _GXDraw_Image(GWindow, GImage *, GRect *src, int32 x, int32 y);
366 extern void _GXDraw_TileImage(GWindow, GImage *, GRect *src, int32 x, int32 y);
367 extern void _GXDraw_Glyph(GWindow, GImage *, GRect *src, int32 x, int32 y);
368 extern void _GXDraw_ImageMagnified(GWindow, GImage *, GRect *src, int32 x, int32 y, int32 width, int32 height);
369 extern GImage *_GXDraw_CopyScreenToImage(GWindow, GRect *rect);
370 
371 extern void _GXDraw_SetClipFunc(GXDisplay *gdisp, GGC *mine);
372 extern struct gcol *_GXDraw_GetScreenPixelInfo(GXDisplay *gdisp, int red, int green, int blue);
373 extern unsigned long _GXDraw_GetScreenPixel(GXDisplay *gdisp, Color col);
374 extern GImage *_GImageExtract(struct _GImage *base,GRect *src,GRect *size, double xscale, double yscale);
375 
376 extern void _XSyncScreen(void);
377 
378 #if !defined(__MINGW32__)
379 extern int GDrawKeyToXK(int keysym);
380 #else
381 extern int GDrawKeyToVK(int keysym);
382 #endif
383 
384 # ifdef _WACOM_DRV_BROKEN
385 void _GXDraw_Wacom_Init(GXDisplay *gdisp);
386 void _GXDraw_Wacom_TestEvents(GXDisplay *gdisp);
387 # endif	/* Wacom fix */
388 
389 
390 #endif // FONTFORGE_CAN_USE_GDK
391 
392 #endif /* FONTFORGE_XDRAW_H */
393