summaryrefslogtreecommitdiff
path: root/documentation/src/cmp.dox
blob: 5da340682cdbd11204a8d8f2a4b0e361a5c61beb (plain)
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
// vim:syntax=doxygen
/**

 \page cmp FLTK Code Management Plan (CMP)

<center><h2>*** WORK IN PROGRESS ***</h2></center>

\section cmp_intro CMP Coding Intro

This document defines the coding standards that all FLTK developers must
follow when developing source code and related documentation for the FLTK
library. The purpose of defining formal standards is to organize and focus
our development efforts, ensure that all developers communicate and develop
software with a common vocabulary/style, and make it possible for us to
generate and release a high-quality GUI toolkit which can be used with a
high degree of confidence.

Much of this file describes existing practices that have been used up
through FLTK 1.1.x, however some new standards have been added for future
code and releases.

\section cmp_communication Communication

The fltk.coredev mailing list/newsgroup are the primary means of communication between developers.
All major design changes must be discussed prior to implementation.

We use GitHub Issues to manage bugs.
Please see the CMP section on Managing GitHub Issues for how developers should manage GitHub issues.

It is wise for all developers to monitor these github related mailing list/newsgroups for bug and commit acitivity:

 - fltk.commit — (nntp/web) All fltk developer commits on GitHub commit. Includes old pre-Oct 2018 SVN commits

 - fltk.issues — (nntp/web) All new/current fltk bugs as GitHub Issues. See "Managing GitHub Issues"

 - fltk.bugs   — (nntp/web) The "Old STR Bug Management System" activity (replaced by GitHub Issues). See "Managing Old STR's"

To monitor these groups, either configure github to cc you on activity, or see the https://www.fltk.org/newsgroups.php page
and use either the web interface or NNTP instructions.

\section cmp_goals Specific Goals

The specific goals of the FLTK are as follows:

 - Develop a C++ GUI toolkit based upon sound object-oriented design principles and experience.
 - Minimize CPU usage (fast).
 - Minimize memory usage (light).
 - Support multiple operating systems and windowing environments, including UNIX/Linux, macOS,
   Microsoft Windows, and X11, using the "native" graphics interfaces.
 - Support OpenGL rendering in environments that provide it.
 - Provide a graphical development environment for designing GUI interfaces, classes, and simple programs.
 - Support UTF-8 text.
 - Support printer rendering in environments that provide it.
 - Support "schemes", "styles", "themes", "skinning", etc. to alter the appearance of widgets
   in the toolkit easily and efficiently. The purpose is to allow applications to tailor their
   appearance to the underlying OS or based upon personal/user preferences.
 - Support newer C++ language features, such as templating via the Standard Template Library
   ("STL"), and certain Standard C++ library interfaces, such as streams. However, FLTK will
   not depend upon such features and interfaces to minimize portability issues.
 - Support intelligent layout of widgets.

Many of these goals are satisfied by FLTK 1.1.x, and many complex
applications have been written using FLTK on a wide range of platforms
and devices.

\section cmp_practices_docs Documentation

All widgets are documented using the Doxygen software; Doxygen comments
are placed in the header file for the class comments and any inline
methods, while non-inline methods should have their comments placed in
the corresponding source file. The purpose of this separation is to place
the comments near the implementation to reduce the possibility of the
documentation getting out of sync with the code.

All widgets must have a corresponding test program which exercises
all widget functionality and can be used to generate image(s) for the
documentation. Complex widgets must have a written tutorial, either as
full text or an outline for later publication

Starting with FLTK 1.3 Doxygen is used for HTML and PDF documentation.

\section cmp_coding_standards Coding Standards

The following is a guide to the coding style that must be used when adding
or modifying code in FLTK. Most of this should be obvious from looking at
the code, but here it all is in one spot.

\section cmp_coding_style General Coding Style

The FLTK code basically follows the K&R coding style. While many of the
developers are not entirely satisfied with this coding style, no one has
volunteered to change all of the FLTK source code (currently about 54,000
lines of code!) to a new style.

The K&R coding style can be summarized with the following example code:

\verbatim
int function(int arg) {
  if (arg != 10) {
    printf("arg = %d\n", arg);
    return (0);
  } else {
    return 1;
  }
}

int function2(int arg) {
  for (int i = 0; i < arg; i++) {
    stuff();
  }
  while (something) {
    stuff();
  }
  switch (arg) {
    case 0:
      stuff_here();
      break;
    case 1: {
      int var;
      stuff_here();
      break;
    }
    case 2:
      stuff();
      /* FALLTHROUGH */
    case 3: simple_stuff1(); break;
    case 4: simple_stuff2(); break;
    default:
      break;
  }
  return (0);
}
\endverbatim

