1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
|
/**
\page osissues Operating System Issues
This appendix describes the operating system specific interfaces in FLTK:
\li \ref osissues_accessing
\li \ref osissues_unix
\li \ref osissues_win32
\li \ref osissues_macos
\li \ref osissues_wayland
\section osissues_accessing Accessing the OS Interfaces
All programs that need to access the operating system
specific interfaces must include the following header file:
\code
#include <FL/platform.H>
\endcode
This header file will define the appropriate interface for your environment.
The pages that follow describe the functionality that is provided for each
operating system.
\note These definitions used to be in FL/x.H up to FLTK 1.3.x. Usage of
FL/x.H is deprecated since FLTK 1.4.0. You should replace all references
of FL/x.H with FL/platform.H if your target is FLTK 1.4 or later.
FL/x.H will be retained for backwards compatibility for some
releases but will be removed in a later (not yet specified)
FLTK release.
<CENTER>
<TABLE WIDTH="90%" BORDER="1" CELLPADDING="5" CELLSPACING="0" BGCOLOR="#cccccc">
<TR>
<TD><B>WARNING:</B>
The interfaces provided by this header file may
change radically in new FLTK releases. Use them only
when an existing generic FLTK interface is not
sufficient.
</TD>
</TR>
</TABLE>
</CENTER>
\section osissues_unix The UNIX (X11) Interface
The UNIX interface provides access to the X Window System
state information and data structures.
\subsection osissues_x_events Handling Other X Events
void Fl::add_handler(int (*f)(int))
\par
Installs a function to parse unrecognized events. If FLTK
cannot figure out what to do with an event, it calls each of
these functions (most recent first) until one of them returns
non-zero. If none of them returns non-zero then the event is
ignored.
\par
FLTK calls this for any X events it does not recognize, or X
events with a window ID that FLTK does not recognize. You can
look at the X event in the \c fl_xevent variable.
\par
The argument is the FLTK event type that was not handled, or
zero for unrecognized X events. These handlers are also called
for global shortcuts and some other events that the widget they
were passed to did not handle, for example
\c FL_SHORTCUT.
extern XEvent *fl_xevent
\par
This variable contains the most recent X event.
extern ulong fl_event_time
\par
This variable contains the time stamp from the most recent X
event that reported it; not all events do. Many X calls like cut
and paste need this value.
Window fl_xid(const Fl_Window *)
\par
Returns the XID for a window, or zero if not \c shown().
Fl_Window *fl_find(ulong xid)
\par
Returns the Fl_Window that corresponds to the given
XID, or \c NULL if not found. This function uses a cache
so it is slightly faster than iterating through the windows
yourself.
int fl_handle(const XEvent &)
\par
This call allows you to supply the X events to FLTK, which
may allow FLTK to cooperate with another toolkit or library. The
return value is non-zero if FLTK understood the event. If the
window does not belong to FLTK and the \c add_handler()
functions all return 0, this function will return false.
\par
Besides feeding events your code should call Fl::flush()
periodically so that FLTK redraws its windows.
\par
This function will call the callback functions. It will not
return until they complete. In particular, if a callback pops up
a modal window by calling
fl_ask(),
for instance, it will not return until the modal function
returns.
\subsection osissues_drawing_xlib Drawing using Xlib
The following global variables are set before
Fl_Widget::draw() is called, or by Fl_Window::make_current():
\code
extern Display *fl_display;
extern Window fl_window;
extern GC fl_gc;
extern int fl_screen;
extern XVisualInfo *fl_visual;
extern Colormap fl_colormap;
\endcode
You must use them to produce Xlib calls. Don't attempt to change
them. A typical X drawing call is written like this:
\code
XDrawSomething(fl_display, fl_window, fl_gc, ...);
\endcode
Other information such as the position or size of the X
window can be found by looking at Fl_Window::current(),
which returns a pointer to the Fl_Window being drawn.
unsigned long fl_xpixel(Fl_Color i) <br>
unsigned long fl_xpixel(uchar r, uchar g, uchar b)
\par
Returns the X pixel number used to draw the given FLTK color
index or RGB color. This is the X pixel that
\ref drawing_colors "fl_color()"
would use.
int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b)
\par
Convert a name into the red, green, and blue values of a color
by parsing the X11 color names. On other systems, \c fl_parse_color()
can only convert names in hexadecimal encoding, for example <tt>\#ff8083</tt>.
extern XFontStruct *fl_xfont
\par
Points to the font selected by the most recent
\ref drawing_fonts "fl_font()".
This is not necessarily the current font of \c fl_gc,
which is not set until
\ref drawing_text "fl_draw()"
is called. If FLTK was compiled with Xft support, \c fl_xfont
will usually be 0 and \c fl_xftfont will contain a pointer
to the \c XftFont structure instead.
extern void *fl_xftfont
\par
If FLTK was compiled with Xft support enabled, \c fl_xftfont
points to the xft font selected by the most recent
\ref drawing_fonts "fl_font()".
Otherwise it will be 0. \c fl_xftfont should be cast to
<tt>XftFont*</tt>.
\subsection osissues_xvisual Changing the Display, Screen, or X Visual
FLTK uses only a single display, screen, X visual, and X
colormap. This greatly simplifies its internal structure and
makes it much smaller and faster. You can change which it uses
by setting global variables
<I>
before the first Fl_Window::show() is called.
</I>
You may also want to call Fl::visual(), which is a portable interface
to get a full color and/or double buffered visual.
int Fl::display(const char *)
\par
Set which X display to use. This actually does
<tt>putenv("DISPLAY=...")</tt> so that child programs
will display on the same screen if called with \c exec().
This must be done before the display is opened. This call is
provided under MacOS and Windows but it has no effect.
extern Display *fl_display
\par
The open X display. This is needed as an argument to most
Xlib calls. Don't attempt to change it! This is \c NULL
before the display is opened.
void fl_open_display()
\par
Opens the display. Does nothing if it is already open. This
will make sure \c fl_display is non-zero. You should call
this if you wish to do X calls and there is a chance that your
code will be called before the first \c show() of a window.
\par
This may call Fl::abort() if there is an error opening the display.
void fl_close_display()
\par
This closes the X connection. You do \e not need to call
this to exit, and in fact it is faster to not do so! It may be
useful to call this if you want your program to continue without
the X connection. You cannot open the display again, and
probably cannot call any FLTK functions.
extern int fl_screen
\par
Which screen number to use. This is set by
\c fl_open_display() to the default screen. You can change
it by setting this to a different value immediately afterwards.
It can also be set by changing the last number in the
Fl::display() string to "host:0.#".
extern XVisualInfo *fl_visual <br>
extern Colormap fl_colormap
\par
The visual and colormap that FLTK will use for all windows.
These are set by \c fl_open_display() to the default
visual and colormap. You can change them before calling
\c show() on the first window. Typical code for changing
the default visual is:
\code
Fl::args(argc, argv); // do this first so $DISPLAY is set
fl_open_display();
fl_visual = find_a_good_visual(fl_display, fl_screen);
if (!fl_visual) Fl::abort("No good visual");
fl_colormap = make_a_colormap(fl_display, fl_visual->visual, fl_visual->depth);
// it is now ok to show() windows:
window->show(argc, argv);
\endcode
\subsection osissues_specialx Using a Subclass of Fl_Window for Special X Stuff
FLTK can manage an X window on a different screen, visual
and/or colormap, you just can't use FLTK's drawing routines to
draw into it. But you can write your own \c draw() method
that uses Xlib (and/or OpenGL) calls only.
FLTK can also manage XID's provided by other libraries or
programs, and call those libraries when the window needs to be
redrawn.
To do this, you need to make a subclass of
Fl_Window
and override some of these virtual functions:
virtual void Fl_Window::show()
\par
If the window is already \c shown() this must cause it
to be raised, this can usually be done by calling Fl_Window::show().
If not \c shown() your implementation must call either
Fl_X::set_xid() or Fl_X::make_xid().
\par
An example:
\code
void MyWindow::show() {
if (shown()) {Fl_Window::show(); return;} // you must do this!
fl_open_display(); // necessary if this is first window
// we only calculate the necessary visual colormap once:
static XVisualInfo *visual;
static Colormap colormap;
if (!visual) {
visual = figure_out_visual();
colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
vis->visual, AllocNone);
}
Fl_X::make_xid(this, visual, colormap);
}
\endcode
\verbatim
Fl_X *Fl_X::set_xid(Fl_Window*, Window xid)
\endverbatim
\par
Allocate a hidden class called an Fl_X, put the
XID into it, and set a pointer to it from the Fl_Window.
This causes Fl_Window::shown() to return true.
void Fl_X::make_xid(Fl_Window*, XVisualInfo* = fl_visual, Colormap = fl_colormap)
\par
This static method does the most onerous parts of creating an
X window, including setting the label, resize limitations, etc.
It then does Fl_X::set_xid() with this new window and maps the window.
virtual void Fl_Window::flush()
\par
This virtual function is called by Fl::flush() to
update the window. For FLTK's own windows it does this by
setting the global variables \c fl_window and \c fl_gc
and then calling the \c draw() method. For
your own windows you might just want to put all the drawing code
in here.
\par
The X region that is a combination of all \c damage()
calls done so far is in <tt>Fl_X::i(this)->region</tt>. If
\c NULL then you should redraw the entire window. The
undocumented function \c fl_clip_region(XRegion) will
initialize the FLTK clip stack with a region or \c NULL
for no clipping. You must set region to \c NULL afterwards
as \c fl_clip_region() will own and delete it when
done.
\par
If <tt>damage() & FL_DAMAGE_EXPOSE</tt> then only X
expose events have happened. This may be useful if you have an
undamaged image (such as a backing buffer) around.
\par
Here is a sample where an undamaged image is kept somewhere:
\code
void MyWindow::flush() {
fl_clip_region(Fl_X::i(this)->region);
Fl_X::i(this)->region = 0;
if (damage() != 2) {... draw things into backing store ...}
... copy backing store to window ...
}
\endcode
virtual void Fl_Window::hide()
\par
Destroy the window server copy of the window. Usually you
will destroy contexts, pixmaps, or other resources used by the
window, and then call Fl_Window::hide() to get rid of
the main window identified by \c xid(). If you override
this, you must also override the destructor as shown:
\code
void MyWindow::hide() {
if (mypixmap) {
XFreePixmap(fl_display,mypixmap);
mypixmap = 0;
}
Fl_Window::hide(); // you must call this
}
\endcode
virtual void Fl_Window::~Fl_Window()
\par
Because of the way C++ works, if you override \c hide()
you \e must override the destructor as well (otherwise only
the base class \c hide() is called):
\code
MyWindow::~MyWindow() {
hide();
}
\endcode
\note Access to the Fl_X hidden class requires to \#define FL_INTERNALS
before compilation.
\subsection osissues_x_icon Setting the Icon of a Window
FLTK currently supports setting a window's icon \b before it
is shown using the Fl_Window::icon() method.
void Fl_Window::icon(const void *)
\par
Sets the icon for the window to the passed pointer. You will
need to cast the icon \c Pixmap to a \c char* when
calling this method. To set a monochrome icon using a bitmap compiled
with your application use:
\code
#include "icon.xbm"
fl_open_display(); // needed if display has not been previously opened
Pixmap p = XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
icon_bits, icon_width, icon_height);
window->icon((const void*)p);
\endcode
\par
To use a multi-colored icon, the XPM format and library
should be used as follows:
\code
#include <X11/xpm.h>
#include "icon.xpm"
fl_open_display(); // needed if display has not been previously opened
Pixmap p, mask;
XpmCreatePixmapFromData(fl_display, DefaultRootWindow(fl_display),
icon_xpm, &p, &mask, NULL);
window->icon((const void *)p);
\endcode
\par
When using the Xpm library, be sure to include it in the list
of libraries that are used to link the application (usually "-lXpm").
<CENTER>
<TABLE WIDTH="90%" BORDER="1" CELLPADDING="5" CELLSPACING="0" BGCOLOR="#cccccc">
<TR>
<TD><B>NOTE:</B>
You must call Fl_Window::show(int argc, char** argv)
for the icon to be used. The Fl_Window::show() method
does not bind the icon to the window.
</TD>
</TR>
</TABLE>
</CENTER>
\subsection osissues_xresources X Resources
When the
Fl_Window::show(int argc, char** argv)
method is called, FLTK looks for the following X resources:
\li \c background - The default background color
for widgets (color).
\li \c dndTextOps - The default setting for
drag and drop text operations (boolean).
\li \c foreground - The default foreground (label)
color for widgets (color).
\li \c scheme - The default scheme to use (string).
\li \c selectBackground - The default selection
color for menus, etc. (color).
\li <tt>Text.background</tt> - The default background
color for text fields (color).
\li \c tooltips - The default setting for
tooltips (boolean).
\li \c visibleFocus - The default setting for
visible keyboard focus on non-text widgets (boolean).
Resources associated with the first window's Fl_Window::xclass()
string are queried first, or if no class has been specified then
the class "fltk" is used (e.g. <tt>fltk.background</tt>). If no
match is found, a global search is done (e.g.
<tt>*background</tt>).
\subsection osissues_x_scaling Display Scaling Factor
FLTK uses the value of the Xft.dpi resource divided by 96.
to initialize the display scaling factor. That is also
what is done by the gnome and KDE desktops.
\section osissues_win32 The Windows Interface
The Windows interface provides access to the Windows GDI
state information and data structures.
\subsection non_ascii_filenames Using filenames with non-ASCII characters
In FLTK, all strings, including filenames, are UTF-8 encoded. The utility functions
fl_fopen() and fl_open() allow to open files potentially having non-ASCII names in a
cross-platform fashion, whereas the standard fopen()/open() functions fail to do so.
\subsection osissues_wm_quit Responding to WM_QUIT
FLTK will intercept WM_QUIT messages that are directed towards the
thread that runs the main loop. These are converted to SIGTERM signals
via \c raise(). This allows you to deal with outside termination
requests with the same code on both Windows and UNIX systems.
Other processes can send this message via \c PostThreadMessage() in
order to request, rather than force your application to terminate.
\subsection osissues_win32_messages Handling Other Windows API Messages
By default a single WNDCLASSEX called "FLTK" is
created. All Fl_Window's are of this class unless you
use Fl_Window::xclass(). The window class is created
the first time Fl_Window::show() is called.
You can probably combine FLTK with other libraries that make
their own window classes. The easiest way is to call
Fl::wait(), as it will call \c DispatchMessage()
for all messages to the other windows. If necessary you can let
the other library take over as long as it calls
\c DispatchMessage(), but you will have to arrange for the
function Fl::flush() to be called regularly so that
widgets are updated, timeouts are handled, and the idle
functions are called.
extern MSG fl_msg
\par
This variable contains the most recent message read by
\c GetMessage(), which is called by Fl::wait().
This may not be the
most recent message sent to an FLTK window, because silly Windows
calls the handle procedures directly for some events (sigh).
void Fl::add_handler(int (*f)(int))
\par
Installs a function to parse unrecognized messages sent to
FLTK windows. If FLTK cannot figure out what to do with a
message, it calls each of these functions (most recent first)
until one of them returns non-zero. The argument passed to the
functions is the FLTK event that was not handled or zero for
unknown messages. If all the handlers return zero then FLTK
calls \c DefWindowProc().
HWND fl_xid(const Fl_Window *)
\par
Returns the window handle for a Fl_Window, or zero
if not \c shown().
Fl_Window *fl_find(HWND xid)
\par
Returns the Fl_Window that corresponds to the given
window handle, or \c NULL if not found. This function uses
a cache so it is slightly faster than iterating through the
windows yourself.
\subsection osissues_win32_gdi Drawing Things Using the Windows GDI
When the virtual function Fl_Widget::draw() is
called, FLTK stores all the extra arguments you need to
make a proper GDI call in some global variables:
\code
extern HINSTANCE fl_display;
extern HWND fl_window;
extern HDC fl_gc;
COLORREF fl_RGB();
HPEN fl_pen();
HBRUSH fl_brush();
\endcode
These global variables are set before Fl_Widget::draw() is called, or by
Fl_Window::make_current().
You can refer to them when needed to produce GDI calls, but don't
attempt to change them. The functions return GDI objects for
the current color set by
\ref drawing_colors "fl_color()"
and are created as
needed and cached. A typical GDI drawing call is written like
this:
\code
DrawSomething(fl_gc, ..., fl_brush());
\endcode
It may also be useful to refer to Fl_Window::current()
to get the window's size or position.
\subsection osissues_windows_highdpi HighDPI support
FLTK apps for the Windows platform are by default "Per-monitor DPI-aware V2".
This means that any window automatically adjusts its physical size
in relation to the scaling factor of the display where it maps.
This also means that all drawings (e.g., text, lines, images)
take advantage of the full resolution of the display in use.
FLTK apps may also use the manifest mechanism
to declare their level of DPI awareness. The FLTK library
adapts to the DPI awareness level set in the app's manifest, which can be lower
than the default level if the manifest sets it so.
\subsection osissues_windows_scaling Display Scaling Factor
FLTK uses the value given by function GetDpiForMonitor() divided by 96.
to initialize the scaling factor of each display in the system.
This matches the value of
"Change the size of text, apps and other items" found in section
"System" subsection "Display" of Windows settings.
\subsection osissues_icon_windows Setting the Icon of a Window
FLTK currently supports setting a window's icon *before* it
is shown using the Fl_Window::icon() method.
void Fl_Window::icon(const void *)
\par
Sets the icon for the window to the passed pointer. You will
need to cast the \c HICON handle to a \c char* when
calling this method. To set the icon using an icon resource
compiled with your application use:
\code
window->icon((const void *)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));
\endcode
\par
You can also use the \c LoadImage() and related
functions to load specific resolutions or create the icon from
bitmap data.
<CENTER>
<TABLE WIDTH="90%" BORDER="1" CELLPADDING="5" CELLSPACING="0" BGCOLOR="#cccccc">
<TR>
<TD><B>NOTE:</B>
You must call Fl_Window::show(int argc, char** argv)
for the icon to be used. The Fl_Window::show() method
does not bind the icon to the window.
</TD>
</TR>
</TABLE>
</CENTER>
\subsection osissues_msdos_console How to Not Get a MSDOS Console Window
Windows has a really stupid mode switch stored in the
executables that controls whether or not to make a console
window.
To always get a console window you simply create a console
application (the "/SUBSYSTEM:CONSOLE" option for the
linker). For a GUI-only application create a Windows application
(the "/SUBSYSTEM:WINDOWS" option for the linker).
FLTK includes a \c WinMain() function that calls the
ANSI standard \c main() entry point for you.
<I>
This function creates a console window when you use the debug
version of the library.
</I>
Windows applications without a console cannot write to
\c stdout or \c stderr, even if they are run from a
console window. Any output is silently thrown away.
Additionally, Windows applications are run in the background by
the console, although you can use "start /wait program" to run
them in the foreground.
\subsection osissues_win32_problems Known Windows Bugs and Problems
The following is a list of known bugs and problems in the Windows
version of FLTK:
\li If a program is deactivated, <tt>Fl::wait()</tt>
does not return until it is activated again, even though
many events are delivered to the program. This can cause
idle background processes to stop unexpectedly. This
also happens while the user is dragging or resizing
windows or otherwise holding the mouse down. We were
forced to remove most of the efficiency FLTK uses for
redrawing in order to get windows to update while being
moved. This is a design error in Windows and probably
impossible to get around.
\li <tt>Fl_Gl_Window::can_do_overlay()</tt> returns true
until the first time it attempts to draw an overlay, and
then correctly returns whether or not there is overlay
hardware.
\li <tt>SetCapture</tt> (used by <tt>Fl::grab()</tt>)
doesn't work, and the main window title bar turns gray
while menus are popped up.
\li Compilation with <tt>gcc 3.4.4</tt> and <tt>-Os</tt> exposes an
optimisation bug in gcc. The symptom is that when drawing
filled circles only the perimeter is drawn. This can for instance
be seen in the symbols demo. Other optimisation options such
as -O2 and -O3 seem to work OK. More details can be found
in STR#1656
\section osissues_macos The Apple OS X Interface
FLTK supports Apple OS X using the Apple Cocoa library. Older
versions of MacOS are no longer supported.
Control, Option, and Command Modifier Keys
\par
FLTK maps the Mac 'control' key to \c FL_CTRL, the
'option' key to \c FL_ALT and the 'Apple' key to
\c FL_META. Furthermore, \c FL_COMMAND designates the 'Apple' key on Mac OS X
and the 'control' key on other platforms.
Keyboard events return the key name in
Fl::event_key() and the keystroke translation in
Fl::event_text(). For example, typing Option-Y on a Mac
US keyboard will set \c FL_ALT in Fl::event_state(),
set Fl::event_key() to 'y' and return the Yen symbol in
Fl::event_text().
Right Click simulation with Ctrl Click
\par
The Apple HIG guidelines indicate applications should support
'Ctrl Click' to simulate 'Right Click' for e.g. context menus,
so users with one-button mice and one-click trackpads can still
access right-click features. However, paraphrasing
<A HREF="https://www.fltk.org/newsgroups.php?gfltk.coredev+v:14725">
Manolo's comment on the fltk.coredev newsgroup</A>:
\par
<UL><LI>
<I>FLTK does /not/ support Ctrl-Click == Right Click itself because Mac OS
X event processing doesn't support this at the system level: the system
reports left-clicks with the ctrl modifier when the user ctrl-clicks, and
OS X system preferences don't allow changing this behavior. Therefore,
applications must handle simulation of Right Click with Ctrl Click
in the application code.</I>
</LI></UL>
\par
Ian MacArthur provided the following handle() method code snippet
showing an example of how to do this:
\code
case FL_PUSH:
{
int btn = Fl::event_button();
#ifdef __APPLE__
int ev_state = Fl::event_state();
#endif
//
// Context menu can be called up in one of two ways: -
// 1 - right click, as normally used on Windows and Linux
// 2 - Ctrl + left click, as sometimes used on Mac
//
#ifdef __APPLE__
// On apple, check right click, and ctrl+left click
if ((btn == FL_RIGHT_MOUSE) || (ev_state == (FL_CTRL | FL_BUTTON1)))
#else
// On other platforms, only check right click as ctrl+left is used for selections
if (btn == FL_RIGHT_MOUSE)
#endif
{
// Did we right click on the object?..
\endcode
\par
There is a thread about this subject on fltk.coredev (Aug 1-14, 2014)
entitled "[RFC] Right click emulation for one button mouse on Mac".
Apple "Quit" Event
\par
When the user presses Cmd-Q or requests a termination of the
application, FLTK sends an \c FL_CLOSE event to all open
windows. If any window remains open, the termination request aborts.
If all windows close, the application's event loop terminates,
that is, Fl::run() returns. The application can then follow
FLTK's normal termination path executing cleanup code that may be programmed
after termination of the event loop, and returning from main().
Function Fl::program_should_quit() allows to detect whether the event loop
terminated because of a program termination request.
Apple "Open" Event
\par
Whenever the user drops a file onto an application icon, OS X
generates an Apple Event of the type "Open". You can have FLTK
notify you of an Open event by calling the \ref fl_open_callback()
function.
void fl_open_display()
\par
Opens the display. Does nothing if it is already open. You should call
this if you wish to do Cocoa or Quartz calls and there is a chance that your
code will be called before the first \c show() of a window.
Window fl_xid(const Fl_Window *)
\par
Returns the window reference for an Fl_Window, or
\c NULL if the window has not been shown. This reference is a pointer
to an instance of the subclass FLWindow of Cocoa's NSWindow class.
Fl_Window *fl_find(Window xid)
\par
Returns the Fl_Window that corresponds to the given window reference,
or \c NULL if not found.
void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut)
\par
Attaches the callback \c cb to the "About myprog" item of the system application menu.
\c cb will be called with NULL first argument and \c user_data second argument.
This MacOS-specific function is deprecated in FLTK 1.4 and replaced by
Fl_Sys_Menu_Bar::about(Fl_Callback *cb, void *data) which is cross-platform.
Fl_Sys_Menu_Bar class
\par
The Fl_Sys_Menu_Bar class allows to build menu bars that, on Mac OS X, are
placed in the system menu bar (at top-left of display), and, on other platforms,
at a user-chosen location of a user-chosen window.
\subsection osissues_icon_osx Setting the icon of an application
\li First, create a .icns file containing several copies of your icon of decreasing sizes.
This can be done using the Preview application or the Icon Composer application
available in "Graphics Tools for Xcode". To create a high resolution icon file,
it is necessary to use the iconutil command-line utility.
\li Put your .icns file in the Resources subdirectory of your application bundle.
\li Add these two lines to the Info.plist file of your application bundle
\verbatim
<key>CFBundleIconFile</key>
<string>foo.icns</string>
\endverbatim
replacing <tt>foo</tt> by your application name. If you use Xcode, just add your .icns file to your
application target.
\subsection osissues_quartz Drawing Things Using Quartz
All code inside Fl_Widget::draw()
is expected to call Quartz drawing functions. The Quartz coordinate system
is flipped to match
FLTK's coordinate system. The origin for all drawing is in the top
left corner of the enclosing Fl_Window. The global variable
\c fl_gc (of type \c CGContextRef) is the appropriate Quartz 2D drawing environment.
Include FL/platform.H to declare the \c fl_gc variable.
\subsection osissues_localize Internationalization
All FLTK programs contain an application menu with, e.g., the About xxx, Hide xxx, and Quit xxx items.
This menu can be internationalized/localized by any of two means.
\li using the Fl_Mac_App_Menu class.
\li using the standard Mac OS X localization procedure. Create a language-specific .lproj directory
(e.g., <tt>German.lproj</tt>) in the Resources subdirectory of the application bundle.
Create therein a <tt>Localizable.strings</tt> file that translates all menu items to this language.
The German <tt>Localizable.strings</tt> file, for example, contains:
\verbatim
"About %@" = "Über %@";
"Print Front Window"="Frontfenster drucken";
"Services" = "Dienste";
"Hide %@"="%@ ausblenden";
"Hide Others"="Andere ausblenden";
"Show All"="Alle einblenden";
"Quit %@"="%@ beenden";
\endverbatim
Set <tt>"Print Front Window" = "";</tt> therein so the application menu doesn't show a "Print Front Window" item.
To localize the application name itself, create a file <tt>InfoPlist.strings</tt> in each .lproj directory
and put <tt>CFBundleName = "localized name";</tt> in each such file.
\subsection osissues_retina OpenGL and 'retina' displays
It is possible to have OpenGL produce graphics at the high pixel resolution allowed by the so-called 'retina' displays
present on recent Apple hardware.
For this, call
\verbatim
Fl::use_high_res_GL(1);
\endverbatim
before any Fl_Gl_Window is shown. Also, adapt your Fl_Gl_Window::draw() and Fl_Gl_Window::draw_overlay() methods replacing
\verbatim
glViewport(0, 0, w(), h());
\endverbatim
by
\verbatim
glViewport(0, 0, pixel_w(), pixel_h());
\endverbatim
making use of the Fl_Gl_Window::pixel_w() and Fl_Gl_Window::pixel_h() methods that return the width and height of
the GL scene in pixels: if the Fl_Gl_Window is mapped on a retina display, these methods return twice as much as
reported by Fl_Widget::w() and Fl_Widget::h(); if it's mapped on a regular display, they return the same values
as w() and h(). These methods dynamically change their values if the window is moved into/out from a retina
display. If Fl::use_high_res_GL(1) is not called, all Fl_Gl_Window 's are drawn at low resolution.
These methods are useful on all platforms because Fl_Gl_Window::w() and Fl_Gl_Window::h() don't return,
on HighDPI displays, the quantitites in pixels necessary to OpenGL functions .
The Fl_Gl_Window::pixels_per_unit() method is useful when the OpenGL code depends on the pixel dimension
of the GL scene. This occurs, e.g., if a window's handle() method uses Fl::event_x() and Fl::event_y()
whose returned values should be multiplied by Fl_Gl_Window::pixels_per_unit() to obtain the adequate pixel units.
This method may also be useful, for example, to adjust the width of a line in a high resolution GL scene.
\subsection double_window Fl_Double_Window
OS X double-buffers all windows automatically. On OS X, Fl_Window and Fl_Double_Window are handled
internally in the same way.
\subsection osissues_mac_files Mac File System Specifics
\par Resource Forks
FLTK does not access the resource fork of an application.
However, a minimal resource fork must be created for OS X
applications. Starting with OS X 10.6, resource forks are
no longer needed.
<CENTER>
<TABLE WIDTH="80%" BORDER="1" BGCOLOR="#cccccc" CELLPADDING="5">
<TR><TD><B>Caution (OS X 10.2 and older):</B>
When using UNIX commands to copy or move executables, OS X
will NOT copy any resource forks! For copying and moving use
CpMac and MvMac respectively. For creating a tar archive, all
executables need to be stripped from their Resource Fork before
packing, e.g. "DeRez fluid > fluid.r". After unpacking the
Resource Fork needs to be reattached, e.g. "Rez fluid.r -o
fluid".
</TD></TR></TABLE>
</CENTER>
It is advisable to use the Finder for moving and copying and
Mac archiving tools like Sit for distribution as they will
handle the Resource Fork correctly.
\par Mac File Paths
FLTK uses UTF-8-encoded UNIX-style filenames and paths.
\sa group_macosx
\section osissues_wayland The Wayland Interface
Wayland-specific source code can be organized as follows to be distinguished
from X11-specific source code :
\code
#include <FL/platform.H> // defines FLTK_USE_WAYLAND or FLTK_USE_X11 as appropriate
#if defined(FLTK_USE_WAYLAND)
… Wayland-specific source code …
#elif defined(FLTK_USE_X11)
… X11-specific source code …
#endif
\endcode
extern struct wl_display *fl_display;
\par
After fl_open_display() has run, the \c fl_display global variable points to the
struct wl_display representing the connection between the application and Wayland.
Therefore, \c wl_display_get_fd(fl_display) gives the file descriptor one can
use to communicate with the Wayland compositor according to the Wayland protocol.
Window fl_xid(const Fl_Window *)
\par
Returns a pointer to an <u>FLTK-defined</u> structure holding Wayland-related
data created when a window gets show()'n, or NULL if not show()'n.
Fl_Window *fl_find(Window wld_win)
\par
Returns the Fl_Window that corresponds to the given Window, or NULL if not found.
struct wl_surface *fl_wl_surface(Window wld_win)
\par
Returns a pointer to the struct wl_surface corresponding to a show()'n
top-level window or subwindow.
struct _cairo *fl_wl_cairo(void)
\par
Drawing natively to a Wayland window : Within an overridden Fl_Widget::draw() method,
or after a call to Fl_Window::make_current(), it's possible to draw
<u>using the Cairo library</u>. Function \c fl_wl_cairo() returns the adequate
\c cairo_t* (equivalent to <tt>struct _cairo*</tt>) value. All FLTK-defined
drawing functions (e.g., fl_rect(), fl_draw()) can be used too.
void fl_close_display()
\par
This closes the Wayland connection. You do not need to call
this to exit. It may be useful to call this if you want your program to continue
without the Wayland connection. You cannot open the display again, and
cannot call any FLTK functions.
\subsection osissues_wayland_scaling HiDPI display support
FLTK Wayland apps automatically scale according to the Wayland-defined, integer-valued
scale factor. On a HiDPI display, it's enough to set this factor to 2 for
any FLTK app to be drawn using twice as many pixels and thus to be as readable
as it is on a regular display. With the gnome desktop, that is achieved in the
"Displays" section of the "Settings" application, selecting 200 % for the "Scale" parameter.
In addition to this, FLTK apps can also be scaled up or down typing ctrl/+/-/0/
and with the \c FLTK_SCALING_FACTOR environment variable.
\subsection osissues_wayland_decoration Window titlebars
Wayland supports both client-side window decoration (CSD), where client applications
are responsible for drawing window titlebars, and server-side window
decoration (SSD), where the Wayland compositor itself draws window titlebars. Among 3
tested Wayland compositors, Mutter (gnome's compositor) and Weston use CSD mode
whereas the KDE compositor uses SSD mode. When running in CSD mode, FLTK uses a library called
<a href=https://gitlab.gnome.org/jadahl/libdecor>libdecor</a> to draw titlebars.
The libdecor library has been conceived to use various plug-in's to draw
titlebars in various fashions intended to match any desktop's preferred titlebar style.
FLTK supports drawing titlebars with any libdecor plug-in via an environment variable
called \c LIBDECOR_PLUGIN_DIR which can be given the name of a directory containing the
desired plug-in. When \c LIBDECOR_PLUGIN_DIR is not defined, or points to a directory
that doesn't contain a libdecor plug-in, FLTK uses its built-in plug-in to draw titlebars.
That is the most common situation, until libdecor plug-in's become available
for popular UNIX desktops.
\htmlonly
<hr>
<table summary="navigation bar" width="100%" border="0">
<tr>
<td width="45%" align="LEFT">
<a class="el" href="forms.html">
[Prev]
Forms Compatibility
</a>
</td>
<td width="10%" align="CENTER">
<a class="el" href="index.html">[Index]</a>
</td>
<td width="45%" align="RIGHT">
<a class="el" href="migration_1_4.html">
Migrating Code from FLTK 1.3 to 1.4
[Next]
</a>
</td>
</tr>
</table>
\endhtmlonly
*/
|