fltk  1.3.5-source
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X.
  Fossies Dox: fltk-1.3.5-source.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_x.cxx
Go to the documentation of this file.
1 //
2 // "$Id$"
3 //
4 // X specific code for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2016 by Bill Spitzak and others.
7 //
8 // This library is free software. Distribution and use rights are outlined in
9 // the file "COPYING" which should have been included with this file. If this
10 // file is missing or damaged, see the license at:
11 //
12 // http://www.fltk.org/COPYING.php
13 //
14 // Please report all bugs and problems on the following page:
15 //
16 // http://www.fltk.org/str.php
17 //
18 
19 #ifdef WIN32
20 //# include "Fl_win32.cxx"
21 #elif defined(__APPLE__)
22 //# include "Fl_mac.cxx" // now Fl_cocoa.mm
23 #elif !defined(FL_DOXYGEN)
24 
25 # define CONSOLIDATE_MOTION 1
26 /**** Define this if your keyboard lacks a backspace key... ****/
27 /* #define BACKSPACE_HACK 1 */
28 
29 # include <config.h>
30 # include <FL/Fl.H>
31 # include <FL/x.H>
32 # include <FL/Fl_Window.H>
33 # include <FL/fl_utf8.h>
34 # include <FL/Fl_Tooltip.H>
35 # include <FL/fl_draw.H>
36 # include <FL/Fl_Paged_Device.H>
37 # include <FL/Fl_Shared_Image.H>
38 # include <FL/fl_ask.H>
39 # include <FL/filename.H>
40 # include <stdio.h>
41 # include <stdlib.h>
42 # include "flstring.h"
43 # include <unistd.h>
44 # include <time.h>
45 # include <sys/time.h>
46 # include <X11/Xmd.h>
47 # include <X11/Xlocale.h>
48 # include <X11/Xlib.h>
49 # include <X11/keysym.h>
50 # include "Xutf8.h"
51 #define USE_XRANDR (HAVE_DLSYM && HAVE_DLFCN_H) // means attempt to dynamically load libXrandr.so
52 #if USE_XRANDR
53 #include <dlfcn.h>
54 #define RRScreenChangeNotifyMask (1L << 0) // from X11/extensions/Xrandr.h
55 #define RRScreenChangeNotify 0 // from X11/extensions/Xrandr.h
56 typedef int (*XRRUpdateConfiguration_type)(XEvent *event);
57 static XRRUpdateConfiguration_type XRRUpdateConfiguration_f;
58 static int randrEventBase; // base of RandR-defined events
59 #endif
60 
61 # if HAVE_XFIXES
62 # include <X11/extensions/Xfixes.h>
63 static int xfixes_event_base = 0;
64 static bool have_xfixes = false;
65 # endif
66 
67 # include <X11/cursorfont.h>
68 
69 # if HAVE_XCURSOR
70 # include <X11/Xcursor/Xcursor.h>
71 # endif
72 # if HAVE_XRENDER
73 # include <X11/extensions/Xrender.h>
74 # endif
75 
77 // interface to poll/select call:
78 
79 # if USE_POLL
80 
81 # include <poll.h>
82 static pollfd *pollfds = 0;
83 
84 # else
85 # if HAVE_SYS_SELECT_H
86 # include <sys/select.h>
87 # endif /* HAVE_SYS_SELECT_H */
88 
89 // The following #define is only needed for HP-UX 9.x and earlier:
90 //#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e))
91 
92 static fd_set fdsets[3];
93 static int maxfd;
94 # define POLLIN 1
95 # define POLLOUT 4
96 # define POLLERR 8
97 
98 # endif /* USE_POLL */
99 
100 static int nfds = 0;
101 static int fd_array_size = 0;
102 struct FD {
103 # if !USE_POLL
104  int fd;
105  short events;
106 # endif
107  void (*cb)(int, void*);
108  void* arg;
109 };
110 
111 static FD *fd = 0;
112 
113 void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
114  remove_fd(n,events);
115  int i = nfds++;
116  if (i >= fd_array_size) {
117  FD *temp;
119 
120  if (!fd) temp = (FD*)malloc(fd_array_size*sizeof(FD));
121  else temp = (FD*)realloc(fd, fd_array_size*sizeof(FD));
122 
123  if (!temp) return;
124  fd = temp;
125 
126 # if USE_POLL
127  pollfd *tpoll;
128 
129  if (!pollfds) tpoll = (pollfd*)malloc(fd_array_size*sizeof(pollfd));
130  else tpoll = (pollfd*)realloc(pollfds, fd_array_size*sizeof(pollfd));
131 
132  if (!tpoll) return;
133  pollfds = tpoll;
134 # endif
135  }
136  fd[i].cb = cb;
137  fd[i].arg = v;
138 # if USE_POLL
139  pollfds[i].fd = n;
140  pollfds[i].events = events;
141 # else
142  fd[i].fd = n;
143  fd[i].events = events;
144  if (events & POLLIN) FD_SET(n, &fdsets[0]);
145  if (events & POLLOUT) FD_SET(n, &fdsets[1]);
146  if (events & POLLERR) FD_SET(n, &fdsets[2]);
147  if (n > maxfd) maxfd = n;
148 # endif
149 }
150 
151 void Fl::add_fd(int n, void (*cb)(int, void*), void* v) {
152  Fl::add_fd(n, POLLIN, cb, v);
153 }
154 
155 void Fl::remove_fd(int n, int events) {
156  int i,j;
157 # if !USE_POLL
158  maxfd = -1; // recalculate maxfd on the fly
159 # endif
160  for (i=j=0; i<nfds; i++) {
161 # if USE_POLL
162  if (pollfds[i].fd == n) {
163  int e = pollfds[i].events & ~events;
164  if (!e) continue; // if no events left, delete this fd
165  pollfds[j].events = e;
166  }
167 # else
168  if (fd[i].fd == n) {
169  int e = fd[i].events & ~events;
170  if (!e) continue; // if no events left, delete this fd
171  fd[i].events = e;
172  }
173  if (fd[i].fd > maxfd) maxfd = fd[i].fd;
174 # endif
175  // move it down in the array if necessary:
176  if (j<i) {
177  fd[j] = fd[i];
178 # if USE_POLL
179  pollfds[j] = pollfds[i];
180 # endif
181  }
182  j++;
183  }
184  nfds = j;
185 # if !USE_POLL
186  if (events & POLLIN) FD_CLR(n, &fdsets[0]);
187  if (events & POLLOUT) FD_CLR(n, &fdsets[1]);
188  if (events & POLLERR) FD_CLR(n, &fdsets[2]);
189 # endif
190 }
191 
192 void Fl::remove_fd(int n) {
193  remove_fd(n, -1);
194 }
195 
196 extern int fl_send_system_handlers(void *e);
197 
198 #if CONSOLIDATE_MOTION
200 extern Fl_Window* fl_xmousewin;
201 #endif
202 static bool in_a_window; // true if in any of our windows, even destroyed ones
203 static void do_queued_events() {
204  in_a_window = true;
205  while (XEventsQueued(fl_display,QueuedAfterReading)) {
206  XEvent xevent;
207  XNextEvent(fl_display, &xevent);
208  if (fl_send_system_handlers(&xevent))
209  continue;
210  fl_handle(xevent);
211  }
212  // we send FL_LEAVE only if the mouse did not enter some other window:
213  if (!in_a_window) Fl::handle(FL_LEAVE, 0);
214 #if CONSOLIDATE_MOTION
215  else if (send_motion == fl_xmousewin) {
216  send_motion = 0;
218  }
219 #endif
220 }
221 
222 // these pointers are set by the Fl::lock() function:
223 static void nothing() {}
226 
227 // This is never called with time_to_wait < 0.0:
228 // It should return negative on error, 0 if nothing happens before
229 // timeout, and >0 if any callbacks were done.
230 int fl_wait(double time_to_wait) {
231 
232  // OpenGL and other broken libraries call XEventsQueued
233  // unnecessarily and thus cause the file descriptor to not be ready,
234  // so we must check for already-read events:
235  if (fl_display && XQLength(fl_display)) {do_queued_events(); return 1;}
236 
237 # if !USE_POLL
238  fd_set fdt[3];
239  fdt[0] = fdsets[0];
240  fdt[1] = fdsets[1];
241  fdt[2] = fdsets[2];
242 # endif
243  int n;
244 
246 
247  if (time_to_wait < 2147483.648) {
248 # if USE_POLL
249  n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5));
250 # else
251  timeval t;
252  t.tv_sec = int(time_to_wait);
253  t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec));
254  n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
255 # endif
256  } else {
257 # if USE_POLL
258  n = ::poll(pollfds, nfds, -1);
259 # else
260  n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0);
261 # endif
262  }
263 
265 
266  if (n > 0) {
267  for (int i=0; i<nfds; i++) {
268 # if USE_POLL
269  if (pollfds[i].revents) fd[i].cb(pollfds[i].fd, fd[i].arg);
270 # else
271  int f = fd[i].fd;
272  short revents = 0;
273  if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
274  if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
275  if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
276  if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
277 # endif
278  }
279  }
280  return n;
281 }
282 
283 // fl_ready() is just like fl_wait(0.0) except no callbacks are done:
284 int fl_ready() {
285  if (XQLength(fl_display)) return 1;
286  if (!nfds) return 0; // nothing to select or poll
287 # if USE_POLL
288  return ::poll(pollfds, nfds, 0);
289 # else
290  timeval t;
291  t.tv_sec = 0;
292  t.tv_usec = 0;
293  fd_set fdt[3];
294  fdt[0] = fdsets[0];
295  fdt[1] = fdsets[1];
296  fdt[2] = fdsets[2];
297  return ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
298 # endif
299 }
300 
301 // replace \r\n by \n
302 static void convert_crlf(unsigned char *string, long& len) {
303  unsigned char *a, *b;
304  a = b = string;
305  while (*a) {
306  if (*a == '\r' && a[1] == '\n') { a++; len--; }
307  else *b++ = *a++;
308  }
309  *b = 0;
310 }
311 
313 
314 Display *fl_display;
317 XVisualInfo *fl_visual;
318 Colormap fl_colormap;
319 static XIM fl_xim_im = 0;
320 XIC fl_xim_ic = 0;
321 static Window fl_xim_win = 0;
322 static char fl_is_over_the_spot = 0;
323 static XRectangle status_area;
324 
325 static Atom WM_DELETE_WINDOW;
326 static Atom WM_PROTOCOLS;
327 static Atom fl_MOTIF_WM_HINTS;
328 static Atom TARGETS;
329 static Atom CLIPBOARD;
330 static Atom TIMESTAMP;
331 static Atom PRIMARY_TIMESTAMP;
343 //Atom fl_XdndProxy;
345 static Atom fl_Xatextplainutf;
346 static Atom fl_Xatextplainutf2; // STR#2930
347 static Atom fl_Xatextplain;
348 static Atom fl_XaText;
349 static Atom fl_XaCompoundText;
351 static Atom fl_XaTextUriList;
352 static Atom fl_XaImageBmp;
353 static Atom fl_XaImagePNG;
354 static Atom fl_INCR;
355 static Atom fl_NET_WM_PID;
356 static Atom fl_NET_WM_NAME; // utf8 aware window label
357 static Atom fl_NET_WM_ICON_NAME; // utf8 aware window icon name
359 static Atom fl_NET_WM_STATE;
362 static Atom fl_NET_WORKAREA;
363 static Atom fl_NET_WM_ICON;
365 
366 /*
367  X defines 32-bit-entities to have a format value of max. 32,
368  although sizeof(atom) can be 8 (64 bits) on a 64-bit OS.
369  See also fl_open_display() for sizeof(atom) < 4.
370  Used for XChangeProperty (see STR #2419).
371 */
372 static int atom_bits = 32;
373 
374 static void fd_callback(int,void *) {
376 }
377 
378 extern "C" {
379  static int io_error_handler(Display*) {
380  Fl::fatal("X I/O error");
381  return 0;
382  }
383 
384  static int xerror_handler(Display* d, XErrorEvent* e) {
385  char buf1[128], buf2[128];
386  sprintf(buf1, "XRequest.%d", e->request_code);
387  XGetErrorDatabaseText(d,"",buf1,buf1,buf2,128);
388  XGetErrorText(d, e->error_code, buf1, 128);
389  Fl::warning("%s: %s 0x%lx", buf2, buf1, e->resourceid);
390  return 0;
391  }
392 }
393 
394 extern char *fl_get_font_xfld(int fnum, int size);
395 
396 static void fl_new_ic()
397 {
398  XVaNestedList preedit_attr = NULL;
399  XVaNestedList status_attr = NULL;
400  static XFontSet fs = NULL;
401  char *fnt;
402  char **missing_list = 0;
403  int missing_count = 0;
404  char *def_string;
405  static XRectangle spot;
406  int predit = 0;
407  int sarea = 0;
408  XIMStyles* xim_styles = NULL;
409 
410 #if USE_XFT
411 
412 #if defined(__GNUC__)
413 // FIXME: warning XFT support here
414 #endif /*__GNUC__*/
415 
416  if (!fs) {
417  fnt = (char*)"-misc-fixed-*";
418  fs = XCreateFontSet(fl_display, fnt, &missing_list,
419  &missing_count, &def_string);
420  }
421 #else
422  if (!fs) {
423  bool must_free_fnt = true;
424  fnt = fl_get_font_xfld(0, 14);
425  if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;}
426  fs = XCreateFontSet(fl_display, fnt, &missing_list,
427  &missing_count, &def_string);
428  if (must_free_fnt) free(fnt);
429  }
430 #endif
431 
432  if (missing_list) XFreeStringList(missing_list);
433 
434  preedit_attr = XVaCreateNestedList(0,
435  XNSpotLocation, &spot,
436  XNFontSet, fs, NULL);
437  status_attr = XVaCreateNestedList(0,
438  XNAreaNeeded, &status_area,
439  XNFontSet, fs, NULL);
440 
441  if (!XGetIMValues(fl_xim_im, XNQueryInputStyle,
442  &xim_styles, NULL, NULL)) {
443  int i;
444  XIMStyle *style;
445  for (i = 0, style = xim_styles->supported_styles;
446  i < xim_styles->count_styles; i++, style++) {
447  if (*style == (XIMPreeditPosition | XIMStatusArea)) {
448  sarea = 1;
449  predit = 1;
450  } else if (*style == (XIMPreeditPosition | XIMStatusNothing)) {
451  predit = 1;
452  }
453  }
454  }
455  XFree(xim_styles);
456 
457  if (sarea) {
458  fl_xim_ic = XCreateIC(fl_xim_im,
459  XNInputStyle, (XIMPreeditPosition | XIMStatusArea),
460  XNPreeditAttributes, preedit_attr,
461  XNStatusAttributes, status_attr,
462  NULL);
463  }
464 
465  if (!fl_xim_ic && predit) {
466  fl_xim_ic = XCreateIC(fl_xim_im,
467  XNInputStyle, (XIMPreeditPosition | XIMStatusNothing),
468  XNPreeditAttributes, preedit_attr,
469  NULL);
470  }
471  XFree(preedit_attr);
472  XFree(status_attr);
473  if (!fl_xim_ic) {
475  fl_xim_ic = XCreateIC(fl_xim_im,
476  XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
477  NULL);
478  } else {
480  XVaNestedList status_attr = NULL;
481  status_attr = XVaCreateNestedList(0, XNAreaNeeded, &status_area, NULL);
482 
483  XGetICValues(fl_xim_ic, XNStatusAttributes, status_attr, NULL);
484  XFree(status_attr);
485  }
486 }
487 
488 
489 static XRectangle spot;
490 static int spotf = -1;
491 static int spots = -1;
492 
493 void fl_reset_spot(void)
494 {
495  spot.x = -1;
496  spot.y = -1;
497  //if (fl_xim_ic) XUnsetICFocus(fl_xim_ic);
498 }
499 
500 void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
501 {
502  int change = 0;
503  XVaNestedList preedit_attr;
504  static XFontSet fs = NULL;
505  char **missing_list;
506  int missing_count;
507  char *def_string;
508  char *fnt = NULL;
509  bool must_free_fnt =true;
510 
511  static XIC ic = NULL;
512 
513  if (!fl_xim_ic || !fl_is_over_the_spot) return;
514  //XSetICFocus(fl_xim_ic);
515  if (X != spot.x || Y != spot.y) {
516  spot.x = X;
517  spot.y = Y;
518  spot.height = H;
519  spot.width = W;
520  change = 1;
521  }
522  if (font != spotf || size != spots) {
523  spotf = font;
524  spots = size;
525  change = 1;
526  if (fs) {
527  XFreeFontSet(fl_display, fs);
528  }
529 #if USE_XFT
530 
531 #if defined(__GNUC__)
532 // FIXME: warning XFT support here
533 #endif /*__GNUC__*/
534 
535  fnt = NULL; // fl_get_font_xfld(font, size);
536  if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;}
537  fs = XCreateFontSet(fl_display, fnt, &missing_list,
538  &missing_count, &def_string);
539 #else
540  fnt = fl_get_font_xfld(font, size);
541  if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;}
542  fs = XCreateFontSet(fl_display, fnt, &missing_list,
543  &missing_count, &def_string);
544 #endif
545  }
546  if (fl_xim_ic != ic) {
547  ic = fl_xim_ic;
548  change = 1;
549  }
550 
551  if (fnt && must_free_fnt) free(fnt);
552  if (!change) return;
553 
554 
555  preedit_attr = XVaCreateNestedList(0,
556  XNSpotLocation, &spot,
557  XNFontSet, fs, NULL);
558  XSetICValues(fl_xim_ic, XNPreeditAttributes, preedit_attr, NULL);
559  XFree(preedit_attr);
560 }
561 
562 void fl_set_status(int x, int y, int w, int h)
563 {
564  XVaNestedList status_attr;
565  status_area.x = x;
566  status_area.y = y;
567  status_area.width = w;
568  status_area.height = h;
569  if (!fl_xim_ic) return;
570  status_attr = XVaCreateNestedList(0, XNArea, &status_area, NULL);
571 
572  XSetICValues(fl_xim_ic, XNStatusAttributes, status_attr, NULL);
573  XFree(status_attr);
574 }
575 
576 static void fl_init_xim() {
577  static int xim_warning = 2;
578  if (xim_warning > 0) xim_warning--;
579 
580  //XIMStyle *style;
581  XIMStyles *xim_styles;
582  if (!fl_display) return;
583  if (fl_xim_im) return;
584 
585  fl_xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
586  xim_styles = NULL;
587  fl_xim_ic = NULL;
588 
589  if (fl_xim_im) {
590  XGetIMValues (fl_xim_im, XNQueryInputStyle,
591  &xim_styles, NULL, NULL);
592  } else {
593  if (xim_warning)
594  Fl::warning("XOpenIM() failed");
595  // if xim_styles is allocated, free it now
596  if (xim_styles) XFree(xim_styles);
597  return;
598  }
599 
600  if (xim_styles && xim_styles->count_styles) {
601  fl_new_ic();
602  } else {
603  if (xim_warning)
604  Fl::warning("No XIM style found");
605  XCloseIM(fl_xim_im);
606  fl_xim_im = NULL;
607  // if xim_styles is allocated, free it now
608  if (xim_styles) XFree(xim_styles);
609  return;
610  }
611  if (!fl_xim_ic) {
612  if (xim_warning)
613  Fl::warning("XCreateIC() failed");
614  XCloseIM(fl_xim_im);
615  fl_xim_im = NULL;
616  }
617  // if xim_styles is still allocated, free it now
618  if(xim_styles) XFree(xim_styles);
619 }
620 
621 void fl_xim_deactivate(void);
622 
624  if (!fl_xim_im)
625  return;
626 
627  // If the focused window has changed, then use the brute force method
628  // of completely recreating the input context.
629  if (fl_xim_win != xid) {
631 
632  fl_new_ic();
633  fl_xim_win = xid;
634 
635  XSetICValues(fl_xim_ic,
636  XNFocusWindow, fl_xim_win,
637  XNClientWindow, fl_xim_win,
638  NULL);
639  }
640 
641  fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
642 }
643 
644 void fl_xim_deactivate(void) {
645  if (!fl_xim_ic)
646  return;
647 
648  XDestroyIC(fl_xim_ic);
649  fl_xim_ic = NULL;
650 
651  fl_xim_win = 0;
652 }
653 
654 void Fl::enable_im() {
655  Fl_Window *win;
656 
657  win = Fl::first_window();
658  if (win && win->shown()) {
659  fl_xim_activate(fl_xid(win));
660  XSetICFocus(fl_xim_ic);
661  } else {
662  fl_new_ic();
663  }
664 }
665 
666 void Fl::disable_im() {
668 }
669 
671  if (fl_display) return;
672 
673  setlocale(LC_CTYPE, "");
674  XSetLocaleModifiers("@im=");
675 
676  XSetIOErrorHandler(io_error_handler);
677  XSetErrorHandler(xerror_handler);
678 
679  Display *d = XOpenDisplay(0);
680  if (!d) Fl::fatal("Can't open display: %s",XDisplayName(0));
681 
682  fl_open_display(d);
683 }
684 
685 
686 void fl_open_display(Display* d) {
687  fl_display = d;
688 
689  WM_DELETE_WINDOW = XInternAtom(d, "WM_DELETE_WINDOW", 0);
690  WM_PROTOCOLS = XInternAtom(d, "WM_PROTOCOLS", 0);
691  fl_MOTIF_WM_HINTS = XInternAtom(d, "_MOTIF_WM_HINTS", 0);
692  TARGETS = XInternAtom(d, "TARGETS", 0);
693  CLIPBOARD = XInternAtom(d, "CLIPBOARD", 0);
694  TIMESTAMP = XInternAtom(d, "TIMESTAMP", 0);
695  PRIMARY_TIMESTAMP = XInternAtom(d, "PRIMARY_TIMESTAMP", 0);
696  CLIPBOARD_TIMESTAMP = XInternAtom(d, "CLIPBOARD_TIMESTAMP", 0);
697  fl_XdndAware = XInternAtom(d, "XdndAware", 0);
698  fl_XdndSelection = XInternAtom(d, "XdndSelection", 0);
699  fl_XdndEnter = XInternAtom(d, "XdndEnter", 0);
700  fl_XdndTypeList = XInternAtom(d, "XdndTypeList", 0);
701  fl_XdndPosition = XInternAtom(d, "XdndPosition", 0);
702  fl_XdndLeave = XInternAtom(d, "XdndLeave", 0);
703  fl_XdndDrop = XInternAtom(d, "XdndDrop", 0);
704  fl_XdndStatus = XInternAtom(d, "XdndStatus", 0);
705  fl_XdndActionCopy = XInternAtom(d, "XdndActionCopy", 0);
706  fl_XdndFinished = XInternAtom(d, "XdndFinished", 0);
707  //fl_XdndProxy = XInternAtom(d, "XdndProxy", 0);
708  fl_XdndEnter = XInternAtom(d, "XdndEnter", 0);
709  fl_XdndURIList = XInternAtom(d, "text/uri-list", 0);
710  fl_Xatextplainutf = XInternAtom(d, "text/plain;charset=UTF-8",0);
711  fl_Xatextplainutf2 = XInternAtom(d, "text/plain;charset=utf-8",0); // Firefox/Thunderbird needs this - See STR#2930
712  fl_Xatextplain = XInternAtom(d, "text/plain", 0);
713  fl_XaText = XInternAtom(d, "TEXT", 0);
714  fl_XaCompoundText = XInternAtom(d, "COMPOUND_TEXT", 0);
715  fl_XaUtf8String = XInternAtom(d, "UTF8_STRING", 0);
716  fl_XaTextUriList = XInternAtom(d, "text/uri-list", 0);
717  fl_XaImageBmp = XInternAtom(d, "image/bmp", 0);
718  fl_XaImagePNG = XInternAtom(d, "image/png", 0);
719  fl_INCR = XInternAtom(d, "INCR", 0);
720  fl_NET_WM_PID = XInternAtom(d, "_NET_WM_PID", 0);
721  fl_NET_WM_NAME = XInternAtom(d, "_NET_WM_NAME", 0);
722  fl_NET_WM_ICON_NAME = XInternAtom(d, "_NET_WM_ICON_NAME", 0);
723  fl_NET_SUPPORTING_WM_CHECK = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", 0);
724  fl_NET_WM_STATE = XInternAtom(d, "_NET_WM_STATE", 0);
725  fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0);
726  fl_NET_WM_FULLSCREEN_MONITORS = XInternAtom(d, "_NET_WM_FULLSCREEN_MONITORS", 0);
727  fl_NET_WORKAREA = XInternAtom(d, "_NET_WORKAREA", 0);
728  fl_NET_WM_ICON = XInternAtom(d, "_NET_WM_ICON", 0);
729  fl_NET_ACTIVE_WINDOW = XInternAtom(d, "_NET_ACTIVE_WINDOW", 0);
730 
731  if (sizeof(Atom) < 4)
732  atom_bits = sizeof(Atom) * 8;
733 
734  Fl::add_fd(ConnectionNumber(d), POLLIN, fd_callback);
735 
736  fl_screen = DefaultScreen(d);
737 
739  XCreateSimpleWindow(d, RootWindow(d,fl_screen), 0,0,1,1,0, 0, 0);
740 
741 // construct an XVisualInfo that matches the default Visual:
742  XVisualInfo templt; int num;
743  templt.visualid = XVisualIDFromVisual(DefaultVisual(d, fl_screen));
744  fl_visual = XGetVisualInfo(d, VisualIDMask, &templt, &num);
745  fl_colormap = DefaultColormap(d, fl_screen);
746  fl_init_xim();
747 
748 #if !USE_COLORMAP
750 #endif
751 
752 #if HAVE_XFIXES
753  int error_base;
754  if (XFixesQueryExtension(fl_display, &xfixes_event_base, &error_base))
755  have_xfixes = true;
756  else
757  have_xfixes = false;
758 #endif
759 
760 #if USE_XRANDR
761  void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY);
762  if (!libxrandr_addr) libxrandr_addr = dlopen("libXrandr.so", RTLD_LAZY);
763  if (libxrandr_addr) {
764  int error_base;
765  typedef Bool (*XRRQueryExtension_type)(Display*, int*, int*);
766  typedef void (*XRRSelectInput_type)(Display*, Window, int);
767  XRRQueryExtension_type XRRQueryExtension_f = (XRRQueryExtension_type)dlsym(libxrandr_addr, "XRRQueryExtension");
768  XRRSelectInput_type XRRSelectInput_f = (XRRSelectInput_type)dlsym(libxrandr_addr, "XRRSelectInput");
769  XRRUpdateConfiguration_f = (XRRUpdateConfiguration_type)dlsym(libxrandr_addr, "XRRUpdateConfiguration");
770  if (XRRQueryExtension_f && XRRSelectInput_f && XRRQueryExtension_f(d, &randrEventBase, &error_base))
771  XRRSelectInput_f(d, RootWindow(d, fl_screen), RRScreenChangeNotifyMask);
772  else XRRUpdateConfiguration_f = NULL;
773  }
774 #endif
775 
776  // Listen for changes to _NET_WORKAREA
777  XSelectInput(d, RootWindow(d, fl_screen), PropertyChangeMask);
778 }
779 
781  Fl::remove_fd(ConnectionNumber(fl_display));
782  XCloseDisplay(fl_display);
783 }
784 
785 static int fl_workarea_xywh[4] = { -1, -1, -1, -1 };
786 
787 static void fl_init_workarea() {
788  fl_open_display();
789 
790  Atom actual;
791  unsigned long count, remaining;
792  int format;
793  long *xywh = 0;
794 
795  /* If there are several screens, the _NET_WORKAREA property
796  does not give the work area of the main screen, but that of all screens together.
797  Therefore, we use this property only when there is a single screen,
798  and fall back to the main screen full area when there are several screens.
799  */
800  if (Fl::screen_count() > 1 || XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
801  fl_NET_WORKAREA, 0, 4, False,
802  XA_CARDINAL, &actual, &format, &count, &remaining,
803  (unsigned char **)&xywh) || !xywh || !xywh[2] ||
804  !xywh[3])
805  {
807  fl_workarea_xywh[1],
808  fl_workarea_xywh[2],
809  fl_workarea_xywh[3], 0);
810  }
811  else
812  {
813  fl_workarea_xywh[0] = (int)xywh[0];
814  fl_workarea_xywh[1] = (int)xywh[1];
815  fl_workarea_xywh[2] = (int)xywh[2];
816  fl_workarea_xywh[3] = (int)xywh[3];
817  }
818  if ( xywh ) { XFree(xywh); xywh = 0; }
819 }
820 
821 int Fl::x() {
822  if (fl_workarea_xywh[0] < 0) fl_init_workarea();
823  return fl_workarea_xywh[0];
824 }
825 
826 int Fl::y() {
827  if (fl_workarea_xywh[0] < 0) fl_init_workarea();
828  return fl_workarea_xywh[1];
829 }
830 
831 int Fl::w() {
832  if (fl_workarea_xywh[0] < 0) fl_init_workarea();
833  return fl_workarea_xywh[2];
834 }
835 
836 int Fl::h() {
837  if (fl_workarea_xywh[0] < 0) fl_init_workarea();
838  return fl_workarea_xywh[3];
839 }
840 
841 void Fl::get_mouse(int &xx, int &yy) {
842  fl_open_display();
843  Window root = RootWindow(fl_display, fl_screen);
844  Window c; int mx,my,cx,cy; unsigned int mask;
845  XQueryPointer(fl_display,root,&root,&c,&mx,&my,&cx,&cy,&mask);
846  xx = mx;
847  yy = my;
848 }
849 
851 // Code used for paste and DnD into the program:
852 
856 const char * fl_selection_type[2];
858 char fl_i_own_selection[2] = {0,0};
859 
860 // Call this when a "paste" operation happens:
861 void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) {
862  if (fl_i_own_selection[clipboard]) {
863  // We already have it, do it quickly without window server.
864  // Notice that the text is clobbered if set_selection is
865  // called in response to FL_PASTE!
866  // However, for now, we only paste text in this function
867  if (fl_selection_type[clipboard] != Fl::clipboard_plain_text) return; //TODO: allow copy/paste of image within same app
868  Fl::e_text = fl_selection_buffer[clipboard];
869  Fl::e_length = fl_selection_length[clipboard];
870  if (!Fl::e_text) Fl::e_text = (char *)"";
871  receiver.handle(FL_PASTE);
872  return;
873  }
874  // otherwise get the window server to return it:
875  fl_selection_requestor = &receiver;
876  Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
877  Fl::e_clipboard_type = type;
878  XConvertSelection(fl_display, property, TARGETS, property,
880 }
881 
882 int Fl::clipboard_contains(const char *type)
883 {
884  XEvent event;
885  Atom actual; int format; unsigned long count, remaining, i = 0;
886  unsigned char* portion = NULL;
887  Fl_Window *win = Fl::first_window();
888  if (!win || !fl_xid(win)) return 0;
889  XConvertSelection(fl_display, CLIPBOARD, TARGETS, CLIPBOARD, fl_xid(win), CurrentTime);
890  XFlush(fl_display);
891  do {
892  XNextEvent(fl_display, &event);
893  if (event.type == SelectionNotify && event.xselection.property == None) return 0;
894  i++;
895  }
896  while (i < 50 && event.type != SelectionNotify);
897  if (i >= 50) return 0;
898  XGetWindowProperty(fl_display,
899  event.xselection.requestor,
900  event.xselection.property,
901  0, 4000, 0, 0,
902  &actual, &format, &count, &remaining, &portion);
903  if (actual != XA_ATOM) return 0;
904  Atom t;
905  int retval = 0;
906  if (strcmp(type, Fl::clipboard_plain_text) == 0) {
907  for (i = 0; i<count; i++) { // searching for text data
908  t = ((Atom*)portion)[i];
909  if (t == fl_Xatextplainutf ||
910  t == fl_Xatextplainutf2 ||
911  t == fl_Xatextplain ||
912  t == fl_XaUtf8String) {
913  retval = 1;
914  break;
915  }
916  }
917  }
918  else if (strcmp(type, Fl::clipboard_image) == 0) {
919  for (i = 0; i<count; i++) { // searching for image data
920  t = ((Atom*)portion)[i];
921  if (t == fl_XaImageBmp || t == fl_XaImagePNG) {
922  retval = 1;
923  break;
924  }
925  }
926  }
927  XFree(portion);
928  return retval;
929 }
930 
932 static Atom *fl_dnd_source_types; // null-terminated list of data types being supplied
933 static Atom fl_dnd_type;
935 static Atom fl_dnd_action;
936 
938  unsigned long d0,
939  unsigned long d1=0,
940  unsigned long d2=0,
941  unsigned long d3=0,
942  unsigned long d4=0)
943 {
944  XEvent e;
945  e.xany.type = ClientMessage;
946  e.xany.window = window;
947  e.xclient.message_type = message;
948  e.xclient.format = 32;
949  e.xclient.data.l[0] = (long)d0;
950  e.xclient.data.l[1] = (long)d1;
951  e.xclient.data.l[2] = (long)d2;
952  e.xclient.data.l[3] = (long)d3;
953  e.xclient.data.l[4] = (long)d4;
954  XSendEvent(fl_display, window, 0, 0, &e);
955 }
956 
957 
958 /*
959  Get window property value (32 bit format)
960  Returns zero on success, -1 on error
961 
962  'data' should be freed with XFree() using this pattern:
963 
964  unsigned long *data = 0;
965  if (0 == get_xwinprop(....., &nitems, &data) ) { ..success.. }
966  else { ..fail.. }
967  if ( data ) { XFree(data); data=0; }
968 
969  Note: 'data' can be non-zero, even if the return value is -1 (error) and
970  should hence be XFree'd *after* the if/else statement, as described above.
971 */
972 static int get_xwinprop(Window wnd, Atom prop, long max_length,
973  unsigned long *nitems, unsigned long **data) {
974  Atom actual;
975  int format;
976  unsigned long bytes_after;
977 
978  if (Success != XGetWindowProperty(fl_display, wnd, prop, 0, max_length,
979  False, AnyPropertyType, &actual, &format,
980  nitems, &bytes_after, (unsigned char**)data)) {
981  return -1;
982  }
983 
984  if (actual == None || format != 32) {
985  return -1;
986  }
987 
988  return 0;
989 }
990 
991 
993 // Code for copying to clipboard and DnD out of the program:
994 
995 void Fl::copy(const char *stuff, int len, int clipboard, const char *type) {
996  if (!stuff || len<0) return;
997 
998  if (clipboard >= 2) {
999  copy(stuff, len, 0, type);
1000  copy(stuff, len, 1, type);
1001  return;
1002  }
1003 
1004  if (len+1 > fl_selection_buffer_length[clipboard]) {
1005  delete[] fl_selection_buffer[clipboard];
1006  fl_selection_buffer[clipboard] = new char[len+100];
1007  fl_selection_buffer_length[clipboard] = len+100;
1008  }
1009  memcpy(fl_selection_buffer[clipboard], stuff, len);
1010  fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
1011  fl_selection_length[clipboard] = len;
1012  fl_i_own_selection[clipboard] = 1;
1014  Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
1015  XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time);
1016 }
1017 
1018 static void write_short(unsigned char **cp,short i){
1019  unsigned char *c=*cp;
1020  *c++=i&0xFF;i>>=8;
1021  *c++=i&0xFF;i>>=8;
1022  *cp=c;
1023 }
1024 
1025 static void write_int(unsigned char **cp,int i){
1026  unsigned char *c=*cp;
1027  *c++=i&0xFF;i>>=8;
1028  *c++=i&0xFF;i>>=8;
1029  *c++=i&0xFF;i>>=8;
1030  *c++=i&0xFF;i>>=8;
1031  *cp=c;
1032 }
1033 
1034 static unsigned char *create_bmp(const unsigned char *data, int W, int H, int *return_size){
1035  int R=(3*W+3)/4 * 4; // the number of bytes per row, rounded up to multiple of 4
1036  int s=H*R;
1037  int fs=14+40+s;
1038  unsigned char *b=new unsigned char[fs];
1039  unsigned char *c=b;
1040  // BMP header
1041  *c++='B';
1042  *c++='M';
1043  write_int(&c,fs);
1044  write_int(&c,0);
1045  write_int(&c,14+40);
1046  // DIB header:
1047  write_int(&c,40);
1048  write_int(&c,W);
1049  write_int(&c,H);
1050  write_short(&c,1);
1051  write_short(&c,24);//bits ber pixel
1052  write_int(&c,0);//RGB
1053  write_int(&c,s);
1054  write_int(&c,0);// horizontal resolution
1055  write_int(&c,0);// vertical resolution
1056  write_int(&c,0);//number of colors. 0 -> 1<<bits_per_pixel
1057  write_int(&c,0);
1058  // Pixel data
1059  data+=3*W*H;
1060  for (int y=0;y<H;++y){
1061  data-=3*W;
1062  const unsigned char *s=data;
1063  unsigned char *p=c;
1064  for (int x=0;x<W;++x){
1065  *p++=s[2];
1066  *p++=s[1];
1067  *p++=s[0];
1068  s+=3;
1069  }
1070  c+=R;
1071  }
1072  *return_size = fs;
1073  return b;
1074 }
1075 
1076 void Fl::copy_image(const unsigned char *data, int W, int H, int clipboard){
1077  if(!data || W<=0 || H<=0) return;
1078  delete[] fl_selection_buffer[clipboard];
1079  fl_selection_buffer[clipboard] = (char *) create_bmp(data,W,H,&fl_selection_length[clipboard]);
1080  fl_selection_buffer_length[clipboard] = fl_selection_length[clipboard];
1081  fl_i_own_selection[clipboard] = 1;
1083 
1084  Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
1085  XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time);
1086 }
1087 
1089 // Code for tracking clipboard changes:
1090 
1091 static Time primary_timestamp = (Time)-1;
1092 static Time clipboard_timestamp = (Time)-1;
1093 
1094 extern bool fl_clipboard_notify_empty(void);
1095 extern void fl_trigger_clipboard_notify(int source);
1096 
1097 static void poll_clipboard_owner(void) {
1098  Window xid;
1099 
1100 #if HAVE_XFIXES
1101  // No polling needed with Xfixes
1102  if (have_xfixes)
1103  return;
1104 #endif
1105 
1106  // No one is interested, so no point polling
1108  return;
1109 
1110  // We need a window for this to work
1111  if (!Fl::first_window())
1112  return;
1113  xid = fl_xid(Fl::first_window());
1114  if (!xid)
1115  return;
1116 
1117  // Request an update of the selection time for both the primary and
1118  // clipboard selections. Magic continues when we get a SelectionNotify.
1119  if (!fl_i_own_selection[0])
1120  XConvertSelection(fl_display, XA_PRIMARY, TIMESTAMP, PRIMARY_TIMESTAMP,
1121  xid, fl_event_time);
1122  if (!fl_i_own_selection[1])
1123  XConvertSelection(fl_display, CLIPBOARD, TIMESTAMP, CLIPBOARD_TIMESTAMP,
1124  xid, fl_event_time);
1125 }
1126 
1127 static void clipboard_timeout(void *data)
1128 {
1129  // No one is interested, so stop polling
1131  return;
1132 
1134 
1136 }
1137 
1138 static void handle_clipboard_timestamp(int clipboard, Time time)
1139 {
1140  Time *timestamp;
1141 
1142  timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp;
1143 
1144 #if HAVE_XFIXES
1145  if (!have_xfixes)
1146 #endif
1147  {
1148  // Initial scan, just store the value
1149  if (*timestamp == (Time)-1) {
1150  *timestamp = time;
1151  return;
1152  }
1153  }
1154 
1155  // Same selection
1156  if (time == *timestamp)
1157  return;
1158 
1159  *timestamp = time;
1160 
1161  // The clipboard change is the event that caused us to request
1162  // the clipboard data, so use that time as the latest event.
1163  if (time > fl_event_time)
1164  fl_event_time = time;
1165 
1166  // Something happened! Let's tell someone!
1167  fl_trigger_clipboard_notify(clipboard);
1168 }
1169 
1171  // Reset the timestamps if we've going idle so that you don't
1172  // get a bogus immediate trigger next time they're activated.
1173  if (fl_clipboard_notify_empty()) {
1174  primary_timestamp = (Time)-1;
1175  clipboard_timestamp = (Time)-1;
1176  } else {
1177 #if HAVE_XFIXES
1178  if (!have_xfixes)
1179 #endif
1180  {
1182 
1185  }
1186  }
1187 }
1188 
1190 
1191 const XEvent* fl_xevent; // the current x event
1192 ulong fl_event_time; // the last timestamp from an x event
1193 
1194 char fl_key_vector[32]; // used by Fl::get_key()
1195 
1196 // Record event mouse position and state from an XEvent:
1197 
1198 static int px, py;
1199 static ulong ptime;
1200 
1201 static void set_event_xy() {
1202 # if CONSOLIDATE_MOTION
1203  send_motion = 0;
1204 # endif
1205  Fl::e_x_root = fl_xevent->xbutton.x_root;
1206  Fl::e_x = fl_xevent->xbutton.x;
1207  Fl::e_y_root = fl_xevent->xbutton.y_root;
1208  Fl::e_y = fl_xevent->xbutton.y;
1209  Fl::e_state = fl_xevent->xbutton.state << 16;
1210  fl_event_time = fl_xevent->xbutton.time;
1211 # ifdef __sgi
1212  // get the meta key off PC keyboards:
1213  if (fl_key_vector[18]&0x18) Fl::e_state |= FL_META;
1214 # endif
1215  // turn off is_click if enough time or mouse movement has passed:
1216  if (abs(Fl::e_x_root-px)+abs(Fl::e_y_root-py) > 3 ||
1217  fl_event_time >= ptime+1000)
1218  Fl::e_is_click = 0;
1219 }
1220 
1221 // if this is same event as last && is_click, increment click count:
1222 static inline void checkdouble() {
1224  Fl::e_clicks++;
1225  else {
1226  Fl::e_clicks = 0;
1228  }
1229  px = Fl::e_x_root;
1230  py = Fl::e_y_root;
1231  ptime = fl_event_time;
1232 }
1233 
1235 
1237 
1238 static char unknown[] = "<unknown>";
1239 const int unknown_len = 10;
1240 
1241 extern "C" {
1242 
1243 static int xerror = 0;
1244 
1245 static int ignoreXEvents(Display *display, XErrorEvent *event) {
1246  xerror = 1;
1247  return 0;
1248 }
1249 
1250 static XErrorHandler catchXExceptions() {
1251  xerror = 0;
1252  return ignoreXEvents;
1253 }
1254 
1255 static int wasXExceptionRaised() {
1256  return xerror;
1257 }
1258 
1259 }
1260 
1261 static bool getNextEvent(XEvent *event_return)
1262 {
1263  time_t t = time(NULL);
1264  while(!XPending(fl_display))
1265  {
1266  if(time(NULL) - t > 10.0)
1267  {
1268  //fprintf(stderr,"Error: The XNextEvent never came...\n");
1269  return false;
1270  }
1271  }
1272  XNextEvent(fl_display, event_return);
1273  return true;
1274 }
1275 
1276 static long getIncrData(uchar* &data, const XSelectionEvent& selevent, long lower_bound)
1277 {
1278 //fprintf(stderr,"Incremental transfer starting due to INCR property\n");
1279  size_t total = 0;
1280  XEvent event;
1281  XDeleteProperty(fl_display, selevent.requestor, selevent.property);
1282  data = (uchar*)realloc(data, lower_bound);
1283  for (;;)
1284  {
1285  if (!getNextEvent(&event)) break;
1286  if (event.type == PropertyNotify)
1287  {
1288  if (event.xproperty.state != PropertyNewValue) continue;
1289  Atom actual_type;
1290  int actual_format;
1291  unsigned long nitems;
1292  unsigned long bytes_after;
1293  unsigned char* prop = 0;
1294  long offset = 0;
1295  size_t num_bytes;
1296  //size_t slice_size = 0;
1297  do
1298  {
1299  XGetWindowProperty(fl_display, selevent.requestor, selevent.property, offset, 70000, True,
1300  AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop);
1301  num_bytes = nitems * (actual_format / 8);
1302  offset += num_bytes/4;
1303  //slice_size += num_bytes;
1304  if (total + num_bytes > (size_t)lower_bound) data = (uchar*)realloc(data, total + num_bytes);
1305  memcpy(data + total, prop, num_bytes); total += num_bytes;
1306  if (prop) XFree(prop);
1307  } while (bytes_after != 0);
1308 //fprintf(stderr,"INCR data size:%ld\n", slice_size);
1309  if (num_bytes == 0) break;
1310  }
1311  else break;
1312  }
1313  XDeleteProperty(fl_display, selevent.requestor, selevent.property);
1314  return (long)total;
1315 }
1316 
1317 /* Internal function to reduce "deprecated" warnings for XKeycodeToKeysym().
1318  This way we get only one warning. The option to use XkbKeycodeToKeysym()
1319  instead would not help much - see STR #2913 for more information.
1320 */
1321 static KeySym fl_KeycodeToKeysym(Display *d, KeyCode k, unsigned i) {
1322  return XKeycodeToKeysym(d, k, i);
1323 }
1324 
1325 int fl_handle(const XEvent& thisevent)
1326 {
1327  XEvent xevent = thisevent;
1328  fl_xevent = &thisevent;
1329  Window xid = xevent.xany.window;
1330 
1331  if (fl_xim_ic && xevent.type == DestroyNotify &&
1332  xid != fl_xim_win && !fl_find(xid))
1333  {
1334  XIM xim_im;
1335  xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
1336  if (!xim_im) {
1337  /* XIM server has crashed */
1338  XSetLocaleModifiers("@im=");
1339  fl_xim_im = NULL;
1340  fl_init_xim();
1341  } else {
1342  XCloseIM(xim_im); // see STR 2185 for comment
1343  }
1344  return 0;
1345  }
1346 
1347  if (fl_xim_ic && (xevent.type == FocusIn))
1348  fl_xim_activate(xid);
1349 
1350  if (fl_xim_ic && XFilterEvent((XEvent *)&xevent, 0))
1351  return(1);
1352 
1353 #if USE_XRANDR
1354  if( XRRUpdateConfiguration_f && xevent.type == randrEventBase + RRScreenChangeNotify) {
1355  XRRUpdateConfiguration_f(&xevent);
1357  fl_init_workarea();
1359  }
1360 #endif
1361 
1362  if (xevent.type == PropertyNotify && xevent.xproperty.atom == fl_NET_WORKAREA) {
1363  fl_init_workarea();
1364  }
1365 
1366  switch (xevent.type) {
1367 
1368  case KeymapNotify:
1369  memcpy(fl_key_vector, xevent.xkeymap.key_vector, 32);
1370  return 0;
1371 
1372  case MappingNotify:
1373  XRefreshKeyboardMapping((XMappingEvent*)&xevent.xmapping);
1374  return 0;
1375 
1376  case SelectionNotify: {
1377  static unsigned char* sn_buffer = 0;
1378  //static const char *buffer_format = 0;
1379  if (sn_buffer) {XFree(sn_buffer); sn_buffer = 0;}
1380  long bytesread = 0;
1381  if (fl_xevent->xselection.property) for (;;) {
1382  // The Xdnd code pastes 64K chunks together, possibly to avoid
1383  // bugs in X servers, or maybe to avoid an extra round-trip to
1384  // get the property length. I copy this here:
1385  Atom actual; int format; unsigned long count, remaining;
1386  unsigned char* portion = NULL;
1387  if (XGetWindowProperty(fl_display,
1388  fl_xevent->xselection.requestor,
1389  fl_xevent->xselection.property,
1390  bytesread/4, 65536, 1, AnyPropertyType,
1391  &actual, &format, &count, &remaining,
1392  &portion)) break; // quit on error
1393 
1394  if ((fl_xevent->xselection.property == PRIMARY_TIMESTAMP) ||
1395  (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)) {
1396  if (portion && format == 32 && count == 1) {
1397  Time t = *(unsigned int*)portion;
1398  if (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)
1400  else
1402  }
1403  XFree(portion); portion = 0;
1404  return true;
1405  }
1406 
1407  if (actual == TARGETS || actual == XA_ATOM) {
1408 /*for (unsigned i = 0; i<count; i++) {
1409  fprintf(stderr," %s", XGetAtomName(fl_display, ((Atom*)portion)[i]) );
1410  }
1411 fprintf(stderr,"\n");*/
1412  Atom t, type = XA_STRING;
1413  if (Fl::e_clipboard_type == Fl::clipboard_image) { // searching for image data
1414  for (unsigned i = 0; i<count; i++) {
1415  t = ((Atom*)portion)[i];
1416  if (t == fl_XaImageBmp || t == fl_XaImagePNG) {
1417  type = t;
1418  goto found;
1419  }
1420  }
1421  XFree(portion);
1422  return true;
1423  }
1424  for (unsigned i = 0; i<count; i++) { // searching for text data
1425  t = ((Atom*)portion)[i];
1426  if (t == fl_Xatextplainutf ||
1427  t == fl_Xatextplainutf2 ||
1428  t == fl_Xatextplain ||
1429  t == fl_XaUtf8String) {
1430  type = t;
1431  break;
1432  }
1433  // rest are only used if no utf-8 available:
1434  if (t == fl_XaText ||
1435  t == fl_XaTextUriList ||
1436  t == fl_XaCompoundText) type = t;
1437  }
1438  found:
1439  XFree(portion); portion = 0;
1440  Atom property = xevent.xselection.property;
1441  XConvertSelection(fl_display, property, type, property,
1443  fl_event_time);
1444  if (type == fl_XaImageBmp) {
1446  //buffer_format = "image/bmp";
1447  }
1448  else if (type == fl_XaImagePNG) {
1450  //buffer_format = "image/png";
1451  }
1452  else {
1454  //buffer_format = Fl::clipboard_plain_text;
1455  }
1456 //fprintf(stderr,"used format=%s\n", buffer_format);
1457  return true;
1458  }
1459  if (actual == fl_INCR) {
1460  bytesread = getIncrData(sn_buffer, xevent.xselection, *(long*)portion);
1461  XFree(portion);
1462  break;
1463  }
1464  // Make sure we got something sane...
1465  if ((portion == NULL) || (format != 8) || (count == 0)) {
1466  if (portion) { XFree(portion); portion = 0; }
1467  return true;
1468  }
1469  sn_buffer = (unsigned char*)realloc(sn_buffer, bytesread+count+remaining+1);
1470  memcpy(sn_buffer+bytesread, portion, count);
1471  if (portion) { XFree(portion); portion = 0; }
1472  bytesread += count;
1473  // Cannot trust data to be null terminated
1474  sn_buffer[bytesread] = '\0';
1475  if (!remaining) break;
1476  }
1477  if (sn_buffer && Fl::e_clipboard_type == Fl::clipboard_plain_text) {
1478  sn_buffer[bytesread] = 0;
1479  convert_crlf(sn_buffer, bytesread);
1480  }
1481  if (!fl_selection_requestor) return 0;
1483  if (bytesread == 0) return 0;
1484  static char tmp_fname[21];
1485  static Fl_Shared_Image *shared = 0;
1486  strcpy(tmp_fname, "/tmp/clipboardXXXXXX");
1487  int fd = mkstemp(tmp_fname);
1488  if (fd == -1) return 0;
1489  uchar *p = sn_buffer; ssize_t towrite = bytesread, written;
1490  while (towrite) {
1491  written = write(fd, p, towrite);
1492  p += written; towrite -= written;
1493  }
1494  close(fd);
1495  free(sn_buffer); sn_buffer = 0;
1496  shared = Fl_Shared_Image::get(tmp_fname);
1497  unlink(tmp_fname);
1498  if (!shared) return 0;
1499  uchar *rgb = new uchar[shared->w() * shared->h() * shared->d()];
1500  memcpy(rgb, shared->data()[0], shared->w() * shared->h() * shared->d());
1501  Fl_RGB_Image *image = new Fl_RGB_Image(rgb, shared->w(), shared->h(), shared->d());
1502  shared->release();
1503  image->alloc_array = 1;
1504  Fl::e_clipboard_data = (void*)image;
1505  }
1507  Fl::e_text = sn_buffer ? (char*)sn_buffer : (char *)"";
1508  Fl::e_length = bytesread;
1509  }
1510  int old_event = Fl::e_number;
1512  if (!retval && Fl::e_clipboard_type == Fl::clipboard_image) {
1515  }
1516  Fl::e_number = old_event;
1517  // Detect if this paste is due to Xdnd by the property name (I use
1518  // XA_SECONDARY for that) and send an XdndFinished message. It is not
1519  // clear if this has to be delayed until now or if it can be done
1520  // immediately after calling XConvertSelection.
1521  if (fl_xevent->xselection.property == XA_SECONDARY &&
1524  fl_xevent->xselection.requestor);
1525  fl_dnd_source_window = 0; // don't send a second time
1526  }
1527  return 1;}
1528 
1529  case SelectionClear: {
1530  int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD;
1531  fl_i_own_selection[clipboard] = 0;
1533  return 1;}
1534 
1535  case SelectionRequest: {
1536  XSelectionEvent e;
1537  e.type = SelectionNotify;
1538  e.requestor = fl_xevent->xselectionrequest.requestor;
1539  e.selection = fl_xevent->xselectionrequest.selection;
1540  int clipboard = e.selection == CLIPBOARD;
1541  e.target = fl_xevent->xselectionrequest.target;
1542  e.time = fl_xevent->xselectionrequest.time;
1543  e.property = fl_xevent->xselectionrequest.property;
1544  if (fl_selection_type[clipboard] == Fl::clipboard_plain_text) {
1545  if (e.target == TARGETS) {
1546  Atom a[3] = {fl_XaUtf8String, XA_STRING, fl_XaText};
1547  XChangeProperty(fl_display, e.requestor, e.property,
1548  XA_ATOM, atom_bits, 0, (unsigned char*)a, 3);
1549  } else {
1550  if (/*e.target == XA_STRING &&*/ fl_selection_length[clipboard]) {
1551  if (e.target == fl_XaUtf8String ||
1552  e.target == XA_STRING ||
1553  e.target == fl_XaCompoundText ||
1554  e.target == fl_XaText ||
1555  e.target == fl_Xatextplain ||
1556  e.target == fl_Xatextplainutf ||
1557  e.target == fl_Xatextplainutf2) {
1558  // clobber the target type, this seems to make some applications
1559  // behave that insist on asking for XA_TEXT instead of UTF8_STRING
1560  // Does not change XA_STRING as that breaks xclipboard.
1561  if (e.target != XA_STRING) e.target = fl_XaUtf8String;
1562  XChangeProperty(fl_display, e.requestor, e.property,
1563  e.target, 8, 0,
1564  (unsigned char *)fl_selection_buffer[clipboard],
1565  fl_selection_length[clipboard]);
1566  }
1567  } else {
1568  // char* x = XGetAtomName(fl_display,e.target);
1569  // fprintf(stderr,"selection request of %s\n",x);
1570  // XFree(x);
1571  e.property = 0;
1572  }
1573  }
1574  } else { // image in clipboard
1575  if (e.target == TARGETS) {
1576  Atom a[1] = {fl_XaImageBmp};
1577  XChangeProperty(fl_display, e.requestor, e.property,
1578  XA_ATOM, atom_bits, 0, (unsigned char*)a, 1);
1579  } else {
1580  if (e.target == fl_XaImageBmp && fl_selection_length[clipboard]) {
1581  XChangeProperty(fl_display, e.requestor, e.property,
1582  e.target, 8, 0,
1583  (unsigned char *)fl_selection_buffer[clipboard],
1584  fl_selection_length[clipboard]);
1585  } else {
1586  e.property = 0;
1587  }
1588  }
1589  }
1590  XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);}
1591  return 1;
1592 
1593  // events where interesting window id is in a different place:
1594  case CirculateNotify:
1595  case CirculateRequest:
1596  case ConfigureNotify:
1597  case ConfigureRequest:
1598  case CreateNotify:
1599  case DestroyNotify:
1600  case GravityNotify:
1601  case MapNotify:
1602  case MapRequest:
1603  case ReparentNotify:
1604  case UnmapNotify:
1605  xid = xevent.xmaprequest.window;
1606  break;
1607  }
1608 
1609  int event = 0;
1610  Fl_Window* window = fl_find(xid);
1611 
1612  if (window) switch (xevent.type) {
1613 
1614  case DestroyNotify: { // an X11 window was closed externally from the program
1616  Fl_X* X = Fl_X::i(window);
1617  if (X) { // indicates the FLTK window was not closed
1618  X->xid = (Window)0; // indicates the X11 window was already destroyed
1619  window->hide();
1620  int oldx = window->x(), oldy = window->y();
1621  window->position(0, 0);
1622  window->position(oldx, oldy);
1623  window->show(); // recreate the X11 window in support of the FLTK window
1624  }
1625  return 1;
1626  }
1627  case ClientMessage: {
1628  Atom message = fl_xevent->xclient.message_type;
1629  const long* data = fl_xevent->xclient.data.l;
1630  if ((Atom)(data[0]) == WM_DELETE_WINDOW) {
1631  event = FL_CLOSE;
1632  } else if (message == fl_XdndEnter) {
1633  fl_xmousewin = window;
1634  in_a_window = true;
1635  fl_dnd_source_window = data[0];
1636  // version number is data[1]>>24
1637 // printf("XdndEnter, version %ld\n", data[1] >> 24);
1638  if (data[1]&1) {
1639  // get list of data types:
1640  Atom actual; int format; unsigned long count, remaining;
1641  unsigned char *cm_buffer = 0;
1642  XGetWindowProperty(fl_display, fl_dnd_source_window, fl_XdndTypeList,
1643  0, 0x8000000L, False, XA_ATOM, &actual, &format,
1644  &count, &remaining, &cm_buffer);
1645  if (actual != XA_ATOM || format != 32 || count<4 || !cm_buffer) {
1646  if ( cm_buffer ) { XFree(cm_buffer); cm_buffer = 0; }
1647  goto FAILED;
1648  }
1649  delete [] fl_dnd_source_types;
1650  fl_dnd_source_types = new Atom[count+1];
1651  for (unsigned i = 0; i < count; i++) {
1652  fl_dnd_source_types[i] = ((Atom*)cm_buffer)[i];
1653  }
1654  fl_dnd_source_types[count] = 0;
1655  XFree(cm_buffer); cm_buffer = 0;
1656  } else {
1657  FAILED:
1658  // less than four data types, or if the above messes up:
1659  if (!fl_dnd_source_types) fl_dnd_source_types = new Atom[4];
1660  fl_dnd_source_types[0] = data[2];
1661  fl_dnd_source_types[1] = data[3];
1662  fl_dnd_source_types[2] = data[4];
1663  fl_dnd_source_types[3] = 0;
1664  }
1665 
1666  // Loop through the source types and pick the first text type...
1667  unsigned i;
1668  Atom type = ((Atom*)fl_dnd_source_types)[0];
1669  for (i = 0; fl_dnd_source_types[i]; i ++) {
1670  Atom t = ((Atom*)fl_dnd_source_types)[i];
1671  //printf("fl_dnd_source_types[%d]=%ld(%s)\n",i,t,XGetAtomName(fl_display,t));
1672  if (t == fl_Xatextplainutf || // "text/plain;charset=UTF-8"
1673  t == fl_Xatextplainutf2 || // "text/plain;charset=utf-8" -- See STR#2930
1674  t == fl_Xatextplain || // "text/plain"
1675  t == fl_XaUtf8String) { // "UTF8_STRING"
1676  type = t;
1677  break;
1678  }
1679  // rest are only used if no utf-8 available:
1680  if (t == fl_XaText || // "TEXT"
1681  t == fl_XaTextUriList || // "text/uri-list"
1682  t == fl_XaCompoundText) type = t; // "COMPOUND_TEXT"
1683  }
1684  fl_dnd_type = type;
1685 
1686  event = FL_DND_ENTER;
1687  Fl::e_text = unknown;
1689  break;
1690 
1691  } else if (message == fl_XdndPosition) {
1692  fl_xmousewin = window;
1693  in_a_window = true;
1694  fl_dnd_source_window = data[0];
1695  Fl::e_x_root = data[2]>>16;
1696  Fl::e_y_root = data[2]&0xFFFF;
1697  if (window) {
1700  }
1701  fl_event_time = data[3];
1702  fl_dnd_source_action = data[4];
1704  Fl::e_text = unknown;
1706  int accept = Fl::handle(FL_DND_DRAG, window);
1708  fl_xevent->xclient.window,
1709  accept ? 1 : 0,
1710  0, // used for xy rectangle to not send position inside
1711  0, // used for width+height of rectangle
1712  accept ? fl_dnd_action : None);
1713  return 1;
1714 
1715  } else if (message == fl_XdndLeave) {
1716  fl_dnd_source_window = 0; // don't send a finished message to it
1717  event = FL_DND_LEAVE;
1718  Fl::e_text = unknown;
1720  break;
1721 
1722  } else if (message == fl_XdndDrop) {
1723  fl_xmousewin = window;
1724  in_a_window = true;
1725  fl_dnd_source_window = data[0];
1726  fl_event_time = data[2];
1727  Window to_window = fl_xevent->xclient.window;
1728  Fl::e_text = unknown;
1733  XConvertSelection(fl_display, fl_XdndSelection,
1734  fl_dnd_type, XA_SECONDARY,
1735  to_window, fl_event_time);
1736  } else {
1737  // Send the finished message if I refuse the drop.
1738  // It is not clear whether I can just send finished always,
1739  // or if I have to wait for the SelectionNotify event as the
1740  // code is currently doing.
1743  }
1744  return 1;
1745 
1746  }
1747  break;}
1748 
1749  case UnmapNotify:
1750  event = FL_HIDE;
1751  break;
1752 
1753  case Expose:
1754  Fl_X::i(window)->wait_for_expose = 0;
1755 # if 0
1756  // try to keep windows on top even if WM_TRANSIENT_FOR does not work:
1757  // opaque move/resize window managers do not like this, so I disabled it.
1758  if (Fl::first_window()->non_modal() && window != Fl::first_window())
1759  Fl::first_window()->show();
1760 # endif
1761 
1762  case GraphicsExpose:
1763  window->damage(FL_DAMAGE_EXPOSE, xevent.xexpose.x, xevent.xexpose.y,
1764  xevent.xexpose.width, xevent.xexpose.height);
1765  return 1;
1766 
1767  case FocusIn:
1768  if (fl_xim_ic) XSetICFocus(fl_xim_ic);
1769  event = FL_FOCUS;
1770  // If the user has toggled from another application to this one,
1771  // then it's a good time to check for clipboard changes.
1773  break;
1774 
1775  case FocusOut:
1776  if (fl_xim_ic) XUnsetICFocus(fl_xim_ic);
1777  event = FL_UNFOCUS;
1778  break;
1779 
1780  case KeyPress:
1781  case KeyRelease: {
1782  KEYPRESS:
1783  int keycode = xevent.xkey.keycode;
1784  fl_key_vector[keycode/8] |= (1 << (keycode%8));
1785  static char *kp_buffer = NULL;
1786  static int kp_buffer_len = 0;
1787  int len=0;
1788  KeySym keysym;
1789  if (kp_buffer_len == 0) {
1790  kp_buffer_len = 4096;
1791  kp_buffer = (char*) malloc(kp_buffer_len);
1792  }
1793  if (xevent.type == KeyPress) {
1794  event = FL_KEYDOWN;
1795  len = 0;
1796 
1797  if (fl_xim_ic) {
1798  Status status;
1799  len = XUtf8LookupString(fl_xim_ic, (XKeyPressedEvent *)&xevent.xkey,
1800  kp_buffer, kp_buffer_len, &keysym, &status);
1801 
1802  while (status == XBufferOverflow && kp_buffer_len < 50000) {
1803  kp_buffer_len = kp_buffer_len * 5 + 1;
1804  kp_buffer = (char*)realloc(kp_buffer, kp_buffer_len);
1805  len = XUtf8LookupString(fl_xim_ic, (XKeyPressedEvent *)&xevent.xkey,
1806  kp_buffer, kp_buffer_len, &keysym, &status);
1807  }
1808  keysym = fl_KeycodeToKeysym(fl_display, keycode, 0);
1809  } else {
1810  //static XComposeStatus compose;
1811  len = XLookupString((XKeyEvent*)&(xevent.xkey),
1812  kp_buffer, kp_buffer_len, &keysym, 0/*&compose*/);
1813  if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets
1814  // force it to type a character (not sure if this ever is needed):
1815  // if (!len) {kp_buffer[0] = char(keysym); len = 1;}
1816  len = fl_utf8encode(XKeysymToUcs(keysym), kp_buffer);
1817  if (len < 1) len = 1;
1818  // ignore all effects of shift on the keysyms, which makes it a lot
1819  // easier to program shortcuts and is Windoze-compatible:
1820  keysym = fl_KeycodeToKeysym(fl_display, keycode, 0);
1821  }
1822  }
1823  kp_buffer[len] = 0;
1824  Fl::e_text = kp_buffer;
1825  Fl::e_length = len;
1826  } else {
1827  // Stupid X sends fake key-up events when a repeating key is held
1828  // down, probably due to some back compatibility problem. Fortunately
1829  // we can detect this because the repeating KeyPress event is in
1830  // the queue, get it and execute it instead:
1831 
1832  // Bool XkbSetDetectableAutoRepeat ( display, detectable, supported_rtrn )
1833  // Display * display ;
1834  // Bool detectable ;
1835  // Bool * supported_rtrn ;
1836  // ...would be the easy way to correct this issue. Unfortunately, this call is also
1837  // broken on many Unix distros including Ubuntu and Solaris (as of Dec 2009)
1838 
1839  // Bogus KeyUp events are generated by repeated KeyDown events. One
1840  // necessary condition is an identical key event pending right after
1841  // the bogus KeyUp.
1842  // The new code introduced Dec 2009 differs in that it only checks the very
1843  // next event in the queue, not the entire queue of events.
1844  // This function wrongly detects a repeat key if a software keyboard
1845  // sends a burst of events containing two consecutive equal keys. However,
1846  // in every non-gaming situation, this is no problem because both KeyPress
1847  // events will cause the expected behavior.
1848  XEvent peekevent;
1849  if (XPending(fl_display)) {
1850  XPeekEvent(fl_display, &peekevent);
1851  if ( (peekevent.type == KeyPress) // must be a KeyPress event
1852  && (peekevent.xkey.keycode == xevent.xkey.keycode) // must be the same key
1853  && (peekevent.xkey.time == xevent.xkey.time) // must be sent at the exact same time
1854  ) {
1855  XNextEvent(fl_display, &xevent);
1856  goto KEYPRESS;
1857  }
1858  }
1859 
1860  event = FL_KEYUP;
1861  fl_key_vector[keycode/8] &= ~(1 << (keycode%8));
1862  // keyup events just get the unshifted keysym:
1863  keysym = fl_KeycodeToKeysym(fl_display, keycode, 0);
1864  }
1865 # ifdef __sgi
1866  // You can plug a microsoft keyboard into an sgi but the extra shift
1867  // keys are not translated. Make them translate like XFree86 does:
1868  if (!keysym) switch(keycode) {
1869  case 147: keysym = FL_Meta_L; break;
1870  case 148: keysym = FL_Meta_R; break;
1871  case 149: keysym = FL_Menu; break;
1872  }
1873 # endif
1874 # ifdef BACKSPACE_HACK
1875  // Attempt to fix keyboards that send "delete" for the key in the
1876  // upper-right corner of the main keyboard. But it appears that
1877  // very few of these remain?
1878  static int got_backspace = 0;
1879  if (!got_backspace) {
1880  if (keysym == FL_Delete) keysym = FL_BackSpace;
1881  else if (keysym == FL_BackSpace) got_backspace = 1;
1882  }
1883 # endif
1884  // For the first few years, there wasn't a good consensus on what the
1885  // Windows keys should be mapped to for X11. So we need to help out a
1886  // bit and map all variants to the same FLTK key...
1887  switch (keysym) {
1888  case XK_Meta_L:
1889  case XK_Hyper_L:
1890  case XK_Super_L:
1891  keysym = FL_Meta_L;
1892  break;
1893  case XK_Meta_R:
1894  case XK_Hyper_R:
1895  case XK_Super_R:
1896  keysym = FL_Meta_R;
1897  break;
1898  }
1899  // Convert the multimedia keys to safer, portable values
1900  switch (keysym) { // XF names come from X11/XF86keysym.h
1901  case 0x1008FF11: // XF86XK_AudioLowerVolume:
1902  keysym = FL_Volume_Down;
1903  break;
1904  case 0x1008FF12: // XF86XK_AudioMute:
1905  keysym = FL_Volume_Mute;
1906  break;
1907  case 0x1008FF13: // XF86XK_AudioRaiseVolume:
1908  keysym = FL_Volume_Up;
1909  break;
1910  case 0x1008FF14: // XF86XK_AudioPlay:
1911  keysym = FL_Media_Play;
1912  break;
1913  case 0x1008FF15: // XF86XK_AudioStop:
1914  keysym = FL_Media_Stop;
1915  break;
1916  case 0x1008FF16: // XF86XK_AudioPrev:
1917  keysym = FL_Media_Prev;
1918  break;
1919  case 0x1008FF17: // XF86XK_AudioNext:
1920  keysym = FL_Media_Next;
1921  break;
1922  case 0x1008FF18: // XF86XK_HomePage:
1923  keysym = FL_Home_Page;
1924  break;
1925  case 0x1008FF19: // XF86XK_Mail:
1926  keysym = FL_Mail;
1927  break;
1928  case 0x1008FF1B: // XF86XK_Search:
1929  keysym = FL_Search;
1930  break;
1931  case 0x1008FF26: // XF86XK_Back:
1932  keysym = FL_Back;
1933  break;
1934  case 0x1008FF27: // XF86XK_Forward:
1935  keysym = FL_Forward;
1936  break;
1937  case 0x1008FF28: // XF86XK_Stop:
1938  keysym = FL_Stop;
1939  break;
1940  case 0x1008FF29: // XF86XK_Refresh:
1941  keysym = FL_Refresh;
1942  break;
1943  case 0x1008FF2F: // XF86XK_Sleep:
1944  keysym = FL_Sleep;
1945  break;
1946  case 0x1008FF30: // XF86XK_Favorites:
1947  keysym = FL_Favorites;
1948  break;
1949  }
1950  // We have to get rid of the XK_KP_function keys, because they are
1951  // not produced on Windoze and thus case statements tend not to check
1952  // for them. There are 15 of these in the range 0xff91 ... 0xff9f
1953  if (keysym >= 0xff91 && keysym <= 0xff9f) {
1954  // Map keypad keysym to character or keysym depending on
1955  // numlock state...
1956  unsigned long keysym1 = fl_KeycodeToKeysym(fl_display, keycode, 1);
1957  if (keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last))
1958  Fl::e_original_keysym = (int)(keysym1 | FL_KP);
1959  if ((xevent.xkey.state & Mod2Mask) &&
1960  (keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last))) {
1961  // Store ASCII numeric keypad value...
1962  keysym = keysym1 | FL_KP;
1963  kp_buffer[0] = char(keysym1) & 0x7F;
1964  len = 1;
1965  } else {
1966  // Map keypad to special key...
1967  static const unsigned short table[15] = {
1968  FL_F+1, FL_F+2, FL_F+3, FL_F+4,
1971  0xff0b/*XK_Clear*/, FL_Insert, FL_Delete};
1972  keysym = table[keysym-0xff91];
1973  }
1974  } else {
1975  // Store this so we can later know if the KP was used
1976  Fl::e_original_keysym = (int)keysym;
1977  }
1978  Fl::e_keysym = int(keysym);
1979 
1980  // replace XK_ISO_Left_Tab (Shift-TAB) with FL_Tab (modifier flags are set correctly by X11)
1981  if (Fl::e_keysym == 0xfe20) Fl::e_keysym = FL_Tab;
1982 
1983  set_event_xy();
1984  Fl::e_is_click = 0; }
1985  break;
1986 
1987  case ButtonPress:
1988  Fl::e_keysym = FL_Button + xevent.xbutton.button;
1989  set_event_xy();
1990  Fl::e_dx = Fl::e_dy = 0;
1991  if (xevent.xbutton.button == Button4) {
1992  Fl::e_dy = -1; // Up
1993  event = FL_MOUSEWHEEL;
1994  } else if (xevent.xbutton.button == Button5) {
1995  Fl::e_dy = +1; // Down
1996  event = FL_MOUSEWHEEL;
1997  } else if (xevent.xbutton.button == 6) {
1998  Fl::e_dx = -1; // Left
1999  event = FL_MOUSEWHEEL;
2000  } else if (xevent.xbutton.button == 7) {
2001  Fl::e_dx = +1; // Right
2002  event = FL_MOUSEWHEEL;
2003  } else {
2004  Fl::e_state |= (FL_BUTTON1 << (xevent.xbutton.button-1));
2005  event = FL_PUSH;
2006  checkdouble();
2007  }
2008 
2009  fl_xmousewin = window;
2010  in_a_window = true;
2011  break;
2012 
2013  case PropertyNotify:
2014  if (xevent.xproperty.atom == fl_NET_WM_STATE) {
2015  int fullscreen_state = 0;
2016  if (xevent.xproperty.state != PropertyDelete) {
2017  unsigned long nitems;
2018  unsigned long *words = 0;
2019  if (0 == get_xwinprop(xid, fl_NET_WM_STATE, 64, &nitems, &words) ) {
2020  for (unsigned long item = 0; item < nitems; item++) {
2021  if (words[item] == fl_NET_WM_STATE_FULLSCREEN) {
2022  fullscreen_state = 1;
2023  }
2024  }
2025  }
2026  if ( words ) { XFree(words); words = 0; }
2027  }
2028  if (window->fullscreen_active() && !fullscreen_state) {
2030  event = FL_FULLSCREEN;
2031  }
2032  if (!window->fullscreen_active() && fullscreen_state) {
2034  event = FL_FULLSCREEN;
2035  }
2036  }
2037  break;
2038 
2039  case MotionNotify:
2040  set_event_xy();
2041 # if CONSOLIDATE_MOTION
2043  in_a_window = true;
2044  return 0;
2045 # else
2046  event = FL_MOVE;
2047  fl_xmousewin = window;
2048  in_a_window = true;
2049  break;
2050 # endif
2051 
2052  case ButtonRelease:
2053  Fl::e_keysym = FL_Button + xevent.xbutton.button;
2054  set_event_xy();
2055  Fl::e_state &= ~(FL_BUTTON1 << (xevent.xbutton.button-1));
2056  if (xevent.xbutton.button == Button4 ||
2057  xevent.xbutton.button == Button5) return 0;
2058  event = FL_RELEASE;
2059 
2060  fl_xmousewin = window;
2061  in_a_window = true;
2062  break;
2063 
2064  case EnterNotify:
2065  if (xevent.xcrossing.detail == NotifyInferior) break;
2066  // XInstallColormap(fl_display, Fl_X::i(window)->colormap);
2067  set_event_xy();
2068  Fl::e_state = xevent.xcrossing.state << 16;
2069  event = FL_ENTER;
2070 
2071  fl_xmousewin = window;
2072  in_a_window = true;
2073  { XIMStyles *xim_styles = NULL;
2074  if(!fl_xim_im || XGetIMValues(fl_xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL)) {
2075  fl_init_xim();
2076  }
2077  if (xim_styles) XFree(xim_styles);
2078  }
2079  break;
2080 
2081  case LeaveNotify:
2082  if (xevent.xcrossing.detail == NotifyInferior) break;
2083  set_event_xy();
2084  Fl::e_state = xevent.xcrossing.state << 16;
2085  fl_xmousewin = 0;
2086  in_a_window = false; // make do_queued_events produce FL_LEAVE event
2087  return 0;
2088 
2089  // We cannot rely on the x,y position in the configure notify event.
2090  // I now think this is an unavoidable problem with X: it is impossible
2091  // for a window manager to prevent the "real" notify event from being
2092  // sent when it resizes the contents, even though it can send an
2093  // artificial event with the correct position afterwards (and some
2094  // window managers do not send this fake event anyway)
2095  // So anyway, do a round trip to find the correct x,y:
2096  case MapNotify:
2097  event = FL_SHOW;
2098 
2099  case ConfigureNotify: {
2100  if (window->parent()) break; // ignore child windows
2101 
2102  // figure out where OS really put window
2103  XWindowAttributes actual;
2104  XGetWindowAttributes(fl_display, fl_xid(window), &actual);
2105  Window cr; int X, Y, W = actual.width, H = actual.height;
2106  XTranslateCoordinates(fl_display, fl_xid(window), actual.root,
2107  0, 0, &X, &Y, &cr);
2108 
2109  // tell Fl_Window about it and set flag to prevent echoing:
2111  window->resize(X, Y, W, H);
2112  break; // allow add_handler to do something too
2113  }
2114 
2115  case ReparentNotify: {
2116  int xpos, ypos;
2117  Window junk;
2118 
2119  // on some systems, the ReparentNotify event is not handled as we would expect.
2120  XErrorHandler oldHandler = XSetErrorHandler(catchXExceptions());
2121 
2122  //ReparentNotify gives the new position of the window relative to
2123  //the new parent. FLTK cares about the position on the root window.
2124  XTranslateCoordinates(fl_display, xevent.xreparent.parent,
2125  XRootWindow(fl_display, fl_screen),
2126  xevent.xreparent.x, xevent.xreparent.y,
2127  &xpos, &ypos, &junk);
2128  XSetErrorHandler(oldHandler);
2129 
2130  // tell Fl_Window about it and set flag to prevent echoing:
2131  if ( !wasXExceptionRaised() ) {
2133  window->position(xpos, ypos);
2134  }
2135  break;
2136  }
2137  }
2138 
2139 #if HAVE_XFIXES
2140  switch (xevent.type - xfixes_event_base) {
2141  case XFixesSelectionNotify: {
2142  // Someone feeding us bogus events?
2143  if (!have_xfixes)
2144  return true;
2145 
2146  XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)&xevent;
2147 
2148  if ((selection_notify->selection == XA_PRIMARY) && !fl_i_own_selection[0])
2149  handle_clipboard_timestamp(0, selection_notify->selection_timestamp);
2150  else if ((selection_notify->selection == CLIPBOARD) && !fl_i_own_selection[1])
2151  handle_clipboard_timestamp(1, selection_notify->selection_timestamp);
2152 
2153  return true;
2154  }
2155  }
2156 #endif
2157 
2158  return Fl::handle(event, window);
2159 }
2160 
2162 
2163 void Fl_Window::resize(int X,int Y,int W,int H) {
2164  int is_a_move = (X != x() || Y != y());
2165  int is_a_resize = (W != w() || H != h());
2166  int resize_from_program = (this != resize_bug_fix);
2167  if (!resize_from_program) resize_bug_fix = 0;
2168  if (is_a_move && resize_from_program) set_flag(FORCE_POSITION);
2169  else if (!is_a_resize && !is_a_move) return;
2170  if (is_a_resize) {
2171  Fl_Group::resize(X,Y,W,H);
2172  if (shown()) {redraw();}
2173  } else {
2174  x(X); y(Y);
2175  }
2176 
2177  if (resize_from_program && is_a_resize && !resizable()) {
2178  size_range(w(), h(), w(), h());
2179  }
2180 
2181  if (resize_from_program && shown()) {
2182  if (is_a_resize) {
2183  if (!resizable()) size_range(w(),h(),w(),h());
2184  if (is_a_move) {
2185  XMoveResizeWindow(fl_display, i->xid, X, Y, W>0 ? W : 1, H>0 ? H : 1);
2186  } else {
2187  XResizeWindow(fl_display, i->xid, W>0 ? W : 1, H>0 ? H : 1);
2188  }
2189  } else
2190  XMoveWindow(fl_display, i->xid, X, Y);
2191  }
2192 }
2193 
2195 
2196 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
2197 #define _NET_WM_STATE_ADD 1 /* add/set property */
2198 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
2199 
2200 static void send_wm_event(Window wnd, Atom message,
2201  unsigned long d0, unsigned long d1=0,
2202  unsigned long d2=0, unsigned long d3=0,
2203  unsigned long d4=0) {
2204  XEvent e;
2205  e.xany.type = ClientMessage;
2206  e.xany.window = wnd;
2207  e.xclient.message_type = message;
2208  e.xclient.format = 32;
2209  e.xclient.data.l[0] = d0;
2210  e.xclient.data.l[1] = d1;
2211  e.xclient.data.l[2] = d2;
2212  e.xclient.data.l[3] = d3;
2213  e.xclient.data.l[4] = d4;
2214  XSendEvent(fl_display, RootWindow(fl_display, fl_screen),
2215  0, SubstructureNotifyMask | SubstructureRedirectMask,
2216  &e);
2217 }
2218 
2219 static void send_wm_state_event(Window wnd, int add, Atom prop) {
2221  add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, prop);
2222 }
2223 
2224 int Fl_X::ewmh_supported() {
2225  static int result = -1;
2226 
2227  if (result == -1) {
2228  fl_open_display();
2229  result = 0;
2230  unsigned long nitems;
2231  unsigned long *words = 0;
2232  if (0 == get_xwinprop(XRootWindow(fl_display, fl_screen), fl_NET_SUPPORTING_WM_CHECK, 64,
2233  &nitems, &words) && nitems == 1) {
2234  Window child = words[0];
2235  if ( words ) { XFree(words); words = 0; }
2236  if (0 == get_xwinprop(child, fl_NET_SUPPORTING_WM_CHECK, 64,
2237  &nitems, &words) ) {
2238  if ( nitems == 1) result = (child == words[0]);
2239  }
2240  }
2241  if ( words ) { XFree(words); words = 0; }
2242  }
2243 
2244  return result;
2245 }
2246 
2247 int Fl_X::xrender_supported() {
2248 #if HAVE_XRENDER
2249  static int result = -1;
2250 
2251  if (result == -1) {
2252  fl_open_display();
2253 
2254  int nop1, nop2;
2255  result = XRenderQueryExtension(fl_display, &nop1, &nop2);
2256  }
2257 
2258  return result;
2259 #else
2260  return 0;
2261 #endif
2262 }
2263 
2264 extern Fl_Window *fl_xfocus;
2265 
2266 void Fl_X::activate_window(Window w) {
2267  if (!ewmh_supported())
2268  return;
2269 
2270  Window prev = 0;
2271 
2272  if (fl_xfocus) {
2273  Fl_X *x = Fl_X::i(fl_xfocus);
2274  if (!x)
2275  return;
2276  prev = x->xid;
2277  }
2278 
2279  send_wm_event(w, fl_NET_ACTIVE_WINDOW, 1 /* application */,
2280  0 /* timestamp */, prev /* previously active window */);
2281 }
2282 
2283 /* Change an existing window to fullscreen */
2284 void Fl_Window::fullscreen_x() {
2285  if (Fl_X::ewmh_supported()) {
2286  int top, bottom, left, right;
2287 
2288  top = fullscreen_screen_top;
2289  bottom = fullscreen_screen_bottom;
2290  left = fullscreen_screen_left;
2291  right = fullscreen_screen_right;
2292 
2293  if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
2294  top = Fl::screen_num(x(), y(), w(), h());
2295  bottom = top;
2296  left = top;
2297  right = top;
2298  }
2299 
2301  top, bottom, left, right);
2303  } else {
2304  _set_fullscreen();
2305  hide();
2306  show();
2307  /* We want to grab the window, not a widget, so we cannot use Fl::grab */
2308  XGrabKeyboard(fl_display, fl_xid(this), 1, GrabModeAsync, GrabModeAsync, fl_event_time);
2309  Fl::handle(FL_FULLSCREEN, this);
2310  }
2311 }
2312 
2313 void Fl_Window::fullscreen_off_x(int X, int Y, int W, int H) {
2314  if (Fl_X::ewmh_supported()) {
2316  } else {
2318  /* The grab will be lost when the window is destroyed */
2319  hide();
2320  resize(X,Y,W,H);
2321  show();
2322  Fl::handle(FL_FULLSCREEN, this);
2323  }
2324 }
2325 
2327 
2328 // A subclass of Fl_Window may call this to associate an X window it
2329 // creates with the Fl_Window:
2330 
2331 void fl_fix_focus(); // in Fl.cxx
2332 
2333 Fl_X* Fl_X::set_xid(Fl_Window* win, Window winxid) {
2334  Fl_X* xp = new Fl_X;
2335  xp->xid = winxid;
2336  xp->other_xid = 0;
2337  xp->setwindow(win);
2338  xp->next = Fl_X::first;
2339  xp->region = 0;
2340  xp->wait_for_expose = 1;
2341  xp->backbuffer_bad = 1;
2342  Fl_X::first = xp;
2343  if (win->modal()) {Fl::modal_ = win; fl_fix_focus();}
2344  return xp;
2345 }
2346 
2347 // More commonly a subclass calls this, because it hides the really
2348 // ugly parts of X and sets all the stuff for a window that is set
2349 // normally. The global variables like fl_show_iconic are so that
2350 // subclasses of *that* class may change the behavior...
2351 
2352 char fl_show_iconic; // hack for iconize()
2353 int fl_background_pixel = -1; // hack to speed up bg box drawing
2354 int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
2355 
2356 static const int childEventMask = ExposureMask;
2357 
2358 static const int XEventMask =
2359 ExposureMask|StructureNotifyMask
2360 |KeyPressMask|KeyReleaseMask|KeymapStateMask|FocusChangeMask
2361 |ButtonPressMask|ButtonReleaseMask
2362 |EnterWindowMask|LeaveWindowMask
2363 |PropertyChangeMask
2364 |PointerMotionMask;
2365 
2366 void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
2367 {
2368  Fl_Group::current(0); // get rid of very common user bug: forgot end()
2369 
2370  int X = win->x();
2371  int Y = win->y();
2372  int W = win->w();
2373  if (W <= 0) W = 1; // X don't like zero...
2374  int H = win->h();
2375  if (H <= 0) H = 1; // X don't like zero...
2376  if (!win->parent() && !Fl::grab()) {
2377  // center windows in case window manager does not do anything:
2378 #ifdef FL_CENTER_WINDOWS
2379  if (!win->force_position()) {
2380  win->x(X = scr_x+(scr_w-W)/2);
2381  win->y(Y = scr_y+(scr_h-H)/2);
2382  }
2383 #endif // FL_CENTER_WINDOWS
2384 
2385  // force the window to be on-screen. Usually the X window manager
2386  // does this, but a few don't, so we do it here for consistency:
2387  int scr_x, scr_y, scr_w, scr_h;
2388  Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y, W, H);
2389 
2390  if (win->border()) {
2391  // ensure border is on screen:
2392  // (assume extremely minimal dimensions for this border)
2393  const int top = 20;
2394  const int left = 1;
2395  const int right = 1;
2396  const int bottom = 1;
2397  if (X+W+right > scr_x+scr_w) X = scr_x+scr_w-right-W;
2398  if (X-left < scr_x) X = scr_x+left;
2399  if (Y+H+bottom > scr_y+scr_h) Y = scr_y+scr_h-bottom-H;
2400  if (Y-top < scr_y) Y = scr_y+top;
2401  }
2402  // now insure contents are on-screen (more important than border):
2403  if (X+W > scr_x+scr_w) X = scr_x+scr_w-W;
2404  if (X < scr_x) X = scr_x;
2405  if (Y+H > scr_y+scr_h) Y = scr_y+scr_h-H;
2406  if (Y < scr_y) Y = scr_y;
2407  }
2408 
2409  // if the window is a subwindow and our parent is not mapped yet, we
2410  // mark this window visible, so that mapping the parent at a later
2411  // point in time will call this function again to finally map the subwindow.
2412  if (win->parent() && !Fl_X::i(win->window())) {
2413  win->set_visible();
2414  return;
2415  }
2416 
2417  // Compute which screen(s) we should be on if we want to go fullscreen
2418  int fullscreen_top, fullscreen_bottom, fullscreen_left, fullscreen_right;
2419 
2420  fullscreen_top = win->fullscreen_screen_top;
2421  fullscreen_bottom = win->fullscreen_screen_bottom;
2422  fullscreen_left = win->fullscreen_screen_left;
2423  fullscreen_right = win->fullscreen_screen_right;
2424 
2425  if ((fullscreen_top < 0) || (fullscreen_bottom < 0) ||
2426  (fullscreen_left < 0) || (fullscreen_right < 0)) {
2427  fullscreen_top = Fl::screen_num(X, Y, W, H);
2428  fullscreen_bottom = fullscreen_top;
2429  fullscreen_left = fullscreen_top;
2430  fullscreen_right = fullscreen_top;
2431  }
2432 
2433 
2434  ulong root = win->parent() ?
2435  fl_xid(win->window()) : RootWindow(fl_display, fl_screen);
2436 
2437  XSetWindowAttributes attr;
2438  int mask = CWBorderPixel|CWColormap|CWEventMask|CWBitGravity;
2439  attr.event_mask = win->parent() ? childEventMask : XEventMask;
2440  attr.colormap = colormap;
2441  attr.border_pixel = 0;
2442  attr.bit_gravity = 0; // StaticGravity;
2443  if (win->override()) {
2444  attr.override_redirect = 1;
2445  attr.save_under = 1;
2446  mask |= CWOverrideRedirect | CWSaveUnder;
2447  } else attr.override_redirect = 0;
2448  if (Fl::grab()) {
2449  attr.save_under = 1; mask |= CWSaveUnder;
2450  if (!win->border()) {attr.override_redirect = 1; mask |= CWOverrideRedirect;}
2451  }
2452  // For the non-EWMH fullscreen case, we cannot use the code above,
2453  // since we do not want save_under, do not want to turn off the
2454  // border, and cannot grab without an existing window. Besides,
2455  // there is no clear_override().
2456  if (win->fullscreen_active() && !Fl_X::ewmh_supported()) {
2457  int sx, sy, sw, sh;
2458  attr.override_redirect = 1;
2459  mask |= CWOverrideRedirect;
2460  Fl::screen_xywh(sx, sy, sw, sh, fullscreen_left);
2461  X = sx;
2462  Fl::screen_xywh(sx, sy, sw, sh, fullscreen_right);
2463  W = sx + sw - X;
2464  Fl::screen_xywh(sx, sy, sw, sh, fullscreen_top);
2465  Y = sy;
2466  Fl::screen_xywh(sx, sy, sw, sh, fullscreen_bottom);
2467  H = sy + sh - Y;
2468  }
2469 
2470  if (fl_background_pixel >= 0) {
2471  attr.background_pixel = fl_background_pixel;
2472  fl_background_pixel = -1;
2473  mask |= CWBackPixel;
2474  }
2475 
2476  Fl_X* xp =
2477  set_xid(win, XCreateWindow(fl_display,
2478  root,
2479  X, Y, W, H,
2480  0, // borderwidth
2481  visual->depth,
2482  InputOutput,
2483  visual->visual,
2484  mask, &attr));
2485  int showit = 1;
2486 
2487  // Set WM_CLIENT_MACHINE and WM_LOCALE_NAME
2488  XSetWMProperties(fl_display, xp->xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
2489 
2490  // Set _NET_WM_PID
2491  long pid;
2492  pid = getpid();
2493  XChangeProperty(fl_display, xp->xid, fl_NET_WM_PID,
2494  XA_CARDINAL, 32, 0, (unsigned char *)&pid, 1);
2495 
2496  if (!win->parent() && !attr.override_redirect) {
2497  // Communicate all kinds 'o junk to the X Window Manager:
2498 
2499  win->label(win->label(), win->iconlabel());
2500 
2501  XChangeProperty(fl_display, xp->xid, WM_PROTOCOLS,
2502  XA_ATOM, 32, 0, (uchar*)&WM_DELETE_WINDOW, 1);
2503 
2504  // send size limits and border:
2505  xp->sendxjunk();
2506 
2507  // set the class property, which controls the icon used:
2508  if (win->xclass()) {
2509  char buffer[1024];
2510  const char *xclass = win->xclass();
2511  const int len = strlen(xclass);
2512  // duplicate the xclass string for use as XA_WM_CLASS
2513  strcpy(buffer, xclass);
2514  strcpy(buffer + len + 1, xclass);
2515  // create the capitalized version:
2516  buffer[len + 1] = toupper(buffer[len + 1]);
2517  if (buffer[len + 1] == 'X')
2518  buffer[len + 2] = toupper(buffer[len + 2]);
2519  XChangeProperty(fl_display, xp->xid, XA_WM_CLASS, XA_STRING, 8, 0,
2520  (unsigned char *)buffer, len * 2 + 2);
2521  }
2522 
2523  if (win->non_modal() && xp->next && !fl_disable_transient_for) {
2524  // find some other window to be "transient for":
2525  Fl_Window* wp = xp->next->w;
2526  while (wp->parent()) wp = wp->window();
2527  XSetTransientForHint(fl_display, xp->xid, fl_xid(wp));
2528  if (!wp->visible()) showit = 0; // guess that wm will not show it
2529  if (win->modal()) {
2530  Atom net_wm_state = XInternAtom (fl_display, "_NET_WM_STATE", 0);
2531  Atom net_wm_state_skip_taskbar = XInternAtom (fl_display, "_NET_WM_STATE_MODAL", 0);
2532  XChangeProperty (fl_display, xp->xid, net_wm_state, XA_ATOM, 32,
2533  PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1);
2534  }
2535  }
2536 
2537  // Make sure that borderless windows do not show in the task bar
2538  if (!win->border()) {
2539  Atom net_wm_state = XInternAtom (fl_display, "_NET_WM_STATE", 0);
2540  Atom net_wm_state_skip_taskbar = XInternAtom (fl_display, "_NET_WM_STATE_SKIP_TASKBAR", 0);
2541  XChangeProperty (fl_display, xp->xid, net_wm_state, XA_ATOM, 32,
2542  PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1);
2543  }
2544 
2545  // If asked for, create fullscreen
2546  if (win->fullscreen_active() && Fl_X::ewmh_supported()) {
2547  unsigned long data[4];
2548  data[0] = fullscreen_top;
2549  data[1] = fullscreen_bottom;
2550  data[2] = fullscreen_left;
2551  data[3] = fullscreen_right;
2552  XChangeProperty (fl_display, xp->xid, fl_NET_WM_FULLSCREEN_MONITORS, XA_ATOM, 32,
2553  PropModeReplace, (unsigned char*) data, 4);
2554  XChangeProperty (fl_display, xp->xid, fl_NET_WM_STATE, XA_ATOM, 32,
2555  PropModeAppend, (unsigned char*) &fl_NET_WM_STATE_FULLSCREEN, 1);
2556  }
2557 
2558  // Make it receptive to DnD:
2559  long version = 4;
2560  XChangeProperty(fl_display, xp->xid, fl_XdndAware,
2561  XA_ATOM, sizeof(int)*8, 0, (unsigned char*)&version, 1);
2562 
2563  XWMHints *hints = XAllocWMHints();
2564  hints->input = True;
2565  hints->flags = InputHint;
2566  if (fl_show_iconic) {
2567  hints->flags |= StateHint;
2568  hints->initial_state = IconicState;
2569  fl_show_iconic = 0;
2570  showit = 0;
2571  }
2572  if (win->icon_->legacy_icon) {
2573  hints->icon_pixmap = (Pixmap)win->icon_->legacy_icon;
2574  hints->flags |= IconPixmapHint;
2575  }
2576  XSetWMHints(fl_display, xp->xid, hints);
2577  XFree(hints);
2578 
2579  xp->set_icons();
2580  }
2581 
2582  // set the window type for menu and tooltip windows to avoid animations (compiz)
2583  if (win->menu_window() || win->tooltip_window()) {
2584  Atom net_wm_type = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE", False);
2585  Atom net_wm_type_kind = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_MENU", False);
2586  XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1);
2587  }
2588 
2589 #if HAVE_XFIXES
2590  // register for clipboard change notifications
2591  if (have_xfixes && !win->parent()) {
2592  XFixesSelectSelectionInput(fl_display, xp->xid, XA_PRIMARY,
2593  XFixesSetSelectionOwnerNotifyMask);
2594  XFixesSelectSelectionInput(fl_display, xp->xid, CLIPBOARD,
2595  XFixesSetSelectionOwnerNotifyMask);
2596  }
2597 #endif
2598 
2599  if (win->shape_data_) {
2600  win->combine_mask();
2601  }
2602  XMapWindow(fl_display, xp->xid);
2603  if (showit) {
2604  win->set_visible();
2605  int old_event = Fl::e_number;
2606  win->handle(Fl::e_number = FL_SHOW); // get child windows to appear
2607  Fl::e_number = old_event;
2608  win->redraw();
2609  }
2610 
2611  // non-EWMH fullscreen case, need grab
2612  if (win->fullscreen_active() && !Fl_X::ewmh_supported()) {
2613  XGrabKeyboard(fl_display, xp->xid, 1, GrabModeAsync, GrabModeAsync, fl_event_time);
2614  }
2615 
2616 }
2617 
2619 // Send X window stuff that can be changed over time:
2620 
2621 void Fl_X::sendxjunk() {
2622  if (w->parent() || w->override()) return; // it's not a window manager window!
2623 
2624  if (!w->size_range_set) { // default size_range based on resizable():
2625  if (w->resizable()) {
2626  Fl_Widget *o = w->resizable();
2627  int minw = o->w(); if (minw > 100) minw = 100;
2628  int minh = o->h(); if (minh > 100) minh = 100;
2629  w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
2630  } else {
2631  w->size_range(w->w(), w->h(), w->w(), w->h());
2632  }
2633  return; // because this recursively called here
2634  }
2635 
2636  XSizeHints *hints = XAllocSizeHints();
2637  // memset(&hints, 0, sizeof(hints)); jreiser suggestion to fix purify?
2638  hints->min_width = w->minw;
2639  hints->min_height = w->minh;
2640  hints->max_width = w->maxw;
2641  hints->max_height = w->maxh;
2642  hints->width_inc = w->dw;
2643  hints->height_inc = w->dh;
2644  hints->win_gravity = StaticGravity;
2645 
2646  // see the file /usr/include/X11/Xm/MwmUtil.h:
2647  // fill all fields to avoid bugs in kwm and perhaps other window managers:
2648  // 0, MWM_FUNC_ALL, MWM_DECOR_ALL
2649  long prop[5] = {0, 1, 1, 0, 0};
2650 
2651  if (hints->min_width != hints->max_width ||
2652  hints->min_height != hints->max_height) { // resizable
2653  hints->flags = PMinSize|PWinGravity;
2654  if (hints->max_width >= hints->min_width ||
2655  hints->max_height >= hints->min_height) {
2656  hints->flags = PMinSize|PMaxSize|PWinGravity;
2657  // unfortunately we can't set just one maximum size. Guess a
2658  // value for the other one. Some window managers will make the
2659  // window fit on screen when maximized, others will put it off screen:
2660  if (hints->max_width < hints->min_width) hints->max_width = Fl::w();
2661  if (hints->max_height < hints->min_height) hints->max_height = Fl::h();
2662  }
2663  if (hints->width_inc && hints->height_inc) hints->flags |= PResizeInc;
2664  if (w->aspect) {
2665  // stupid X! It could insist that the corner go on the
2666  // straight line between min and max...
2667  hints->min_aspect.x = hints->max_aspect.x = hints->min_width;
2668  hints->min_aspect.y = hints->max_aspect.y = hints->min_height;
2669  hints->flags |= PAspect;
2670  }
2671  } else { // not resizable:
2672  hints->flags = PMinSize|PMaxSize|PWinGravity;
2673  prop[0] = 1; // MWM_HINTS_FUNCTIONS
2674  prop[1] = 1|2|16; // MWM_FUNC_ALL | MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE
2675  }
2676 
2677  if (w->force_position()) {
2678  hints->flags |= USPosition;
2679  hints->x = w->x();
2680  hints->y = w->y();
2681  }
2682 
2683  if (!w->border()) {
2684  prop[0] |= 2; // MWM_HINTS_DECORATIONS
2685  prop[2] = 0; // no decorations
2686  }
2687 
2688  XSetWMNormalHints(fl_display, xid, hints);
2689  XChangeProperty(fl_display, xid,
2691  32, 0, (unsigned char *)prop, 5);
2692  XFree(hints);
2693 }
2694 
2695 void Fl_Window::size_range_() {
2696  size_range_set = 1;
2697  if (shown()) i->sendxjunk();
2698 }
2699 
2701 
2702 static unsigned long *default_net_wm_icons = 0L;
2703 static size_t default_net_wm_icons_size = 0;
2704 
2705 // Note: icons[] *must* contain at least <count> valid image pointers (!NULL),
2706 // but: <count> *may* be 0
2707 static void icons_to_property(const Fl_RGB_Image *icons[], int count,
2708  unsigned long **property, size_t *len) {
2709  size_t sz;
2710  unsigned long *data;
2711 
2712  sz = 0;
2713  for (int i = 0;i < count;i++)
2714  sz += 2 + icons[i]->w() * icons[i]->h();
2715 
2716  // FIXME: Might want to sort the icons
2717 
2718  *property = data = new unsigned long[sz];
2719  *len = sz;
2720 
2721  for (int i = 0;i < count;i++) {
2722  const Fl_RGB_Image *image;
2723 
2724  image = icons[i];
2725 
2726  data[0] = image->w();
2727  data[1] = image->h();
2728  data += 2;
2729 
2730  const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
2731 
2732  const uchar *in = (const uchar*)*image->data();
2733  for (int y = 0; y < image->h(); y++) {
2734  for (int x = 0; x < image->w(); x++) {
2735  switch (image->d()) {
2736  case 1:
2737  *data = ( 0xff<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
2738  break;
2739  case 2:
2740  *data = (in[1]<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
2741  break;
2742  case 3:
2743  *data = ( 0xff<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
2744  break;
2745  case 4:
2746  *data = (in[3]<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
2747  break;
2748  }
2749  in += image->d();
2750  data++;
2751  }
2752  in += extra_data;
2753  }
2754  }
2755 }
2756 
2757 void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
2758  if (default_net_wm_icons) {
2759  delete [] default_net_wm_icons;
2760  default_net_wm_icons = 0L;
2762  }
2763 
2764  if (count > 0)
2765  icons_to_property(icons, count,
2767 }
2768 
2769 void Fl_X::set_icons() {
2770  unsigned long *net_wm_icons;
2771  size_t net_wm_icons_size;
2772 
2773  if (w->icon_->count) {
2774  icons_to_property((const Fl_RGB_Image **)w->icon_->icons, w->icon_->count,
2775  &net_wm_icons, &net_wm_icons_size);
2776  } else {
2777  net_wm_icons = default_net_wm_icons;
2778  net_wm_icons_size = default_net_wm_icons_size;
2779  }
2780 
2781  XChangeProperty (fl_display, xid, fl_NET_WM_ICON, XA_CARDINAL, 32,
2782  PropModeReplace, (unsigned char*) net_wm_icons, net_wm_icons_size);
2783 
2784  if (w->icon_->count) {
2785  delete [] net_wm_icons;
2786  net_wm_icons = 0L;
2787  net_wm_icons_size = 0;
2788  }
2789 }
2790 
2792 
2793 int Fl_X::set_cursor(Fl_Cursor c) {
2794 
2795  /* The cursors are cached, because creating one takes 0.5ms including
2796  opening, reading, and closing theme files. They are kept until program
2797  exit by design, which valgrind will note as reachable. */
2798  static Cursor xc_arrow = None;
2799  static Cursor xc_cross = None;
2800  static Cursor xc_wait = None;
2801  static Cursor xc_insert = None;
2802  static Cursor xc_hand = None;
2803  static Cursor xc_help = None;
2804  static Cursor xc_move = None;
2805  static Cursor xc_ns = None;
2806  static Cursor xc_we = None;
2807  static Cursor xc_ne = None;
2808  static Cursor xc_n = None;
2809  static Cursor xc_nw = None;
2810  static Cursor xc_e = None;
2811  static Cursor xc_w = None;
2812  static Cursor xc_se = None;
2813  static Cursor xc_s = None;
2814  static Cursor xc_sw = None;
2815 
2816  Cursor xc;
2817 
2818 #define cache_cursor(name, var) if (var == None) { \
2819  var = XCreateFontCursor(fl_display, name); \
2820  } \
2821  xc = var
2822 
2823  switch (c) {
2824  case FL_CURSOR_ARROW: cache_cursor(XC_left_ptr, xc_arrow); break;
2825  case FL_CURSOR_CROSS: cache_cursor(XC_tcross, xc_cross); break;
2826  case FL_CURSOR_WAIT: cache_cursor(XC_watch, xc_wait); break;
2827  case FL_CURSOR_INSERT: cache_cursor(XC_xterm, xc_insert); break;
2828  case FL_CURSOR_HAND: cache_cursor(XC_hand2, xc_hand); break;
2829  case FL_CURSOR_HELP: cache_cursor(XC_question_arrow, xc_help); break;
2830  case FL_CURSOR_MOVE: cache_cursor(XC_fleur, xc_move); break;
2831  case FL_CURSOR_NS: cache_cursor(XC_sb_v_double_arrow, xc_ns); break;
2832  case FL_CURSOR_WE: cache_cursor(XC_sb_h_double_arrow, xc_we); break;
2833  case FL_CURSOR_NE: cache_cursor(XC_top_right_corner, xc_ne); break;
2834  case FL_CURSOR_N: cache_cursor(XC_top_side, xc_n); break;
2835  case FL_CURSOR_NW: cache_cursor(XC_top_left_corner, xc_nw); break;
2836  case FL_CURSOR_E: cache_cursor(XC_right_side, xc_e); break;
2837  case FL_CURSOR_W: cache_cursor(XC_left_side, xc_w); break;
2838  case FL_CURSOR_SE: cache_cursor(XC_bottom_right_corner, xc_se); break;
2839  case FL_CURSOR_S: cache_cursor(XC_bottom_side, xc_s); break;
2840  case FL_CURSOR_SW: cache_cursor(XC_bottom_left_corner, xc_sw); break;
2841  default:
2842  return 0;
2843  }
2844 
2845 #undef cache_cursor
2846 
2847  XDefineCursor(fl_display, xid, xc);
2848 
2849  return 1;
2850 }
2851 
2852 int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
2853 #if ! HAVE_XCURSOR
2854  return 0;
2855 #else
2856  XcursorImage *cursor;
2857  Cursor xc;
2858 
2859  if ((hotx < 0) || (hotx >= image->w()))
2860  return 0;
2861  if ((hoty < 0) || (hoty >= image->h()))
2862  return 0;
2863 
2864  cursor = XcursorImageCreate(image->w(), image->h());
2865  if (!cursor)
2866  return 0;
2867 
2868  const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
2869  const uchar *i = (const uchar*)*image->data();
2870  XcursorPixel *o = cursor->pixels;
2871  for (int y = 0;y < image->h();y++) {
2872  for (int x = 0;x < image->w();x++) {
2873  switch (image->d()) {
2874  case 1:
2875  *o = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
2876  break;
2877  case 2:
2878  *o = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
2879  break;
2880  case 3:
2881  *o = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
2882  break;
2883  case 4:
2884  *o = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
2885  break;
2886  }
2887  i += image->d();
2888  o++;
2889  }
2890  i += extra_data;
2891  }
2892 
2893  cursor->xhot = hotx;
2894  cursor->yhot = hoty;
2895 
2896  xc = XcursorImageLoadCursor(fl_display, cursor);
2897  XDefineCursor(fl_display, xid, xc);
2898  XFreeCursor(fl_display, xc);
2899 
2900  XcursorImageDestroy(cursor);
2901 
2902  return 1;
2903 #endif
2904 }
2905 
2907 
2908 // returns pointer to the filename, or null if name ends with '/'
2909 const char *fl_filename_name(const char *name) {
2910  const char *p,*q;
2911  if (!name) return (0);
2912  for (p=q=name; *p;) if (*p++ == '/') q = p;
2913  return q;
2914 }
2915 
2916 void Fl_Window::label(const char *name,const char *iname) {
2918  iconlabel_ = iname;
2919  if (shown() && !parent()) {
2920  if (!name) name = "";
2921  int namelen = strlen(name);
2922  if (!iname) iname = fl_filename_name(name);
2923  int inamelen = strlen(iname);
2924  XChangeProperty(fl_display, i->xid, fl_NET_WM_NAME, fl_XaUtf8String, 8, 0, (uchar*)name, namelen); // utf8
2925  XChangeProperty(fl_display, i->xid, XA_WM_NAME, XA_STRING, 8, 0, (uchar*)name, namelen); // non-utf8
2926  XChangeProperty(fl_display, i->xid, fl_NET_WM_ICON_NAME, fl_XaUtf8String, 8, 0, (uchar*)iname, inamelen); // utf8
2927  XChangeProperty(fl_display, i->xid, XA_WM_ICON_NAME, XA_STRING, 8, 0, (uchar*)iname, inamelen); // non-utf8
2928  }
2929 }
2930 
2932 // Implement the virtual functions for the base Fl_Window class:
2933 
2934 // If the box is a filled rectangle, we can make the redisplay *look*
2935 // faster by using X's background pixel erasing. We can make it
2936 // actually *be* faster by drawing the frame only, this is done by
2937 // setting fl_boxcheat, which is seen by code in fl_drawbox.cxx:
2938 //
2939 // On XFree86 (and prehaps all X's) this has a problem if the window
2940 // is resized while a save-behind window is atop it. The previous
2941 // contents are restored to the area, but this assumes the area
2942 // is cleared to background color. So this is disabled in this version.
2943 // Fl_Window *fl_boxcheat;
2944 static inline int can_boxcheat(uchar b) {return (b==1 || ((b&2) && b<=15));}
2945 
2946 void Fl_Window::show() {
2948  if (Fl::scheme_bg_) {
2951  } else {
2953  }
2954  Fl_Tooltip::exit(this);
2955  if (!shown()) {
2956  fl_open_display();
2957  // Don't set background pixel for double-buffered windows...
2958  if (type() != FL_DOUBLE_WINDOW && can_boxcheat(box())) {
2960  }
2961  Fl_X::make_xid(this);
2962  } else {
2963  XMapRaised(fl_display, i->xid);
2964  }
2965 #ifdef USE_PRINT_BUTTON
2966 void preparePrintFront(void);
2967 preparePrintFront();
2968 #endif
2969 }
2970 
2974 
2975 // make X drawing go into this window (called by subclass flush() impl.)
2976 void Fl_Window::make_current() {
2977  static GC gc; // the GC used by all X windows
2978  if (!shown()) {
2979  fl_alert("Fl_Window::make_current(), but window is not shown().");
2980  Fl::fatal("Fl_Window::make_current(), but window is not shown().");
2981  }
2982  if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0);
2983  fl_window = i->xid;
2984  fl_gc = gc;
2985  current_ = this;
2986  fl_clip_region(0);
2987 
2988 #ifdef FLTK_USE_CAIRO
2989  // update the cairo_t context
2990  if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this);
2991 #endif
2992 }
2993 
2995  Fl_X *temp = Fl_X::i(w);
2996  return temp ? temp->xid : 0;
2997 }
2998 
2999 static void decorated_win_size(Fl_Window *win, int &w, int &h)
3000 {
3001  w = win->w();
3002  h = win->h();
3003  if (!win->shown() || win->parent() || !win->border() || !win->visible()) return;
3004  Window root, parent, *children;
3005  unsigned n = 0;
3006  Status status = XQueryTree(fl_display, Fl_X::i(win)->xid, &root, &parent, &children, &n);
3007  if (status != 0 && n) XFree(children);
3008  // when compiz is used, root and parent are the same window
3009  // and I don't know where to find the window decoration
3010  if (status == 0 || root == parent) return;
3011  XWindowAttributes attributes;
3012  XGetWindowAttributes(fl_display, parent, &attributes);
3013  w = attributes.width;
3014  h = attributes.height;
3015 }
3016 
3018 {
3019  int w, h;
3020  decorated_win_size(this, w, h);
3021  return h;
3022 }
3023 
3025 {
3026  int w, h;
3027  decorated_win_size(this, w, h);
3028  return w;
3029 }
3030 
3031 void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
3032 {
3033  if (!win->shown() || win->parent() || !win->border() || !win->visible()) {
3034  this->print_widget(win, x_offset, y_offset);
3035  return;
3036  }
3038 }
3039 
3040 void Fl_Paged_Device::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset)
3041 {
3043  win->show();
3044  Fl::check();
3045  win->make_current();
3046  Window root, parent, *children, child_win, from;
3047  unsigned n = 0;
3048  int bx, bt, do_it;
3049  from = fl_window;
3050  do_it = (XQueryTree(fl_display, fl_window, &root, &parent, &children, &n) != 0 &&
3051  XTranslateCoordinates(fl_display, fl_window, parent, 0, 0, &bx, &bt, &child_win) == True);
3052  if (n) XFree(children);
3053  // hack to bypass STR #2648: when compiz is used, root and parent are the same window
3054  // and I don't know where to find the window decoration
3055  if (do_it && root == parent) do_it = 0;
3056  if (!do_it) {
3057  toset->set_current();
3058  this->print_widget(win, x_offset, y_offset);
3059  return;
3060  }
3061  fl_window = parent;
3062  uchar *top_image = 0, *left_image = 0, *right_image = 0, *bottom_image = 0;
3063  top_image = fl_read_image(NULL, 0, 0, - (win->w() + 2 * bx), bt);
3064  if (bx) {
3065  left_image = fl_read_image(NULL, 0, bt, -bx, win->h() + bx);
3066  right_image = fl_read_image(NULL, win->w() + bx, bt, -bx, win->h() + bx);
3067  bottom_image = fl_read_image(NULL, 0, bt + win->h(), -(win->w() + 2*bx), bx);
3068  }
3069  fl_window = from;
3070  toset->set_current();
3071  if (top_image) {
3072  fl_draw_image(top_image, x_offset, y_offset, win->w() + 2 * bx, bt, 3);
3073  delete[] top_image;
3074  }
3075  if (bx) {
3076  if (left_image) fl_draw_image(left_image, x_offset, y_offset + bt, bx, win->h() + bx, 3);
3077  if (right_image) fl_draw_image(right_image, x_offset + win->w() + bx, y_offset + bt, bx, win->h() + bx, 3);
3078  if (bottom_image) fl_draw_image(bottom_image, x_offset, y_offset + bt + win->h(), win->w() + 2*bx, bx, 3);
3079  if (left_image) delete[] left_image;
3080  if (right_image) delete[] right_image;
3081  if (bottom_image) delete[] bottom_image;
3082  }
3083  this->print_widget( win, x_offset + bx, y_offset + bt );
3084 }
3085 
3086 #ifdef USE_PRINT_BUTTON
3087 // to test the Fl_Printer class creating a "Print front window" button in a separate window
3088 // contains also preparePrintFront call above
3089 #include <FL/Fl_Printer.H>
3090 #include <FL/Fl_Button.H>
3091 void printFront(Fl_Widget *o, void *data)
3092 {
3093  Fl_Printer printer;
3094  o->window()->hide();
3095  Fl_Window *win = Fl::first_window();
3096  if(!win) return;
3097  int w, h;
3098  if( printer.start_job(1) ) { o->window()->show(); return; }
3099  if( printer.start_page() ) { o->window()->show(); return; }
3100  printer.printable_rect(&w,&h);
3101  // scale the printer device so that the window fits on the page
3102  float scale = 1;
3103  int ww = win->decorated_w();
3104  int wh = win->decorated_h();
3105  if (ww > w || wh > h) {
3106  scale = (float)w/ww;
3107  if ((float)h/wh < scale) scale = (float)h/wh;
3108  printer.scale(scale, scale);
3109  }
3110 
3111 // #define ROTATE 20.0
3112 #ifdef ROTATE
3113  printer.scale(scale * 0.8, scale * 0.8);
3114  printer.printable_rect(&w, &h);
3115  printer.origin(w/2, h/2 );
3116  printer.rotate(ROTATE);
3117  printer.print_widget( win, - win->w()/2, - win->h()/2 );
3118  //printer.print_window_part( win, 0,0, win->w(), win->h(), - win->w()/2, - win->h()/2 );
3119 #else
3120  printer.print_window(win);
3121 #endif
3122 
3123  printer.end_page();
3124  printer.end_job();
3125  o->window()->show();
3126 }
3127 
3128 #include <FL/Fl_Copy_Surface.H>
3129 void copyFront(Fl_Widget *o, void *data)
3130 {
3131  o->window()->hide();
3132  Fl_Window *win = Fl::first_window();
3133  if (!win) return;
3134  Fl_Copy_Surface *surf = new Fl_Copy_Surface(win->decorated_w(), win->decorated_h());
3135  surf->set_current();
3136  surf->draw_decorated_window(win); // draw the window content
3137  delete surf; // put the window on the clipboard
3138  o->window()->show();
3139 }
3140 
3141 void preparePrintFront(void)
3142 {
3143  static int first=1;
3144  if(!first) return;
3145  first=0;
3146  static Fl_Window w(0,0,140,60);
3147  static Fl_Button bp(0,0,w.w(),30, "Print front window");
3148  bp.callback(printFront);
3149  static Fl_Button bc(0,30,w.w(),30, "Copy front window");
3150  bc.callback(copyFront);
3151  w.end();
3152  w.show();
3153 }
3154 #endif // USE_PRINT_BUTTON
3155 
3156 #endif
3157 
3158 //
3159 // End of "$Id$".
3160 //
fl_xpixel
ulong fl_xpixel(Fl_Color i)
Definition: fl_color.cxx:203
FL_Sleep
#define FL_Sleep
Definition: Enumerations.H:526
fl_init_workarea
static void fl_init_workarea()
Definition: Fl_x.cxx:787
Fl_Image::d
void d(int D)
Definition: Fl_Image.H:84
FL_Up
#define FL_Up
The up arrow key.
Definition: Enumerations.H:481
fl_lock_function
void(* fl_lock_function)()
Definition: Fl_x.cxx:224
Fl_Widget::FORCE_POSITION
don't let the window manager position the window (Fl_Window)
Definition: Fl_Widget.H:160
Fl_Copy_Surface::set_current
void set_current()
Make this surface the current drawing surface. This surface will receive all future graphics requests...
Definition: Fl_Copy_Surface.cxx:162
fl_INCR
static Atom fl_INCR
Definition: Fl_x.cxx:354
Fl_Widget::y
int y() const
Definition: Fl_Widget.H:289
Fl_Group::resizable
Fl_Widget * resizable() const
Definition: Fl_Group.H:152
FL_Mail
#define FL_Mail
Definition: Enumerations.H:520
Fl.H
clipboard_timeout
static void clipboard_timeout(void *data)
Definition: Fl_x.cxx:1127
Fl::e_y
static int e_y
Definition: Fl.H:145
send_motion
static Fl_Window * send_motion
Definition: Fl_x.cxx:199
Fl_Widget::align
Fl_Align align() const
Definition: Fl_Widget.H:348
_NET_WM_STATE_REMOVE
#define _NET_WM_STATE_REMOVE
Definition: Fl_x.cxx:2196
FL_CLOSE
Definition: Enumerations.H:327
FL_NO_LABEL
does nothing
Definition: Enumerations.H:765
Fl_Window::show
virtual void show()
Definition: Fl_win32.cxx:2542
can_boxcheat
static int can_boxcheat(uchar b)
Definition: Fl_x.cxx:2944
fl_screen
int fl_screen
Definition: Fl_x.cxx:316
FL_HIDE
Definition: Enumerations.H:369
FL_DND_ENTER
Definition: Enumerations.H:401
FL_BackSpace
#define FL_BackSpace
The backspace key.
Definition: Enumerations.H:468
FL_META
#define FL_META
One of the meta/Windows keys is down.
Definition: Enumerations.H:563
FL_KEYUP
Definition: Enumerations.H:320
Fl_Window::modal
unsigned int modal() const
Definition: Fl_Window.H:291
POLLERR
#define POLLERR
Definition: Fl_x.cxx:96
FL_Volume_Down
#define FL_Volume_Down
Definition: Enumerations.H:512
fl_message_window
Window fl_message_window
Definition: Fl_x.cxx:315
fl_XdndEnter
Atom fl_XdndEnter
Definition: Fl_x.cxx:335
Fl_Image::data
void data(const char *const *p, int c)
Definition: Fl_Image.H:100
fl_send_system_handlers
int fl_send_system_handlers(void *e)
Definition: Fl.cxx:962
fl_close_display
void fl_close_display()
Definition: Fl_x.cxx:780
fl_xid_
FL_EXPORT Window fl_xid_(const Fl_Window *w)
Definition: Fl_x.cxx:2994
FL_UNFOCUS
Definition: Enumerations.H:288
FL_DND_RELEASE
Definition: Enumerations.H:417
fl_NET_WM_STATE
static Atom fl_NET_WM_STATE
Definition: Fl_x.cxx:359
default_net_wm_icons
static unsigned long * default_net_wm_icons
Definition: Fl_x.cxx:2702
Fl::fatal
static void(* fatal)(const char *,...)
Definition: Fl.H:530
Fl_Image::h
void h(int H)
Definition: Fl_Image.H:80
FD::events
short events
Definition: Fl_win32.cxx:264
fl_colormap
Colormap fl_colormap
Definition: Fl_x.cxx:318
fl_XdndFinished
Atom fl_XdndFinished
Definition: Fl_x.cxx:342
fl_key_vector
char fl_key_vector[32]
Definition: Fl_x.cxx:1194
fl_workarea_xywh
static int fl_workarea_xywh[4]
Definition: Fl_x.cxx:785
poll_clipboard_owner
static void poll_clipboard_owner(void)
Definition: Fl_x.cxx:1097
getIncrData
static long getIncrData(uchar *&data, const XSelectionEvent &selevent, long lower_bound)
Definition: Fl_x.cxx:1276
PRIMARY_TIMESTAMP
static Atom PRIMARY_TIMESTAMP
Definition: Fl_x.cxx:331
POLLOUT
#define POLLOUT
Definition: Fl_x.cxx:95
FL_Media_Next
#define FL_Media_Next
Definition: Enumerations.H:518
Fl::e_state
static int e_state
Definition: Fl.H:150
fl_xevent
const XEvent * fl_xevent
Definition: Fl_x.cxx:1191
xim_styles
static XIMStyles * xim_styles
Definition: test.c:70
get_xwinprop
static int get_xwinprop(Window wnd, Atom prop, long max_length, unsigned long *nitems, unsigned long **data)
Definition: Fl_x.cxx:972
fl_set_spot
void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
Definition: Fl_x.cxx:500
Fl_Window::fullscreen_active
unsigned int fullscreen_active() const
Definition: Fl_Window.H:567
Fl::e_clipboard_data
static void * e_clipboard_data
Definition: Fl.H:156
xim_im
XIM xim_im
Definition: test.c:68
fl_ask.H
Fl_Menu_Window::hide
void hide()
Definition: Fl_Menu_Window.cxx:90
Fl_Printer::printable_rect
int printable_rect(int *w, int *h)
Computes the width and height of the printable area of the page.
Definition: Fl_Printer.cxx:123
message
static Fl_Box * message
Definition: fl_ask.cxx:47
Fl_Button
Buttons generate callbacks when they are clicked by the user.
Definition: Fl_Button.H:79
Fl::e_is_click
static int e_is_click
Definition: Fl.H:152
fl_XdndURIList
Atom fl_XdndURIList
Definition: Fl_x.cxx:344
fl_KeycodeToKeysym
static KeySym fl_KeycodeToKeysym(Display *d, KeyCode k, unsigned i)
Definition: Fl_x.cxx:1321
Fl_Widget::window
Fl_Window * window() const
Definition: Fl_Window.cxx:118
py
static int py
Definition: Fl_x.cxx:1198
Fl::e_text
static char * e_text
Definition: Fl.H:154
FL_Page_Down
#define FL_Page_Down
The page-down key.
Definition: Enumerations.H:485
Fl_Window::menu_window
unsigned int menu_window() const
Definition: Fl_Window.H:357
x.H
atom_bits
static int atom_bits
Definition: Fl_x.cxx:372
Fl_Surface_Device
Definition: Fl_Device.H:556
unknown_len
const int unknown_len
Definition: Fl_x.cxx:1239
Fl::e_y_root
static int e_y_root
Definition: Fl.H:147
filename.H
Fl_Widget::_clear_fullscreen
void _clear_fullscreen()
Definition: Fl_Widget.H:883
FL_Volume_Mute
#define FL_Volume_Mute
Definition: Enumerations.H:513
fl_Xatextplainutf
static Atom fl_Xatextplainutf
Definition: Fl_x.cxx:345
fl_sendClientMessage
void fl_sendClientMessage(Window window, Atom message, unsigned long d0, unsigned long d1=0, unsigned long d2=0, unsigned long d3=0, unsigned long d4=0)
Definition: Fl_x.cxx:937
Fl_Window::fullscreen_x
void fullscreen_x()
Definition: Fl_win32.cxx:1721
Fl::screen_xywh
static void screen_xywh(int &X, int &Y, int &W, int &H)
Definition: Fl.H:1000
free
void free()
H
static int H
Definition: Fl_Tooltip.cxx:76
offset
static double offset[5]
Definition: fl_rounded_box.cxx:32
xerror_handler
static int xerror_handler(Display *d, XErrorEvent *e)
Definition: Fl_x.cxx:384
Fl::visual
static int visual(int)
Definition: Fl_visual.cxx:118
Fl::has_timeout
static int has_timeout(Fl_Timeout_Handler, void *=0)
Definition: Fl.cxx:355
fl_dnd_source_types
static Atom * fl_dnd_source_types
Definition: Fl_x.cxx:932
Fl::modal_
static Fl_Window * modal_
Definition: Fl.H:164
Fl::paste
static void paste(Fl_Widget &receiver, int source, const char *type)
Definition: Fl_win32.cxx:704
fl_Xatextplainutf2
static Atom fl_Xatextplainutf2
Definition: Fl_x.cxx:346
write_short
static void write_short(unsigned char **cp, short i)
Definition: Fl_x.cxx:1018
FL_RGB
Definition: Enumerations.H:1085
Fl_Widget::set_flag
void set_flag(unsigned int c)
Definition: Fl_Widget.H:149
fl_ready
int fl_ready()
Definition: Fl_x.cxx:284
Fl_Widget::x
int x() const
Definition: Fl_Widget.H:284
NULL
#define NULL
Definition: forms.H:34
Fl_Widget::set_visible
void set_visible()
Definition: Fl_Widget.H:696
window
static Fl_TooltipBox * window
Definition: Fl_Tooltip.cxx:75
FL_Forward
#define FL_Forward
Definition: Enumerations.H:523
FL_PASTE
Definition: Enumerations.H:383
FL_CURSOR_NS
Definition: Enumerations.H:1059
FL_KEYDOWN
Definition: Enumerations.H:310
Fl::e_number
static int e_number
Definition: Fl.H:143
spotf
static int spotf
Definition: Fl_x.cxx:490
convert_crlf
static void convert_crlf(unsigned char *string, long &len)
Definition: Fl_x.cxx:302
fl_XaCompoundText
static Atom fl_XaCompoundText
Definition: Fl_x.cxx:349
Fl::screen_num
static int screen_num(int x, int y)
Definition: screen_xywh.cxx:380
FL_CURSOR_MOVE
Definition: Enumerations.H:1056
fl_dnd_source_window
static Window fl_dnd_source_window
Definition: Fl_x.cxx:931
Fl::clipboard_plain_text
static const char *const clipboard_plain_text
Definition: Fl.H:956
Fl_Window::icon_data::legacy_icon
const void * legacy_icon
Definition: Fl_Window.H:100
Fl::clipboard_contains
static int clipboard_contains(const char *type)
Definition: Fl_win32.cxx:837
FL_LEAVE
Definition: Enumerations.H:259
fl_NET_WM_PID
static Atom fl_NET_WM_PID
Definition: Fl_x.cxx:355
clipboard_timestamp
static Time clipboard_timestamp
Definition: Fl_x.cxx:1092
Fl_Image::w
void w(int W)
Definition: Fl_Image.H:76
Fl_Widget::labeltype
Fl_Labeltype labeltype() const
Definition: Fl_Widget.H:456
nfds
static int nfds
Definition: Fl_x.cxx:100
fl_clipboard_notify_change
void fl_clipboard_notify_change()
Definition: Fl_x.cxx:1170
FL_SCREEN_CONFIGURATION_CHANGED
Definition: Enumerations.H:421
FL_Back
#define FL_Back
Definition: Enumerations.H:522
b
long b
Definition: jpegint.h:397
Fl::e_x_root
static int e_x_root
Definition: Fl.H:146
FL_EXPORT
#define FL_EXPORT
Definition: Fl_Export.H:35
Fl_Window::icon_
struct icon_data * icon_
Definition: Fl_Window.H:111
FL_CURSOR_SE
Definition: Enumerations.H:1066
Fl_Window::size_range_set
uchar size_range_set
Definition: Fl_Window.H:115
Fl_Window::force_position
void force_position(int force)
Definition: Fl_Window.H:181
fl_NET_ACTIVE_WINDOW
static Atom fl_NET_ACTIVE_WINDOW
Definition: Fl_x.cxx:364
fl_xim_im
static XIM fl_xim_im
Definition: Fl_x.cxx:319
fl_clipboard_notify_empty
bool fl_clipboard_notify_empty(void)
Definition: Fl.cxx:540
Fl_Display_Device::display_device
static Fl_Display_Device * display_device()
Definition: Fl_Device.cxx:83
Fl::h
static int h()
Definition: Fl_win32.cxx:571
handle_clipboard_timestamp
static void handle_clipboard_timestamp(int clipboard, Time time)
Definition: Fl_x.cxx:1138
do_queued_events
static void do_queued_events()
Definition: Fl_x.cxx:203
fl_selection_requestor
Fl_Widget * fl_selection_requestor
Definition: Fl_x.cxx:853
fl_gc
GC fl_gc
Definition: Fl_x.cxx:2973
FL_Page_Up
#define FL_Page_Up
The page-up key.
Definition: Enumerations.H:484
fl_XdndTypeList
Atom fl_XdndTypeList
Definition: Fl_x.cxx:336
Fl_Printer::scale
void scale(float scale_x, float scale_y=0.)
Changes the scaling of page coordinates.
Definition: Fl_Printer.cxx:143
Fl_Window::fullscreen_off_x
void fullscreen_off_x(int X, int Y, int W, int H)
Definition: Fl_win32.cxx:1727
Fl_Widget::w
int w() const
Definition: Fl_Widget.H:294
FL_Down
#define FL_Down
The down arrow key.
Definition: Enumerations.H:483
Fl::e_clipboard_type
static const char * e_clipboard_type
Definition: Fl.H:157
fl_NET_WM_ICON_NAME
static Atom fl_NET_WM_ICON_NAME
Definition: Fl_x.cxx:357
fl_draw_image
void fl_draw_image(const uchar *buf, int X, int Y, int W, int H, int D=3, int L=0)
Definition: fl_draw.H:685
FL_CURSOR_HELP
Definition: Enumerations.H:1055
fl_selection_type
const char * fl_selection_type[2]
Definition: Fl_x.cxx:856
fl_xim_activate
void fl_xim_activate(Window xid)
Definition: Fl_x.cxx:623
buffer
static char * buffer
Definition: file.cxx:215
FL_ALIGN_INSIDE
const Fl_Align FL_ALIGN_INSIDE
Definition: Enumerations.H:843
Fl::first_window
static Fl_Window * first_window()
Definition: Fl.cxx:751
FD::arg
void * arg
Definition: Fl_win32.cxx:266
Fl::belowmouse
static Fl_Widget * belowmouse()
Definition: Fl.H:833
fl_i_own_selection
char fl_i_own_selection[2]
Definition: Fl_x.cxx:858
Fl::e_clicks
static int e_clicks
Definition: Fl.H:151
fl_XdndPosition
Atom fl_XdndPosition
Definition: Fl_x.cxx:337
Fl_Window.H
checkdouble
static void checkdouble()
Definition: Fl_x.cxx:1222
Fl::add_fd
static void add_fd(int fd, int when, Fl_FD_Handler cb, void *=0)
Fl_Window::make_current
void make_current()
Definition: Fl_win32.cxx:2590
fl_dnd_type
static Atom fl_dnd_type
Definition: Fl_x.cxx:933
FL_CURSOR_INSERT
Definition: Enumerations.H:1053
FL_DND_LEAVE
Definition: Enumerations.H:411
decorated_win_size
static void decorated_win_size(Fl_Window *win, int &w, int &h)
Definition: Fl_x.cxx:2999
Fl_Widget::color
Fl_Color color() const
Definition: Fl_Widget.H:378
Fl_Window::xclass
const char * xclass() const
Definition: Fl_Window.cxx:287
FL_End
#define FL_End
The end key.
Definition: Enumerations.H:486
default_net_wm_icons_size
static size_t default_net_wm_icons_size
Definition: Fl_x.cxx:2703
FL_Meta_R
#define FL_Meta_R
The right meta/Windows key.
Definition: Enumerations.H:503
Fl_Widget::_set_fullscreen
void _set_fullscreen()
Definition: Fl_Widget.H:882
Fl::check
static int check()
Definition: Fl.cxx:688
Fl::event
static int event()
Definition: Fl.H:593
fl_xfocus
Fl_Window * fl_xfocus
Definition: Fl.cxx:148
TARGETS
static Atom TARGETS
Definition: Fl_x.cxx:328
FL_DND_DRAG
Definition: Enumerations.H:407
p
static menustate * p
Definition: Fl_Menu.cxx:606
fl_dnd_source_action
static Atom fl_dnd_source_action
Definition: Fl_x.cxx:934
fl_NET_WORKAREA
static Atom fl_NET_WORKAREA
Definition: Fl_x.cxx:362
FL_CURSOR_HAND
Definition: Enumerations.H:1054
FL_Left
#define FL_Left
The left arrow key.
Definition: Enumerations.H:480
Fl_Widget::position
void position(int X, int Y)
Definition: Fl_Widget.H:332
Fl_Widget::w
void w(int v)
Definition: Fl_Widget.H:143
fl_find
Fl_Window * fl_find(Window xid)
Definition: Fl.cxx:730
FL_Right
#define FL_Right
The right arrow key.
Definition: Enumerations.H:482
fd_callback
static void fd_callback(int, void *)
Definition: Fl_x.cxx:374
Fl_Printer::end_page
int end_page(void)
To be called at the end of each page.
Definition: Fl_Printer.cxx:163
Fl_Widget::x
void x(int v)
Definition: Fl_Widget.H:139
FL_Tab
#define FL_Tab
The tab key.
Definition: Enumerations.H:469
fl_utf8.h
header for Unicode and UTF-8 character handling
nothing
static void nothing()
Definition: Fl_x.cxx:223
fd_array_size
static int fd_array_size
Definition: Fl_x.cxx:101
FL_MOVE
Definition: Enumerations.H:335
FL_MOUSEWHEEL
Definition: Enumerations.H:395
FL_CURSOR_WAIT
Definition: Enumerations.H:1052
FL_Home
#define FL_Home
The home key.
Definition: Enumerations.H:479
FL_CURSOR_NW
Definition: Enumerations.H:1070
fl_background_pixel
int fl_background_pixel
Definition: Fl_x.cxx:2353
FD::fd
int fd
Definition: Fl_win32.cxx:263
send_wm_state_event
static void send_wm_state_event(Window wnd, int add, Atom prop)
Definition: Fl_x.cxx:2219
xerror
static int xerror
Definition: Fl_x.cxx:1243
fl_draw.H
utility header to pull drawing functions together
fl_filename_name
const char * fl_filename_name(const char *name)
Definition: Fl_x.cxx:2909
fl_fix_focus
void fl_fix_focus()
Definition: Fl.cxx:1087
fl_xim_ic
XIC fl_xim_ic
Definition: Fl_x.cxx:320
Fl_Window::decorated_h
int decorated_h()
Definition: Fl_win32.cxx:2764
fl_XdndStatus
Atom fl_XdndStatus
Definition: Fl_x.cxx:340
Fl::copy_image
static void copy_image(const unsigned char *data, int W, int H, int destination=0)
Definition: Fl_x.cxx:1076
arg
static int arg(int argc, char **argv, int &i)
Definition: fluid.cxx:1723
fdsets
static fd_set fdsets[3]
Definition: Fl_x.cxx:92
Fl_Window::non_modal
unsigned int non_modal() const
Definition: Fl_Window.H:300
Fl::e_keysym
static int e_keysym
Definition: Fl.H:153
wasXExceptionRaised
static int wasXExceptionRaised()
Definition: Fl_x.cxx:1255
fl_XdndDrop
Atom fl_XdndDrop
Definition: Fl_x.cxx:339
Fl::clipboard_image
static const char *const clipboard_image
Definition: Fl.H:959
fl_read_image
FL_EXPORT uchar * fl_read_image(uchar *p, int X, int Y, int W, int H, int alpha=0)
Definition: fl_read_image.cxx:152
getNextEvent
static bool getNextEvent(XEvent *event_return)
Definition: Fl_x.cxx:1261
FL_Media_Stop
#define FL_Media_Stop
Definition: Enumerations.H:516
set_event_xy
static void set_event_xy()
Definition: Fl_x.cxx:1201
FL_FOCUS
Definition: Enumerations.H:283
Fl::e_dy
static int e_dy
Definition: Fl.H:149
Fl_Window::size_range
void size_range(int minw, int minh, int maxw=0, int maxh=0, int dw=0, int dh=0, int aspect=0)
Definition: Fl_Window.H:438
Fl_Widget::visible
unsigned int visible() const
Definition: Fl_Widget.H:660
Fl_Window
Definition: Fl_Window.H:57
fl_xim_win
static Window fl_xim_win
Definition: Fl_x.cxx:321
fl_xmousewin
Fl_Window * fl_xmousewin
Definition: Fl.cxx:149
Fl_Window::resize
virtual void resize(int X, int Y, int W, int H)
Definition: Fl_win32.cxx:1643
FL_KP_Last
#define FL_KP_Last
The last keypad key; use to range-check keypad.
Definition: Enumerations.H:494
Fl_Window::fullscreen_screen_bottom
static int fullscreen_screen_bottom
Definition: Fl_Window.H:86
ulong
unsigned long ulong
Definition: fl_types.h:32
FL_CURSOR_N
Definition: Enumerations.H:1063
unknown
static char unknown[]
Definition: Fl_x.cxx:1238
childEventMask
static const int childEventMask
Definition: Fl_x.cxx:2356
table
static symbol table[]
Definition: factory.cxx:1109
resize_bug_fix
static Fl_Window * resize_bug_fix
Definition: Fl_x.cxx:1234
fl_Xatextplain
static Atom fl_Xatextplain
Definition: Fl_x.cxx:347
FL_PUSH
Definition: Enumerations.H:236
ignoreXEvents
static int ignoreXEvents(Display *display, XErrorEvent *event)
Definition: Fl_x.cxx:1245
gc
GC gc
Definition: test.c:72
Fl_Widget::damage
uchar damage() const
Definition: Fl_Widget.H:917
fl_set_status
void fl_set_status(int x, int y, int w, int h)
Definition: Fl_x.cxx:562
cb
static void cb(Fl_Widget *, void *v)
Definition: factory.cxx:937
fl_NET_WM_NAME
static Atom fl_NET_WM_NAME
Definition: Fl_x.cxx:356
fl_NET_WM_ICON
static Atom fl_NET_WM_ICON
Definition: Fl_x.cxx:363
FL_Volume_Up
#define FL_Volume_Up
Definition: Enumerations.H:514
FL_FULLSCREEN
Definition: Enumerations.H:424
Fl::repeat_timeout
static void repeat_timeout(double t, Fl_Timeout_Handler, void *=0)
Definition: Fl.cxx:334
Fl::x
static int x()
Definition: Fl_win32.cxx:555
Fl_Widget::redraw
void redraw()
Definition: Fl.cxx:1782
Fl::call_screen_init
static void call_screen_init()
Definition: screen_xywh.cxx:259
first
static idle_cb * first
Definition: Fl_add_idle.cxx:33
Fl_Widget
Definition: Fl_Widget.H:101
FL_CURSOR_CROSS
Definition: Enumerations.H:1051
spot
static XRectangle spot
Definition: Fl_x.cxx:489
Fl_Printer.H
declaration of classes Fl_Printer, Fl_System_Printer and Fl_PostScript_Printer.
FL_Media_Play
#define FL_Media_Play
Definition: Enumerations.H:515
Fl_Group::current
static Fl_Group * current()
Definition: Fl_Group.cxx:84
FL_Button
#define FL_Button
A mouse button; use Fl_Button + n for mouse button n.
Definition: Enumerations.H:467
FL_Stop
#define FL_Stop
Definition: Enumerations.H:524
status_area
static XRectangle status_area
Definition: Fl_x.cxx:323
Fl_Printer::start_job
int start_job(int pagecount, int *frompage=NULL, int *topage=NULL)
Definition: Fl_Printer.cxx:113
Fl_Widget::box
Fl_Boxtype box() const
Definition: Fl_Widget.H:363
fl_get_font_xfld
char * fl_get_font_xfld(int fnum, int size)
Definition: fl_font_x.cxx:221
fl_wait
int fl_wait(double time_to_wait)
Definition: Fl_x.cxx:230
fl_reset_spot
void fl_reset_spot(void)
Definition: Fl_x.cxx:493
Fl_Widget::h
int h() const
Definition: Fl_Widget.H:299
Fl_Window::shown
int shown()
Definition: Fl_Window.H:485
select
void select(Fl_Type *, int)
Definition: Fl_Type.cxx:240
fl_is_over_the_spot
static char fl_is_over_the_spot
Definition: Fl_x.cxx:322
Fl_Window::override
unsigned int override() const
Definition: Fl_Window.H:280
Fl_Group::resize
void resize(int, int, int, int)
Definition: Fl_Group.cxx:634
Fl::copy
static void copy(const char *stuff, int len, int destination, const char *type)
Definition: Fl_win32.cxx:680
fl_selection_buffer_length
int fl_selection_buffer_length[2]
Definition: Fl_x.cxx:857
Fl_Window::hide
virtual void hide()
Definition: Fl.cxx:1546
Fl::e_dx
static int e_dx
Definition: Fl.H:148
px
static int px
Definition: Fl_x.cxx:1198
Fl_Widget::h
void h(int v)
Definition: Fl_Widget.H:145
FL_KP
#define FL_KP
One of the keypad numbers; use FL_KP + 'n' for digit n.
Definition: Enumerations.H:492
Fl_Shared_Image.H
Fl_Widget::label
const char * label() const
Definition: Fl_Widget.H:421
FL_Home_Page
#define FL_Home_Page
Definition: Enumerations.H:519
fl_dnd_action
static Atom fl_dnd_action
Definition: Fl_x.cxx:935
Fl_Surface_Device::set_current
virtual void set_current(void)
Make this surface the current drawing surface. This surface will receive all future graphics requests...
Definition: Fl_Device.cxx:44
FL_Refresh
#define FL_Refresh
Definition: Enumerations.H:525
Fl_Tooltip.H
fl_XaTextUriList
static Atom fl_XaTextUriList
Definition: Fl_x.cxx:351
fl_MOTIF_WM_HINTS
static Atom fl_MOTIF_WM_HINTS
Definition: Fl_x.cxx:327
Fl_Copy_Surface.H
fl_init_xim
static void fl_init_xim()
Definition: Fl_x.cxx:576
Fl_Window::iconlabel_
const char * iconlabel_
Definition: Fl_Window.H:109
Fl_Window::label
const char * label() const
Definition: Fl_Window.H:450
fl_open_display
void fl_open_display()
Definition: Fl_x.cxx:670
Fl_Widget::y
void y(int v)
Definition: Fl_Widget.H:141
FL_SHOW
Definition: Enumerations.H:377
FL_CURSOR_SW
Definition: Enumerations.H:1068
Fl_Window::border
void border(int b)
Definition: Fl_Window_fullscreen.cxx:48
Fl_Window::handle
virtual int handle(int)
Definition: Fl.cxx:1684
Fl_Paged_Device::x_offset
int x_offset
horizontal offset to the origin of graphics coordinates
Definition: Fl_Paged_Device.H:110
catchXExceptions
static XErrorHandler catchXExceptions()
Definition: Fl_x.cxx:1250
Fl_Window::iconlabel
const char * iconlabel() const
Definition: Fl_Window.H:452
Fl_TooltipBox::show
void show()
Definition: Fl_Tooltip.cxx:59
WM_DELETE_WINDOW
static Atom WM_DELETE_WINDOW
Definition: Fl_x.cxx:325
Fl_Widget::handle
virtual int handle(int event)
Definition: Fl_Widget.cxx:112
Fl_Printer::end_job
void end_job(void)
To be called at the end of a print job.
Definition: Fl_Printer.cxx:168
fl_NET_WM_FULLSCREEN_MONITORS
static Atom fl_NET_WM_FULLSCREEN_MONITORS
Definition: Fl_x.cxx:361
fl_clip_region
void fl_clip_region(Fl_Region r)
Definition: fl_draw.H:136
fl_XaImageBmp
static Atom fl_XaImageBmp
Definition: Fl_x.cxx:352
x
int x
Definition: test.c:73
Fl_Shared_Image::get
static Fl_Shared_Image * get(const char *name, int W=0, int H=0)
Definition: Fl_Shared_Image.cxx:541
fl_XaUtf8String
Atom fl_XaUtf8String
Definition: Fl_x.cxx:350
Fl_Widget::callback
Fl_Callback_p callback() const
Definition: Fl_Widget.H:561
FL_Search
#define FL_Search
Definition: Enumerations.H:521
fl_window
Window fl_window
Definition: Fl_x.cxx:2971
Fl_Printer::print_widget
void print_widget(Fl_Widget *widget, int delta_x=0, int delta_y=0)
Draws the widget on the printed page.
Definition: Fl_Printer.cxx:173
FL_DAMAGE_EXPOSE
Definition: Enumerations.H:1107
Fl_Printer::start_page
int start_page(void)
Starts a new printed page.
Definition: Fl_Printer.cxx:118
Fl_Paged_Device::print_widget
virtual void print_widget(Fl_Widget *widget, int delta_x=0, int delta_y=0)
Draws the widget on the printed page.
Definition: Fl_Paged_Device.cxx:40
TIMESTAMP
static Atom TIMESTAMP
Definition: Fl_x.cxx:330
cache_cursor
#define cache_cursor(name, var)
Fl::disable_im
static void disable_im()
Definition: Fl_win32.cxx:541
fl_NET_WM_STATE_FULLSCREEN
static Atom fl_NET_WM_STATE_FULLSCREEN
Definition: Fl_x.cxx:360
POLLIN
#define POLLIN
Definition: Fl_x.cxx:94
FL_Favorites
#define FL_Favorites
Definition: Enumerations.H:527
Fl_Tooltip::exit
static void(* exit)(Fl_Widget *w)
Definition: Fl_Tooltip.H:60
FL_ALIGN_CENTER
const Fl_Align FL_ALIGN_CENTER
Definition: Enumerations.H:830
Fl::add_timeout
static void add_timeout(double t, Fl_Timeout_Handler, void *=0)
Definition: Fl.cxx:329
FL_CURSOR_W
Definition: Enumerations.H:1069
icons_to_property
static void icons_to_property(const Fl_RGB_Image *icons[], int count, unsigned long **property, size_t *len)
Definition: Fl_x.cxx:2707
fl_show_iconic
char fl_show_iconic
Definition: Fl_x.cxx:2352
fl_XaText
static Atom fl_XaText
Definition: Fl_x.cxx:348
fl_trigger_clipboard_notify
void fl_trigger_clipboard_notify(int source)
Definition: Fl.cxx:544
maxfd
static int maxfd
Definition: Fl_x.cxx:93
Fl::y
static int y()
Definition: Fl_win32.cxx:563
FL_CURSOR_S
Definition: Enumerations.H:1067
Fl_Window::shape_data_
static shape_data_type * shape_data_
non-null means the window has a non-rectangular shape
Definition: Fl_Window.H:139
Fl::enable_im
static void enable_im()
Definition: Fl_win32.cxx:529
Fl_Window::fullscreen_screen_right
static int fullscreen_screen_right
Definition: Fl_Window.H:94
FL_BUTTON1
#define FL_BUTTON1
Mouse button 1 is pushed.
Definition: Enumerations.H:567
FL_Menu
#define FL_Menu
The menu key.
Definition: Enumerations.H:489
Fl::remove_fd
static void remove_fd(int, int when)
Definition: Fl_win32.cxx:323
XKeysymToUcs
long XKeysymToUcs(KeySym keysym)
Definition: keysym2Ucs.c:24
FL_NORMAL_LABEL
draws the text (0)
Definition: Enumerations.H:764
y
int y
Definition: test.c:74
Fl::handle
static int handle(int, Fl_Window *)
Handle events from the window system.
Definition: Fl.cxx:1291
fl_xim_deactivate
void fl_xim_deactivate(void)
Definition: Fl_x.cxx:644
set_cursor
static void set_cursor(Fl_Tile *t, Fl_Cursor c)
Definition: Fl_Tile.cxx:178
FD
Definition: Fl_win32.cxx:262
fl_utf8encode
int fl_utf8encode(unsigned ucs, char *buf)
Definition: fl_utf.c:309
Fl_Copy_Surface::draw_decorated_window
void draw_decorated_window(Fl_Window *win, int delta_x=0, int delta_y=0)
Definition: Fl_Copy_Surface.cxx:260
FL_CURSOR_ARROW
Definition: Enumerations.H:1050
Fl::e_x
static int e_x
Definition: Fl.H:144
Fl_Widget::type
uchar type() const
Definition: Fl_Widget.H:274
Fl_Printer::rotate
void rotate(float angle)
Rotates the graphics operations relatively to paper.
Definition: Fl_Printer.cxx:148
Fl::screen_count
static int screen_count()
Definition: screen_xywh.cxx:267
CLIPBOARD_TIMESTAMP
static Atom CLIPBOARD_TIMESTAMP
Definition: Fl_x.cxx:332
f
Fl_Box_Draw_F * f
Definition: fl_boxtype.cxx:285
Fl_Widget::parent
Fl_Group * parent() const
Definition: Fl_Widget.H:254
_NET_WM_STATE_ADD
#define _NET_WM_STATE_ADD
Definition: Fl_x.cxx:2197
malloc
voidp malloc()
fl_XdndActionCopy
Atom fl_XdndActionCopy
Definition: Fl_x.cxx:341
FL_Meta_L
#define FL_Meta_L
The left meta/Windows key.
Definition: Enumerations.H:502
Fl::e_length
static int e_length
Definition: Fl.H:155
Fl_Button.H
Fl::scheme_bg_
static Fl_Image * scheme_bg_
Definition: Fl.H:262
Fl_Cursor
Fl_Cursor
Definition: Enumerations.H:1048
Fl::warning
static void(* warning)(const char *,...)
Definition: Fl.H:498
Fl_Printer::origin
void origin(int *x, int *y)
Computes the page coordinates of the current origin of graphics functions.
Definition: Fl_Printer.cxx:133
Fl_Paged_Device.H
declaration of class Fl_Paged_Device.
in_a_window
static bool in_a_window
Definition: Fl_x.cxx:202
Y
static int Y
Definition: Fl_Tooltip.cxx:76
Fl_Paged_Device::y_offset
int y_offset
vertical offset to the origin of graphics coordinates
Definition: Fl_Paged_Device.H:112
flstring.h
CLIPBOARD
static Atom CLIPBOARD
Definition: Fl_x.cxx:329
fl_selection_length
int fl_selection_length[2]
Definition: Fl_x.cxx:855
Fl_Window::i
Fl_X * i
Definition: Fl_Window.H:97
spots
static int spots
Definition: Fl_x.cxx:491
Fl::get_mouse
static void get_mouse(int &, int &)
Definition: Fl_win32.cxx:587
send_wm_event
static void send_wm_event(Window wnd, Atom message, unsigned long d0, unsigned long d1=0, unsigned long d2=0, unsigned long d3=0, unsigned long d4=0)
Definition: Fl_x.cxx:2200
fl_visual
XVisualInfo * fl_visual
Definition: Fl_x.cxx:317
Fl_Image::ld
void ld(int LD)
Definition: Fl_Image.H:96
fl_display
Display * fl_display
END TIMERS.
Definition: Fl_x.cxx:314
fl_disable_transient_for
int fl_disable_transient_for
Definition: Fl_x.cxx:2354
FL_Insert
#define FL_Insert
The insert key.
Definition: Enumerations.H:488
fd
static FD * fd
Definition: Fl_x.cxx:111
Fl_Printer
OS-independent print support.
Definition: Fl_Printer.H:176
Fl_Paged_Device::print_window
void print_window(Fl_Window *win, int x_offset=0, int y_offset=0)
Definition: Fl_win32.cxx:2772
ptime
static ulong ptime
Definition: Fl_x.cxx:1199
Fl_Paged_Device::draw_decorated_window
void draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset)
Definition: Fl_win32.cxx:2777
FL_DOUBLE_WINDOW
#define FL_DOUBLE_WINDOW
double window type id
Definition: Fl_Window.H:34
Fl_Window::fullscreen_screen_left
static int fullscreen_screen_left
Definition: Fl_Window.H:90
Fl::w
static int w()
Definition: Fl_win32.cxx:579
create_bmp
static unsigned char * create_bmp(const unsigned char *data, int W, int H, int *return_size)
Definition: Fl_x.cxx:1034
fl_new_ic
static void fl_new_ic()
Definition: Fl_x.cxx:396
fl_XdndSelection
Atom fl_XdndSelection
Definition: Fl_x.cxx:334
Fl_Window::current_
static Fl_Window * current_
Definition: Fl_Window.H:168
FL_F
#define FL_F
One of the function keys; use FL_F + n for function key n.
Definition: Enumerations.H:495
FL_CURSOR_E
Definition: Enumerations.H:1065
attributes
static CFMutableDictionaryRef attributes
Definition: fl_font_mac.cxx:29
FL_RELEASE
Definition: Enumerations.H:244
fl_XaImagePNG
static Atom fl_XaImagePNG
Definition: Fl_x.cxx:353
Fl_Window::combine_mask
void combine_mask(void)
Definition: Fl_Window_shape.cxx:137
FL_CURSOR_NE
Definition: Enumerations.H:1064
FD::cb
void(* cb)(FL_SOCKET, void *)
Definition: Fl_win32.cxx:265
uchar
unsigned char uchar
Definition: fl_types.h:30
name
static const char * name
Definition: Fl_arg.cxx:53
fl_alert
void fl_alert(const char *,...)
Definition: fl_ask.cxx:361
Fl_RGB_Image
Definition: Fl_Image.H:202
primary_timestamp
static Time primary_timestamp
Definition: Fl_x.cxx:1091
FL_Delete
#define FL_Delete
The delete key.
Definition: Enumerations.H:506
Fl_Window::size_range_
void size_range_()
Definition: Fl_win32.cxx:2149
Fl_Shared_Image
Definition: Fl_Shared_Image.H:50
Window
class FLWindow * Window
Definition: mac.H:32
Fl::grab
static Fl_Window * grab()
Definition: Fl.H:555
fl_XdndLeave
Atom fl_XdndLeave
Definition: Fl_x.cxx:338
FL_Media_Prev
#define FL_Media_Prev
Definition: Enumerations.H:517
FL_ENTER
Definition: Enumerations.H:253
fl_event_time
ulong fl_event_time
Definition: Fl_x.cxx:1192
Fl_Window::decorated_w
int decorated_w()
Definition: Fl_win32.cxx:2757
XEventMask
static const int XEventMask
Definition: Fl_x.cxx:2358
XUtf8LookupString
int XUtf8LookupString(XIC ic, XKeyPressedEvent *event, char *buffer_return, int bytes_buffer, KeySym *keysym, Status *status_return)
Definition: utf8Input.c:412
io_error_handler
static int io_error_handler(Display *)
Definition: Fl_x.cxx:379
Fl_Shared_Image::release
void release()
Definition: Fl_Shared_Image.cxx:230
Fl_Copy_Surface
Definition: Fl_Copy_Surface.H:51
Fl_Window::tooltip_window
unsigned int tooltip_window() const
Definition: Fl_Window.H:378
FL_CURSOR_WE
Definition: Enumerations.H:1060
fl_xid
Window fl_xid(const Fl_Window *)
Fl_Widget::image
Fl_Image * image()
Definition: Fl_Widget.H:514
fl_unlock_function
void(* fl_unlock_function)()
Definition: Fl_x.cxx:225
fl_XdndAware
Atom fl_XdndAware
Definition: Fl_x.cxx:333
Fl::e_original_keysym
static int e_original_keysym
Definition: Fl.H:264
Fl_Window::fullscreen_screen_top
static int fullscreen_screen_top
Definition: Fl_Window.H:82
FL_ALIGN_CLIP
const Fl_Align FL_ALIGN_CLIP
Definition: Enumerations.H:849
write_int
static void write_int(unsigned char **cp, int i)
Definition: Fl_x.cxx:1025
fl_selection_buffer
char * fl_selection_buffer[2]
Definition: Fl_x.cxx:854
fl_NET_SUPPORTING_WM_CHECK
static Atom fl_NET_SUPPORTING_WM_CHECK
Definition: Fl_x.cxx:358
WM_PROTOCOLS
static Atom WM_PROTOCOLS
Definition: Fl_x.cxx:326
fl_handle
int fl_handle(const XEvent &thisevent)
Definition: Fl_x.cxx:1325
Xutf8.h