summaryrefslogtreecommitdiff
path: root/FL/core/events.H
blob: 8454fc501d8b47e7a9e20cd1933499ee42bfe6d8 (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
//
// Global event header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 2025 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
//

/** \file FL/core/events.H
  \brief Global event handling variables and functions.
  This file is included within class Fl in FL/Fl.H.
*/

// --- Event Variables (Internal) ---
// Note: These variables should be private, but would harm back compatibility.

#ifndef FL_DOXYGEN

// Core event information
static FL_EXPORT int                e_number;           ///< Current event type
static FL_EXPORT int                e_state;            ///< Keyboard/mouse button states

// Mouse position and movement
static FL_EXPORT int                e_x;                ///< Mouse X position (window relative)
static FL_EXPORT int                e_y;                ///< Mouse Y position (window relative)
static FL_EXPORT int                e_x_root;           ///< Mouse X position (screen absolute)
static FL_EXPORT int                e_y_root;           ///< Mouse Y position (screen absolute)
static FL_EXPORT int                e_dx;               ///< Mouse wheel horizontal delta
static FL_EXPORT int                e_dy;               ///< Mouse wheel vertical delta

// Mouse click handling
static FL_EXPORT int                e_clicks;           ///< Number of consecutive clicks
static FL_EXPORT int                e_is_click;         ///< True if event qualifies as click

// Keyboard event data
static FL_EXPORT int                e_keysym;           ///< Key symbol for current event
static FL_EXPORT int                e_original_keysym;  ///< Original key before NumLock translation
static FL_EXPORT char*              e_text;             ///< Text associated with key event
static FL_EXPORT int                e_length;           ///< Length of text in e_text

// Clipboard data (for paste events)
static FL_EXPORT void*              e_clipboard_data;   ///< Pasted data pointer
static FL_EXPORT const char*        e_clipboard_type;   ///< Type of pasted data

// Event handling infrastructure
static FL_EXPORT Fl_Event_Dispatch  e_dispatch;         ///< Custom event dispatcher
static FL_EXPORT Fl_Callback_Reason callback_reason_;   ///< Reason for current callback

// Widget state tracking
static FL_EXPORT Fl_Widget*         belowmouse_;        ///< Widget under mouse cursor
static FL_EXPORT Fl_Widget*         pushed_;            ///< Widget receiving drag events
static FL_EXPORT Fl_Widget*         focus_;             ///< Widget with keyboard focus

// Event variables should be private, but would harm back compatibility.

#endif // FL_DOXYGEN


/** \defgroup fl_events Events handling functions
      Fl class events handling API declared in <FL/Fl.H>
      @{
*/

//
// Event Information Functions
//

/**
  Returns the last event that was processed. This can be used
  to determine if a callback is being done in response to a
  keypress, mouse click, etc.
*/
static FL_EXPORT inline int event()                    { return e_number; }

//
// Mouse Position Functions
//

/**
  Returns the mouse position of the event relative to the Fl_Window
  it was passed to.
*/
static FL_EXPORT inline int event_x()                  { return e_x; }

/**
  Returns the mouse position of the event relative to the Fl_Window
  it was passed to.
*/
static FL_EXPORT inline int event_y()                  { return e_y; }

/**
  Returns the mouse position on the screen of the event.  To find the
  absolute position of an Fl_Window on the screen, use the
  difference between event_x_root(),event_y_root() and
  event_x(),event_y().
*/
static FL_EXPORT inline int event_x_root()             { return e_x_root; }

/**
  Returns the mouse position on the screen of the event.  To find the
  absolute position of an Fl_Window on the screen, use the
  difference between event_x_root(),event_y_root() and
  event_x(),event_y().
*/
static FL_EXPORT inline int event_y_root()             { return e_y_root; }

//
// Mouse Wheel Functions
//

/**
  Returns the current horizontal mouse scrolling associated with the
  FL_MOUSEWHEEL event. Right is positive.
*/
static FL_EXPORT inline int event_dx()                 { return e_dx; }

/**
  Returns the current vertical mouse scrolling associated with the
  FL_MOUSEWHEEL event. Down is positive.
*/
static FL_EXPORT inline int event_dy()                 { return e_dy; }

//
// Mouse Query Functions
//

/**
  Return where the mouse is on the screen by doing a round-trip query to
  the server.  You should use Fl::event_x_root() and
  Fl::event_y_root() if possible, but this is necessary if you are
  not sure if a mouse event has been processed recently (such as to
  position your first window).  If the display is not open, this will
  open it.
*/
static FL_EXPORT void get_mouse(int &,int &);

//
// Mouse Click Functions
//

/**
  Returns non zero if we had a double click event.
  \retval Non-zero if the most recent FL_PUSH or FL_KEYBOARD was a "double click".
  \retval  N-1 for  N clicks.
  A double click is counted if the same button is pressed
  again while event_is_click() is true.

 */
static FL_EXPORT inline int event_clicks()             { return e_clicks; }

/**
  Manually sets the number returned by Fl::event_clicks().
  This can be used to set it to zero so that
  later code does not think an item was double-clicked.
  \param[in] i corresponds to no double-click if 0, i+1 mouse clicks otherwise
  \see int event_clicks()
*/
static FL_EXPORT inline void event_clicks(int i)       { e_clicks = i; }

/**
  Returns non-zero if the mouse has not moved far enough
  and not enough time has passed since the last FL_PUSH or
  FL_KEYBOARD event for it to be considered a "drag" rather than a
  "click".  You can test this on FL_DRAG, FL_RELEASE,
  and FL_MOVE events.
*/
static FL_EXPORT inline int event_is_click()           { return e_is_click; }

/**
 Clears the value returned by Fl::event_is_click().
 Useful to prevent the <I>next</I>
 click from being counted as a double-click or to make a popup menu
 pick an item with a single click.  Don't pass non-zero to this.
*/
static FL_EXPORT inline void event_is_click(int i)     { e_is_click = i; }

//
// Mouse Button Functions
//

/**
  Gets which particular mouse button caused the current event.

  This returns garbage if the most recent event was not a FL_PUSH or FL_RELEASE event.
  \retval FL_LEFT_MOUSE
  \retval FL_MIDDLE_MOUSE
  \retval FL_RIGHT_MOUSE
  \retval FL_BACK_MOUSE
  \retval FL_FORWARD_MOUSE
  \see Fl::event_buttons(), Fl::event_state()
*/
static FL_EXPORT inline int event_button()             { return e_keysym - FL_Button; }

//
// Event State Functions
//

/**
  Returns the keyboard and mouse button states of the last event.

  This is a bitfield of what shift states were on and what mouse buttons
  were held down during the most recent event.

  \note FLTK platforms differ in what Fl::event_state() returns when it is called
    while a modifier key or mouse button is being pressed or released.

  - Under X11, Fl::event_state() indicates the state of the modifier keys and
    mouse buttons just \b prior to the event. Thus, during the \c FL_KEYDOWN event generated
    when pressing the shift key, for example, the \c FL_SHIFT bit of event_state() is 0 and
    becomes 1 only at the next event which can be any other event, including e.g. \c FL_MOVE.
  - Fl::event_state() returns the same value under all platforms when it's called while a
    non-modifier key (e.g. a letter or function key) is being pressed or released.
  - X servers do not agree on shift states, and \c FL_NUM_LOCK, \c FL_META, and \c FL_SCROLL_LOCK
    may not work.
  - The values were selected to match the XFree86 server on Linux.

  The legal event state bits are:

    | Device   | State Bit      | Key or Button           | Since  |
    |----------|----------------|-------------------------|--------|
    | Keyboard | FL_SHIFT       | Shift                   |        |
    | Keyboard | FL_CAPS_LOCK   | Caps Lock               |        |
    | Keyboard | FL_CTRL        | Ctrl                    |        |
    | Keyboard | FL_ALT         | Alt                     |        |
    | Keyboard | FL_NUM_LOCK    | Num Lock                |        |
    | Keyboard | FL_META        | Meta, e.g. "Windows"    |        |
    | Keyboard | FL_SCROLL_LOCK | Scroll Lock             |        |
    | Mouse    | FL_BUTTON1     | left button             |        |
    | Mouse    | FL_BUTTON2     | middle button           |        |
    | Mouse    | FL_BUTTON3     | right button            |        |
    | Mouse    | FL_BUTTON4     | side button 1 (back)    | 1.3.10 |
    | Mouse    | FL_BUTTON5     | side button 2 (forward) | 1.3.10 |
*/
static FL_EXPORT inline int event_state()              { return e_state; }

/** Returns non-zero if any of the passed event state bits are turned on.

  Use \p mask to pass the event states you're interested in.
  The legal event state bits are defined in Fl::event_state().
*/
static FL_EXPORT inline int event_state(int mask)      { return e_state & mask; }

//
// Keyboard Event Functions
//

/**
  Gets which key on the keyboard was last pushed.

  The returned integer 'key code' is not necessarily a text
  equivalent for the keystroke. For instance: if someone presses '5' on the
  numeric keypad with numlock on, Fl::event_key() may return the 'key code'
  for this key, and NOT the character '5'. To always get the '5', use Fl::event_text() instead.

  \returns an integer 'key code', or 0 if the last event was not a key press or release.
  \see int event_key(int), event_text(), compose(int&).
*/
static FL_EXPORT inline int event_key()                { return e_keysym; }

/**
  Returns the keycode of the last key event, regardless of the NumLock state.

  If NumLock is deactivated, FLTK translates events from the
  numeric keypad into the corresponding arrow key events.
  event_key() returns the translated key code, whereas
  event_original_key() returns the keycode before NumLock translation.
*/
static FL_EXPORT inline int event_original_key()       { return e_original_keysym; }

/**
  Returns true if the given \p key was held
  down (or pressed) <I>during</I> the last event.  This is constant until
  the next event is read from the server.

  Fl::get_key(int) returns true if the given key is held down <I>now</I>.
  Under X this requires a round-trip to the server and is <I>much</I>
  slower than Fl::event_key(int).

  Keys are identified by the <I>unshifted</I> values. FLTK defines a
  set of symbols that should work on most modern machines for every key
  on the keyboard:

  \li All keys on the main keyboard producing a printable ASCII
      character use the value of that ASCII character (as though shift,
      ctrl, and caps lock were not on). The space bar is 32.
  \li All keys on the numeric keypad producing a printable ASCII
      character use the value of that ASCII character plus FL_KP
      (e.g., FL_KP + '4', FL_KP + '/').
      The highest possible value is FL_KP_Last so you can
      range-check to see if something is  on the keypad.
  \li All numbered function keys use the number on the function key plus
      FL_F.  The highest possible number is FL_F_Last, so you
      can range-check a value.
  \li Buttons on the mouse are considered keys, and use the button
      number (where the left button is 1) plus FL_Button.
  \li All other keys on the keypad have a symbol: FL_Escape,
      FL_BackSpace, FL_Tab, FL_Enter, FL_Print, FL_Scroll_Lock, FL_Pause,
      FL_Insert, FL_Home, FL_Page_Up, FL_Delete, FL_End, FL_Page_Down,
      FL_Left, FL_Up, FL_Right, FL_Down, FL_Iso_Key, FL_Shift_L, FL_Shift_R,
      FL_Control_L, FL_Control_R, FL_Caps_Lock, FL_Alt_L, FL_Alt_R,
      FL_Meta_L, FL_Meta_R, FL_Menu, FL_Num_Lock, FL_KP_Enter.  Be
      careful not to confuse these with the very similar, but all-caps,
      symbols used by Fl::event_state().

  On X Fl::get_key(FL_Button+n) does not work.
*/
static FL_EXPORT int event_key(int key);

/**
  Returns true if the given \p key is held down <I>now</I>.
  Under X this requires a round-trip to the server and is <I>much</I>
  slower than Fl::event_key(int). \see event_key(int)
*/
static FL_EXPORT int get_key(int key); // platform dependent

//
// Text and Clipboard Functions
//

/**
  Returns the text associated with the current event, including FL_PASTE or FL_DND_RELEASE events.
  This can be used in response to FL_KEYUP, FL_KEYDOWN, FL_PASTE, and FL_DND_RELEASE.

  When responding to FL_KEYUP/FL_KEYDOWN, use this function instead of Fl::event_key()
  to get the text equivalent of keystrokes suitable for inserting into strings
  and text widgets.

  The returned string is guaranteed to be NULL terminated.
  However, see Fl::event_length() for the actual length of the string,
  in case the string itself contains NULLs that are part of the text data.

  \returns A NULL terminated text string equivalent of the last keystroke.
 */
static FL_EXPORT inline const char* event_text()       { return e_text; }

/**
  Returns the length of the text in Fl::event_text(). There
  will always be a nul at this position in the text. However there may
  be a nul before that if the keystroke translates to a nul character or
  you paste a nul character.
*/
static FL_EXPORT inline int event_length()             { return e_length; }

/**  Denotes plain textual data
 */
static FL_EXPORT char const * const clipboard_plain_text;

/**  Denotes image data
 */
static FL_EXPORT char const * const clipboard_image;

/** During an FL_PASTE event of non-textual data, returns a pointer to the pasted data.
 The returned data is an Fl_RGB_Image * when the result of Fl::event_clipboard_type() is Fl::clipboard_image.
 */
static FL_EXPORT inline void *event_clipboard()        { return e_clipboard_data; }

/** Returns the type of the pasted data during an FL_PASTE event.
 This type can be Fl::clipboard_plain_text or Fl::clipboard_image.
 */
static FL_EXPORT inline const char *event_clipboard_type() { return e_clipboard_type; }


//
// Advanced Event Functions
//

static FL_EXPORT int compose(int &del);
static FL_EXPORT void compose_reset();
static FL_EXPORT int event_inside(int,int,int,int);
static FL_EXPORT int event_inside(const Fl_Widget*);
static FL_EXPORT int test_shortcut(Fl_Shortcut);

static FL_EXPORT void enable_im();
static FL_EXPORT void disable_im();

//
// Event Handling and Widget Management
//

static FL_EXPORT int handle(int, Fl_Window*);
static FL_EXPORT int handle_(int, Fl_Window*);

/**  Gets the widget that is below the mouse.
     \see  belowmouse(Fl_Widget*) */
static FL_EXPORT inline Fl_Widget* belowmouse()        { return belowmouse_; }
static FL_EXPORT void belowmouse(Fl_Widget*);

/** Gets the widget that is being pushed.
    \see void pushed(Fl_Widget*) */
static FL_EXPORT inline Fl_Widget* pushed()            { return pushed_; }
static FL_EXPORT void pushed(Fl_Widget*);

/** Gets the current Fl::focus() widget. \sa Fl::focus(Fl_Widget*) */
static FL_EXPORT inline Fl_Widget* focus()             { return focus_; }
static FL_EXPORT void focus(Fl_Widget*);

static FL_EXPORT void add_handler(Fl_Event_Handler ha);
static FL_EXPORT void add_handler(Fl_Event_Handler ha, Fl_Event_Handler before);
static FL_EXPORT Fl_Event_Handler last_handler();
static FL_EXPORT void remove_handler(Fl_Event_Handler h);
static FL_EXPORT void add_system_handler(Fl_System_Handler h, void *data);
static FL_EXPORT void remove_system_handler(Fl_System_Handler h);
static FL_EXPORT void event_dispatch(Fl_Event_Dispatch d);
static FL_EXPORT Fl_Event_Dispatch event_dispatch();
static FL_EXPORT Fl_Callback_Reason callback_reason();

//
// Convenience State Check Functions
//

/** Returns non-zero if the Shift key is pressed. */
static FL_EXPORT inline int event_shift()              { return e_state & FL_SHIFT; }

/** Returns non-zero if the Control key is pressed. */
static FL_EXPORT inline int event_ctrl()               { return e_state & FL_CTRL; }

/** Returns non-zero if the FL_COMMAND key is pressed, either FL_CTRL or on OSX FL_META. */
static FL_EXPORT inline int event_command()            { return e_state & FL_COMMAND; }

/** Returns non-zero if the Alt key is pressed. */
static FL_EXPORT inline int event_alt()                { return e_state & FL_ALT; }

//
// Mouse Button State Functions
//

/**
  Returns the mouse buttons state bits; if non-zero, then at least one
  button is pressed now.  This function returns the button state at the
  time of the event. During an FL_RELEASE event, the state
  of the released button will be 0. To find out, which button
  caused an FL_RELEASE event, you can use Fl::event_button() instead.
  \return a bit mask value like { [FL_BUTTON1] | [FL_BUTTON2] | ... | [FL_BUTTON5] }
*/
static FL_EXPORT inline int event_buttons()            { return e_state & FL_BUTTONS; }

/**
  Returns non-zero if mouse button 1 is currently held down.
  For more details, see Fl::event_buttons().
*/
static FL_EXPORT inline int event_button1()            { return e_state & FL_BUTTON1; }

/**
  Returns non-zero if mouse button 2 is currently held down.
  For more details, see Fl::event_buttons().
*/
static FL_EXPORT inline int event_button2()            { return e_state & FL_BUTTON2; }

/**
  Returns non-zero if mouse button 3 is currently held down.
  For more details, see Fl::event_buttons().
*/
static FL_EXPORT inline int event_button3()            { return e_state & FL_BUTTON3; }

/**
  Returns non-zero if mouse button 4 is currently held down.
  For more details, see Fl::event_buttons().
*/
static FL_EXPORT inline int event_button4()            { return e_state & FL_BUTTON4; }

/**
  Returns non-zero if mouse button 5 is currently held down.
  For more details, see Fl::event_buttons().
*/
static FL_EXPORT inline int event_button5()            { return e_state & FL_BUTTON5; }

/**   @} */