4 * The freeglut library callback macro file.
6 * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
7 * Written by Pawel W. Olszta, <olszta@sourceforge.net>
8 * Creation date: Thu Dec 2 1999
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #ifndef FREEGLUT_CALLBACK_MACROS_H
29 #define FREEGLUT_CALLBACK_MACROS_H
31 #ifndef FREEGLUT_INTERNAL_H
32 #error "fg_internal.h needs to be included before this header"
37 * FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK: if the compiler supports GCC's varadic macro implementation (AKA, ##__VA_ARGS__)
38 * FG_COMPILER_SUPPORTS_VA_ARGS: if the compiler supports varadic macros
41 #ifdef FG_COMPILER_SUPPORTS_GCC_VA_ARGS_HACK
44 * EXPAND_WCB() is used as:
48 * ... where {(arg_list)} is the parameter list.
50 * This will take the arg_list and extend it by one argument, adding
51 * the argument "userData" to the end of the list.
53 * All additional args are to get around trailing ',', argument counts,
54 * and not needing a GCC extension to make this work.
57 * http://stackoverflow.com/questions/5355241/generating-function-declaration-using-a-macro-iteration/5355946#5355946
61 * GCC-specific design that doesn't require per-callback defines
63 * The naming is terrible... and it's very convuluted and complex, but
64 * should not require any modification unless additional arguments are to
67 * Supports callbacks up to 5 args (follow the pattern of PP_HAS_ARGS_IMPL2
68 * and PP_HAS_ARGS_SOURCE to add more)
73 #define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
75 #define PP_HAS_ARGS_IMPL2(_0, _1, _2, _3, _4, _5, N, ...) N
76 #define PP_HAS_ARGS_SOURCE() ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ONE_OR_MORE, ZERO
78 #define PP_HAS_ARGS_IMPL(...) PP_HAS_ARGS_IMPL2( __VA_ARGS__ )
79 #define PP_HAS_ARGS(...) PP_HAS_ARGS_IMPL( NOT_EXIST, ##__VA_ARGS__, PP_HAS_ARGS_SOURCE() )
81 #define EXPAND_WCB_ZERO(args, userData) ( userData )
82 #define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
84 #define EXPAND_WCB_DISAMBIGUATE2(has_args, args, userData) EXPAND_WCB_ ## has_args ( args, userData )
85 #define EXPAND_WCB_DISAMBIGUATE(has_args, args, userData) EXPAND_WCB_DISAMBIGUATE2( has_args, args, userData )
87 #define EXPAND_WCB_UNWRAP_ARGS2(args, userData) EXPAND_WCB_DISAMBIGUATE( PP_HAS_ARGS args, args, userData )
88 #define EXPAND_WCB_UNWRAP_ARGS(args) EXPAND_WCB_UNWRAP_ARGS2 args
90 #define EXPAND_WCB(cbname) EXPAND_WCB_UNWRAP_ARGS
95 * EXPAND_WCB() is used as:
97 * EXPAND_WCB( cbname )(( arg_list, userData ))
99 * ... where {(arg_list)} is the parameter list and userData is user
102 * This will take the arg_list and extend it by one argument, adding
103 * the argument "userData" to the end of the list.
105 * In order for this to work, each callback must have a define that
106 * properly handles the arguments as needed by the callback.
107 * This callback is in the format of EXPAND_WCB_SUB_<cbname>.
108 * Helper functions exist for zero to five parameters: EXPAND_WCB_ZERO,
109 * EXPAND_WCB_ONE, EXPAND_WCB_TWO, EXPAND_WCB_THREE< EXPAND_WCB_FOUR,
110 * and EXPAND_WCB_FIVE. Each handle the callback argument counts.
112 * An example for the "Entry" callback, where "Entry" is the cbname:
113 * typedef void (* FGCBEntry )( int );
114 * typedef void (* FGCBEntryUC)( int, FGCBUserData );
115 * #define EXPAND_WCB_SUB_Entry(args) EXPAND_WCB_ONE args
118 #define FG_COMPILER_SUPPORTS_VA_ARGS //XXX (should be compiler defined)
119 #ifdef FG_COMPILER_SUPPORTS_VA_ARGS
121 #define EXPAND_WCB_UNPARAN(...) __VA_ARGS__
122 #define EXPAND_WCB_ONE_OR_MORE(args, userData) ( EXPAND_WCB_UNPARAN args, userData )
124 #define EXPAND_WCB_ONE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
125 #define EXPAND_WCB_TWO(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
126 #define EXPAND_WCB_THREE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
127 #define EXPAND_WCB_FOUR(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
128 #define EXPAND_WCB_FIVE(args, userData) EXPAND_WCB_ONE_OR_MORE( args, userData )
133 #error "Compiler does not support varadic argument macros"
137 #define EXPAND_WCB_ZERO(args, userData) ( userData )
139 #define EXPAND_WCB(cbname) EXPAND_WCB_SUB_ ## cbname
142 * Freeglut callbacks type definitions macros
144 * Every time a callback is updated in fg_internal.h is updated, this needs updated
145 * if argument counts change, new callbacks are added, or callbacks are removed.
148 #define EXPAND_WCB_SUB_Display(args) EXPAND_WCB_ZERO args
149 #define EXPAND_WCB_SUB_Reshape(args) EXPAND_WCB_TWO args
150 #define EXPAND_WCB_SUB_Position(args) EXPAND_WCB_TWO args
151 #define EXPAND_WCB_SUB_Visibility(args) EXPAND_WCB_ONE args
152 #define EXPAND_WCB_SUB_Keyboard(args) EXPAND_WCB_THREE args
153 #define EXPAND_WCB_SUB_KeyboardUp(args) EXPAND_WCB_THREE args
154 #define EXPAND_WCB_SUB_Special(args) EXPAND_WCB_THREE args
155 #define EXPAND_WCB_SUB_SpecialUp(args) EXPAND_WCB_THREE args
156 #define EXPAND_WCB_SUB_Mouse(args) EXPAND_WCB_FOUR args
157 #define EXPAND_WCB_SUB_MouseWheel(args) EXPAND_WCB_FOUR args
158 #define EXPAND_WCB_SUB_Motion(args) EXPAND_WCB_TWO args
159 #define EXPAND_WCB_SUB_Passive(args) EXPAND_WCB_TWO args
160 #define EXPAND_WCB_SUB_Entry(args) EXPAND_WCB_ONE args
161 #define EXPAND_WCB_SUB_WindowStatus(args) EXPAND_WCB_ONE args
162 #define EXPAND_WCB_SUB_Joystick(args) EXPAND_WCB_FOUR args
163 #define EXPAND_WCB_SUB_OverlayDisplay(args) EXPAND_WCB_ZERO args
164 #define EXPAND_WCB_SUB_SpaceMotion(args) EXPAND_WCB_THREE args
165 #define EXPAND_WCB_SUB_SpaceRotation(args) EXPAND_WCB_THREE args
166 #define EXPAND_WCB_SUB_SpaceButton(args) EXPAND_WCB_TWO args
167 #define EXPAND_WCB_SUB_Dials(args) EXPAND_WCB_TWO args
168 #define EXPAND_WCB_SUB_ButtonBox(args) EXPAND_WCB_TWO args
169 #define EXPAND_WCB_SUB_TabletMotion(args) EXPAND_WCB_TWO args
170 #define EXPAND_WCB_SUB_TabletButton(args) EXPAND_WCB_FOUR args
171 #define EXPAND_WCB_SUB_Destroy(args) EXPAND_WCB_ZERO args
172 #define EXPAND_WCB_SUB_MultiEntry(args) EXPAND_WCB_TWO args
173 #define EXPAND_WCB_SUB_MultiButton(args) EXPAND_WCB_FIVE args
174 #define EXPAND_WCB_SUB_MultiMotion(args) EXPAND_WCB_THREE args
175 #define EXPAND_WCB_SUB_MultiPassive(args) EXPAND_WCB_THREE args
176 #define EXPAND_WCB_SUB_InitContext(args) EXPAND_WCB_ZERO args
177 #define EXPAND_WCB_SUB_AppStatus(args) EXPAND_WCB_ONE args
181 #endif /* FREEGLUT_CALLBACK_MACROS_H */
183 /*** END OF FILE ***/