To summarize:

  - All curly braces must open on the same line as the enclosing statement, and close at the same level of indentation.
  - Each block of code must be indented 2 spaces.
  - <b>Tabs are not allowed in source files</b>, please use only spaces for indenting.
  - A space follows all reserved words.
  - A space precedes and follows all operators except prefix and postfix operators (++i, j--, et al).
  - Trailing whitespace (spaces and tabs) must be removed before committing. Please check your
    editor's documentation how to do this.

\note Example Visual Studio Code: use <kbd>ctrl-k ctrl-x</kbd> before saving the file.
      On macOS: use <kbd>cmd-k cmd-x</kbd> instead.


\section cmp_coding_standards_docs Source File Documentation

Each source file must start with the standard FLTK header containing the
description of the file, and FLTK copyright and license notice:

\verbatim
//
// Some descriptive text for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2020 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
//     https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
//     https://www.fltk.org/bugs.php
//
\endverbatim

..or the equivalent comment block using the C or other comment delimiters appropriate for the source file language (shell, CMake, etc).

\section cmp_coding_doxygen Doxygen Documentation (Comments)

FLTK 1.3 and up uses Doxygen with the JavaDoc comment style to document all classes, structures, enumerations, methods, and functions. Doxygen comments are \b mandatory for all FLTK header and source files, and no FLTK release will be made without complete documentation of public APIs. Here is an example of the Doxygen comment style:

\verbatim
/**
  The Foo class implements the Foo widget for FLTK.

  This description text appears in the documentation for
  the class and may include HTML tags as desired.
*/

class FL_EXPORT Foo : public Widget {
  int private_data_;

public:
  /**
    Creates a Foo widget with the given position and label.

    This description text appears in the documentation for the
    method's implementation.

    References to parameters \p X, \p Y, \p W, \p H are
    mentioned this way.

    \param[in] X,Y,W,H Position and size of widget
    \param[in] L Optional label (default is 0 for no label)
  */
  Foo(int X, int Y, int W, int H, const char *L = 0) {
    ..implementation here..
  }
};
\endverbatim

Essentially, a comment starting with `/\**` before the class or method defines the documentation for that class or method. These comments should appear in the header file for classes and inline methods and in the code file for non-inline methods.

In addition to Doxygen comments, block comments must be used liberally in the code to describe what is being done. If what you are doing is not "intuitively obvious to a casual observer", add a comment! Remember, you're not the only one that has to read, maintain, and debug the code.

<b>Never</b> use C++ comments in C code files or in header files that may be included from a C program. (Otherwise builds on strict platforms like SGI will fail). Normally, fltk C files have ".c" and ".h" file extensions, and C++ have ".cxx" and ".H". Currently there are a few exceptions; filename.H and Fl_Exports.H both get interpreted by C and C++, so you must use C style comments in those.

\section cmp_general_recommendations General Developer Recommendations

Most important rule: <b>Put Doxygen comments where the code's implementation is.</b>
This means don't put the docs with the prototypes in the .H file, unless that's where the code is implemented.

  - \p class, \p typedef, \p enum, and \p inline docs go in the headers

  - Most other docs go in the source files

  - For doxygen syntax in C++ files, use:
  \verbatim
  /** for standard doxygen comments */
  ///< for short single line post-declaration doxygen comments
  \endverbatim

  - For doxygen syntax in C files, use:
  \verbatim
  /**  for standard doxygen comments */
  /**< for short single line post-declaration doxygen comments */
  \endverbatim

  - Use `\p` for parameters citation in the description

  - Use `\param[in] xxx` and `\param[out] xxx` for input/output parameters.

  - Don't use doxygen tags between the `\\htmlonly` and `\\endhtmlonly` pair of tags.

  - When commenting out code or writing non-doxygen comments, be sure not to accidentally use doxygen comment styles, or your comments will be published..! Beware doxygen recognizes other comment styles for itself:
  \verbatim
  /*! beware */
  /*@ beware */
  //! beware
  //@ beware
  \endverbatim

  There may be others. For this reason, follow all non-doxygen comment leaders with a space to avoid accidental doxygen parsing:

  \verbatim
  /* safe from doxygen */
  // safe from doxygen
    ↑
    Space immediately after comment characters
  \endverbatim

  Note: Several characters are 'special' within doxygen commments, and must be escaped with a backslash to appear in the docs correctly. Some of these are:

  \verbatim
  \<    -- disambiguates html tags
  \>    -- ""
  \&    -- ""
  \@    -- disambiguates JavaDoc doxygen comments
  \$    -- disambiguates environment variable expansions
  \#    -- disambiguates references to documented entities
  \%    -- prevents auto-linking
  \\   -- escapes the escape character
  \endverbatim

