This repository has been archived by the owner on Mar 6, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreb-event.h
163 lines (130 loc) · 5.32 KB
/
reb-event.h
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
//
// File: %reb-event.h
// Summary: "REBOL event definitions"
// Project: "Rebol 3 Interpreter and Run-time (Ren-C branch)"
// Homepage: https://github.com/metaeducation/ren-c/
//
//=////////////////////////////////////////////////////////////////////////=//
//
// Copyright 2012 REBOL Technologies
// Copyright 2012-2019 Ren-C Open Source Contributors
// REBOL is a trademark of REBOL Technologies
//
// See README.md and CREDITS.md for more information.
//
// Licensed under the Lesser GPL, Version 3.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.gnu.org/licenses/lgpl-3.0.html
//
//=////////////////////////////////////////////////////////////////////////=//
//
// Events are unusual for datatypes defined in extensions, because they use
// a pre-reserved REB_EVENT byte ID in the header to identify the cell type.
// This means they don't have to sacrifice the "EXTRA" uintptr_t field for
// the extension type identity, and can fit an entire event in one cell.
//
// EVENT EXTRA CONTAINS 4 BYTES
//
// uint8_t type; // event id (mouse-move, mouse-button, etc)
// uint8_t flags; // special flags
// uint8_t win; // window id
// uint8_t model; // port, object, gui, callback
//
// EVENT PAYLOAD CONTAINS 2 POINTER-SIZED THINGS
//
// "eventee": REBSER* (port or object)
// "data": "an x/y position or keycode (raw/decoded)"
//
#define REBEVT REBVAL
#define VAL_EVENT_TYPE(v) \
cast(SymId, FIRST_UINT16(EXTRA(Any, (v)).u))
inline static void SET_VAL_EVENT_TYPE(REBVAL *v, SymId sym) {
SET_FIRST_UINT16(EXTRA(Any, (v)).u, sym);
}
// 8-bit event flags (space is at a premium to keep events in a single cell)
enum {
EVF_COPIED = 1 << 0, // event data has been copied !!! REVIEW const abuse
EVF_HAS_XY = 1 << 1, // map-event will work on it
EVF_DOUBLE = 1 << 2, // double click detected
EVF_CONTROL = 1 << 3,
EVF_SHIFT = 1 << 4
};
#define EVF_MASK_NONE 0
#define VAL_EVENT_FLAGS(v) \
THIRD_BYTE(EXTRA(Any, (v)).u)
#define mutable_VAL_EVENT_FLAGS(v) \
mutable_THIRD_BYTE(EXTRA(Any, (v)).u)
//=//// EVENT NODE and "EVENT MODEL" //////////////////////////////////////=//
//
// Much of the single-cell event's space is used for flags, but it can store
// one pointer's worth of "eventee" data indicating the object that the event
// was for--the PORT!, GOB!, etc.
//
// (Note: R3-Alpha also had something called a "callback" which pointed the
// event to the "system.ports.callback port", but there seemed to be no uses.)
//
// In order to keep the core GC agnostic about events, if the pointer's slot
// is to something that needs to participate in GC behavior, it must be a
// Node* and the cell must be marked with CELL_FLAG_PAYLOAD_FIRST_IS_NODE.
//
enum {
EVM_PORT, // event holds port pointer
EVM_OBJECT, // event holds object context pointer
EVM_GUI, // GUI event uses system/view/event/port
EVM_CALLBACK, // Callback event uses system.ports.callback port
EVM_MAX
};
#define VAL_EVENT_MODEL(v) \
FOURTH_BYTE(EXTRA(Any, (v)).u)
#define mutable_VAL_EVENT_MODEL(v) \
mutable_FOURTH_BYTE(EXTRA(Any, (v)).u)
#define VAL_EVENT_NODE(v) \
VAL_NODE1(v)
#define SET_VAL_EVENT_NODE(v,p) \
INIT_VAL_NODE1((v), (p))
#define VAL_EVENT_DATA(v) \
PAYLOAD(Any, (v)).second.u
// Position event data.
//
// Note: There was a use of VAL_EVENT_XY() for optimized comparison. This
// would violate strict aliasing, as you must read and write the same types,
// with the sole exception being char* access. If the fields are assigned
// through uint16_t pointers, you can't read the aggregate with uint32_t.
#define VAL_EVENT_X(v) \
FIRST_UINT16(VAL_EVENT_DATA(v))
inline static void SET_VAL_EVENT_X(REBVAL *v, uint16_t x) {
SET_FIRST_UINT16(VAL_EVENT_DATA(v), x);
}
#define VAL_EVENT_Y(v) \
SECOND_UINT16(VAL_EVENT_DATA(v))
inline static void SET_VAL_EVENT_Y(REBVAL *v, uint16_t y) {
SET_SECOND_UINT16(VAL_EVENT_DATA(v), y);
}
// Key event data (Ren-C expands to use SYM_XXX for named keys; it would take
// an alternate/expanded cell format for EVENT! to store a whole String(*))
//
// Note: It appears the keycode was zeroed when a keysym was assigned, so you
// can only have one or the other.
#define VAL_EVENT_KEYSYM(v) \
cast(SymId, FIRST_UINT16(VAL_EVENT_DATA(v)))
#define SET_VAL_EVENT_KEYSYM(v,keysym) \
SET_FIRST_UINT16(VAL_EVENT_DATA(v), (keysym))
#define VAL_EVENT_KEYCODE(v) \
SECOND_UINT16(VAL_EVENT_DATA(v))
#define SET_VAL_EVENT_KEYCODE(v,keycode) \
SET_SECOND_UINT16(VAL_EVENT_DATA(v), (keycode))
// !!! These hooks allow the REB_EVENT cell type to dispatch to code in the
// EVENT! extension if it is loaded.
//
extern REBINT CT_Event(noquote(Cell(const*)) a, noquote(Cell(const*)) b, bool strict);
extern Bounce MAKE_Event(Frame(*) frame_, enum Reb_Kind kind, option(const REBVAL*) parent, const REBVAL *arg);
extern Bounce TO_Event(Frame(*) frame_, enum Reb_Kind kind, const REBVAL *arg);
extern void MF_Event(REB_MOLD *mo, noquote(Cell(const*)) v, bool form);
extern REBTYPE(Event);
// !!! The port scheme is also being included in the extension.
extern Bounce Event_Actor(Frame(*) frame_, REBVAL *port, Symbol(const*) verb);
extern void Startup_Event_Scheme(void);
extern void Shutdown_Event_Scheme(void);
extern int64_t Delta_Time(int64_t base);