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_win32.cxx
Go to the documentation of this file.
1 //
2 // "$Id$"
3 //
4 // WIN32-specific code for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2018 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 // This file contains win32-specific code for fltk which is always linked
20 // in. Search other files for "WIN32" or filenames ending in _win32.cxx
21 // for other system-specific code.
22 
23 // This file must be #include'd in Fl.cxx and not compiled separately.
24 
25 #ifndef FL_DOXYGEN
26 #include <FL/Fl.H>
27 #include <FL/fl_utf8.h>
28 #include <FL/Fl_Window.H>
29 #include <FL/fl_draw.H>
30 #include <FL/Enumerations.H>
31 #include <FL/Fl_Tooltip.H>
32 #include <FL/Fl_Paged_Device.H>
33 #include "flstring.h"
34 #include "Fl_Font.H"
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <sys/types.h>
38 #include <time.h>
39 #include <signal.h>
40 #ifdef __CYGWIN__
41 # include <sys/time.h>
42 # include <unistd.h>
43 #endif
44 
45 #if !defined(NO_TRACK_MOUSE)
46 # include <commctrl.h> // TrackMouseEvent
47 // fabien: Ms Visual Studio >= 2003 permit embedded lib reference
48 // that makes fltk use easier as only fltk libs are now requested
49 // This idea could be extended to fltk libs themselves,
50 // implementer should then care about DLL linkage flags ...
51 # if defined(_MSC_VER) && (_MSC_VER>=1310)
52 # pragma comment (lib, "comctl32.lib")
53 # endif
54 #endif
55 
56 #if defined(__GNUC__)
57 # include <wchar.h>
58 #endif
59 
60 #include <ole2.h>
61 #include <shellapi.h>
62 
63 // New versions of MinGW (as of Feb 2018) need to include winerror.h to
64 // #define S_OK which used to be defined in ole2.h (STR #3454)
65 
66 #include <winerror.h>
67 
68 //
69 // USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()...
70 // USE_ASYNC_SELECT is OBSOLETED in 1.3 for the following reasons:
71 /*
72  This feature was supposed to provide an efficient alternative to the current
73  polling method, but as it has been discussed (Thanks Albrecht!) :
74  - the async mode would imply to change the socket to non blocking mode.
75  This can have unexpected side effects for 3rd party apps, especially
76  if it is set on-the-fly when socket service is really needed, as it is
77  done today and on purpose, but still the 3rd party developer wouldn't easily
78  control the sequencing of socket operations.
79  - Finer granularity of events furthered by the async select is a plus only
80  for socket 3rd party impl., it is simply not needed for the 'light' fltk
81  use we make of wsock, so here it would also be a bad point, because of all
82  the logic add-ons necessary for using this functionality, without a clear
83  benefit.
84 
85  So async mode select would not add benefits to fltk, worse, it can slowdown
86  fltk because of this finer granularity and instrumentation code to be added
87  for async mode proper operation, not mentioning the side effects...
88 */
89 
90 // Internal functions
91 static void fl_clipboard_notify_target(HWND wnd);
92 static void fl_clipboard_notify_untarget(HWND wnd);
93 
94 // Internal variables
95 static HWND clipboard_wnd = 0;
96 static HWND next_clipboard_wnd = 0;
97 
98 static bool initial_clipboard = true;
99 
100 // dynamic wsock dll handling api:
101 #if defined(__CYGWIN__) && !defined(SOCKET)
102 # define SOCKET int
103 #endif
104 
105 // note: winsock2.h has been #include'd in Fl.cxx
106 #define WSCK_DLL_NAME "WS2_32.DLL"
107 
108 // Patch for MinGW (__MINGW32__): see STR #3454 and src/Fl.cxx
109 #ifdef __MINGW32__
110 typedef int(WINAPI *fl_wsk_fd_is_set_f)(unsigned int, void *);
111 #else
112 typedef int(WINAPI *fl_wsk_fd_is_set_f)(SOCKET, fd_set *);
114 #endif
115 
116 typedef int (WINAPI* fl_wsk_select_f)(int, fd_set*, fd_set*, fd_set*, const struct timeval*);
117 
118 static HMODULE s_wsock_mod = 0;
120 
121 #ifdef __MINGW32__
122 static void * get_wsock_mod() {
123 #else
124 static HMODULE get_wsock_mod() {
125 #endif
126  if (!s_wsock_mod) {
127  s_wsock_mod = LoadLibrary(WSCK_DLL_NAME);
128  if (s_wsock_mod==NULL)
129  Fl::fatal("FLTK Lib Error: %s file not found! Please check your winsock dll accessibility.\n",WSCK_DLL_NAME);
130  s_wsock_select = (fl_wsk_select_f) GetProcAddress(s_wsock_mod, "select");
131  fl_wsk_fd_is_set = (fl_wsk_fd_is_set_f) GetProcAddress(s_wsock_mod, "__WSAFDIsSet");
132  }
133  return s_wsock_mod;
134 }
135 
136 /*
137  * Dynamic linking of imm32.dll
138  * This library is only needed for a hand full (four ATM) functions relating to
139  * international text rendering and locales. Dynamically loading reduces initial
140  * size and link dependencies.
141  */
142 static HMODULE s_imm_module = 0;
143 typedef BOOL (WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
145 typedef HIMC (WINAPI* flTypeImmGetContext)(HWND);
147 typedef BOOL (WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
149 typedef BOOL (WINAPI* flTypeImmReleaseContext)(HWND, HIMC);
151 
152 static void get_imm_module() {
153  s_imm_module = LoadLibrary("IMM32.DLL");
154  if (!s_imm_module)
155  Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
156  "Please check your input method manager library accessibility.");
157  flImmAssociateContextEx = (flTypeImmAssociateContextEx)GetProcAddress(s_imm_module, "ImmAssociateContextEx");
158  flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
159  flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
160  flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
161 }
162 
163 // USE_TRACK_MOUSE - define NO_TRACK_MOUSE if you don't have
164 // TrackMouseEvent()...
165 //
166 // Now (Dec. 2008) we can assume that current Cygwin/MinGW versions
167 // support the TrackMouseEvent() function, but WinCE obviously doesn't
168 // support it (STR 2095). Therefore, USE_TRACK_MOUSE is enabled by
169 // default, but you can disable it by defining NO_TRACK_MOUSE.
170 //
171 // TrackMouseEvent is only used to support window leave notifications
172 // under Windows. It can be used to get FL_LEAVE events, when the
173 // mouse leaves the _main_ application window (FLTK detects subwindow
174 // leave events by using normal move events).
175 //
176 // Implementation note: If the mouse cursor leaves one subwindow and
177 // enters another window, then Windows sends a WM_MOUSEMOVE message to
178 // the new window before it sends a WM_MOUSELEAVE message to the old
179 // (just left) window. We save the current mouse window in a static variable,
180 // and if we get a WM_MOUSELEAVE event for the current mouse window, this
181 // means that the top level window has been left (otherwise we would have
182 // got another WM_MOUSEMOVE message before).
183 
184 // #define NO_TRACK_MOUSE
185 
186 #if !defined(NO_TRACK_MOUSE)
187 # define USE_TRACK_MOUSE
188 #endif // NO_TRACK_MOUSE
189 
190 static Fl_Window *track_mouse_win=0; // current TrackMouseEvent() window
191 
192 // USE_CAPTURE_MOUSE_WIN - this must be defined for TrackMouseEvent to work
193 // correctly with subwindows - otherwise a single mouse click and release
194 // (without a move) would generate phantom leave events.
195 // This defines, if the current mouse window (maybe a subwindow) or the
196 // main window should get mouse events after pushing (and holding) a mouse
197 // button, i.e. when dragging the mouse. This is done by calling SetCapture
198 // (see below).
199 
200 #ifdef USE_TRACK_MOUSE
201 #define USE_CAPTURE_MOUSE_WIN
202 #endif // USE_TRACK_MOUSE
203 
204 //
205 // WM_SYNCPAINT is an "undocumented" message, which is finally defined in
206 // VC++ 6.0.
207 //
208 
209 #ifndef WM_SYNCPAINT
210 # define WM_SYNCPAINT 0x0088
211 #endif
212 
213 #ifndef WM_MOUSELEAVE
214 # define WM_MOUSELEAVE 0x02a3
215 #endif
216 
217 #ifndef WM_MOUSEWHEEL
218 # define WM_MOUSEWHEEL 0x020a
219 #endif
220 
221 #ifndef WHEEL_DELTA
222 # define WHEEL_DELTA 120 // according to MSDN.
223 #endif
224 
225 #ifndef SM_CXPADDEDBORDER
226 # define SM_CXPADDEDBORDER (92) // STR #3061
227 #endif
228 
229 //
230 // WM_FLSELECT is the user-defined message that we get when one of
231 // the sockets has pending data, etc.
232 //
233 
234 #define WM_FLSELECT (WM_APP+1) // WM_APP is used for hide-window
235 
236 
238 // interface to poll/select call:
239 
240 // fd's are only implemented for sockets. Microsoft Windows does not
241 // have a unified IO system, so it doesn't support select() on files,
242 // devices, or pipes...
243 //
244 // Microsoft provides the Berkeley select() call and an asynchronous
245 // select function that sends a WIN32 message when the select condition
246 // exists. However, we don't try to use the asynchronous WSAAsyncSelect()
247 // any more for good reasons (see above).
248 //
249 // A.S. Dec 2009: We got reports that current winsock2.h files define
250 // POLLIN, POLLOUT, and POLLERR with conflicting values WRT what we
251 // used before (STR #2301). Therefore we must not use these values
252 // for our internal purposes, but use FL_READ, FL_WRITE, and
253 // FL_EXCEPT, as defined for use in Fl::add_fd().
254 //
255 static int maxfd = 0;
256 static fd_set fdsets[3];
257 
258 extern IDropTarget *flIDropTarget;
259 
260 static int nfds = 0;
261 static int fd_array_size = 0;
262 static struct FD {
263  int fd;
264  short events;
265  void (*cb)(FL_SOCKET, void*); // keep socket api opaque at this level to reduce multiplatform deps headaches
266  void* arg;
267 } *fd = 0;
268 
269 extern unsigned int fl_codepage;
270 
272 {
273 }
274 
275 void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
276 {
277  if (!win) return;
278  Fl_Window* tw = win;
279  while (tw->parent()) tw = tw->window(); // find top level window
280 
281  if (!tw->shown())
282  return;
283 
284  HIMC himc = flImmGetContext(fl_xid(tw));
285 
286  if (himc) {
287  COMPOSITIONFORM cfs;
288  cfs.dwStyle = CFS_POINT;
289  cfs.ptCurrentPos.x = X;
290  cfs.ptCurrentPos.y = Y - tw->labelsize();
291  MapWindowPoints(fl_xid(win), fl_xid(tw), &cfs.ptCurrentPos, 1);
292  flImmSetCompositionWindow(himc, &cfs);
293  flImmReleaseContext(fl_xid(tw), himc);
294  }
295 }
296 
297 void fl_set_status(int x, int y, int w, int h)
298 {
299 }
300 
301 void Fl::add_fd(int n, int events, void (*cb)(FL_SOCKET, void*), void *v) {
302  remove_fd(n,events);
303  int i = nfds++;
304  if (i >= fd_array_size) {
306  fd = (FD*)realloc(fd, fd_array_size*sizeof(FD));
307  }
308  fd[i].fd = n;
309  fd[i].events = (short)events;
310  fd[i].cb = cb;
311  fd[i].arg = v;
312 
313  if (events & FL_READ) FD_SET((unsigned)n, &fdsets[0]);
314  if (events & FL_WRITE) FD_SET((unsigned)n, &fdsets[1]);
315  if (events & FL_EXCEPT) FD_SET((unsigned)n, &fdsets[2]);
316  if (n > maxfd) maxfd = n;
317 }
318 
319 void Fl::add_fd(int fd, void (*cb)(FL_SOCKET, void*), void* v) {
320  Fl::add_fd(fd, FL_READ, cb, v);
321 }
322 
323 void Fl::remove_fd(int n, int events) {
324  int i,j;
325  for (i=j=0; i<nfds; i++) {
326  if (fd[i].fd == n) {
327  short e = fd[i].events & ~events;
328  if (!e) continue; // if no events left, delete this fd
329  fd[i].events = e;
330  }
331  // move it down in the array if necessary:
332  if (j<i) {
333  fd[j]=fd[i];
334  }
335  j++;
336  }
337  nfds = j;
338 
339  if (events & FL_READ) FD_CLR(unsigned(n), &fdsets[0]);
340  if (events & FL_WRITE) FD_CLR(unsigned(n), &fdsets[1]);
341  if (events & FL_EXCEPT) FD_CLR(unsigned(n), &fdsets[2]);
342 }
343 
344 void Fl::remove_fd(int n) {
345  remove_fd(n, -1);
346 }
347 
348 // these pointers are set by the Fl::lock() function:
349 static void nothing() {}
352 
353 static void* thread_message_;
354 void* Fl::thread_message() {
355  void* r = thread_message_;
356  thread_message_ = 0;
357  return r;
358 }
359 
360 extern int fl_send_system_handlers(void *e);
361 
362 MSG fl_msg;
363 
364 // A local helper function to flush any pending callback requests
365 // from the awake ring-buffer
368  void *data;
369  while (Fl::get_awake_handler_(func, data) == 0) {
370  func(data);
371  }
372 }
373 
374 // This is never called with time_to_wait < 0.0.
375 // It *should* return negative on error, 0 if nothing happens before
376 // timeout, and >0 if any callbacks were done. This version only
377 // returns zero if nothing happens during a 0.0 timeout, otherwise
378 // it returns 1.
379 int fl_wait(double time_to_wait) {
380  int have_message = 0;
381 
382  run_checks();
383 
384  // idle processing
385  static char in_idle;
386  if (Fl::idle && !in_idle) {
387  in_idle = 1;
388  Fl::idle();
389  in_idle = 0;
390  }
391 
392  if (nfds) {
393  // For WIN32 we need to poll for socket input FIRST, since
394  // the event queue is not something we can select() on...
395  timeval t;
396  t.tv_sec = 0;
397  t.tv_usec = 0;
398 
399  fd_set fdt[3];
400  memcpy(fdt, fdsets, sizeof fdt); // one shot faster fdt init
401  if (get_wsock_mod()&& s_wsock_select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t)) {
402  // We got something - do the callback!
403  for (int i = 0; i < nfds; i ++) {
404  SOCKET f = fd[i].fd;
405  short revents = 0;
406  if (fl_wsk_fd_is_set(f, &fdt[0])) revents |= FL_READ;
407  if (fl_wsk_fd_is_set(f, &fdt[1])) revents |= FL_WRITE;
408  if (fl_wsk_fd_is_set(f, &fdt[2])) revents |= FL_EXCEPT;
409  if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
410  }
411  time_to_wait = 0.0; // just peek for any messages
412  } else {
413  // we need to check them periodically, so set a short timeout:
414  if (time_to_wait > .001) time_to_wait = .001;
415  }
416  }
417 
418  if (Fl::idle || Fl::damage())
419  time_to_wait = 0.0;
420 
421  // if there are no more windows and this timer is set
422  // to FOREVER, continue through or look up indefinitely
423  if (!Fl::first_window() && time_to_wait==1e20)
424  time_to_wait = 0.0;
425 
427 
428  time_to_wait = (time_to_wait > 10000 ? 10000 : time_to_wait);
429  int t_msec = (int) (time_to_wait * 1000.0 + 0.5);
430  MsgWaitForMultipleObjects(0, NULL, FALSE, t_msec, QS_ALLINPUT);
431 
433 
434  // Execute the message we got, and all other pending messages:
435  // have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
436  while ((have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE)) > 0) {
438  continue;
439 
440  // Let applications treat WM_QUIT identical to SIGTERM on *nix
441  if (fl_msg.message == WM_QUIT)
442  raise(SIGTERM);
443 
444  if (fl_msg.message == fl_wake_msg) {
445  // Used for awaking wait() from another thread
446  thread_message_ = (void*)fl_msg.wParam;
448  }
449 
450  TranslateMessage(&fl_msg);
451  DispatchMessageW(&fl_msg);
452  }
453 
454  // The following conditional test:
455  // (Fl::awake_ring_head_ != Fl::awake_ring_tail_)
456  // is a workaround / fix for STR #3143. This works, but a better solution
457  // would be to understand why the PostThreadMessage() messages are not
458  // seen by the main window if it is being dragged/ resized at the time.
459  // If a worker thread posts an awake callback to the ring buffer
460  // whilst the main window is unresponsive (if a drag or resize operation
461  // is in progress) we may miss the PostThreadMessage(). So here, we check if
462  // there is anything pending in the awake ring buffer and if so process
463  // it. This is not strictly thread safe (for speed it compares the head
464  // and tail indices without first locking the ring buffer) but is intended
465  // only as a fall-back recovery mechanism if the awake processing stalls.
466  // If the test erroneously returns true (may happen if we test the indices
467  // whilst they are being modified) we will call process_awake_handler_requests()
468  // unnecessarily, but this has no harmful consequences so is safe to do.
469  // Note also that if we miss the PostThreadMessage(), then thread_message_
470  // will not be updated, so this is not a perfect solution, but it does
471  // recover and process any pending awake callbacks.
472  // Normally the ring buffer head and tail indices will match and this
473  // comparison will do nothing. Addresses STR #3143
476  }
477 
478  Fl::flush();
479 
480  // This should return 0 if only timer events were handled:
481  return 1;
482 }
483 
484 // fl_ready() is just like fl_wait(0.0) except no callbacks are done:
485 int fl_ready() {
486  if (PeekMessage(&fl_msg, NULL, 0, 0, PM_NOREMOVE)) return 1;
487  if (!nfds) return 0;
488  timeval t;
489  t.tv_sec = 0;
490  t.tv_usec = 0;
491  fd_set fdt[3];
492  memcpy(fdt, fdsets, sizeof fdt);
493  return get_wsock_mod() ? s_wsock_select(0,&fdt[0],&fdt[1],&fdt[2],&t) : 0;
494 }
495 
497  static char beenHereDoneThat = 0;
498 
499  if (beenHereDoneThat)
500  return;
501 
502  beenHereDoneThat = 1;
503 
504  OleInitialize(0L);
505 
506  get_imm_module();
507 }
508 
510 public:
513  fl_free_fonts(); // do some WIN32 cleanup
514  fl_cleanup_pens();
515  OleUninitialize();
516  fl_brush_action(1);
518  // This is actually too late in the cleanup process to remove the
519  // clipboard notifications, but we have no earlier hook so we try
520  // to work around it anyway.
521  if (clipboard_wnd != NULL)
523  }
524 };
526 
527 static char im_enabled = 1;
528 
530  fl_open_display();
531 
532  Fl_X* i = Fl_X::first;
533  while (i) {
534  flImmAssociateContextEx(i->xid, 0, IACE_DEFAULT);
535  i = i->next;
536  }
537 
538  im_enabled = 1;
539 }
540 
542  fl_open_display();
543 
544  Fl_X* i = Fl_X::first;
545  while (i) {
546  flImmAssociateContextEx(i->xid, 0, 0);
547  i = i->next;
548  }
549 
550  im_enabled = 0;
551 }
552 
554 
555 int Fl::x()
556 {
557  RECT r;
558 
559  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
560  return r.left;
561 }
562 
563 int Fl::y()
564 {
565  RECT r;
566 
567  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
568  return r.top;
569 }
570 
571 int Fl::h()
572 {
573  RECT r;
574 
575  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
576  return r.bottom - r.top;
577 }
578 
579 int Fl::w()
580 {
581  RECT r;
582 
583  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
584  return r.right - r.left;
585 }
586 
587 void Fl::get_mouse(int &x, int &y) {
588  POINT p;
589  GetCursorPos(&p);
590  x = p.x;
591  y = p.y;
592 }
593 
595 // code used for selections:
596 
601 
602 UINT fl_get_lcid_codepage(LCID id)
603 {
604  char buf[8];
605  buf[GetLocaleInfo(id, LOCALE_IDEFAULTANSICODEPAGE, buf, 8)] = 0;
606  return atol(buf);
607 }
608 
609 // Convert \n -> \r\n
611  char *out;
612  int outlen;
613 public:
614  Lf2CrlfConvert(const char *in, int inlen) {
615  outlen = 0;
616  const char *i;
617  char *o;
618  int lencount;
619  // Predict size of \r\n conversion buffer
620  for (i = in, lencount = inlen; lencount > 0; lencount--) {
621  if ( *i == '\r' && *(i+1) == '\n' && lencount >= 2 ) // leave \r\n untranslated
622  { i+=2; outlen+=2; lencount--; }
623  else if ( *i == '\n' ) // \n by itself? leave room to insert \r
624  { i++; outlen+=2; }
625  else
626  { ++i; ++outlen; }
627  }
628  // Alloc conversion buffer + NULL
629  out = new char[outlen+1];
630  // Handle \n -> \r\n conversion
631  for (i = in, o=out, lencount = inlen; lencount > 0; lencount--) {
632  if ( *i == '\r' && *(i+1) == '\n' && lencount >= 2 ) // leave \r\n untranslated
633  { *o++ = *i++; *o++ = *i++; lencount--; }
634  else if ( *i == '\n' ) // \n by itself? insert \r
635  { *o++ = '\r'; *o++ = *i++; }
636  else
637  { *o++ = *i++; }
638  }
639  *o++ = 0;
640  }
642  delete[] out;
643  }
644  int GetLength() const { return(outlen); }
645  const char* GetValue() const { return(out); }
646 };
647 
649  Fl_Window *w1 = Fl::first_window();
650  if (!w1)
651  return;
652 
653  HWND hwnd = fl_xid(w1);
654 
655  if (!OpenClipboard(hwnd))
656  return;
657 
658  EmptyClipboard();
659 
660  int utf16_len = fl_utf8toUtf16(fl_selection_buffer[1],
661  fl_selection_length[1], 0, 0);
662 
663  HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc.
664  LPVOID memLock = GlobalLock(hMem);
665 
667  (unsigned short*) memLock, utf16_len + 1);
668 
669  GlobalUnlock(hMem);
670  SetClipboardData(CF_UNICODETEXT, hMem);
671 
672  CloseClipboard();
673 
674  // In case Windows managed to lob of a WM_DESTROYCLIPBOARD during
675  // the above.
676  fl_i_own_selection[1] = 1;
677 }
678 
679 // call this when you create a selection:
680 void Fl::copy(const char *stuff, int len, int clipboard, const char *type) {
681  if (!stuff || len<0) return;
682  if (clipboard >= 2)
683  clipboard = 1; // Only on X11 do multiple clipboards make sense.
684 
685  // Convert \n -> \r\n (for old apps like Notepad, DOS)
686  Lf2CrlfConvert buf(stuff, len);
687  len = buf.GetLength();
688  stuff = buf.GetValue();
689 
690  if (len+1 > fl_selection_buffer_length[clipboard]) {
691  delete[] fl_selection_buffer[clipboard];
692  fl_selection_buffer[clipboard] = new char[len+100];
693  fl_selection_buffer_length[clipboard] = len+100;
694  }
695  memcpy(fl_selection_buffer[clipboard], stuff, len);
696  fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
697  fl_selection_length[clipboard] = len;
698  fl_i_own_selection[clipboard] = 1;
699  if (clipboard)
701 }
702 
703 // Call this when a "paste" operation happens:
704 void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) {
705  if (!clipboard || (fl_i_own_selection[clipboard] && strcmp(type, Fl::clipboard_plain_text) == 0)) {
706  // We already have it, do it quickly without window server.
707  // Notice that the text is clobbered if set_selection is
708  // called in response to FL_PASTE!
709  char *i = fl_selection_buffer[clipboard];
710  if (i==0L) {
711  Fl::e_text = 0;
712  return;
713  }
714  char *clip_text = new char[fl_selection_length[clipboard]+1];
715  char *o = clip_text;
716  while (*i) { // Convert \r\n -> \n
717  if ( *i == '\r' && *(i+1) == '\n') i++;
718  else *o++ = *i++;
719  }
720  *o = 0;
721  Fl::e_text = clip_text;
722  Fl::e_length = (int) (o - Fl::e_text);
724  receiver.handle(FL_PASTE);
725  delete [] clip_text;
726  Fl::e_text = 0;
727  } else if (clipboard) {
728  HANDLE h;
729  if (!OpenClipboard(NULL)) return;
730  if (strcmp(type, Fl::clipboard_plain_text) == 0) { // we want plain text from clipboard
731  if ((h = GetClipboardData(CF_UNICODETEXT))) { // there's text in the clipboard
732  wchar_t *memLock = (wchar_t*) GlobalLock(h);
733  size_t utf16_len = wcslen(memLock);
734  char *clip_text = new char[utf16_len * 4 + 1];
735  unsigned utf8_len = fl_utf8fromwc(clip_text, (unsigned) (utf16_len * 4), memLock, (unsigned) utf16_len);
736  *(clip_text + utf8_len) = 0;
737  GlobalUnlock(h);
738  LPSTR a,b;
739  a = b = clip_text;
740  while (*a) { // strip the CRLF pairs ($%$#@^)
741  if (*a == '\r' && a[1] == '\n') a++;
742  else *b++ = *a++;
743  }
744  *b = 0;
745  Fl::e_text = clip_text;
746  Fl::e_length = (int) (b - Fl::e_text);
747  Fl::e_clipboard_type = Fl::clipboard_plain_text; // indicates that the paste event is for plain UTF8 text
748  receiver.handle(FL_PASTE); // send the FL_PASTE event to the widget
749  delete[] clip_text;
750  Fl::e_text = 0;
751  }
752  }
753  else if (strcmp(type, Fl::clipboard_image) == 0) { // we want an image from clipboard
754  uchar *rgb = NULL;
755  int width = 0, height = 0, depth = 0;
756  if ( (h = GetClipboardData(CF_DIB)) ) { // if there's a DIB in clipboard
757  LPBITMAPINFO lpBI = (LPBITMAPINFO)GlobalLock(h) ;
758  width = lpBI->bmiHeader.biWidth; // bitmap width & height
759  height = lpBI->bmiHeader.biHeight;
760  if ( (lpBI->bmiHeader.biBitCount == 24 || lpBI->bmiHeader.biBitCount == 32) &&
761  lpBI->bmiHeader.biCompression == BI_RGB &&
762  lpBI->bmiHeader.biClrUsed == 0) { // direct use of the DIB data if it's RGB or RGBA
763  int linewidth; // row length
764  depth = lpBI->bmiHeader.biBitCount/8; // 3 or 4
765  if (depth == 3) linewidth = 4 * ((3*width + 3)/4); // row length: series of groups of 3 bytes, rounded to multiple of 4 bytes
766  else linewidth = 4*width;
767  rgb = new uchar[width * height * depth]; // will hold the image data
768  uchar *p = rgb, *r, rr, gg, bb;
769  for (int i=height-1; i>=0; i--) { // for each row, from last to first
770  r = (uchar*)(lpBI->bmiColors) + i*linewidth; // beginning of pixel data for the ith row
771  for (int j=0; j<width; j++) { // for each pixel in a row
772  bb = *r++; // BGR is in DIB
773  gg = *r++;
774  rr = *r++;
775  *p++ = rr; // we want RGB
776  *p++ = gg;
777  *p++ = bb;
778  if (depth == 4) *p++ = *r++; // copy alpha if present
779  }
780  }
781  }
782  else { // the system will decode a complex DIB
783  void *pDIBBits = (void*)(lpBI->bmiColors + 256);
784  if (lpBI->bmiHeader.biCompression == BI_BITFIELDS) pDIBBits = (void*)(lpBI->bmiColors + 3);
785  else if (lpBI->bmiHeader.biClrUsed > 0) pDIBBits = (void*)(lpBI->bmiColors + lpBI->bmiHeader.biClrUsed);
786  Fl_Offscreen off = fl_create_offscreen(width, height);
787  fl_begin_offscreen(off);
788  SetDIBitsToDevice(fl_gc, 0, 0, width, height, 0, 0, 0, height, pDIBBits, lpBI, DIB_RGB_COLORS);
789  rgb = fl_read_image(NULL, 0, 0, width, height);
790  depth = 3;
792  fl_delete_offscreen(off);
793  }
794  GlobalUnlock(h);
795  }
796  else if ((h = GetClipboardData(CF_ENHMETAFILE))) { // if there's an enhanced metafile in clipboard
797  ENHMETAHEADER header;
798  GetEnhMetaFileHeader((HENHMETAFILE)h, sizeof(header), &header); // get structure containing metafile dimensions
799  width = (header.rclFrame.right - header.rclFrame.left + 1); // in .01 mm units
800  height = (header.rclFrame.bottom - header.rclFrame.top + 1);
801  HDC hdc = GetDC(NULL); // get unit correspondance between .01 mm and screen pixels
802  int hmm = GetDeviceCaps(hdc, HORZSIZE);
803  int hdots = GetDeviceCaps(hdc, HORZRES);
804  int dhr = GetDeviceCaps(hdc, DESKTOPHORZRES); // true number of pixels on display
805  ReleaseDC(NULL, hdc);
806  // Global display scaling factor: 1, 1.25, 1.5, 1.75, etc...
807  float scaling = dhr/float(hdots);
808  float factor = (100.f * hmm) / hdots;
809  width = (int)(width*scaling/factor); height = (int)(height*scaling/factor); // convert to screen pixel unit
810  RECT rect = {0, 0, width, height};
811  Fl_Offscreen off = fl_create_offscreen(width, height);
812  fl_begin_offscreen(off);
813  fl_color(FL_WHITE); fl_rectf(0,0,width, height); // draw white background
814  PlayEnhMetaFile(fl_gc, (HENHMETAFILE)h, &rect); // draw metafile to offscreen buffer
815  rgb = fl_read_image(NULL, 0, 0, width, height); // read pixels from offscreen buffer
816  depth = 3;
818  fl_delete_offscreen(off);
819  }
820  if (rgb) {
821  Fl_RGB_Image *image = new Fl_RGB_Image(rgb, width, height, depth); // create new image from pixel data
822  image->alloc_array = 1;
823  Fl::e_clipboard_data = image;
824  Fl::e_clipboard_type = Fl::clipboard_image; // indicates that the paste event is for image data
825  int done = receiver.handle(FL_PASTE); // send FL_PASTE event to widget
827  if (done == 0) { // if widget did not handle the event, delete the image
829  delete image;
830  }
831  }
832  }
833  CloseClipboard();
834  }
835 }
836 
837 int Fl::clipboard_contains(const char *type)
838 {
839  int retval = 0;
840  if (!OpenClipboard(NULL)) return 0;
841  if (strcmp(type, Fl::clipboard_plain_text) == 0 || type[0] == 0) {
842  retval = IsClipboardFormatAvailable(CF_UNICODETEXT);
843  }
844  else if (strcmp(type, Fl::clipboard_image) == 0) {
845  retval = IsClipboardFormatAvailable(CF_DIB) || IsClipboardFormatAvailable(CF_ENHMETAFILE);
846  }
847  CloseClipboard();
848  return retval;
849 }
850 
851 static void fl_clipboard_notify_target(HWND wnd) {
852  if (clipboard_wnd)
853  return;
854 
855  // We get one fake WM_DRAWCLIPBOARD immediately, which we therefore
856  // need to ignore.
857  initial_clipboard = true;
858 
859  clipboard_wnd = wnd;
860  next_clipboard_wnd = SetClipboardViewer(wnd);
861 }
862 
863 static void fl_clipboard_notify_untarget(HWND wnd) {
864  if (wnd != clipboard_wnd)
865  return;
866 
867  // We might be called late in the cleanup where Windows has already
868  // implicitly destroyed our clipboard window. At that point we need
869  // to do some extra work to manually repair the clipboard chain.
870  if (IsWindow(wnd))
871  ChangeClipboardChain(wnd, next_clipboard_wnd);
872  else {
873  HWND tmp, head;
874 
875  tmp = CreateWindow("STATIC", "Temporary FLTK Clipboard Window", 0,
876  0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
877  if (tmp == NULL)
878  return;
879 
880  head = SetClipboardViewer(tmp);
881  if (head == NULL)
882  ChangeClipboardChain(tmp, next_clipboard_wnd);
883  else {
884  SendMessage(head, WM_CHANGECBCHAIN, (WPARAM)wnd, (LPARAM)next_clipboard_wnd);
885  ChangeClipboardChain(tmp, head);
886  }
887 
888  DestroyWindow(tmp);
889  }
890 
892 }
893 
895  // The given window is getting destroyed. If it's part of the
896  // clipboard chain then we need to unregister it and find a
897  // replacement window.
898  if (wnd != clipboard_wnd)
899  return;
900 
902 
903  if (Fl::first_window())
905 }
906 
908  // untarget clipboard monitor if no handlers are registered
911  return;
912  }
913 
914  // if there are clipboard notify handlers but no window targeted
915  // target first window if available
916  if (clipboard_wnd == NULL && Fl::first_window())
918 }
919 
922 {
923  HKL hkl = GetKeyboardLayout(0);
924  TCHAR ld[8];
925 
926  GetLocaleInfo (LOWORD(hkl), LOCALE_IDEFAULTANSICODEPAGE, ld, 6);
927  DWORD ccp = atol(ld);
928  fl_codepage = ccp;
929 }
930 
932 
933 static int mouse_event(Fl_Window *window, int what, int button,
934  WPARAM wParam, LPARAM lParam)
935 {
936  static int px, py, pmx, pmy;
937  POINT pt;
938  Fl::e_x = pt.x = (signed short)LOWORD(lParam);
939  Fl::e_y = pt.y = (signed short)HIWORD(lParam);
940  ClientToScreen(fl_xid(window), &pt);
941  Fl::e_x_root = pt.x;
942  Fl::e_y_root = pt.y;
943 #ifdef USE_CAPTURE_MOUSE_WIN
944  Fl_Window *mouse_window = window; // save "mouse window"
945 #endif
946  while (window->parent()) {
947  Fl::e_x += window->x();
948  Fl::e_y += window->y();
949  window = window->window();
950  }
951 
952  ulong state = Fl::e_state & 0xff0000; // keep shift key states
953 #if 0
954  // mouse event reports some shift flags, perhaps save them?
955  if (wParam & MK_SHIFT) state |= FL_SHIFT;
956  if (wParam & MK_CONTROL) state |= FL_CTRL;
957 #endif
958  if (wParam & MK_LBUTTON) state |= FL_BUTTON1;
959  if (wParam & MK_MBUTTON) state |= FL_BUTTON2;
960  if (wParam & MK_RBUTTON) state |= FL_BUTTON3;
961  Fl::e_state = state;
962 
963  switch (what) {
964  case 1: // double-click
965  if (Fl::e_is_click) {Fl::e_clicks++; goto J1;}
966  case 0: // single-click
967  Fl::e_clicks = 0;
968  J1:
969 #ifdef USE_CAPTURE_MOUSE_WIN
970  if (!fl_capture) SetCapture(fl_xid(mouse_window)); // use mouse window
971 #else
972  if (!fl_capture) SetCapture(fl_xid(window)); // use main window
973 #endif
975  Fl::e_is_click = 1;
976  px = pmx = Fl::e_x_root; py = pmy = Fl::e_y_root;
977  return Fl::handle(FL_PUSH,window);
978 
979  case 2: // release:
980  if (!fl_capture) ReleaseCapture();
982  return Fl::handle(FL_RELEASE,window);
983 
984  case 3: // move:
985  default: // avoid compiler warning
986  // MSWindows produces extra events even if mouse does not move, ignore em:
987  if (Fl::e_x_root == pmx && Fl::e_y_root == pmy) return 1;
988  pmx = Fl::e_x_root; pmy = Fl::e_y_root;
989  if (abs(Fl::e_x_root-px)>5 || abs(Fl::e_y_root-py)>5) Fl::e_is_click = 0;
990  return Fl::handle(FL_MOVE,window);
991 
992  }
993 }
994 
995 // convert a MSWindows VK_x to an Fltk (X) Keysym:
996 // See also the inverse converter in Fl_get_key_win32.cxx
997 // This table is in numeric order by VK:
998 static const struct {unsigned short vk, fltk, extended;} vktab[] = {
999  {VK_BACK, FL_BackSpace},
1000  {VK_TAB, FL_Tab},
1001  {VK_CLEAR, FL_KP+'5', 0xff0b/*XK_Clear*/},
1002  {VK_RETURN, FL_Enter, FL_KP_Enter},
1003  {VK_SHIFT, FL_Shift_L, FL_Shift_R},
1004  {VK_CONTROL, FL_Control_L, FL_Control_R},
1005  {VK_MENU, FL_Alt_L, FL_Alt_R},
1006  {VK_PAUSE, FL_Pause},
1007  {VK_CAPITAL, FL_Caps_Lock},
1008  {VK_ESCAPE, FL_Escape},
1009  {VK_SPACE, ' '},
1010  {VK_PRIOR, FL_KP+'9', FL_Page_Up},
1011  {VK_NEXT, FL_KP+'3', FL_Page_Down},
1012  {VK_END, FL_KP+'1', FL_End},
1013  {VK_HOME, FL_KP+'7', FL_Home},
1014  {VK_LEFT, FL_KP+'4', FL_Left},
1015  {VK_UP, FL_KP+'8', FL_Up},
1016  {VK_RIGHT, FL_KP+'6', FL_Right},
1017  {VK_DOWN, FL_KP+'2', FL_Down},
1018  {VK_SNAPSHOT, FL_Print}, // does not work on NT
1019  {VK_INSERT, FL_KP+'0', FL_Insert},
1020  {VK_DELETE, FL_KP+'.', FL_Delete},
1021  {VK_LWIN, FL_Meta_L},
1022  {VK_RWIN, FL_Meta_R},
1023  {VK_APPS, FL_Menu},
1024  {VK_SLEEP, FL_Sleep},
1025  {VK_MULTIPLY, FL_KP+'*'},
1026  {VK_ADD, FL_KP+'+'},
1027  {VK_SUBTRACT, FL_KP+'-'},
1028  {VK_DECIMAL, FL_KP+'.'},
1029  {VK_DIVIDE, FL_KP+'/'},
1030  {VK_NUMLOCK, FL_Num_Lock},
1031  {VK_SCROLL, FL_Scroll_Lock},
1032 # if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0500)
1033  {VK_BROWSER_BACK, FL_Back},
1034  {VK_BROWSER_FORWARD, FL_Forward},
1035  {VK_BROWSER_REFRESH, FL_Refresh},
1036  {VK_BROWSER_STOP, FL_Stop},
1037  {VK_BROWSER_SEARCH, FL_Search},
1038  {VK_BROWSER_FAVORITES, FL_Favorites},
1039  {VK_BROWSER_HOME, FL_Home_Page},
1040  {VK_VOLUME_MUTE, FL_Volume_Mute},
1041  {VK_VOLUME_DOWN, FL_Volume_Down},
1042  {VK_VOLUME_UP, FL_Volume_Up},
1043  {VK_MEDIA_NEXT_TRACK, FL_Media_Next},
1044  {VK_MEDIA_PREV_TRACK, FL_Media_Prev},
1045  {VK_MEDIA_STOP, FL_Media_Stop},
1046  {VK_MEDIA_PLAY_PAUSE, FL_Media_Play},
1047  {VK_LAUNCH_MAIL, FL_Mail},
1048 #endif
1049  {0xba, ';'},
1050  {0xbb, '='},
1051  {0xbc, ','},
1052  {0xbd, '-'},
1053  {0xbe, '.'},
1054  {0xbf, '/'},
1055  {0xc0, '`'},
1056  {0xdb, '['},
1057  {0xdc, '\\'},
1058  {0xdd, ']'},
1059  {0xde, '\''},
1060  {VK_OEM_102, FL_Iso_Key}
1061 };
1062 static int ms2fltk(WPARAM vk, int extended) {
1063  static unsigned short vklut[256];
1064  static unsigned short extendedlut[256];
1065  if (!vklut[1]) { // init the table
1066  unsigned int i;
1067  for (i = 0; i < 256; i++) vklut[i] = tolower(i);
1068  for (i=VK_F1; i<=VK_F16; i++) vklut[i] = i+(FL_F-(VK_F1-1));
1069  for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++) vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0);
1070  for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++) {
1071  vklut[vktab[i].vk] = vktab[i].fltk;
1072  extendedlut[vktab[i].vk] = vktab[i].extended;
1073  }
1074  for (i = 0; i < 256; i++) if (!extendedlut[i]) extendedlut[i] = vklut[i];
1075  }
1076  return extended ? extendedlut[vk] : vklut[vk];
1077 }
1078 
1079 #if USE_COLORMAP
1080 extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx
1081 #endif
1082 
1083 
1087 
1089 {
1090  UINT_PTR handle;
1092  void *data;
1093 };
1096 static int win32_timer_used;
1097 static HWND s_TimerWnd;
1098 
1099 static void realloc_timers()
1100 {
1101  if (win32_timer_alloc == 0) {
1102  win32_timer_alloc = 8;
1103  }
1104  win32_timer_alloc *= 2;
1105  Win32Timer* new_timers = new Win32Timer[win32_timer_alloc];
1106  memset(new_timers, 0, sizeof(Win32Timer) * win32_timer_used);
1107  memcpy(new_timers, win32_timers, sizeof(Win32Timer) * win32_timer_used);
1108  Win32Timer* delete_me = win32_timers;
1109  win32_timers = new_timers;
1110  delete [] delete_me;
1111 }
1112 
1113 static void delete_timer(Win32Timer& t)
1114 {
1115  KillTimer(s_TimerWnd, t.handle);
1116  memset(&t, 0, sizeof(Win32Timer));
1117 }
1118 
1121 
1123 
1124 extern void fl_save_pen(void);
1125 extern void fl_restore_pen(void);
1126 
1127 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1128 {
1129  // Copy the message to fl_msg so add_handler code can see it, it is
1130  // already there if this is called by DispatchMessage, but not if
1131  // Windows calls this directly.
1132  fl_msg.hwnd = hWnd;
1133  fl_msg.message = uMsg;
1134  fl_msg.wParam = wParam;
1135  fl_msg.lParam = lParam;
1136  //fl_msg.time = ???
1137  //fl_msg.pt = ???
1138  //fl_msg.lPrivate = ???
1139 
1140  Fl_Window *window = fl_find(hWnd);
1141 
1142  if (window) switch (uMsg) {
1143 
1144  case WM_QUIT: // this should not happen?
1145  Fl::fatal("WM_QUIT message");
1146 
1147  case WM_CLOSE: // user clicked close box
1149  return 0;
1150 
1151  case WM_SYNCPAINT :
1152  case WM_NCPAINT :
1153  case WM_ERASEBKGND :
1154  // Andreas Weitl - WM_SYNCPAINT needs to be passed to DefWindowProc
1155  // so that Windows can generate the proper paint messages...
1156  // Similarly, WM_NCPAINT and WM_ERASEBKGND need this, too...
1157  break;
1158 
1159  case WM_PAINT: {
1160  Fl_Region R;
1161  Fl_X *i = Fl_X::i(window);
1162  i->wait_for_expose = 0;
1163  char redraw_whole_window = false;
1164  if (!i->region && window->damage()) {
1165  // Redraw the whole window...
1166  i->region = CreateRectRgn(0, 0, window->w(), window->h());
1167  redraw_whole_window = true;
1168  }
1169 
1170  // We need to merge WIN32's damage into FLTK's damage.
1171  R = CreateRectRgn(0,0,0,0);
1172  int r = GetUpdateRgn(hWnd,R,0);
1173  if (r==NULLREGION && !redraw_whole_window) {
1174  XDestroyRegion(R);
1175  break;
1176  }
1177 
1178  if (i->region) {
1179  // Also tell WIN32 that we are drawing someplace else as well...
1180  CombineRgn(i->region, i->region, R, RGN_OR);
1181  XDestroyRegion(R);
1182  } else {
1183  i->region = R;
1184  }
1185  if (window->type() == FL_DOUBLE_WINDOW) ValidateRgn(hWnd,0);
1186  else ValidateRgn(hWnd,i->region);
1187 
1189  // These next two statements should not be here, so that all update
1190  // is deferred until Fl::flush() is called during idle. However WIN32
1191  // apparently is very unhappy if we don't obey it and draw right now.
1192  // Very annoying!
1193  fl_GetDC(hWnd); // Make sure we have a DC for this window...
1194  fl_save_pen();
1195  i->flush();
1196  fl_restore_pen();
1197  window->clear_damage();
1198  } return 0;
1199 
1200  case WM_LBUTTONDOWN: mouse_event(window, 0, 1, wParam, lParam); return 0;
1201  case WM_LBUTTONDBLCLK:mouse_event(window, 1, 1, wParam, lParam); return 0;
1202  case WM_LBUTTONUP: mouse_event(window, 2, 1, wParam, lParam); return 0;
1203  case WM_MBUTTONDOWN: mouse_event(window, 0, 2, wParam, lParam); return 0;
1204  case WM_MBUTTONDBLCLK:mouse_event(window, 1, 2, wParam, lParam); return 0;
1205  case WM_MBUTTONUP: mouse_event(window, 2, 2, wParam, lParam); return 0;
1206  case WM_RBUTTONDOWN: mouse_event(window, 0, 3, wParam, lParam); return 0;
1207  case WM_RBUTTONDBLCLK:mouse_event(window, 1, 3, wParam, lParam); return 0;
1208  case WM_RBUTTONUP: mouse_event(window, 2, 3, wParam, lParam); return 0;
1209 
1210  case WM_MOUSEMOVE:
1211 #ifdef USE_TRACK_MOUSE
1212  if (track_mouse_win != window) {
1213  TRACKMOUSEEVENT tme;
1214  tme.cbSize = sizeof(TRACKMOUSEEVENT);
1215  tme.dwFlags = TME_LEAVE;
1216  tme.hwndTrack = hWnd;
1217  _TrackMouseEvent(&tme);
1219  }
1220 #endif // USE_TRACK_MOUSE
1221  mouse_event(window, 3, 0, wParam, lParam);
1222  return 0;
1223 
1224  case WM_MOUSELEAVE:
1225  if (track_mouse_win == window) { // we left the top level window !
1226  Fl_Window *tw = window;
1227  while (tw->parent()) tw = tw->window(); // find top level window
1228  Fl::belowmouse(0);
1229  Fl::handle(FL_LEAVE, tw);
1230  }
1231  track_mouse_win = 0; // force TrackMouseEvent() restart
1232  break;
1233 
1234  case WM_SETFOCUS:
1235  if ((Fl::modal_) && (Fl::modal_ != window)) {
1236  SetFocus(fl_xid(Fl::modal_));
1237  return 0;
1238  }
1240  break;
1241 
1242  case WM_KILLFOCUS:
1244  Fl::flush(); // it never returns to main loop when deactivated...
1245  break;
1246 
1247  case WM_SHOWWINDOW:
1248  if (!window->parent()) {
1249  Fl::handle(wParam ? FL_SHOW : FL_HIDE, window);
1250  }
1251  break;
1252 
1253  case WM_ACTIVATEAPP:
1254  // From eric@vfx.sel.sony.com, we should process WM_ACTIVATEAPP
1255  // messages to restore the correct state of the shift/ctrl/alt/lock
1256  // keys... Added control, shift, alt, and meta keys, and changed
1257  // to use GetAsyncKeyState and do it when wParam is 1
1258  // (that means we have focus...)
1259  if (wParam)
1260  {
1261  ulong state = 0;
1262  if (GetAsyncKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK;
1263  if (GetAsyncKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK;
1264  if (GetAsyncKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK;
1265  if (GetAsyncKeyState(VK_CONTROL)&~1) state |= FL_CTRL;
1266  if (GetAsyncKeyState(VK_SHIFT)&~1) state |= FL_SHIFT;
1267  if (GetAsyncKeyState(VK_MENU)) state |= FL_ALT;
1268  if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1) state |= FL_META;
1269  Fl::e_state = state;
1270  return 0;
1271  }
1272  break;
1273 
1274  case WM_INPUTLANGCHANGE:
1275  fl_get_codepage();
1276  break;
1277  case WM_IME_COMPOSITION:
1278 // if (!fl_is_nt4() && lParam & GCS_RESULTCLAUSE) {
1279 // HIMC himc = ImmGetContext(hWnd);
1280 // wlen = ImmGetCompositionStringW(himc, GCS_RESULTSTR,
1281 // wbuf, sizeof(wbuf)) / sizeof(short);
1282 // if (wlen < 0) wlen = 0;
1283 // wbuf[wlen] = 0;
1284 // ImmReleaseContext(hWnd, himc);
1285 // }
1286  break;
1287  case WM_KEYDOWN:
1288  case WM_SYSKEYDOWN:
1289  case WM_KEYUP:
1290  case WM_SYSKEYUP:
1291  // save the keysym until we figure out the characters:
1292  Fl::e_keysym = Fl::e_original_keysym = ms2fltk(wParam,lParam&(1<<24));
1293  // See if TranslateMessage turned it into a WM_*CHAR message:
1294  if (PeekMessageW(&fl_msg, hWnd, WM_CHAR, WM_SYSDEADCHAR, PM_REMOVE))
1295  {
1296  uMsg = fl_msg.message;
1297  wParam = fl_msg.wParam;
1298  lParam = fl_msg.lParam;
1299  }
1300  case WM_DEADCHAR:
1301  case WM_SYSDEADCHAR:
1302  case WM_CHAR:
1303  case WM_SYSCHAR: {
1304  ulong state = Fl::e_state & 0xff000000; // keep the mouse button state
1305  // if GetKeyState is expensive we might want to comment some of these out:
1306  if (GetKeyState(VK_SHIFT)&~1) state |= FL_SHIFT;
1307  if (GetKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK;
1308  if (GetKeyState(VK_CONTROL)&~1) state |= FL_CTRL;
1309  // Alt gets reported for the Alt-GR switch on foreign keyboards.
1310  // so we need to check the event as well to get it right:
1311  if ((lParam&(1<<29)) //same as GetKeyState(VK_MENU)
1312  && uMsg != WM_CHAR) state |= FL_ALT;
1313  if (GetKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK;
1314  if ((GetKeyState(VK_LWIN)|GetKeyState(VK_RWIN))&~1) {
1315  // WIN32 bug? GetKeyState returns garbage if the user hit the
1316  // meta key to pop up start menu. Sigh.
1317  if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1)
1318  state |= FL_META;
1319  }
1320  if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK;
1321  Fl::e_state = state;
1322  static char buffer[1024];
1323  if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
1324 
1325  xchar u = (xchar) wParam;
1326 // Fl::e_length = fl_unicode2utf(&u, 1, buffer);
1327  Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
1328  buffer[Fl::e_length] = 0;
1329 
1330 
1331  } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
1332  if (state & FL_NUM_LOCK) {
1333  // Convert to regular keypress...
1334  buffer[0] = Fl::e_keysym-FL_KP;
1335  Fl::e_length = 1;
1336  } else {
1337  // Convert to special keypress...
1338  buffer[0] = 0;
1339  Fl::e_length = 0;
1340  switch (Fl::e_keysym) {
1341  case FL_KP + '0' :
1343  break;
1344  case FL_KP + '1' :
1345  Fl::e_keysym = FL_End;
1346  break;
1347  case FL_KP + '2' :
1349  break;
1350  case FL_KP + '3' :
1352  break;
1353  case FL_KP + '4' :
1355  break;
1356  case FL_KP + '6' :
1358  break;
1359  case FL_KP + '7' :
1361  break;
1362  case FL_KP + '8' :
1363  Fl::e_keysym = FL_Up;
1364  break;
1365  case FL_KP + '9' :
1367  break;
1368  case FL_KP + '.' :
1370  break;
1371  case FL_KP + '/' :
1372  case FL_KP + '*' :
1373  case FL_KP + '-' :
1374  case FL_KP + '+' :
1375  buffer[0] = Fl::e_keysym-FL_KP;
1376  Fl::e_length = 1;
1377  break;
1378  }
1379  }
1380  } else if ((lParam & (1<<31))==0) {
1381 #ifdef FLTK_PREVIEW_DEAD_KEYS
1382  if ((lParam & (1<<24))==0) { // clear if dead key (always?)
1383  xchar u = (xchar) wParam;
1384  Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
1385  buffer[Fl::e_length] = 0;
1386  } else { // set if "extended key" (never printable?)
1387  buffer[0] = 0;
1388  Fl::e_length = 0;
1389  }
1390 #else
1391  buffer[0] = 0;
1392  Fl::e_length = 0;
1393 #endif
1394  }
1395  Fl::e_text = buffer;
1396  if (lParam & (1<<31)) { // key up events.
1397  if (Fl::handle(FL_KEYUP, window)) return 0;
1398  break;
1399  }
1400  // for (int i = lParam&0xff; i--;)
1401  while (window->parent()) window = window->window();
1402  if (Fl::handle(FL_KEYBOARD,window)) {
1403  if (uMsg==WM_DEADCHAR || uMsg==WM_SYSDEADCHAR)
1404  Fl::compose_state = 1;
1405  return 0;
1406  }
1407  break;}
1408 
1409  case WM_MOUSEWHEEL: {
1410  static int delta = 0; // running total of all motion
1411  delta += (SHORT)(HIWORD(wParam));
1412  Fl::e_dx = 0;
1413  Fl::e_dy = -delta / WHEEL_DELTA;
1414  delta += Fl::e_dy * WHEEL_DELTA;
1416  return 0;
1417  }
1418 
1419 // This is only defined on Vista and upwards...
1420 #ifndef WM_MOUSEHWHEEL
1421 #define WM_MOUSEHWHEEL 0x020E
1422 #endif
1423 
1424  case WM_MOUSEHWHEEL: {
1425  static int delta = 0; // running total of all motion
1426  delta += (SHORT)(HIWORD(wParam));
1427  Fl::e_dy = 0;
1428  Fl::e_dx = delta / WHEEL_DELTA;
1429  delta -= Fl::e_dx * WHEEL_DELTA;
1431  return 0;
1432  }
1433 
1434  case WM_GETMINMAXINFO:
1435  Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam);
1436  break;
1437 
1438  case WM_SIZE:
1439  if (!window->parent()) {
1440  if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE) {
1442  } else {
1445  window->size(LOWORD(lParam), HIWORD(lParam));
1446  }
1447  }
1448  break;
1449 
1450  case WM_MOVE: {
1452  int nx = LOWORD(lParam);
1453  int ny = HIWORD(lParam);
1454  if (nx & 0x8000) nx -= 65536;
1455  if (ny & 0x8000) ny -= 65536;
1456  window->position(nx, ny); }
1457  break;
1458 
1459  case WM_SETCURSOR:
1460  if (LOWORD(lParam) == HTCLIENT) {
1461  while (window->parent()) window = window->window();
1462  SetCursor(Fl_X::i(window)->cursor);
1463  return 0;
1464  }
1465  break;
1466 
1467 #if USE_COLORMAP
1468  case WM_QUERYNEWPALETTE :
1469  fl_GetDC(hWnd);
1470  if (fl_select_palette()) InvalidateRect(hWnd, NULL, FALSE);
1471  break;
1472 
1473  case WM_PALETTECHANGED:
1474  fl_GetDC(hWnd);
1475  if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_gc);
1476  break;
1477 
1478  case WM_CREATE :
1479  fl_GetDC(hWnd);
1480  fl_select_palette();
1481  break;
1482 #endif
1483 
1484  case WM_DESTROYCLIPBOARD:
1485  fl_i_own_selection[1] = 0;
1486  return 1;
1487 
1488  case WM_DISPLAYCHANGE: // occurs when screen configuration (number, position) changes
1491  return 0;
1492 
1493  case WM_CHANGECBCHAIN:
1494  if ((hWnd == clipboard_wnd) && (next_clipboard_wnd == (HWND)wParam))
1495  next_clipboard_wnd = (HWND)lParam;
1496  else
1497  SendMessage(next_clipboard_wnd, WM_CHANGECBCHAIN, wParam, lParam);
1498  return 0;
1499 
1500  case WM_DRAWCLIPBOARD:
1501  // When the clipboard moves between two FLTK windows,
1502  // fl_i_own_selection will temporarily be false as we are
1503  // processing this message. Hence the need to use fl_find().
1504  if (!initial_clipboard && !fl_find(GetClipboardOwner()))
1506  initial_clipboard = false;
1507 
1508  if (next_clipboard_wnd)
1509  SendMessage(next_clipboard_wnd, WM_DRAWCLIPBOARD, wParam, lParam);
1510 
1511  return 0;
1512 
1513  default:
1514  if (Fl::handle(0,0)) return 0;
1515  break;
1516  }
1517 
1518 
1519  return DefWindowProcW(hWnd, uMsg, wParam, lParam);
1520 }
1521 
1523 // This function gets the dimensions of the top/left borders and
1524 // the title bar, if there is one, based on the FL_BORDER, FL_MODAL
1525 // and FL_NONMODAL flags, and on the window's size range.
1526 // It returns the following values:
1527 //
1528 // value | border | title bar
1529 // 0 | none | no
1530 // 1 | fix | yes
1531 // 2 | size | yes
1532 
1533 static int fake_X_wm_style(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by, DWORD style, DWORD styleEx,
1534  int w_maxw, int w_minw, int w_maxh, int w_minh, uchar w_size_range_set) {
1535  int W = 0, H = 0, xoff = 0, yoff = 0, dx = 0, dy = 0;
1536  int ret = bx = by = bt = 0;
1537 
1538  int fallback = 1;
1539  if (!w->parent()) {
1540  if (fl_xid(w) || style) {
1541  // The block below calculates the window borders by requesting the
1542  // required decorated window rectangle for a desired client rectangle.
1543  // If any part of the function above fails, we will drop to a
1544  // fallback to get the best guess which is always available.
1545 
1546  if (!style) {
1547  HWND hwnd = fl_xid(w);
1548  // request the style flags of this window, as WIN32 sees them
1549  style = GetWindowLong(hwnd, GWL_STYLE);
1550  styleEx = GetWindowLong(hwnd, GWL_EXSTYLE);
1551  }
1552 
1553  RECT r;
1554  r.left = w->x();
1555  r.top = w->y();
1556  r.right = w->x()+w->w();
1557  r.bottom = w->y()+w->h();
1558  // get the decoration rectangle for the desired client rectangle
1559  BOOL ok = AdjustWindowRectEx(&r, style, FALSE, styleEx);
1560  if (ok) {
1561  X = r.left;
1562  Y = r.top;
1563  W = r.right - r.left;
1564  H = r.bottom - r.top;
1565  bx = w->x() - r.left;
1566  by = r.bottom - w->y() - w->h(); // height of the bottom frame
1567  bt = w->y() - r.top - by; // height of top caption bar
1568  xoff = bx;
1569  yoff = by + bt;
1570  dx = W - w->w();
1571  dy = H - w->h();
1572  if (w_size_range_set && (w_maxw != w_minw || w_maxh != w_minh))
1573  ret = 2;
1574  else
1575  ret = 1;
1576  fallback = 0;
1577  }
1578  }
1579  }
1580  // This is the original (pre 1.1.7) routine to calculate window border sizes.
1581  if (fallback) {
1582  if (w->border() && !w->parent()) {
1583  if (w_size_range_set && (w_maxw != w_minw || w_maxh != w_minh)) {
1584  ret = 2;
1585  bx = GetSystemMetrics(SM_CXSIZEFRAME);
1586  by = GetSystemMetrics(SM_CYSIZEFRAME);
1587  } else {
1588  ret = 1;
1589  int padding = GetSystemMetrics(SM_CXPADDEDBORDER);
1590  NONCLIENTMETRICS ncm;
1591  ncm.cbSize = sizeof(NONCLIENTMETRICS);
1592  SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
1593  bx = GetSystemMetrics(SM_CXFIXEDFRAME) + (padding ? padding + ncm.iBorderWidth : 0);
1594  by = GetSystemMetrics(SM_CYFIXEDFRAME) + (padding ? padding + ncm.iBorderWidth : 0);
1595  }
1596  bt = GetSystemMetrics(SM_CYCAPTION);
1597  }
1598  //The coordinates of the whole window, including non-client area
1599  xoff = bx;
1600  yoff = by + bt;
1601  dx = 2*bx;
1602  dy = 2*by + bt;
1603  X = w->x()-xoff;
1604  Y = w->y()-yoff;
1605  W = w->w()+dx;
1606  H = w->h()+dy;
1607  }
1608 
1609  //Proceed to positioning the window fully inside the screen, if possible
1610  //Find screen that contains most of the window
1611  //FIXME: this ought to be the "work area" instead of the entire screen !
1612  int scr_x = 0, scr_y = 0, scr_w = 0, scr_h = 0;
1613  Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y, W, H);
1614  //Make border's lower right corner visible
1615  if (scr_x+scr_w < X+W) X = scr_x+scr_w - W;
1616  if (scr_y+scr_h < Y+H) Y = scr_y+scr_h - H;
1617  //Make border's upper left corner visible
1618  if (X<scr_x) X = scr_x;
1619  if (Y<scr_y) Y = scr_y;
1620  //Make client area's lower right corner visible
1621  if (scr_x+scr_w < X+dx+ w->w()) X = scr_x+scr_w - w->w() - dx;
1622  if (scr_y+scr_h < Y+dy+ w->h()) Y = scr_y+scr_h - w->h() - dy;
1623  //Make client area's upper left corner visible
1624  if (X+xoff < scr_x) X = scr_x-xoff;
1625  if (Y+yoff < scr_y) Y = scr_y-yoff;
1626  //Return the client area's top left corner in (X,Y)
1627  X+=xoff;
1628  Y+=yoff;
1629 
1630  if (w->fullscreen_active()) {
1631  bx = by = bt = 0;
1632  }
1633 
1634  return ret;
1635 }
1636 
1637 int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) {
1638  return fake_X_wm_style(w, X, Y, bt, bx, by, 0, 0, w->maxw, w->minw, w->maxh, w->minh, w->size_range_set);
1639 }
1640 
1642 
1643 void Fl_Window::resize(int X,int Y,int W,int H) {
1644  UINT flags = SWP_NOSENDCHANGING | SWP_NOZORDER
1645  | SWP_NOACTIVATE | SWP_NOOWNERZORDER;
1646  int is_a_resize = (W != w() || H != h());
1647  int resize_from_program = (this != resize_bug_fix);
1648  if (!resize_from_program) resize_bug_fix = 0;
1649  if (X != x() || Y != y()) {
1650  force_position(1);
1651  } else {
1652  if (!is_a_resize) return;
1653  flags |= SWP_NOMOVE;
1654  }
1655  if (is_a_resize) {
1656  Fl_Group::resize(X,Y,W,H);
1657  if (visible_r()) {
1658  redraw();
1659  // only wait for exposure if this window has a size - a window
1660  // with no width or height will never get an exposure event
1661  if (i && W>0 && H>0)
1662  i->wait_for_expose = 1;
1663  }
1664  } else {
1665  x(X); y(Y);
1666  flags |= SWP_NOSIZE;
1667  }
1668  if (!border()) flags |= SWP_NOACTIVATE;
1669  if (resize_from_program && shown()) {
1670  if (!resizable()) size_range(w(),h(),w(),h());
1671  int dummy_x, dummy_y, bt, bx, by;
1672  //Ignore window managing when resizing, so that windows (and more
1673  //specifically menus) can be moved offscreen.
1674  if (Fl_X::fake_X_wm(this, dummy_x, dummy_y, bt, bx, by)) {
1675  X -= bx;
1676  Y -= by+bt;
1677  W += 2*bx;
1678  H += 2*by+bt;
1679  }
1680  // avoid zero size windows. A zero sized window on Win32
1681  // will cause continouly new redraw events.
1682  if (W<=0) W = 1;
1683  if (H<=0) H = 1;
1684  SetWindowPos(i->xid, 0, X, Y, W, H, flags);
1685  }
1686 }
1687 
1688 void Fl_X::make_fullscreen(int X, int Y, int W, int H) {
1689  int top, bottom, left, right;
1690  int sx, sy, sw, sh;
1691 
1692  top = w->fullscreen_screen_top;
1693  bottom = w->fullscreen_screen_bottom;
1694  left = w->fullscreen_screen_left;
1695  right = w->fullscreen_screen_right;
1696 
1697  if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
1698  top = Fl::screen_num(X, Y, W, H);
1699  bottom = top;
1700  left = top;
1701  right = top;
1702  }
1703 
1704  Fl::screen_xywh(sx, sy, sw, sh, top);
1705  Y = sy;
1706  Fl::screen_xywh(sx, sy, sw, sh, bottom);
1707  H = sy + sh - Y;
1708  Fl::screen_xywh(sx, sy, sw, sh, left);
1709  X = sx;
1710  Fl::screen_xywh(sx, sy, sw, sh, right);
1711  W = sx + sw - X;
1712 
1713  DWORD flags = GetWindowLong(xid, GWL_STYLE);
1714  flags = flags & ~(WS_THICKFRAME|WS_CAPTION);
1715  SetWindowLong(xid, GWL_STYLE, flags);
1716 
1717  // SWP_NOSENDCHANGING is so that we can override size limits
1718  SetWindowPos(xid, HWND_TOP, X, Y, W, H, SWP_NOSENDCHANGING | SWP_FRAMECHANGED);
1719 }
1720 
1722  _set_fullscreen();
1723  i->make_fullscreen(x(), y(), w(), h());
1724  Fl::handle(FL_FULLSCREEN, this);
1725 }
1726 
1727 void Fl_Window::fullscreen_off_x(int X, int Y, int W, int H) {
1729  DWORD style = GetWindowLong(fl_xid(this), GWL_STYLE);
1730  // Remove the xid temporarily so that Fl_X::fake_X_wm() behaves like it
1731  // does in Fl_X::make().
1732  HWND xid = fl_xid(this);
1733  Fl_X::i(this)->xid = NULL;
1734  int wx, wy, bt, bx, by;
1735  switch (Fl_X::fake_X_wm(this, wx, wy, bt, bx, by)) {
1736  case 0:
1737  break;
1738  case 1:
1739  style |= WS_CAPTION;
1740  break;
1741  case 2:
1742  if (border()) {
1743  style |= WS_THICKFRAME | WS_CAPTION;
1744  }
1745  break;
1746  }
1747  Fl_X::i(this)->xid = xid;
1748  // Adjust for decorations (but not if that puts the decorations
1749  // outside the screen)
1750  if ((X != x()) || (Y != y())) {
1751  X -= bx;
1752  Y -= by+bt;
1753  }
1754  W += bx*2;
1755  H += by*2+bt;
1756  SetWindowLong(fl_xid(this), GWL_STYLE, style);
1757  SetWindowPos(fl_xid(this), 0, X, Y, W, H,
1758  SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
1759  Fl::handle(FL_FULLSCREEN, this);
1760 }
1761 
1762 
1764 
1765 /*
1766  * This silly little class remembers the name of all window classes
1767  * we register to avoid double registration. It has the added bonus
1768  * of freeing everything on application close as well.
1769  */
1770 class NameList {
1771 public:
1772  NameList() { name = (char**)malloc(sizeof(char**)); NName = 1; nName = 0; }
1774  int i;
1775  for (i=0; i<nName; i++) free(name[i]);
1776  if (name) free(name);
1777  }
1778  void add_name(const char *n) {
1779  if (NName==nName) {
1780  NName += 5;
1781  name = (char**)realloc(name, NName * sizeof(char*));
1782  }
1783  name[nName++] = strdup(n);
1784  }
1785  char has_name(const char *n) {
1786  int i;
1787  for (i=0; i<nName; i++) {
1788  if (strcmp(name[i], n)==0) return 1;
1789  }
1790  return 0;
1791  }
1792 private:
1793  char **name;
1794  int nName, NName;
1795 };
1796 
1797 void fl_fix_focus(); // in Fl.cxx
1798 
1799 char fl_show_iconic; // hack for Fl_Window::iconic()
1800 // int fl_background_pixel = -1; // color to use for background
1801 UINT fl_wake_msg = 0;
1802 int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
1803 
1804 Fl_X* Fl_X::make(Fl_Window* w) {
1805  Fl_Group::current(0); // get rid of very common user bug: forgot end()
1806 
1807  fl_open_display();
1808 
1809  // if the window is a subwindow and our parent is not mapped yet, we
1810  // mark this window visible, so that mapping the parent at a later
1811  // point in time will call this function again to finally map the subwindow.
1812  if (w->parent() && !Fl_X::i(w->window())) {
1813  w->set_visible();
1814  return 0L;
1815  }
1816 
1817  static NameList class_name_list;
1818  static const char *first_class_name = 0L;
1819  const char *class_name = w->xclass();
1820  if (!class_name) class_name = first_class_name; // reuse first class name used
1821  if (!class_name) class_name = "FLTK"; // default to create a "FLTK" WNDCLASS
1822  if (!first_class_name) {
1823  first_class_name = class_name;
1824  }
1825 
1826  wchar_t class_namew[100]; // (limited) buffer for Windows class name
1827 
1828  // convert UTF-8 class_name to wchar_t for RegisterClassExW and CreateWindowExW
1829 
1830  fl_utf8toUtf16(class_name,
1831  (unsigned)strlen(class_name), // in
1832  (unsigned short*)class_namew, // out
1833  (unsigned)sizeof(class_namew)/sizeof(wchar_t)); // max. size
1834 
1835  if (!class_name_list.has_name(class_name)) {
1836  WNDCLASSEXW wcw;
1837  memset(&wcw, 0, sizeof(wcw));
1838  wcw.cbSize = sizeof(WNDCLASSEXW);
1839 
1840  // Documentation states a device context consumes about 800 bytes
1841  // of memory... so who cares? If 800 bytes per window is what it
1842  // takes to speed things up, I'm game.
1843  //wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS;
1844  wcw.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
1845  wcw.lpfnWndProc = (WNDPROC)WndProc;
1846  wcw.cbClsExtra = wcw.cbWndExtra = 0;
1847  wcw.hInstance = fl_display;
1848  if (!w->icon() && !w->icon_->count)
1849  w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
1850  wcw.hIcon = wcw.hIconSm = (HICON)w->icon();
1851  wcw.hCursor = LoadCursor(NULL, IDC_ARROW);
1852  //uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
1853  //wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
1854  wcw.hbrBackground = NULL;
1855  wcw.lpszMenuName = NULL;
1856  wcw.lpszClassName = class_namew;
1857  RegisterClassExW(&wcw);
1858  class_name_list.add_name(class_name);
1859  }
1860 
1861  const wchar_t* message_namew = L"FLTK::ThreadWakeup";
1862  if (!fl_wake_msg) fl_wake_msg = RegisterWindowMessageW(message_namew);
1863 
1864  HWND parent;
1865  DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
1866  DWORD styleEx = WS_EX_LEFT;
1867 
1868  int xp = w->x();
1869  int yp = w->y();
1870  int wp = w->w();
1871  int hp = w->h();
1872 
1873  int showit = 1;
1874 
1875  if (w->parent()) {
1876  style |= WS_CHILD;
1877  styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
1878  parent = fl_xid(w->window());
1879  } else {
1880  if (!w->size_range_set) {
1881  if (w->resizable()) {
1882  Fl_Widget *o = w->resizable();
1883  int minw = o->w(); if (minw > 100) minw = 100;
1884  int minh = o->h(); if (minh > 100) minh = 100;
1885  w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
1886  } else {
1887  w->size_range(w->w(), w->h(), w->w(), w->h());
1888  }
1889  }
1890  styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
1891 
1892  int wintype = 0;
1893  if (w->border() && !w->parent()) {
1894  if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) wintype = 2;
1895  else wintype = 1;
1896  }
1897 
1898  switch (wintype) {
1899  // No border (used for menus)
1900  case 0:
1901  style |= WS_POPUP;
1902  styleEx |= WS_EX_TOOLWINDOW;
1903  break;
1904 
1905  // Thin border and title bar
1906  case 1:
1907  style |= WS_DLGFRAME | WS_CAPTION;
1908  if (!w->modal())
1909  style |= WS_SYSMENU | WS_MINIMIZEBOX;
1910  break;
1911 
1912  // Thick, resizable border and title bar, with maximize button
1913  case 2:
1914  style |= WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_CAPTION;
1915  if (!w->modal())
1916  style |= WS_MINIMIZEBOX;
1917  break;
1918  }
1919 
1920  int xwm = xp , ywm = yp , bt, bx, by;
1921  fake_X_wm_style(w, xwm, ywm, bt, bx, by, style, styleEx, w->maxw, w->minw, w->maxh, w->minh, w->size_range_set);
1922  if (by+bt) {
1923  wp += 2*bx;
1924  hp += 2*by+bt;
1925  }
1926  if (!w->force_position()) {
1927  xp = yp = CW_USEDEFAULT;
1928  } else {
1929  if (!Fl::grab()) {
1930  xp = xwm; yp = ywm;
1931  w->x(xp);w->y(yp);
1932  }
1933  xp -= bx;
1934  yp -= by+bt;
1935  }
1936 
1937  parent = 0;
1939  // find some other window to be "transient for":
1940  Fl_Window* w = Fl_X::first->w;
1941  while (w->parent()) w = w->window();
1942  parent = fl_xid(w);
1943  if (!w->visible()) showit = 0;
1944  } else if (Fl::grab()) parent = fl_xid(Fl::grab());
1945  }
1946 
1947  Fl_X* x = new Fl_X;
1948  x->other_xid = 0;
1949  x->setwindow(w);
1950  x->region = 0;
1951  x->private_dc = 0;
1952  x->cursor = LoadCursor(NULL, IDC_ARROW);
1953  x->custom_cursor = 0;
1954  if (!fl_codepage) fl_get_codepage();
1955 
1956  WCHAR *lab = NULL;
1957  if (w->label()) {
1958  size_t l = strlen(w->label());
1959 // lab = (WCHAR*) malloc((l + 1) * sizeof(short));
1960 // l = fl_utf2unicode((unsigned char*)w->label(), l, (xchar*)lab);
1961 // lab[l] = 0;
1962  unsigned wlen = fl_utf8toUtf16(w->label(), (unsigned) l, NULL, 0); // Pass NULL to query length
1963  wlen++;
1964  lab = (WCHAR *) malloc(sizeof(WCHAR)*wlen);
1965  wlen = fl_utf8toUtf16(w->label(), (unsigned) l, (unsigned short*)lab, wlen);
1966  lab[wlen] = 0;
1967  }
1968  x->xid = CreateWindowExW(
1969  styleEx,
1970  class_namew, lab, style,
1971  xp, yp, wp, hp,
1972  parent,
1973  NULL, // menu
1974  fl_display,
1975  NULL // creation parameters
1976  );
1977  if (lab) free(lab);
1978 
1979  x->next = Fl_X::first;
1980  Fl_X::first = x;
1981 
1982  x->set_icons();
1983 
1984  if (w->fullscreen_active()) {
1985  /* We need to make sure that the fullscreen is created on the
1986  default monitor, ie the desktop where the shortcut is located
1987  etc. This requires that CreateWindow is called with CW_USEDEFAULT
1988  for x and y. We can then use GetWindowRect to determine which
1989  monitor the window was placed on. */
1990  RECT rect;
1991  GetWindowRect(x->xid, &rect);
1992  x->make_fullscreen(rect.left, rect.top,
1993  rect.right - rect.left, rect.bottom - rect.top);
1994  }
1995 
1996  // Setup clipboard monitor target if there are registered handlers and
1997  // no window is targeted.
2000 
2001  x->wait_for_expose = 1;
2002  if (fl_show_iconic) {showit = 0; fl_show_iconic = 0;}
2003  if (showit) {
2004  w->set_visible();
2005  int old_event = Fl::e_number;
2006  w->handle(Fl::e_number = FL_SHOW); // get child windows to appear
2007  Fl::e_number = old_event;
2008  w->redraw(); // force draw to happen
2009  }
2010 
2011  // Needs to be done before ShowWindow() to get the correct behaviour
2012  // when we get WM_SETFOCUS.
2013  if (w->modal()) {Fl::modal_ = w; fl_fix_focus();}
2014 
2015  // If we've captured the mouse, we dont want to activate any
2016  // other windows from the code, or we lose the capture.
2017  ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
2018  (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
2019 
2020  // Register all windows for potential drag'n'drop operations
2021  RegisterDragDrop(x->xid, flIDropTarget);
2022 
2023  if (!im_enabled)
2024  flImmAssociateContextEx(x->xid, 0, 0);
2025 
2026  return x;
2027 }
2028 
2029 
2030 
2031 
2035 
2036 
2037 static LRESULT CALLBACK s_TimerProc(HWND hwnd, UINT msg,
2038  WPARAM wParam, LPARAM lParam)
2039 {
2040  switch (msg) {
2041  case WM_TIMER:
2042  {
2043  unsigned int id = (unsigned) (wParam - 1);
2044  if (id < (unsigned int)win32_timer_used && win32_timers[id].handle) {
2046  void* data = win32_timers[id].data;
2048  if (cb) {
2049  (*cb)(data);
2050  }
2051  }
2052  }
2053  return 0;
2054 
2055  default:
2056  break;
2057  }
2058 
2059  return DefWindowProc(hwnd, msg, wParam, lParam);
2060 }
2061 
2062 void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
2063 {
2064  repeat_timeout(time, cb, data);
2065 }
2066 
2067 void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data)
2068 {
2069  int timer_id = -1;
2070  for (int i = 0; i < win32_timer_used; ++i) {
2071  if ( !win32_timers[i].handle ) {
2072  timer_id = i;
2073  break;
2074  }
2075  }
2076  if (timer_id == -1) {
2078  realloc_timers();
2079  }
2080  timer_id = win32_timer_used++;
2081  }
2082  unsigned int elapsed = (unsigned int)(time * 1000);
2083 
2084  if ( !s_TimerWnd ) {
2085  const char* timer_class = "FLTimer";
2086  WNDCLASSEX wc;
2087  memset(&wc, 0, sizeof(wc));
2088  wc.cbSize = sizeof (wc);
2089  wc.style = CS_CLASSDC;
2090  wc.lpfnWndProc = (WNDPROC)s_TimerProc;
2091  wc.hInstance = fl_display;
2092  wc.lpszClassName = timer_class;
2093  /*ATOM atom =*/ RegisterClassEx(&wc);
2094  // create a zero size window to handle timer events
2095  s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW,
2096  timer_class, "",
2097  WS_POPUP,
2098  0, 0, 0, 0,
2099  NULL, NULL, fl_display, NULL);
2100  // just in case this OS won't let us create a 0x0 size window:
2101  if (!s_TimerWnd)
2102  s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW,
2103  timer_class, "",
2104  WS_POPUP,
2105  0, 0, 1, 1,
2106  NULL, NULL, fl_display, NULL);
2107  ShowWindow(s_TimerWnd, SW_SHOWNOACTIVATE);
2108  }
2109 
2110  win32_timers[timer_id].callback = cb;
2111  win32_timers[timer_id].data = data;
2112 
2113  win32_timers[timer_id].handle =
2114  SetTimer(s_TimerWnd, timer_id + 1, elapsed, NULL);
2115 }
2116 
2117 int Fl::has_timeout(Fl_Timeout_Handler cb, void* data)
2118 {
2119  for (int i = 0; i < win32_timer_used; ++i) {
2120  Win32Timer& t = win32_timers[i];
2121  if (t.handle && t.callback == cb && t.data == data) {
2122  return 1;
2123  }
2124  }
2125  return 0;
2126 }
2127 
2128 void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data)
2129 {
2130  int i;
2131  for (i = 0; i < win32_timer_used; ++i) {
2132  Win32Timer& t = win32_timers[i];
2133  if (t.handle && t.callback == cb &&
2134  (t.data == data || data == NULL)) {
2135  delete_timer(t);
2136  }
2137  }
2138 }
2139 
2142 
2143 
2144 
2146 
2147 HINSTANCE fl_display = GetModuleHandle(NULL);
2148 
2150  size_range_set = 1;
2151 }
2152 
2153 void Fl_X::set_minmax(LPMINMAXINFO minmax)
2154 {
2155  int td, wd, hd, dummy_x, dummy_y;
2156 
2157  fake_X_wm(w, dummy_x, dummy_y, td, wd, hd);
2158  wd *= 2;
2159  hd *= 2;
2160  hd += td;
2161 
2162  minmax->ptMinTrackSize.x = w->minw + wd;
2163  minmax->ptMinTrackSize.y = w->minh + hd;
2164  if (w->maxw) {
2165  minmax->ptMaxTrackSize.x = w->maxw + wd;
2166  minmax->ptMaxSize.x = w->maxw + wd;
2167  }
2168  if (w->maxh) {
2169  minmax->ptMaxTrackSize.y = w->maxh + hd;
2170  minmax->ptMaxSize.y = w->maxh + hd;
2171  }
2172 }
2173 
2175 
2176 #include <FL/filename.H> // need so FL_EXPORT fl_filename_name works
2177 
2178 // returns pointer to the filename, or null if name ends with '/'
2179 const char *fl_filename_name(const char *name) {
2180  const char *p,*q;
2181  if (!name) return (0);
2182  q = name;
2183  if (q[0] && q[1]==':') q += 2; // skip leading drive letter
2184  for (p = q; *p; p++) if (*p == '/' || *p == '\\') q = p+1;
2185  return q;
2186 }
2187 
2188 void Fl_Window::label(const char *name,const char *iname) {
2190  iconlabel_ = iname;
2191  if (shown() && !parent()) {
2192  if (!name) name = "";
2193  size_t l = strlen(name);
2194 // WCHAR *lab = (WCHAR*) malloc((l + 1) * sizeof(short));
2195 // l = fl_utf2unicode((unsigned char*)name, l, (xchar*)lab);
2196  unsigned wlen = fl_utf8toUtf16(name, (unsigned) l, NULL, 0); // Pass NULL to query length
2197  wlen++;
2198  unsigned short * lab = (unsigned short*)malloc(sizeof(unsigned short)*wlen);
2199  wlen = fl_utf8toUtf16(name, (unsigned) l, lab, wlen);
2200  lab[wlen] = 0;
2201  SetWindowTextW(i->xid, (WCHAR *)lab);
2202  free(lab);
2203  }
2204 }
2205 
2207 
2208 static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon,
2209  int hotx, int hoty) {
2210  BITMAPV5HEADER bi;
2211  HBITMAP bitmap, mask;
2212  DWORD *bits;
2213  HICON icon;
2214 
2215  if (!is_icon) {
2216  if ((hotx < 0) || (hotx >= image->w()))
2217  return NULL;
2218  if ((hoty < 0) || (hoty >= image->h()))
2219  return NULL;
2220  }
2221 
2222  memset(&bi, 0, sizeof(BITMAPV5HEADER));
2223 
2224  bi.bV5Size = sizeof(BITMAPV5HEADER);
2225  bi.bV5Width = image->w();
2226  bi.bV5Height = -image->h(); // Negative for top-down
2227  bi.bV5Planes = 1;
2228  bi.bV5BitCount = 32;
2229  bi.bV5Compression = BI_BITFIELDS;
2230  bi.bV5RedMask = 0x00FF0000;
2231  bi.bV5GreenMask = 0x0000FF00;
2232  bi.bV5BlueMask = 0x000000FF;
2233  bi.bV5AlphaMask = 0xFF000000;
2234 
2235  HDC hdc;
2236 
2237  hdc = GetDC(NULL);
2238  bitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
2239  ReleaseDC(NULL, hdc);
2240 
2241  if (bits == NULL)
2242  return NULL;
2243 
2244  const uchar *i = (const uchar*)*image->data();
2245  const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
2246 
2247  for (int y = 0; y < image->h(); y++) {
2248  for (int x = 0; x < image->w(); x++) {
2249  switch (image->d()) {
2250  case 1:
2251  *bits = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
2252  break;
2253  case 2:
2254  *bits = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
2255  break;
2256  case 3:
2257  *bits = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
2258  break;
2259  case 4:
2260  *bits = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
2261  break;
2262  }
2263  i += image->d();
2264  bits++;
2265  }
2266  i += extra_data;
2267  }
2268 
2269  // A mask bitmap is still needed even though it isn't used
2270  mask = CreateBitmap(image->w(),image->h(),1,1,NULL);
2271  if (mask == NULL) {
2272  DeleteObject(bitmap);
2273  return NULL;
2274  }
2275 
2276  ICONINFO ii;
2277 
2278  ii.fIcon = is_icon;
2279  ii.xHotspot = hotx;
2280  ii.yHotspot = hoty;
2281  ii.hbmMask = mask;
2282  ii.hbmColor = bitmap;
2283 
2284  icon = CreateIconIndirect(&ii);
2285 
2286  DeleteObject(bitmap);
2287  DeleteObject(mask);
2288 
2289  return icon;
2290 }
2291 
2293 
2294 static HICON default_big_icon = NULL;
2295 static HICON default_small_icon = NULL;
2296 
2297 static const Fl_RGB_Image *find_best_icon(int ideal_width,
2298  const Fl_RGB_Image *icons[],
2299  int count) {
2300  const Fl_RGB_Image *best;
2301 
2302  best = NULL;
2303 
2304  for (int i = 0;i < count;i++) {
2305  if (best == NULL)
2306  best = icons[i];
2307  else {
2308  if (best->w() < ideal_width) {
2309  if (icons[i]->w() > best->w())
2310  best = icons[i];
2311  } else {
2312  if ((icons[i]->w() >= ideal_width) &&
2313  (icons[i]->w() < best->w()))
2314  best = icons[i];
2315  }
2316  }
2317  }
2318 
2319  return best;
2320 }
2321 
2322 void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
2323  const Fl_RGB_Image *best_big, *best_small;
2324 
2325  if (default_big_icon != NULL)
2326  DestroyIcon(default_big_icon);
2327  if (default_small_icon != NULL)
2328  DestroyIcon(default_small_icon);
2329 
2332 
2333  best_big = find_best_icon(GetSystemMetrics(SM_CXICON), icons, count);
2334  best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON), icons, count);
2335 
2336  if (best_big != NULL)
2337  default_big_icon = image_to_icon(best_big, true, 0, 0);
2338 
2339  if (best_small != NULL)
2340  default_small_icon = image_to_icon(best_small, true, 0, 0);
2341 }
2342 
2343 void Fl_X::set_default_icons(HICON big_icon, HICON small_icon) {
2344  if (default_big_icon != NULL)
2345  DestroyIcon(default_big_icon);
2346  if (default_small_icon != NULL)
2347  DestroyIcon(default_small_icon);
2348 
2351 
2352  if (big_icon != NULL)
2353  default_big_icon = CopyIcon(big_icon);
2354  if (small_icon != NULL)
2355  default_small_icon = CopyIcon(small_icon);
2356 }
2357 
2358 void Fl_X::set_icons() {
2359  HICON big_icon, small_icon;
2360 
2361  // Windows doesn't copy the icons, so we have to "leak" them when
2362  // setting, and clean up when we change to some other icons.
2363  big_icon = (HICON)SendMessage(xid, WM_GETICON, ICON_BIG, 0);
2364  if ((big_icon != NULL) && (big_icon != default_big_icon))
2365  DestroyIcon(big_icon);
2366  small_icon = (HICON)SendMessage(xid, WM_GETICON, ICON_SMALL, 0);
2367  if ((small_icon != NULL) && (small_icon != default_small_icon))
2368  DestroyIcon(small_icon);
2369 
2370  big_icon = NULL;
2371  small_icon = NULL;
2372 
2373  if (w->icon_->count) {
2374  const Fl_RGB_Image *best_big, *best_small;
2375 
2376  best_big = find_best_icon(GetSystemMetrics(SM_CXICON),
2377  (const Fl_RGB_Image **)w->icon_->icons,
2378  w->icon_->count);
2379  best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON),
2380  (const Fl_RGB_Image **)w->icon_->icons,
2381  w->icon_->count);
2382 
2383  if (best_big != NULL)
2384  big_icon = image_to_icon(best_big, true, 0, 0);
2385  if (best_small != NULL)
2386  small_icon = image_to_icon(best_small, true, 0, 0);
2387  } else {
2388  if ((w->icon_->big_icon != NULL) || (w->icon_->small_icon != NULL)) {
2389  big_icon = w->icon_->big_icon;
2390  small_icon = w->icon_->small_icon;
2391  } else {
2392  big_icon = default_big_icon;
2393  small_icon = default_small_icon;
2394  }
2395  }
2396 
2397  SendMessage(xid, WM_SETICON, ICON_BIG, (LPARAM)big_icon);
2398  SendMessage(xid, WM_SETICON, ICON_SMALL, (LPARAM)small_icon);
2399 }
2400 
2420 void Fl_Window::default_icons(HICON big_icon, HICON small_icon) {
2421  Fl_X::set_default_icons(big_icon, small_icon);
2422 }
2423 
2441 void Fl_Window::icons(HICON big_icon, HICON small_icon) {
2442  free_icons();
2443 
2444  if (big_icon != NULL)
2445  icon_->big_icon = CopyIcon(big_icon);
2446  if (small_icon != NULL)
2447  icon_->small_icon = CopyIcon(small_icon);
2448 
2449  if (i)
2450  i->set_icons();
2451 }
2452 
2454 
2455 #ifndef IDC_HAND
2456 # define IDC_HAND MAKEINTRESOURCE(32649)
2457 #endif // !IDC_HAND
2458 
2459 int Fl_X::set_cursor(Fl_Cursor c) {
2460  LPSTR n;
2461  HCURSOR new_cursor;
2462 
2463  if (c == FL_CURSOR_NONE)
2464  new_cursor = NULL;
2465  else {
2466  switch (c) {
2467  case FL_CURSOR_ARROW: n = IDC_ARROW; break;
2468  case FL_CURSOR_CROSS: n = IDC_CROSS; break;
2469  case FL_CURSOR_WAIT: n = IDC_WAIT; break;
2470  case FL_CURSOR_INSERT: n = IDC_IBEAM; break;
2471  case FL_CURSOR_HAND: n = IDC_HAND; break;
2472  case FL_CURSOR_HELP: n = IDC_HELP; break;
2473  case FL_CURSOR_MOVE: n = IDC_SIZEALL; break;
2474  case FL_CURSOR_N:
2475  case FL_CURSOR_S:
2476  // FIXME: Should probably have fallbacks for these instead
2477  case FL_CURSOR_NS: n = IDC_SIZENS; break;
2478  case FL_CURSOR_NE:
2479  case FL_CURSOR_SW:
2480  // FIXME: Dito.
2481  case FL_CURSOR_NESW: n = IDC_SIZENESW; break;
2482  case FL_CURSOR_E:
2483  case FL_CURSOR_W:
2484  // FIXME: Dito.
2485  case FL_CURSOR_WE: n = IDC_SIZEWE; break;
2486  case FL_CURSOR_SE:
2487  case FL_CURSOR_NW:
2488  // FIXME: Dito.
2489  case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break;
2490  default:
2491  return 0;
2492  }
2493 
2494  new_cursor = LoadCursor(NULL, n);
2495  if (new_cursor == NULL)
2496  return 0;
2497  }
2498 
2499  if ((cursor != NULL) && custom_cursor)
2500  DestroyIcon(cursor);
2501 
2502  cursor = new_cursor;
2503  custom_cursor = 0;
2504 
2505  SetCursor(cursor);
2506 
2507  return 1;
2508 }
2509 
2510 int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
2511  HCURSOR new_cursor;
2512 
2513  new_cursor = image_to_icon(image, false, hotx, hoty);
2514  if (new_cursor == NULL)
2515  return 0;
2516 
2517  if ((cursor != NULL) && custom_cursor)
2518  DestroyIcon(cursor);
2519 
2520  cursor = new_cursor;
2521  custom_cursor = 1;
2522 
2523  SetCursor(cursor);
2524 
2525  return 1;
2526 }
2527 
2529 // Implement the virtual functions for the base Fl_Window class:
2530 
2531 // If the box is a filled rectangle, we can make the redisplay *look*
2532 // faster by using X's background pixel erasing. We can make it
2533 // actually *be* faster by drawing the frame only, this is done by
2534 // setting fl_boxcheat, which is seen by code in fl_drawbox.cxx:
2535 // For WIN32 it looks like all windows share a background color, so
2536 // I use FL_GRAY for this and only do this cheat for windows that are
2537 // that color.
2538 // Actually it is totally disabled.
2539 // Fl_Widget *fl_boxcheat;
2540 //static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);}
2541 
2544  if (Fl::scheme_bg_) {
2547  } else {
2549  }
2550  Fl_Tooltip::exit(this);
2551  if (!shown()) {
2552  // if (can_boxcheat(box())) fl_background_pixel = fl_xpixel(color());
2553  Fl_X::make(this);
2554  } else {
2555  // Once again, we would lose the capture if we activated the window.
2556  if (IsIconic(i->xid)) OpenIcon(i->xid);
2557  if (!fl_capture) BringWindowToTop(i->xid);
2558  //ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE);
2559  }
2560 #ifdef USE_PRINT_BUTTON
2561  void preparePrintFront(void);
2562  preparePrintFront();
2563 #endif
2564 }
2565 
2567 // the current context
2568 HDC fl_gc = 0;
2569 // the current window handle, initially set to -1 so we can correctly
2570 // allocate fl_GetDC(0)
2572 
2573 // Here we ensure only one GetDC is ever in place.
2574 HDC fl_GetDC(HWND w) {
2575  if (fl_gc) {
2576  if (w == fl_window && fl_window != NULL) return fl_gc;
2577  if (fl_window) fl_release_dc(fl_window, fl_gc); // ReleaseDC
2578  }
2579  fl_gc = GetDC(w);
2580  fl_save_dc(w, fl_gc);
2581  fl_window = w;
2582  // calling GetDC seems to always reset these: (?)
2583  SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT);
2584  SetBkMode(fl_gc, TRANSPARENT);
2585 
2586  return fl_gc;
2587 }
2588 
2589 // make X drawing go into this window (called by subclass flush() impl.)
2591  fl_GetDC(fl_xid(this));
2592 
2593 #if USE_COLORMAP
2594  // Windows maintains a hardware and software color palette; the
2595  // SelectPalette() call updates the current soft->hard mapping
2596  // for all drawing calls, so we must select it here before any
2597  // code does any drawing...
2598 
2599  fl_select_palette();
2600 #endif // USE_COLORMAP
2601 
2602  current_ = this;
2603  fl_clip_region(0);
2604 
2605 
2606 }
2607 
2608 /* Make sure that all allocated fonts are released. This works only if
2609  Fl::run() is allowed to exit by closing all windows. Calling 'exit(int)'
2610  will not automatically free any fonts. */
2611 void fl_free_fonts(void)
2612 {
2613 // remove the Fl_Font_Descriptor chains
2614  int i;
2615  Fl_Fontdesc * s;
2617  Fl_Font_Descriptor * ff;
2618  for (i=0; i<FL_FREE_FONT; i++) {
2619  s = fl_fonts + i;
2620  for (f=s->first; f; f=ff) {
2621  ff = f->next;
2622  delete f;
2623  s->first = ff;
2624  }
2625  }
2626 }
2627 
2628 
2630 //
2631 // The following routines help fix a problem with the leaking of Windows
2632 // Device Context (DC) objects. The 'proper' protocol is for a program to
2633 // acquire a DC, save its state, do the modifications needed for drawing,
2634 // perform the drawing, restore the initial state, and release the DC. In
2635 // FLTK, the save and restore steps have previously been omitted and DCs are
2636 // not properly released, leading to a great number of DC leaks. As some
2637 // Windows "OSs" will hang when any process exceeds roughly 10,000 GDI objects,
2638 // it is important to control GDI leaks, which are much more important than memory
2639 // leaks. The following struct, global variable, and routines help implement
2640 // the above protocol for those cases where the GetDC and RestoreDC are not in
2641 // the same routine. For each GetDC, fl_save_dc is used to create an entry in
2642 // a linked list that saves the window handle, the DC handle, and the initial
2643 // state. When the DC is to be released, 'fl_release_dc' is called. It restores
2644 // the initial state and releases the DC. When the program exits, 'fl_cleanup_dc_list'
2645 // frees any remaining nodes in the list.
2646 
2647 struct Win_DC_List { // linked list
2648  HWND window; // window handle
2649  HDC dc; // device context handle
2650  int saved_dc; // initial state of DC
2651  Win_DC_List * next; // pointer to next item
2652 };
2653 
2655 
2656 void fl_save_dc( HWND w, HDC dc) {
2657  Win_DC_List * t;
2658  t = new Win_DC_List;
2659  t->window = w;
2660  t->dc = dc;
2661  t->saved_dc = SaveDC(dc);
2662  if (win_DC_list)
2663  t->next = win_DC_list;
2664  else
2665  t->next = NULL;
2666  win_DC_list = t;
2667 }
2668 
2669 void fl_release_dc(HWND w, HDC dc) {
2670  Win_DC_List * t= win_DC_list;
2671  Win_DC_List * prev = 0;
2672  if (!t)
2673  return;
2674  do {
2675  if (t->dc == dc) {
2676  RestoreDC(dc, t->saved_dc);
2677  ReleaseDC(w, dc);
2678  if (!prev) {
2679  win_DC_list = t->next; // delete first item
2680  } else {
2681  prev->next = t->next; // one in the middle
2682  }
2683  delete (t);
2684  return;
2685  }
2686  prev = t;
2687  t = t->next;
2688  } while (t);
2689 }
2690 
2691 void fl_cleanup_dc_list(void) { // clean up the list
2692  Win_DC_List * t = win_DC_list;
2693  if (!t)return;
2694  do {
2695  RestoreDC(t->dc, t->saved_dc);
2696  ReleaseDC(t->window, t->dc);
2697  win_DC_list = t->next;
2698  delete (t);
2699  t = win_DC_list;
2700  } while(t);
2701 }
2702 
2703 Fl_Region XRectangleRegion(int x, int y, int w, int h) {
2704  if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) return CreateRectRgn(x,y,x+w,y+h);
2705  // because rotation may apply, the rectangle becomes a polygon in device coords
2706  POINT pt[4] = { {x, y}, {x + w, y}, {x + w, y + h}, {x, y + h} };
2707  LPtoDP(fl_gc, pt, 4);
2708  return CreatePolygonRgn(pt, 4, ALTERNATE);
2709 }
2710 
2712  Fl_X *temp = Fl_X::i(w);
2713  return temp ? temp->xid : 0;
2714 }
2715 
2716 static RECT border_width_title_bar_height(Fl_Window *win, int &bx, int &by, int &bt, float *pscaling=0)
2717 {
2718  RECT r = {0,0,0,0};
2719  bx = by = bt = 0;
2720  float scaling = 1;
2721  if (win->shown() && !win->parent() && win->border() && win->visible()) {
2722  static HMODULE dwmapi_dll = LoadLibrary("dwmapi.dll");
2723  typedef HRESULT (WINAPI* DwmGetWindowAttribute_type)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute);
2724  static DwmGetWindowAttribute_type DwmGetWindowAttribute = dwmapi_dll ?
2725  (DwmGetWindowAttribute_type)GetProcAddress(dwmapi_dll, "DwmGetWindowAttribute") : NULL;
2726  int need_r = 1;
2727  if (DwmGetWindowAttribute) {
2728  const DWORD DWMWA_EXTENDED_FRAME_BOUNDS = 9;
2729  if ( DwmGetWindowAttribute(fl_xid(win), DWMWA_EXTENDED_FRAME_BOUNDS, &r, sizeof(RECT)) == S_OK ) {
2730  need_r = 0;
2731  // Compute the global display scaling factor: 1, 1.25, 1.5, 1.75, etc...
2732  // This factor can be set in Windows 10 by
2733  // "Change the size of text, apps and other items" in display settings.
2734  HDC hdc = GetDC(NULL);
2735  int hr = GetDeviceCaps(hdc, HORZRES); // pixels visible to the app
2736 #ifndef DESKTOPHORZRES
2737 #define DESKTOPHORZRES 118
2738 #endif
2739  int dhr = GetDeviceCaps(hdc, DESKTOPHORZRES); // true number of pixels on display
2740  ReleaseDC(NULL, hdc);
2741  scaling = dhr/float(hr); // display scaling factor
2742  scaling = int(scaling * 100 + 0.5)/100.; // round to 2 digits after decimal point
2743  }
2744  }
2745  if (need_r) {
2746  GetWindowRect(fl_xid(win), &r);
2747  }
2748  bx = (r.right - r.left - int(win->w() * scaling))/2;
2749  if (bx < 1) bx = 1;
2750  by = bx;
2751  bt = r.bottom - r.top - int(win->h() * scaling) - 2 * by;
2752  }
2753  if (pscaling) *pscaling = scaling;
2754  return r;
2755 }
2756 
2758 {
2759  int bt, bx, by;
2760  border_width_title_bar_height(this, bx, by, bt);
2761  return w() + 2 * bx;
2762 }
2763 
2765 {
2766  int bt, bx, by;
2767  float scaling;
2768  border_width_title_bar_height(this, bx, by, bt, &scaling);
2769  return h() + bt/scaling + 2 * by;
2770 }
2771 
2772 void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
2773 {
2775 }
2776 
2777 void Fl_Paged_Device::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset)
2778 {
2779  int bt, bx, by; // border width and title bar height of window
2780  float scaling;
2781  RECT r = border_width_title_bar_height(win, bx, by, bt, &scaling);
2782  if (bt) {
2783  Fl_Display_Device::display_device()->set_current(); // make window current
2784  win->show();
2785  Fl::check();
2786  win->make_current();
2787  HDC save_gc = fl_gc;
2788  fl_gc = GetDC(NULL); // get the screen device context
2789  int ww = win->w() + 2 * bx;
2790  int wh = win->h() + bt + 2 * by;
2791  // capture the 4 window sides from screen
2792  Window save_win = fl_window;
2793  fl_window = NULL; // force use of read_win_rectangle() by fl_read_image()
2794  uchar *top_image = fl_read_image(NULL, r.left, r.top, r.right - r.left + 1, bt + by);
2795  uchar *left_image = bx ? fl_read_image(NULL, r.left, r.top, bx, wh) : NULL;
2796  uchar *right_image = bx ? fl_read_image(NULL, r.right - bx, r.top, bx, wh) : NULL;
2797  uchar *bottom_image = by ? fl_read_image(NULL, r.left, r.bottom-by, ww, by) : NULL;
2798  fl_window = save_win;
2799  ReleaseDC(NULL, fl_gc); fl_gc = save_gc;
2800  toset->set_current();
2801  // draw the 4 window sides
2802  //fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3);
2803  Fl_RGB_Image *top_r = new Fl_RGB_Image(top_image, r.right - r.left + 1, bt + by, 3);
2804  top_r->alloc_array = 1;
2805  if (scaling > 1) {
2808  Fl_RGB_Image *tmp_img = (Fl_RGB_Image*)top_r->copy(ww, (bt + by)/scaling);
2809  Fl_Image::RGB_scaling(current);
2810  delete top_r;
2811  top_r = tmp_img;
2812  }
2813  top_r->draw(x_offset, y_offset);
2814  delete top_r;
2815 
2816  if (left_image) { fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3); delete left_image; }
2817  if (right_image) { fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3); delete right_image; }
2818  if (bottom_image) { fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3); delete bottom_image; }
2819  }
2820  // draw the window inner part
2821  this->print_widget(win, x_offset + bx, y_offset + (bt + by)/scaling);
2822 }
2823 
2824 #ifdef USE_PRINT_BUTTON
2825 // to test the Fl_Printer class creating a "Print front window" button in a separate window
2826 // contains also preparePrintFront call above
2827 #include <FL/Fl_Printer.H>
2828 #include <FL/Fl_Button.H>
2829 void printFront(Fl_Widget *o, void *data)
2830 {
2831  Fl_Printer printer;
2832  o->window()->hide();
2833  Fl_Window *win = Fl::first_window();
2834  if(!win) return;
2835  int w, h;
2836  if( printer.start_job(1) ) { o->window()->show(); return; }
2837  if( printer.start_page() ) { o->window()->show(); return; }
2838  printer.printable_rect(&w,&h);
2839  int wh, ww;
2840  wh = win->decorated_h();
2841  ww = win->decorated_w();
2842  // scale the printer device so that the window fits on the page
2843  float scale = 1;
2844  if (ww > w || wh > h) {
2845  scale = (float)w/ww;
2846  if ((float)h/wh < scale) scale = (float)h/wh;
2847  printer.scale(scale, scale);
2848  }
2849 // #define ROTATE 20.0
2850 #ifdef ROTATE
2851  printer.scale(scale * 0.8, scale * 0.8);
2852  printer.printable_rect(&w, &h);
2853  printer.origin(w/2, h/2 );
2854  printer.rotate(ROTATE);
2855  printer.print_widget( win, - win->w()/2, - win->h()/2 );
2856  //printer.print_window_part( win, 0,0, win->w(), win->h(), - win->w()/2, - win->h()/2 );
2857 #else
2858  printer.print_window(win);
2859 #endif
2860  printer.end_page();
2861  printer.end_job();
2862  o->window()->show();
2863 }
2864 
2865 #include <FL/Fl_Copy_Surface.H>
2866 void copyFront(Fl_Widget *o, void *data)
2867 {
2868  o->window()->hide();
2869  Fl_Window *win = Fl::first_window();
2870  if (!win) return;
2871  Fl_Copy_Surface *surf = new Fl_Copy_Surface(win->decorated_w(), win->decorated_h());
2872  surf->set_current();
2873  surf->draw_decorated_window(win); // draw the window content
2874  delete surf; // put the window on the clipboard
2876  o->window()->show();
2877 }
2878 
2879 void preparePrintFront(void)
2880 {
2881  static BOOL first=TRUE;
2882  if(!first) return;
2883  first=FALSE;
2884  static Fl_Window w(0,0,120,60);
2885  static Fl_Button bp(0,0,w.w(),30, "Print front window");
2886  bp.callback(printFront);
2887  static Fl_Button bc(0,30,w.w(),30, "Copy front window");
2888  bc.callback(copyFront);
2889  w.end();
2890  w.show();
2891 }
2892 #endif // USE_PRINT_BUTTON
2893 
2894 #endif // FL_DOXYGEN
2895 
2896 //
2897 // End of "$Id$".
2898 //
xchar
#define xchar
Definition: fl_utf8.h:68
FL_Sleep
#define FL_Sleep
Definition: Enumerations.H:526
maxfd
static int maxfd
Definition: Fl_win32.cxx:255
NameList::NName
int NName
Definition: Fl_win32.cxx:1794
Fl_Image::d
void d(int D)
Definition: Fl_Image.H:84
Fl_Window::minw
int minw
Definition: Fl_Window.H:113
Lf2CrlfConvert::GetLength
int GetLength() const
Definition: Fl_win32.cxx:644
WndProc
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: Fl_win32.cxx:1127
FL_Up
#define FL_Up
The up arrow key.
Definition: Enumerations.H:481
FL_Shift_L
#define FL_Shift_L
The lefthand shift key.
Definition: Enumerations.H:497
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
Lf2CrlfConvert::out
char * out
Definition: Fl_win32.cxx:611
Fl_Widget::y
int y() const
Definition: Fl_Widget.H:289
Fl_Group::resizable
Fl_Widget * resizable() const
Definition: Fl_Group.H:152
FL_Enter
#define FL_Enter
The enter key.
Definition: Enumerations.H:471
win32_at_exit
static Fl_Win32_At_Exit win32_at_exit
Definition: Fl_win32.cxx:525
s_TimerProc
static LRESULT CALLBACK s_TimerProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: Fl_win32.cxx:2037
fl_selection_buffer_length
int fl_selection_buffer_length[2]
Definition: Fl_win32.cxx:599
FL_Mail
#define FL_Mail
Definition: Enumerations.H:520
Fl.H
buf
static char * buf
Definition: fl_encoding_mac_roman.cxx:76
thread_message_
static void * thread_message_
Definition: Fl_win32.cxx:353
FL_CURSOR_NWSE
Definition: Enumerations.H:1061
Fl::e_y
static int e_y
Definition: Fl.H:145
Fl_Widget::align
Fl_Align align() const
Definition: Fl_Widget.H:348
fl_rectf
void fl_rectf(int x, int y, int w, int h)
Definition: fl_draw.H:206
FL_CLOSE
Definition: Enumerations.H:327
fl_wake_msg
UINT fl_wake_msg
Definition: Fl_win32.cxx:1801
FL_NO_LABEL
does nothing
Definition: Enumerations.H:765
vk
unsigned short vk
Definition: Fl_win32.cxx:998
Fl_Window::show
virtual void show()
Definition: Fl_win32.cxx:2542
FL_HIDE
Definition: Enumerations.H:369
s_wsock_select
static fl_wsk_select_f s_wsock_select
Definition: Fl_win32.cxx:119
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
flImmReleaseContext
static flTypeImmReleaseContext flImmReleaseContext
Definition: Fl_win32.cxx:150
Fl_Window::modal
unsigned int modal() const
Definition: Fl_Window.H:291
fl_open_display
void fl_open_display()
Definition: Fl_win32.cxx:496
fl_utf8toUtf16
unsigned fl_utf8toUtf16(const char *src, unsigned srclen, unsigned short *dst, unsigned dstlen)
Definition: fl_utf.c:432
FL_Volume_Down
#define FL_Volume_Down
Definition: Enumerations.H:512
flImmAssociateContextEx
static flTypeImmAssociateContextEx flImmAssociateContextEx
Definition: Fl_win32.cxx:144
IDC_HAND
#define IDC_HAND
Definition: Fl_win32.cxx:2456
Fl_Win32_At_Exit::~Fl_Win32_At_Exit
~Fl_Win32_At_Exit()
Definition: Fl_win32.cxx:512
Fl_Image::data
void data(const char *const *p, int c)
Definition: Fl_Image.H:100
FL_UNFOCUS
Definition: Enumerations.H:288
vktab
static const struct @45 vktab[]
Fl::thread_message
static void * thread_message()
Definition: Fl_lock.cxx:410
Fl::fatal
static void(* fatal)(const char *,...)
Definition: Fl.H:530
Fl_Image::h
void h(int H)
Definition: Fl_Image.H:80
border_width_title_bar_height
static RECT border_width_title_bar_height(Fl_Window *win, int &bx, int &by, int &bt, float *pscaling=0)
Definition: Fl_win32.cxx:2716
Fl_Fontdesc
Definition: Fl_Font.H:86
FD::events
short events
Definition: Fl_win32.cxx:264
Win_DC_List::next
Win_DC_List * next
Definition: Fl_win32.cxx:2651
Lf2CrlfConvert::Lf2CrlfConvert
Lf2CrlfConvert(const char *in, int inlen)
Definition: Fl_win32.cxx:614
get_wsock_mod
static HMODULE get_wsock_mod()
Definition: Fl_win32.cxx:124
FL_Media_Next
#define FL_Media_Next
Definition: Enumerations.H:518
realloc_timers
static void realloc_timers()
Definition: Fl_win32.cxx:1099
Fl::e_state
static int e_state
Definition: Fl.H:150
FL_WHITE
const Fl_Color FL_WHITE
Definition: Enumerations.H:971
Fl_Window::icon_data::count
int count
Definition: Fl_Window.H:102
fl_set_spot
void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
Definition: Fl_win32.cxx:275
Fl_Window::fullscreen_active
unsigned int fullscreen_active() const
Definition: Fl_Window.H:567
fdsets
static fd_set fdsets[3]
Definition: Fl_win32.cxx:256
mouse_event
static int mouse_event(Fl_Window *window, int what, int button, WPARAM wParam, LPARAM lParam)
Definition: Fl_win32.cxx:933
Fl::e_clipboard_data
static void * e_clipboard_data
Definition: Fl.H:156
fl_save_pen
void fl_save_pen(void)
Definition: fl_color_win32.cxx:52
fl_i_own_selection
char fl_i_own_selection[2]
Definition: Fl_win32.cxx:600
fl_selection_length
int fl_selection_length[2]
Definition: Fl_win32.cxx:598
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
s_TimerWnd
static HWND s_TimerWnd
Definition: Fl_win32.cxx:1097
fl_color
void fl_color(Fl_Color c)
Definition: fl_draw.H:52
state
int state
Definition: Fl_Text_Editor.cxx:92
fl_get_codepage
void fl_get_codepage()
Definition: Fl_win32.cxx:921
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_Widget::window
Fl_Window * window() const
Definition: Fl_Window.cxx:118
fl_display
HINSTANCE fl_display
END TIMERS.
Definition: Fl_win32.cxx:2147
Fl::e_text
static char * e_text
Definition: Fl.H:154
FL_SHIFT
#define FL_SHIFT
One of the shift keys is down.
Definition: Enumerations.H:557
FL_Page_Down
#define FL_Page_Down
The page-down key.
Definition: Enumerations.H:485
Fl_RGB_Scaling
Fl_RGB_Scaling
Definition: Fl_Image.H:37
Fl::idle
static void(* idle)()
Definition: Fl.H:253
Fl_Surface_Device
Definition: Fl_Device.H:556
Fl::e_y_root
static int e_y_root
Definition: Fl.H:147
find_best_icon
static const Fl_RGB_Image * find_best_icon(int ideal_width, const Fl_RGB_Image *icons[], int count)
Definition: Fl_win32.cxx:2297
filename.H
fl_wait
int fl_wait(double time_to_wait)
Definition: Fl_win32.cxx:379
Fl_Widget::_clear_fullscreen
void _clear_fullscreen()
Definition: Fl_Widget.H:883
FL_Volume_Mute
#define FL_Volume_Mute
Definition: Enumerations.H:513
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
process_awake_handler_requests
static void process_awake_handler_requests(void)
Definition: Fl_win32.cxx:366
free
void free()
H
static int H
Definition: Fl_Tooltip.cxx:76
FL_CURSOR_NESW
Definition: Enumerations.H:1062
Lf2CrlfConvert::~Lf2CrlfConvert
~Lf2CrlfConvert()
Definition: Fl_win32.cxx:641
Fl::has_timeout
static int has_timeout(Fl_Timeout_Handler, void *=0)
Definition: Fl.cxx:355
fl_restore_pen
void fl_restore_pen(void)
Definition: fl_color_win32.cxx:57
Fl::modal_
static Fl_Window * modal_
Definition: Fl.H:164
FL_KP_Enter
#define FL_KP_Enter
The enter key on the keypad, same as Fl_KP+'\r'.
Definition: Enumerations.H:493
Fl::paste
static void paste(Fl_Widget &receiver, int source, const char *type)
Definition: Fl_win32.cxx:704
Fl_Window::minh
int minh
Definition: Fl_Window.H:113
fl_lock_function
void(* fl_lock_function)()
Definition: Fl_win32.cxx:350
Win32Timer::data
void * data
Definition: Fl_win32.cxx:1092
Fl_Window::border
unsigned int border() const
Definition: Fl_Window.H:276
resize_bug_fix
static Fl_Window * resize_bug_fix
END TIMERS.
Definition: Fl_win32.cxx:1122
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
Win32Timer
Definition: Fl_win32.cxx:1088
FL_Forward
#define FL_Forward
Definition: Enumerations.H:523
FL_PASTE
Definition: Enumerations.H:383
FL_CURSOR_NS
Definition: Enumerations.H:1059
fl_utf8fromwc
unsigned fl_utf8fromwc(char *dst, unsigned dstlen, const wchar_t *src, unsigned srclen)
Definition: fl_utf.c:617
Fl::e_number
static int e_number
Definition: Fl.H:143
Win_DC_List::window
HWND window
Definition: Fl_win32.cxx:2648
Fl_Win32_At_Exit
Definition: Fl_win32.cxx:509
Fl::screen_num
static int screen_num(int x, int y)
Definition: screen_xywh.cxx:380
FL_CURSOR_MOVE
Definition: Enumerations.H:1056
Fl::clipboard_plain_text
static const char *const clipboard_plain_text
Definition: Fl.H:956
Fl::clipboard_contains
static int clipboard_contains(const char *type)
Definition: Fl_win32.cxx:837
NameList::name
char ** name
Definition: Fl_win32.cxx:1793
FL_LEAVE
Definition: Enumerations.H:259
nothing
static void nothing()
Definition: Fl_win32.cxx:349
Fl_Image::w
void w(int W)
Definition: Fl_Image.H:76
Fl_Widget::labeltype
Fl_Labeltype labeltype() const
Definition: Fl_Widget.H:456
fl_unlock_function
void(* fl_unlock_function)()
Definition: Fl_win32.cxx:351
flImmGetContext
static flTypeImmGetContext flImmGetContext
Definition: Fl_win32.cxx:146
fl_cleanup_pens
void fl_cleanup_pens(void)
Definition: fl_color_win32.cxx:46
FL_SCREEN_CONFIGURATION_CHANGED
Definition: Enumerations.H:421
default_small_icon
static HICON default_small_icon
Definition: Fl_win32.cxx:2295
FL_Back
#define FL_Back
Definition: Enumerations.H:522
b
long b
Definition: jpegint.h:397
fl_clipboard_notify_untarget
static void fl_clipboard_notify_untarget(HWND wnd)
Definition: Fl_win32.cxx:863
win_DC_list
static Win_DC_List * win_DC_list
Definition: Fl_win32.cxx:2654
clipboard_wnd
static HWND clipboard_wnd
Definition: Fl_win32.cxx:95
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
bi
static int bi
Definition: fl_draw_image.cxx:68
fl_clipboard_notify_retarget
void fl_clipboard_notify_retarget(HWND wnd)
Definition: Fl_win32.cxx:894
icon
static Fl_Box * icon
Definition: fl_ask.cxx:48
FL_Print
#define FL_Print
The print (or print-screen) key.
Definition: Enumerations.H:487
Win_DC_List::dc
HDC dc
Definition: Fl_win32.cxx:2649
Fl_Awake_Handler
void(* Fl_Awake_Handler)(void *data)
Definition: Fl.H:95
flImmSetCompositionWindow
static flTypeImmSetCompositionWindow flImmSetCompositionWindow
Definition: Fl_win32.cxx:148
Fl_Display_Device::display_device
static Fl_Display_Device * display_device()
Definition: Fl_Device.cxx:83
get_imm_module
static void get_imm_module()
Definition: Fl_win32.cxx:152
Fl::h
static int h()
Definition: Fl_win32.cxx:571
s_imm_module
static HMODULE s_imm_module
Definition: Fl_win32.cxx:142
WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL
FL_Page_Up
#define FL_Page_Up
The page-up key.
Definition: Enumerations.H:484
Fl_Printer::scale
void scale(float scale_x, float scale_y=0.)
Changes the scaling of page coordinates.
Definition: Fl_Printer.cxx:143
fd_array_size
static int fd_array_size
Definition: Fl_win32.cxx:261
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
WM_SYNCPAINT
#define WM_SYNCPAINT
Definition: Fl_win32.cxx:210
Fl::e_clipboard_type
static const char * e_clipboard_type
Definition: Fl.H:157
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
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
Fl_Window::force_position
int force_position() const
Definition: Fl_Window.H:193
FD::arg
void * arg
Definition: Fl_win32.cxx:266
Fl::belowmouse
static Fl_Widget * belowmouse()
Definition: Fl.H:833
Fl::e_clicks
static int e_clicks
Definition: Fl.H:151
Fl_Window.H
FL_CAPS_LOCK
#define FL_CAPS_LOCK
The caps lock is on.
Definition: Enumerations.H:558
fl_selection_buffer
char * fl_selection_buffer[2]
Definition: Fl_win32.cxx:597
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
fltk
unsigned short fltk
Definition: Fl_win32.cxx:998
FL_CURSOR_INSERT
Definition: Enumerations.H:1053
XRectangleRegion
Fl_Region XRectangleRegion(int x, int y, int w, int h)
Definition: Fl_win32.cxx:2703
Fl_Window::xclass
const char * xclass() const
Definition: Fl_Window.cxx:287
button
static Fl_Button * button[3]
Definition: fl_ask.cxx:49
FL_End
#define FL_End
The end key.
Definition: Enumerations.H:486
FL_Meta_R
#define FL_Meta_R
The right meta/Windows key.
Definition: Enumerations.H:503
NameList::NameList
NameList()
Definition: Fl_win32.cxx:1772
Fl_Widget::_set_fullscreen
void _set_fullscreen()
Definition: Fl_Widget.H:882
Fl::check
static int check()
Definition: Fl.cxx:688
NameList::add_name
void add_name(const char *n)
Definition: Fl_win32.cxx:1778
delete_timer
static void delete_timer(Win32Timer &t)
Definition: Fl_win32.cxx:1113
initial_clipboard
static bool initial_clipboard
Definition: Fl_win32.cxx:98
p
static menustate * p
Definition: Fl_Menu.cxx:606
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_get_lcid_codepage
UINT fl_get_lcid_codepage(LCID id)
Definition: Fl_win32.cxx:602
fl_find
Fl_Window * fl_find(Window xid)
Definition: Fl.cxx:730
win32_timer_alloc
static int win32_timer_alloc
Definition: Fl_win32.cxx:1095
FL_Right
#define FL_Right
The right arrow key.
Definition: Enumerations.H:482
win32_timer_used
static int win32_timer_used
Definition: Fl_win32.cxx:1096
FL_FREE_FONT
const Fl_Font FL_FREE_FONT
first one to allocate
Definition: Enumerations.H:896
Fl_Printer::end_page
int end_page(void)
To be called at the end of each page.
Definition: Fl_Printer.cxx:163
flTypeImmReleaseContext
BOOL(WINAPI * flTypeImmReleaseContext)(HWND, HIMC)
Definition: Fl_win32.cxx:149
TRUE
Definition: jmorecfg.h:317
Fl_Widget::x
void x(int v)
Definition: Fl_Widget.H:139
FL_Alt_R
#define FL_Alt_R
The right alt key.
Definition: Enumerations.H:505
FL_BUTTON2
#define FL_BUTTON2
Mouse button 2 is pushed.
Definition: Enumerations.H:568
fl_window
HWND fl_window
Definition: Fl_win32.cxx:2571
fl_msg
MSG fl_msg
Definition: Fl_win32.cxx:362
Fl_RGB_Image::alloc_array
int alloc_array
Definition: Fl_Image.H:215
FL_Tab
#define FL_Tab
The tab key.
Definition: Enumerations.H:469
fl_save_dc
void fl_save_dc(HWND w, HDC dc)
Definition: Fl_win32.cxx:2656
fl_utf8.h
header for Unicode and UTF-8 character handling
FL_ALT
#define FL_ALT
One of the alt keys is down.
Definition: Enumerations.H:560
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
ms2fltk
static int ms2fltk(WPARAM vk, int extended)
Definition: Fl_win32.cxx:1062
FL_WRITE
Definition: Enumerations.H:1079
FD::fd
int fd
Definition: Fl_win32.cxx:263
fl_draw.H
utility header to pull drawing functions together
FL_Control_R
#define FL_Control_R
The righthand control key.
Definition: Enumerations.H:500
Fl_Widget::flags
unsigned int flags() const
Definition: Fl_Widget.H:147
fl_filename_name
const char * fl_filename_name(const char *name)
Definition: Fl_win32.cxx:2179
flTypeImmSetCompositionWindow
BOOL(WINAPI * flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM)
Definition: Fl_win32.cxx:147
Fl_Window::decorated_h
int decorated_h()
Definition: Fl_win32.cxx:2764
arg
static int arg(int argc, char **argv, int &i)
Definition: fluid.cxx:1723
Fl_Window::non_modal
unsigned int non_modal() const
Definition: Fl_Window.H:300
NameList::has_name
char has_name(const char *n)
Definition: Fl_win32.cxx:1785
Fl::e_keysym
static int e_keysym
Definition: Fl.H:153
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
FL_Media_Stop
#define FL_Media_Stop
Definition: Enumerations.H:516
id
Definition: code.cxx:47
fl_free_fonts
void fl_free_fonts(void)
Definition: Fl_win32.cxx:2611
FL_FOCUS
Definition: Enumerations.H:283
Fl::e_dy
static int e_dy
Definition: Fl.H:149
Fl_Surface_Device::surface
static Fl_Surface_Device * surface()
Definition: Fl_Device.H:574
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_Window::resize
virtual void resize(int X, int Y, int W, int H)
Definition: Fl_win32.cxx:1643
Fl_RGB_Image::copy
virtual Fl_Image * copy(int W, int H)
Definition: Fl_Image.cxx:346
fl_gc
HDC fl_gc
Definition: Fl_win32.cxx:2568
FL_KP_Last
#define FL_KP_Last
The last keypad key; use to range-check keypad.
Definition: Enumerations.H:494
NameList::~NameList
~NameList()
Definition: Fl_win32.cxx:1773
in_idle
static char in_idle
Definition: Fl.cxx:488
DESKTOPHORZRES
#define DESKTOPHORZRES
FL_NUM_LOCK
#define FL_NUM_LOCK
The num lock is on.
Definition: Enumerations.H:561
FL_Pause
#define FL_Pause
The pause key.
Definition: Enumerations.H:472
ulong
unsigned long ulong
Definition: fl_types.h:32
FL_CURSOR_N
Definition: Enumerations.H:1063
Win32Timer::callback
Fl_Timeout_Handler callback
Definition: Fl_win32.cxx:1091
fl_clipboard_notify_target
static void fl_clipboard_notify_target(HWND wnd)
Definition: Fl_win32.cxx:851
FL_PUSH
Definition: Enumerations.H:236
Fl_Widget::damage
uchar damage() const
Definition: Fl_Widget.H:917
Win_DC_List
Definition: Fl_win32.cxx:2647
FL_BUTTON3
#define FL_BUTTON3
Mouse button 3 is pushed.
Definition: Enumerations.H:569
fl_set_status
void fl_set_status(int x, int y, int w, int h)
Definition: Fl_win32.cxx:297
cb
static void cb(Fl_Widget *, void *v)
Definition: factory.cxx:937
Fl::remove_timeout
static void remove_timeout(Fl_Timeout_Handler, void *=0)
Definition: Fl.cxx:368
next_clipboard_wnd
static HWND next_clipboard_wnd
Definition: Fl_win32.cxx:96
Fl_Image::RGB_scaling
static Fl_RGB_Scaling RGB_scaling()
Definition: Fl_Image.cxx:226
WM_MOUSEWHEEL
#define WM_MOUSEWHEEL
Definition: Fl_win32.cxx:218
Fl_Window::icon
void icon(const Fl_RGB_Image *)
Definition: Fl_Window.cxx:352
Fl_Window::icons
void icons(const Fl_RGB_Image *[], int)
Definition: Fl_win32.cxx:2441
FL_Volume_Up
#define FL_Volume_Up
Definition: Enumerations.H:514
fl_brush_action
FL_EXPORT HBRUSH fl_brush_action(int)
Definition: fl_color_win32.cxx:126
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_Region
struct flCocoaRegion * Fl_Region
Definition: mac.H:38
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
nfds
static int nfds
Definition: Fl_win32.cxx:260
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
fl_xid_
FL_EXPORT Window fl_xid_(const Fl_Window *w)
Definition: Fl_win32.cxx:2711
fl_wsk_fd_is_set_f
int(WINAPI * fl_wsk_fd_is_set_f)(SOCKET, fd_set *)
Definition: Fl_win32.cxx:112
Fl_Printer::start_job
int start_job(int pagecount, int *frompage=NULL, int *topage=NULL)
Definition: Fl_Printer.cxx:113
fl_clipboard_notify_change
void fl_clipboard_notify_change()
Definition: Fl_win32.cxx:907
win32_timers
static Win32Timer * win32_timers
Definition: Fl_win32.cxx:1094
Fl_RGB_Image::draw
virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0)
Definition: Fl_Image.cxx:651
fl_delete_offscreen
void fl_delete_offscreen(Fl_Offscreen gWorld)
fd
static struct FD * fd
fl_reset_spot
void fl_reset_spot()
Definition: Fl_win32.cxx:271
Fl_Widget::h
int h() const
Definition: Fl_Widget.H:299
Fl_Window::shown
int shown()
Definition: Fl_Window.H:485
FL_KEYBOARD
Definition: Enumerations.H:315
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
run_checks
static void run_checks()
Definition: Fl.cxx:473
Fl_Window::hide
virtual void hide()
Definition: Fl.cxx:1546
Fl::e_dx
static int e_dx
Definition: Fl.H:148
Fl_Fontdesc::first
Fl_Font_Descriptor * first
Definition: Fl_Font.H:89
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_Widget::label
const char * label() const
Definition: Fl_Widget.H:421
BI_BITFIELDS
#define BI_BITFIELDS
Definition: Fl_BMP_Image.cxx:44
FL_Home_Page
#define FL_Home_Page
Definition: Enumerations.H:519
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
func
Fl_Text_Editor::Key_Func func
Definition: Fl_Text_Editor.cxx:93
fl_update_clipboard
void fl_update_clipboard(void)
Definition: Fl_win32.cxx:648
flTypeImmGetContext
HIMC(WINAPI * flTypeImmGetContext)(HWND)
Definition: Fl_win32.cxx:145
Fl_Copy_Surface.H
WM_MOUSELEAVE
#define WM_MOUSELEAVE
Definition: Fl_win32.cxx:214
Fl_Window::iconlabel_
const char * iconlabel_
Definition: Fl_Window.H:109
Fl_Window::label
const char * label() const
Definition: Fl_Window.H:450
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
fl_cleanup_dc_list
void fl_cleanup_dc_list(void)
Definition: Fl_win32.cxx:2691
im_enabled
static char im_enabled
Definition: Fl_win32.cxx:527
track_mouse_win
static Fl_Window * track_mouse_win
Definition: Fl_win32.cxx:190
fl_begin_offscreen
void fl_begin_offscreen(Fl_Offscreen gWorld)
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_clip_region
void fl_clip_region(Fl_Region r)
Definition: fl_draw.H:136
Fl_Widget::size
void size(int W, int H)
Definition: Fl_Widget.H:341
FL_Control_L
#define FL_Control_L
The lefthand control key.
Definition: Enumerations.H:499
fl_release_dc
void fl_release_dc(HWND w, HDC dc)
Definition: Fl_win32.cxx:2669
Lf2CrlfConvert::GetValue
const char * GetValue() const
Definition: Fl_win32.cxx:645
x
int x
Definition: test.c:73
FL_Scroll_Lock
#define FL_Scroll_Lock
The scroll lock key.
Definition: Enumerations.H:473
Fl_Widget::callback
Fl_Callback_p callback() const
Definition: Fl_Widget.H:561
FL_Search
#define FL_Search
Definition: Enumerations.H:521
Fl_Widget::visible_r
int visible_r() const
Definition: Fl_Widget.cxx:295
FL_Shift_R
#define FL_Shift_R
The righthand shift key.
Definition: Enumerations.H:498
WHEEL_DELTA
#define WHEEL_DELTA
Definition: Fl_win32.cxx:222
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::flush
static void flush()
Definition: Fl.cxx:797
Fl_Widget::clear_damage
void clear_damage(uchar c=0)
Definition: Fl_Widget.H:931
FL_SCROLL_LOCK
#define FL_SCROLL_LOCK
The scroll lock is on.
Definition: Enumerations.H:565
Fl_Printer::start_page
int start_page(void)
Starts a new printed page.
Definition: Fl_Printer.cxx:118
fl_ready
int fl_ready()
Definition: Fl_win32.cxx:485
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
s_wsock_mod
static HMODULE s_wsock_mod
Definition: Fl_win32.cxx:118
FL_RGB_SCALING_BILINEAR
more accurate, but slower RGB image scaling algorithm
Definition: Fl_Image.H:39
Fl::disable_im
static void disable_im()
Definition: Fl_win32.cxx:541
FL_CURSOR_NONE
Definition: Enumerations.H:1072
FL_Favorites
#define FL_Favorites
Definition: Enumerations.H:527
Fl_Tooltip::exit
static void(* exit)(Fl_Widget *w)
Definition: Fl_Tooltip.H:60
FALSE
Definition: jmorecfg.h:317
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
Fl::y
static int y()
Definition: Fl_win32.cxx:563
FL_CURSOR_S
Definition: Enumerations.H:1067
Fl::enable_im
static void enable_im()
Definition: Fl_win32.cxx:529
dy
uchar dy
Definition: fl_boxtype.cxx:286
Fl::get_awake_handler_
static int get_awake_handler_(Fl_Awake_Handler &, void *&)
Definition: Fl_lock.cxx:106
fake_X_wm_style
static int fake_X_wm_style(const Fl_Window *w, int &X, int &Y, int &bt, int &bx, int &by, DWORD style, DWORD styleEx, int w_maxw, int w_minw, int w_maxh, int w_minh, uchar w_size_range_set)
Definition: Fl_win32.cxx:1533
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
fl_wsk_fd_is_set
static fl_wsk_fd_is_set_f fl_wsk_fd_is_set
Definition: Fl_win32.cxx:113
FL_NORMAL_LABEL
draws the text (0)
Definition: Enumerations.H:764
WSCK_DLL_NAME
#define WSCK_DLL_NAME
Definition: Fl_win32.cxx:106
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
set_cursor
static void set_cursor(Fl_Tile *t, Fl_Cursor c)
Definition: Fl_Tile.cxx:178
FL_EXCEPT
Definition: Enumerations.H:1080
FD
Definition: Fl_win32.cxx:262
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_Iso_Key
#define FL_Iso_Key
The additional key of ISO keyboards.
Definition: Enumerations.H:470
fl_GetDC
HDC fl_GetDC(HWND w)
Definition: Fl_win32.cxx:2574
Fl::e_x
static int e_x
Definition: Fl.H:144
fl_wsk_select_f
int(WINAPI * fl_wsk_select_f)(int, fd_set *, fd_set *, fd_set *, const struct timeval *)
Definition: Fl_win32.cxx:116
fl_end_offscreen
void fl_end_offscreen()
Fl_Window::maxh
int maxh
Definition: Fl_Window.H:113
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_disable_transient_for
int fl_disable_transient_for
Definition: Fl_win32.cxx:1802
FL_READ
Definition: Enumerations.H:1078
fl_fix_focus
void fl_fix_focus()
Definition: Fl.cxx:1087
FL_Num_Lock
#define FL_Num_Lock
The num lock key.
Definition: Enumerations.H:491
f
Fl_Box_Draw_F * f
Definition: fl_boxtype.cxx:285
Fl_Widget::parent
Fl_Group * parent() const
Definition: Fl_Widget.H:254
Fl_Offscreen
CGContextRef Fl_Offscreen
Definition: mac.H:45
malloc
voidp malloc()
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_Alt_L
#define FL_Alt_L
The left alt key.
Definition: Enumerations.H:504
fl_create_offscreen
Fl_Offscreen fl_create_offscreen(int w, int h)
Win_DC_List::saved_dc
int saved_dc
Definition: Fl_win32.cxx:2650
Fl::scheme_bg_
static Fl_Image * scheme_bg_
Definition: Fl.H:262
Fl_Cursor
Fl_Cursor
Definition: Enumerations.H:1048
Fl_Window::free_icons
void free_icons()
Definition: Fl_Window.cxx:413
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
SM_CXPADDEDBORDER
#define SM_CXPADDEDBORDER
Definition: Fl_win32.cxx:226
Fl_Timeout_Handler
void(* Fl_Timeout_Handler)(void *data)
Definition: Fl.H:92
Fl_Paged_Device.H
declaration of class Fl_Paged_Device.
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
Fl::compose_state
static int compose_state
Definition: Fl.H:166
Fl_Window::i
Fl_X * i
Definition: Fl_Window.H:97
Fl::awake_ring_head_
static int awake_ring_head_
Definition: Fl.H:259
Fl_Window::default_icons
static void default_icons(const Fl_RGB_Image *[], int)
Definition: Fl_win32.cxx:2420
Fl::get_mouse
static void get_mouse(int &, int &)
Definition: Fl_win32.cxx:587
Fl_Window::maxw
int maxw
Definition: Fl_Window.H:113
Fl_Image::ld
void ld(int LD)
Definition: Fl_Image.H:96
NameList
Definition: Fl_win32.cxx:1770
Fl_Win32_At_Exit::Fl_Win32_At_Exit
Fl_Win32_At_Exit()
Definition: Fl_win32.cxx:511
px
static int px
Definition: fl_overlay.cxx:32
FL_Insert
#define FL_Insert
The insert key.
Definition: Enumerations.H:488
fl_fonts
FL_EXPORT Fl_Fontdesc * fl_fonts
Definition: fl_font_mac.cxx:22
Fl_Printer
OS-independent print support.
Definition: Fl_Printer.H:176
rect
void rect(int x, int y, int r, int t)
Definition: gl2opengl.h:30
Fl_Paged_Device::print_window
void print_window(Fl_Window *win, int x_offset=0, int y_offset=0)
Definition: Fl_win32.cxx:2772
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_trigger_clipboard_notify
void fl_trigger_clipboard_notify(int source)
Definition: Fl.cxx:544
FL_DOUBLE_WINDOW
#define FL_DOUBLE_WINDOW
double window type id
Definition: Fl_Window.H:34
Fl::w
static int w()
Definition: Fl_win32.cxx:579
Fl::awake_ring_tail_
static int awake_ring_tail_
Definition: Fl.H:260
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
Fl::damage
static int damage()
Definition: Fl.H:475
FL_RELEASE
Definition: Enumerations.H:244
BI_RGB
#define BI_RGB
Definition: Fl_BMP_Image.cxx:41
Fl_Widget::labelsize
Fl_Fontsize labelsize() const
Definition: Fl_Widget.H:502
extended
unsigned short extended
Definition: Fl_win32.cxx:998
image_to_icon
static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon, int hotx, int hoty)
Definition: Fl_win32.cxx:2208
flIDropTarget
IDropTarget * flIDropTarget
Definition: fl_dnd_win32.cxx:317
FL_CURSOR_NE
Definition: Enumerations.H:1064
FL_Caps_Lock
#define FL_Caps_Lock
The caps lock key.
Definition: Enumerations.H:501
FD::cb
void(* cb)(FL_SOCKET, void *)
Definition: Fl_win32.cxx:265
uchar
unsigned char uchar
Definition: fl_types.h:30
py
static int py
Definition: fl_overlay.cxx:32
name
static const char * name
Definition: Fl_arg.cxx:53
FL_CTRL
#define FL_CTRL
One of the ctrl keys is down.
Definition: Enumerations.H:559
Fl_RGB_Image
Definition: Fl_Image.H:202
fl_capture
HWND fl_capture
Definition: Fl_win32.cxx:931
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_show_iconic
char fl_show_iconic
Definition: Fl_win32.cxx:1799
Window
class FLWindow * Window
Definition: mac.H:32
Enumerations.H
Fl::grab
static Fl_Window * grab()
Definition: Fl.H:555
FL_Media_Prev
#define FL_Media_Prev
Definition: Enumerations.H:517
Lf2CrlfConvert
Definition: Fl_win32.cxx:610
dx
uchar dx
Definition: fl_boxtype.cxx:286
FL_Escape
#define FL_Escape
The escape key.
Definition: Enumerations.H:474
Fl_Window::decorated_w
int decorated_w()
Definition: Fl_win32.cxx:2757
fl_clipboard_notify_empty
bool fl_clipboard_notify_empty(void)
Definition: Fl.cxx:540
FL_SOCKET
#define FL_SOCKET
Definition: Fl.H:56
fl_codepage
unsigned int fl_codepage
Fl_Font.H
default_big_icon
static HICON default_big_icon
Definition: Fl_win32.cxx:2294
Fl_Copy_Surface
Definition: Fl_Copy_Surface.H:51
NameList::nName
int nName
Definition: Fl_win32.cxx:1794
Win32Timer::handle
UINT_PTR handle
Definition: Fl_win32.cxx:1090
flTypeImmAssociateContextEx
BOOL(WINAPI * flTypeImmAssociateContextEx)(HWND, HIMC, DWORD)
Definition: Fl_win32.cxx:143
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
Lf2CrlfConvert::outlen
int outlen
Definition: Fl_win32.cxx:612
Fl_Group::resizable
void resizable(Fl_Widget &o)
Definition: Fl_Group.H:117
Fl::e_original_keysym
static int e_original_keysym
Definition: Fl.H:264
FL_ALIGN_CLIP
const Fl_Align FL_ALIGN_CLIP
Definition: Enumerations.H:849
fl_send_system_handlers
int fl_send_system_handlers(void *e)
Definition: Fl.cxx:962
Fl_Font_Descriptor
Definition: Fl_Font.H:41