\htmlonly

  Itemized lists can be specified two ways; both work, left is preferred:

<table>
  <tr><th> Preferred </th> <th> Old </th></tr>
  <tr><td>
  \verbatim

   Here's a bullet list:

   - Apples
   - Oranges

   Here's a numbered list:

   -# First thing
   -# Second thing

  \endverbatim
  </td><td>
  \verbatim

   Here's a bullet list:
   <ul>
     <li> Apples</li>
     <li> Oranges</li>
   </ul>
   Here's a numbered list:
   <ol>
     <li> First thing</li>
     <li> Second thing</li>
   </ol>

   \endverbatim
  </td></tr>
</table>

\endhtmlonly

\todo Find a way to describe itemized lists in PDF docs. The table above would
  break Doxygen's PDF generation (pdflatex).

  \verbatim

   Here's a bullet list:

   - Apples
   - Oranges

   Here's a numbered list:

   -# First thing
   -# Second thing

  \endverbatim



\section cmp_temporary_code Documenting Temporary Code or Issues

Temporary code and code that has a known issue MUST be documented in-line with the following (Doxygen) comment style:

\verbatim
  /** \todo this code is temporary */
\endverbatim

<b>`\todo`</b> items are listed by Doxygen making it easy to locate any code that has an outstanding issue or code that should be removed or commented out prior to a release.

\section cmp_documenting_class_and_struct Documenting Classes and Structures

Classes and structures start with a comment block that looks like the following:

\verbatim
/**
  A brief description of the class/structure.

  A complete description of the class/structure.
*/
class MyClass {
  ...implementation...
};
\endverbatim

\section cmp_documenting_enum Documenting Enumerations

Enumerations start with a comment block that looks like the following:

\verbatim
/**
  A brief description of the enumeration.

  A complete description of the enumeration.
*/
enum MyEnum {
  ...implementation...
};
\endverbatim

Each enumeration value must be documented in-line next to the corresponding definition as follows:

\verbatim
/* C++ STYLE */
enum MyEnum {
  BLACK,    ///< The color black.
  RED,      ///< The color red.
  GREEN,    ///< The color green.
  YELLOW,   ///< The color yellow.
  BLUE      ///< The color blue.
};
\endverbatim

If the enum is included in a C file, be sure to use C style commenting:

\verbatim
/* C STYLE */
enum MyEnum {
  BLACK,    /**< The color black. */
  RED,      /**< The color red. */
  GREEN,    /**< The color green. */
  YELLOW,   /**< The color yellow. */
  BLUE      /**< The color blue. */
};
\endverbatim

\section cmp_documenting_functions_and_methods Documenting Functions and Methods

Functions and methods start with a comment block that looks like the following:

\verbatim
/**
  A brief description of the function/method.

  A complete description of the function/method.
  Optional passing mention of parameter \p a and \p out1.

  Optional code example goes here if needed:
  \code
  ..code showing how to use it..
  \endcode

  \param[in] a Description of input variable a
  \param[in] x,y Description of input variables x and y in one comment
  \param[out] out1 Description of output variable out1
  \param[out] out2 Description of output variable out2
  \return 0 on success, -1 on error
  \see other_func1(), other_func2()
*/
int my_function(int a, int x, int y, float &out1, float &out2) {
  ...implementation...
}
\endverbatim

Some details on the above:

- <b>Parameters</b>

  Use `\param` to document function/method parameters using either of the following formats, the latter being preferred:

  \verbatim
  \param var Some description
  \param[in|out] var Some description.
  \endverbatim

  Mention of parameters in docs should use `"\p varname"`. (Use `\p` instead of `\a`)

  Note: Doxygen checks your `\param` variable names against the actual function signatures in your code.
  It does NOT check `\p` names for consistency.

- <b>Return Values</b>

  Use `\return` to document return values. Omit this if there is no return value.

- <b>Reference related methods</b>

  Use `\see` to help the reader find related methods.
  (Methods are sorted alphabetically by doxygen, so 'related' methods might not appear together)

  Locate `\see` references below `\param[]` and `\return` as shown in the above example.

- <b>Code examples</b>

  Use `\code` and `\endcode` when code examples are needed.
  Text within will be exempt from html and doxygen escape code parsing,
  so you don't have to escape characters \<, \>, \&, etc. as you would normally.

  Be careful not to embed C style comments within `\code` and `\endcode` or it
  will break the outer doxygen comment block. (A good reason to always test
  build the code base before commiting documentation-only mods)

- <b>Where to put docs</b>

  Function/method documentation must be placed next to the corresponding code.
  (Rule: "Put the docs where the code implementation is.")
  Comments for in-line functions and methods are placed in the header file where they're defined.

\section cmp_documenting_members_and_variables Documenting Members and Variables

Members and variables can be documented in one of two ways; in block comment form:

\verbatim
/**
  A brief doxygen description of the member/variable.

  A complete description of the member/variable.
  More text goes here..
*/
int my_variable_;
\endverbatim

or in the preferred form as in-line comments as follows:

\verbatim
int my_variable1_;    ///< C++ file's brief doxygen description of the member/variable
int my_variable2_;    /**< C file's brief doxygen description of the member/variable */
\endverbatim

\section cmp_methodology_algorithms Methodology, Algorithms, Etc.

The goal of FLTK is to provide a robust GUI toolkit that is small, fast,
and reliable. All public API functions and methods must be documented with
the valid values for all input parameters - NULL pointers, number ranges,
etc. - and no public API function may have undefined behaviors. Input
validation should be performed only when the function or method is able
to return an error to the caller.

When solving a particular problem, whether you are writing a widget or adding
functionality to the library, please consider the following guidelines:

  -# Choose the small, simple, easy-to-test algorithm over a more complex, larger one that is harder to debug and maintain.
  -# Choose the fastest algorithm that satisfies #1
  -# Break complex solutions into smaller, more manageable pieces.
  -# If functionality can be separated from the main part of the FLTK library, separate it. The idea is to keep the FLTK "core" as small as possible so that programs use memory proportionate to their complexity rather than starting big.
  -# Choose a general-purpose solution over a single-purpose solution, i.e. don't limit your design to what you think something will be used for.
  -# Don't rely on functionality available on a particular platform or compiler; this ties in with #5.

\section cmp_portability C++ Portability

Since FLTK is targeted at platforms which often lack complete ISO C++
support or have limited memory, all C++ code in FLTK must use a subset
of ISO C++. These restrictions shall be reviewed prior to each minor or
major release of FLTK.

\subsection cmp_fltk_1_1_x_restrictions FLTK 1.1.x Restrictions

The following C++ features may be not used in FLTK 1.1.x code:

  - Exceptions
  - Namespaces
  - Standard C++ headers and library
  - Templates
  - static_cast, dynamic_cast, const_cast

\subsection cmp_fltk_1_3_x_restrictions FLTK 1.3.x Restrictions

The following C++ features may be not used in FLTK 1.3.x code:

  - Exceptions
  - Namespaces
  - Standard C++ headers and library
  - Templates
  - dynamic_cast

\subsection cmp_fltk_1_4_x_restrictions FLTK 1.4.x Restrictions

The following C++ features may be not used in FLTK 1.4.x code:

  - Exceptions
  - Namespaces
  - Standard C++ headers and library
  - Templates
  - dynamic_cast

The `reinterpret_cast` keyword may be used but is not mandatory.

The `static_cast` and `const_cast` keywords should be used when casting pointers of different types.

The `dynamic_cast` keyword must not be used since run-time typing features may not be available at all times.

\subsection cmp_fltk_1_5_x_restrictions FLTK 1.5.x Restrictions

\todo This needs to be populated with the new restrictions/allowed c++ features.

\subsection cmp_source_file_naming Source File Naming

The current practice is to use an extension of ".c" for C source files,
".h" for C header files, ".cxx" for C++ source files, and ".H" for C++
header files in the "FL" directory (".h" otherwise.)

\todo Mention of the "fltk" namespace below is I think fltk2 specific, needs changes for 1.x.x

Function/Method/Variable Naming

All public (exported) functions and variables must be placed in the
"fltk" namespace. Except for constructor and destructor methods, the
names consist of lowercase words separated by the underscore ("_"),
e.g. "fltk::some_variable" and "text_color()". Private member variables
of classes end with an extra underscore, e.g. "text_size_".

\section cmp_struct_class_naming Structure/Class Naming

\todo The following needs modification; AFAIK we don't use the `fltk`
      namespace - I think that was an fltk2 thing - but we do recently
      make some use of `Fl` namespace (matt's recent tablet commits)

All public (exported) structures and classes must be placed in the
"fltk" namespace and consist of capitalized words without the underscore,
e.g. "fltk::SuperWidget".

Private members of classes must end with a trailing underscore ("_")
and have corresponding public access methods without the underscore as
applicable, e.g. "text_size_" and "text_size()".

\section cmp_constant_enum_naming Constant/Enumeration Naming

\todo The following needs modification regarding "fltk" namespace
      (this being an FLTK2 thing IIRC)

Public enumerations and constant variables must be placed inside the "fltk"
namespace and consist of UPPERCASE WORDS separated by the underscore ("_"),
e.g. "ALIGN_LEFT", "COLOR_RED", etc. Enumeration type names consist of
capitalized words without underscores, e.g. "MyEnum". `#define` constants
are prohibited aside from the include guard definitions.

\section cmp_preprocessor_variables Preprocessor Variables

File \c config.h and the C++ compilers define a few preprocessor variables
that help organizing platform-specific code and control access to a few
internal classes. Only code internal to the FLTK library can include the
\c config.h header file. Thus, FLTK header files that are part of the public
API must not, directly or indirectly, include \c config.h.

  - `_WIN32` identifies the MS-Windows platform (both for the 32- and 64-bit versions).
  Note: FLTK 1.3.x and earlier used \c WIN32 which had to be defined by the FLTK build
  system. FLTK 1.4.0 and later versions use \c `_WIN32` (with leading underscore) which
  should be defined by the build tools (preprocessor, compiler) on the Windows platform.

  - `__CYGWIN__` is defined when FLTK runs on Windows but uses Cygwin's POSIX
  emulation features (cygwin1.dll). No longer officially supported but \b may work.

  - `__APPLE__` identifies the macOS platform.

  - `FLTK_USE_X11` is defined by \c 'FL/fl_config.h' (since 1.4) when FLTK is built
    for the Xlib (aka `X`) graphics system. Thus, `FLTK_USE_X11` is defined
    - on Unix and Linux, if built for the X11 or the "hybrid" (X11 + Wayland) platform
    - on Windows, if `configure` used `--enable-cygwin` \b and `--enable-x11`.\n
      Note: FLTK 1.4 is the last minor FLTK version that supports `configure`.
  - Note: Xlib-specific code was also often delimited without reference to the `FLTK_USE_X11`
    macro (thus without the requirement to include \c FL/fl_config.h) as follows:
  \code
    #if defined(_WIN32)
      // Windows specific code ...
    #elif defined(__APPLE__)
      // macOS specific code ...
    #else
      // Xlib specific code ...
    #endif
  \endcode
    This \b must no longer be done because it could be ambiguous since the introduction of Wayland.

  - `FLTK_USE_WAYLAND` is defined by \c 'FL/fl_config.h' (since 1.4) if FLTK is built with
    Wayland support (either with or without X11 support). This is only possible on Linux, Unix,
    or similar platforms.

  - `USE_XFT` is defined by `config.h` if FLTK is built for X11 \b and CMake build option
    \c FLTK_USE_XFT has been enabled (\c ON).
    FLTK 1.4 and earlier: ... or the corresponding configure option `--use-xft`.
    It is set to 1 when the Xft library of scalable, anti-aliased fonts is
    used, and to 0 otherwise.
    Note: This variable is \b not accessible by user code (not in the public interface).
    It is considered an implementation detail.

  - `FL_LIBRARY` is defined by all FLTK library build systems when the FLTK library
    itself is compiled. Application program developers \b must \b not define
    it when compiling their programs.

  - `FL_INTERNALS` can be defined by application program developers to access certain 
    internal FLTK library classes (e.g., the `Fl_X` class) and some global variables
    and definitions (macros) if they need it. APIs to these internal classes are highly
    subject to changes, though.

  - `FL_DLL` is defined by the FLTK build system when building shared
  libraries (DLL's) with Visual Studio. Application program developers
  using Visual Studio and linking against the shared FLTK libraries (DLL's)
  built with Visual Studio must define this macro when compiling their
  source files. Note that this macro must be defined by the build system
  (VS project setup/properties) or on the compiler command line so it is
  "seen" by all included FLTK header files.
  <br><br>
  <br><br>
  - `FL_DOXYGEN` is defined when the Doxygen program that builds the FLTK
  documentation processes the source code. This variable has two major uses:
  <br><br>
   -# `#ifndef FL_DOXYGEN` / `#endif` allows to hide code from Doxygen.
   -# The Doxygen program does not define the platform-specific variables
   `__APPLE__` or `_WIN32` (even if it's run on macOS or Windows).
   Thus, platform-specific (say, macOS-specific) code must be bracketed
   as follows to be seen by Doxygen:
   \verbatim
   #if defined(__APPLE__) || defined(FL_DOXYGEN)
   ... Doxygen-visible, macOS-specific code ...
   #endif
   \endverbatim
  <br><br>
  - `FL_ABI_VERSION` is used to allow developers to implement ABI breaking code
  in Patch Releases. Normally set to the default ABI version for each minor
  version (for instance 10400 for all 1.4.x releases), can be changed by
  users or devs with configure or CMake to enable ABI breaking features
  for testing or use by end users in static builds of FLTK.
  <br><br>
  Note: This preprocessor variable was named FLTK_ABI_VERSION in FLTK
  1.3.x and was renamed to FL_ABI_VERSION since FLTK 1.4.0.
  <br><br>
  When set, the variable's value is expected to be the integer representation
  of the FLTK version number, where the Minor and Patch numbers are padded
  to two digits to allow for numbers 1 thru 99, e.g.
  \verbatim
  #define FL_ABI_VERSION 10401    // FLTK ABI version 1.4.1
        ..'1' is the major version (no padding; avoids octal issues)
        ..'04' is the minor version (2 digit padding)
        ..'01' is the patch version (2 digit padding)
  \endverbatim
  ABI breaking features are by default '\#ifdef'ed out with this variable
  during patch releases, and are merged in by developers during the next
  Minor Release.
  <br><br>
  Example: If the current patch release is 1.4.0, and the developer adds
  an ABI-breaking fix to what will be the next 1.4.1 release, then the
  new code would be implemented as:
  \verbatim
  #if FL_ABI_VERSION >= 10401  // FLTK 1.4.1, the next patch release #
  ... new ABI breaking code ...
  #else
  ... old non-ABI breaking (default builds) ...
  #endif
  \endverbatim
  This variable solves several issues:
   - Allows ABI breaking code to be implemented at any time by developers.
   - Gets fixes into Git sooner, so users can see, test and access it.
   - Testing ABI features during Patch Releases increases the stability of Minor Releases.
   - Prevents devs having to defer ABI breaking code to the small window of time preceding Minor Releases.

\section cmp_miscellaneous_coding_practices Miscellaneous Coding Practices


\subsection cmp_use_of_fallthrough Using switch() and 'FALLTHROUGH' Comments

When using switch/case statements, and your case statement does not end in
break in order to fall through to the next case statement, a
\code
  /* FALLTHROUGH */
\endcode
comment should be added where the break statement would be.


\subsection cmp_useful_vs_macros Useful Visual Studio C++ Macros (Windows)

Here's a list of Visual Studio compiler macros for main Visual Studio versions
that can be used to conditionalize code based on the Visual Studio version:

Version |  Product Name        | _MSC_VER
--------|----------------------|----------
  17.0  |  Visual Studio 2022  |   1930
  16.0  |  Visual Studio 2019  |   1920
  15.0  |  Visual Studio 2017  |   1910
  14.0  |  Visual Studio 2015  |   1900
  12.0  |  Visual Studio 2013  |   1800
  11.0  |  Visual Studio 2012  |   1700
  10.0  |  Visual Studio 2010  |   1600
   9.0  |  Visual Studio 2008  |   1500
   8.0  |  Visual Studio 2005  |   1400
   7.1  |  Visual Studio 2003  |   1310
   7.0  |  Visual Studio 7     |   1300
   6.0  |  Visual Studio 6     |   1200
   5.0  |  Visual Studio 5     |   1100

For details of other versions (patch releases like 15.8) see Microsoft docs.<br>
https://learn.microsoft.com/en-us/cpp/overview/compiler-versions

Recommended usage:

\verbatim
#if defined(_MSC_VER) && (_MSC_VER <= 1300)  /* VS7 and older */
  ..
#else  /* _MSC_VER */
  ..
#endif /* _MSC_VER */
\endverbatim


\subsection cmp_useful_xcode_macros Useful macOS C++ Macros

These macOS macros may be used to write code compatible with different macOS
versions. They are not necessary for standard FLTK user code but can be used
if macOS specific code is needed for an application or inside the FLTK library.

Below is a list of operating system version compiler macros that can be
used to conditionalize code based on the compile time (build host) and the
runtime version of the macOS operating system.

These are made available by Apple's `AvailabilityVersions.h` inside the
current / selected SDK.

\b outdated: For more info on these and other macros, see Apple's "TechNote 2064".
\todo Find current Apple / macOS docs for macOS version macros.

  Version | Macro                  |  Value | Product Name  | Release
  --------|------------------------|--------|---------------|--------
  10.0    | MAC_OS_X_VERSION_10_0  |   1000 | Cheetah       | 2001
  10.1    | MAC_OS_X_VERSION_10_1  |   1010 | Puma          | 2001
  10.2    | MAC_OS_X_VERSION_10_2  |   1020 | Jaguar        | 2002
  10.3    | MAC_OS_X_VERSION_10_3  |   1030 | Panther       | 2003
  10.4    | MAC_OS_X_VERSION_10_4  |   1040 | Tiger         | 2005
  10.5    | MAC_OS_X_VERSION_10_5  |   1050 | Leopard       | 2007
  10.6    | MAC_OS_X_VERSION_10_6  |   1060 | Snow Leopard  | 2009
  10.7    | MAC_OS_X_VERSION_10_7  |   1070 | Lion          | 2011
  10.8    | MAC_OS_X_VERSION_10_8  |   1080 | Mountain Lion | 2012
  10.9    | MAC_OS_X_VERSION_10_9  |   1090 | Mavericks     | 2013
  10.10   | MAC_OS_X_VERSION_10_10 | 101000 | Yosemite      | 2014
  10.11   | MAC_OS_X_VERSION_10_11 | 101100 | El Capitan    | 2015
  10.12   | MAC_OS_X_VERSION_10_12 | 101200 | Sierra        | 2016
  10.13   | MAC_OS_X_VERSION_10_13 | 101200 | High Sierra   | 2017
  10.14   | MAC_OS_X_VERSION_10_14 | 101200 | Mojave        | 2018
  10.15   | MAC_OS_X_VERSION_10_15 | 101200 | Catalina      | 2019
  11.0    | MAC_OS_VERSION_11_0    | 110000 | Big Sur       | 2020
  12.0    | MAC_OS_VERSION_12_0    | 120000 | Monterey      | 2021
  13.0    | MAC_OS_VERSION_13_0    | 130000 | Ventura       | 2022
  14.0    | MAC_OS_VERSION_14_0    | 140000 | Sonoma        | 2023
  15.0    | MAC_OS_VERSION_15_0    | 150000 | Sequoia       | 2024
  26.0    | MAC_OS_VERSION_26_0    | 260000 | Tahoe         | 2025

Notes:
 - The \c Value column is in decimal notation
 - The macro name is MAC_OS_X_VERSION_* up to MacOS X 10.15 (Catalina)
 - The macro name is MAC_OS_VERSION_* (without \c '_X') since macOS 11 (Big Sur)
 - There \e is a gap in version numbers from 15 to 26 because newer versions of
   macOS reflect the release year (+1), e.g. version 26 was released in 2025.
 - The \c Release column (release year) has been included in this table for
   reference. We may use the release date to decide whether we support a
   particular macOS version.
 - See README.macOS.md about which macOS versions FLTK supports.

\b Note: \c MAC_OS_X_VERSION_MAX_ALLOWED is defined automatically by the build system and
represents the highest macOS version the library has been built for. The default
is the SDK version used to build the library. It can be modified by setting the
CMake cache variable CMAKE_OSX_DEPLOYMENT_TARGET to a specific macOS version.

Example:
 - CMAKE_OSX_DEPLOYMENT_TARGET = 15.4
 - -> MAC_OS_X_VERSION_MAX_ALLOWED = 150400

Recommended usage and requirements (include files):

\code
  #define FL_INTERNALS 1        // required to define "internal" macros, define before:
  #include <FL/platform.H>      // defines the MAC_OS_*VERSION_* macros (see table above)

  #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
  if (fl_mac_os_version >= 100500) {
    // macOS 10.5 and newer..
  } else
  #else
  {
    // macOS 10.4 and older..
  }
  #endif
\endcode

This way, code compiled before and after macOS 10.5 will be able to run
on computers running macOS versions before and after 10.5. Modify version
numbers as applicable for specific macOS versions.


\subsection cmp_useful_gnu_macros Useful GNU C++ Macros

\todo To be done.


\section cmp_coding_source_files Source Files

Each source file shall be placed in a sub-directory corresponding to the software
sub-system it belongs to ("fltk", "OpenGL", etc.).

\todo rework paragraph above, explain "sub-systems" and directory names

Source files shall be documented and formatted as described in the Coding
Standards section. To remain compatible with case-insensitive filesystems,
no two filenames and/or directory names shall differ only by the case of the
letters in the name.

C source files shall have an extension of ".c". C++ source files shall have
an extension of ".cxx". Header files shall have an extension of ".h". Public
FLTK 1.x headers (i.e. those in or below the \c FL/ directory) shall have an
extension of ".H", private headers in source directories shall have an
extension of ".h".

<table>
  <tr><th>
    <center><b>Why use the ".cxx" extension?</b></center>
  </th></tr>
  <tr><td>
    C++ source files can have any of the following extensions on various
    platforms: ".C", ".cc", ".cpp", ".cxx". Only the ".cxx" extension is
    universally recognized by C++ compilers as a C++ source file - ".C"
    is not usable on macOS and Windows, ".cc" is not usable on Windows, and
    ".cpp" is historically considered C preprocessor output on UNIX.
    <p>
    Since not all make programs handle C++ source files with the ".cxx"
    extension, the FLTK build system explicitly defines makefile rules
    for compiling C++ source files with an extension of ".cxx".
  </td></tr>
</table>

IDE/compiler support source files (project files, workspaces, makefiles, etc.)
shall have extensions as required by the IDE/compiler tool.
\todo remove this paragraph in FLTK 1.5, remove this 'todo' in 1.4.

Header files must utilitize so-called "guard" definitions to prevent multiple
inclusion. The guard definitions are named using the full path in the FLTK
source tree, e.g.:

    FL/Fl.H becomes _FL_Fl_H_
    fluid/foo.h becomes _fluid_foo_h_

Any non-alphanumeric (letters and numbers) characters are replaced with the
underscore (_) character, and leading and trailing underscores are added to
limit global namespace pollution.


\section cmp_practices_cmake Build System (CMake)

The FLTK build system uses CMake to tailor the library to the local operating
system. Since FLTK 1.4 the primary and recommended build system is CMake. The
older autoconf/configure builds are no longer supported as of FLTK 1.5.x.

To improve portability, Makefiles must not make use of the unique features
offered by GNU make. See the Makefile Standards section for a description
of the allowed make features and makefile guidelines.
\todo Remove this paragraph in 1.5,

Additional GNU build programs such as GNU automake and GNU libtool must
not be used. GNU automake produces non-portable Makefiles which depend
on GNU-specific extensions, and GNU libtool is not portable or reliable
enough for FLTK.

Note: Starting with FLTK 1.4.0 we do no longer bundle IDE files for
Microsoft Windows (Visual Studio) and macOS (Xcode). IDE environments
(project files) can be generated with CMake. See README.CMake.txt for more
information about using CMake.

*/