1 /*
2  Arcan Shared Memory Interface, Event Namespace
3  Copyright (c) 2014-2020, Bjorn Stahl
4  All rights reserved.
5 
6  Redistribution and use in source and binary forms,
7  with or without modification, are permitted provided that the
8  following conditions are met:
9 
10  1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13  2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17  3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software without
19  specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 #ifndef _HAVE_ARCAN_SHMIF_EVENT
35 #define _HAVE_ARCAN_SHMIF_EVENT
36 
37 /*
38  * The types and structures used herein are "transitional" in the sense that
39  * during the later optimization / harderning, we'll likely refactor to use
40  * more compat message sizes in order to consume fewer cache-lines, and split
41  * larger messages over a protobuf+socket.
42  *
43  * The event structure is rather messy as it is the result of quite a number of
44  * years of evolutionary "adding more and more fields" as the engine developed.
45  * The size of some fields are rather arbitrary, and has been picked to cover
46  * the largest (networking discovery messages) matching % 32 == 0 with padding.
47  */
48 
49 enum ARCAN_EVENT_CATEGORY {
50 	EVENT_SYSTEM   = 1,
51 	EVENT_IO       = 2,
52 	EVENT_VIDEO    = 4,
53 	EVENT_AUDIO    = 8,
54 	EVENT_TARGET   = 16,
55 	EVENT_FSRV     = 32,
56 	EVENT_EXTERNAL = 64,
57 
58 /* This is found in every enum that is explicitly used as that enum
59  * as member-of-struct (which debuggers etc. need) rather than the explicit
60  * sized member. The effect is that the standard restricts size to a numeric
61  * type that fits (but not exceeds) an int, but the compiler is allowed to
62  * use a smaller one which is bad for IPC. */
63 	EVENT_LIM      = INT_MAX
64 };
65 
66 /*
67  * Primarily hinting to the running appl, but can also dictate scheduling
68  * groups, priority in terms of resource exhaustion, sandboxing scheme and
69  * similar limitations (e.g. TITLEBAR / CURSOR should not update 1080p60Hz)
70  * While not currently enforced, it is likely that (with real-world use data),
71  * there will be a mask to queuetransfer+enqueue in ARCAN that will react
72  * based on SEGID type (statetransfer for TITLEBAR, no..).
73  *
74  * Special flags (all not enforced yet, will be after hardening phase) :
75  * [INPUT] data from server to client
76  * [LOCKSTEP] signalling may block indefinitely, appl- controlled
77  * [UNIQUE] only one per connection
78  * [DESCRIPTOR_PASSING] for target commands where ioev[0] may be populated
79  * with a descriptor. shmif_control retains ownership and may close after
80  * it has been consumed, so continued use need to be dup:ed.
81  *
82  * [PREROLL, ACTIVATION] -
83  * Preroll / activation is hidden by the shmif implementation and keeps a new
84  * connection (not recovery/reset) in an event blocking/ pending state
85  * until an activation event is received. This is to make sure that some events
86  * that define client rendering properties, like language, dimensions etc. is
87  * available from the start and is used to fill out the shmif_cont.
88  */
89 enum ARCAN_SEGID {
90 /*
91  * New / unclassified segments have this type until the first
92  * _EXTERNAL_REGISTER event has been received. aud/vid signalling is ignored
93  * in this state.
94  */
95 	SEGID_UNKNOWN = 0,
96 
97 /* LIGHTWEIGHT ARCAN (nested execution) */
98 	SEGID_LWA = 1,
99 
100 /* Server->Client exclusive --
101  * External Connection, 1:many */
102 	SEGID_NETWORK_SERVER = 2,
103 
104 /* Server->Client exclusive -- cannot be requested
105  * External Connection, 1:1 */
106 	SEGID_NETWORK_CLIENT = 3,
107 
108 /* External Connection, non-interactive data source. */
109 	SEGID_MEDIA = 4,
110 
111 /* Specifically used to indicate a terminal- emulator connection */
112 	SEGID_TERMINAL = 5,
113 
114 /* External client connection, A/V/latency sensitive */
115 	SEGID_REMOTING = 6,
116 
117 /* [INPUT] High-CPU, Low Latency, data exfiltration risk */
118 	SEGID_ENCODER = 7,
119 
120 /* High-frequency event input, little if any A/V use */
121 	SEGID_SENSOR = 8,
122 
123 /* High-interactivity, CPU load, A/V cost, latency requirements */
124 	SEGID_GAME = 9,
125 
126 /* Input reactive, user- sensitive data */
127 	SEGID_APPLICATION = 10,
128 
129 /* Networking, high-risk for malicious data, aggressive resource consumption */
130 	SEGID_BROWSER = 11,
131 
132 /* Virtual Machine, high-risk for malicious data,
133  * CPU load etc. guarantees support for state- management */
134 	SEGID_VM = 12,
135 
136 /* Head-Mounted display, buffer is split evenly left / right but updated
137  * synchronously */
138 	SEGID_HMD_SBS = 13,
139 
140 /* Head-Mounted display, should be mapped as LEFT view */
141 	SEGID_HMD_L = 14,
142 
143 /* Head-Mounted display, should be mapped as RIGHT view */
144 	SEGID_HMD_R = 15,
145 
146 /*
147  * [LOCKSTEP] Popup-window, use with viewport hints to specify
148  * parent-relative positioning. Labelhints on this message can be used
149  * to send a textual representation for server-side rendering or
150  * accessibility (text-to-speak friendly) data. Prefix message with:
151  * '-' to indicate a group separator.
152  * '*' prefix to indicate the presence of a sublevel
153  * '_' prefix to indicate inactive entry.
154  * '|' terminates / resets the message position.
155  * These can subsequently be activated as a DIGITAL input event with
156  * the subid matching the 0-based index of the item.
157  */
158 	SEGID_POPUP = 16,
159 
160 /*
161  * [UNIQUE] Used for statusbar style visual alert / identification
162  */
163 	SEGID_ICON = 17,
164 
165 /* [UNIQUE] Visual titlebar style for CSD, actual text contents is still
166  * server-side rendered and provided as message on this segment or through
167  * IDENT messages. Server-side rendering of global menus can also be
168  * enabled here by indicating labelhints (and then attaching popups when
169  * the label input arrives) */
170 	SEGID_TITLEBAR = 18,
171 
172 /* [UNIQUE] User- provided cursor, competes with CURSORHINT event. */
173 	SEGID_CURSOR = 19,
174 
175 /*
176  * [UNIQUE]
177  * Indicates that this segment is used to propagate accessibility related data;
178  * High-contrast, simplified text, screen-reader friendly. Messages on this
179  * segment should be text-to-speech friendly.
180  *
181  * A reject on such a segment request indicates that no accessibility options
182  * have been enabled and can thus be used as an initial probe.
183  */
184 	SEGID_ACCESSIBILITY = 20,
185 
186 /*
187  * [UNIQUE] Clipboard style data transfers, for image, text or audio sharing.
188  * Can also have streaming transfers using the bchunk mechanism.  Distinction
189  * between Drag'n'Drop and Clipboard state uses the CURSORHINT mechanism.
190  */
191 	SEGID_CLIPBOARD = 21,
192 
193 /*
194  * [INPUT] Incoming clipboard data
195  */
196 	SEGID_CLIPBOARD_PASTE = 22,
197 
198 /*
199  * [UNIQUE] Not expected to have subwindows, no advanced input, no clipboards
200  * but rather a semi-interactive data source that can be rendered and managed
201  * outside the normal window flow.
202  */
203 	SEGID_WIDGET = 23,
204 
205 /*
206  * Used by the shmif_tui support library to indicate a monospaced text user
207  * interface, with known behavior for cut/paste (drag/drop), state transfers,
208  * resize response, font switching, ...
209  */
210 	SEGID_TUI = 24,
211 
212 /*
213  * Used in order to indicate system service integration, exposed as a control
214  * panel, tray or desktop style icon that expose abstract/simplified information
215  * and a control interface to the respective service.
216  */
217 	SEGID_SERVICE = 25,
218 
219 /*
220  * Used to indicate a protocol bridge and root windows
221  * (where applicable and no other segtype or subsegtype- can be spawned).
222  */
223 	SEGID_BRIDGE_X11 = 26,
224 
225 /*
226  * The current semantics for wayland (subject to change):
227  * note that all subsegment allocations are made relative to the primary
228  * wayland subsegment and not as hierarchical subreq on a subseg.
229  * [ primary segment: SEGID_BRIDGE_WAYLAND ] ->
230  *        subsegment: APPLICATION (message to indicate shell)
231  *        subsegment: MEDIA (act as a subsurface)
232  *        subsegment: POPUP (VIEWPORT hint to show relationships)
233  *        subsegment: CURSOR (bound to a "seat", we always have 1:1)
234  *        subsegment: CLIPBOARD (container for DnD, ...)
235  *        subsegment: ICON (can reparent to application or clipboard for DnD)
236  *        subsegment: SEGID_BRIDGE_X11 (Xwayland surfaces)
237  */
238 	SEGID_BRIDGE_WAYLAND = 27,
239 
240 /*
241  * Used as a forwarding primitive, meaning that the current connection will act
242  * as a mediator / router for a new connection, so the subsegment will not be a
243  * proper subsegment but internally promoted to a primary one. The management
244  * scripts should suspend the source segment if this is accepted, and keep it
245  * suspended until the new segment terminates. Other behavior should simply
246  * create a normal connection point and forward connection data there.
247  */
248 	SEGID_HANDOVER = 28,
249 
250 /* Can always be terminated without risk, may be stored as part of debug format
251  * in terms of unexpected termination etc. */
252 	SEGID_DEBUG = 255,
253 
254 	SEGID_LIM = INT_MAX
255 };
256 
257 /*
258  * These are commands that map from parent to child.
259  * If any ioevs[0..n].iv/fv are used, it is specified in the comments
260  */
261 enum ARCAN_TARGET_COMMAND {
262 /* shutdown sequence:
263  * 0. dms is released,
264  * 1. _EXIT enqueued,
265  * 2. semaphores explicitly unlocked
266  * 3. parent spawns a monitor thread, kills unless exited after
267  *    a set amount of time (for authoritative connections).
268  */
269 	TARGET_COMMAND_EXIT = 1,
270 
271 /*
272  * Hints regarding how the underlying client should treat
273  * rendering and video synchronization.
274  * ioevs[0].iv maps to TARGET_SKIP_*
275  */
276 	TARGET_COMMAND_FRAMESKIP,
277 
278 /*
279  * in case of TARGET_SKIP_STEP, this can be used to specify
280  * a relative amount of frames to process or rollback
281  * ioevs[0].iv represents the number of frames,
282  * ioevs[1].iv can contain an ID (see CLOCKREQ)
283  * ioevs[2].uiv (on CLOCKREQ) 0 or seconds (NTP- jan 1900 64-bit format)
284  * ioevs[3].uiv (on CLOCKREQ) fractional second ( - " - ) in GEOHINT- tz
285  */
286 	TARGET_COMMAND_STEPFRAME,
287 
288 /*
289  * Set a specific key-value pair. These have been registered
290  * in beforehand through EVENT_EXTERNAL_COREOPT.
291  * Uses coreopt substructure.
292  */
293 	TARGET_COMMAND_COREOPT,
294 
295 /*
296  * [DESCRIPTOR_PASSING]
297  * Comes with a single descriptor in ioevs[0].iv that should be dup()ed before
298  * next shmif_ call or used immediately for (user-defined) binary
299  * store/restore. The conversion between socket- transfered descriptor and
300  * ioev[0] is handled internally in shmif_control.c
301  */
302 	TARGET_COMMAND_STORE,
303 	TARGET_COMMAND_RESTORE,
304 
305 /*
306  * [DESCRIPTOR_PASSING]
307  * Similar to store/store, but used to indicate that the data source and binary
308  * protocol carried within is implementation- defined. It is used for advanced
309  * cut/paste or transfer operations, possibly with zero-copy mechanisms like
310  * memfd.
311  * ioevs[0].iv will carry the file descriptor
312  * ioevs[1].iv, lower-32 bits of the expected size (if possible)
313  * ioevs[2].iv, upper-32 bits of the expected size
314  * message field will carry extension or other type identifier string.
315  */
316 	TARGET_COMMAND_BCHUNK_IN,
317 	TARGET_COMMAND_BCHUNK_OUT,
318 
319 /*
320  * User requested that the frameserver should revert to a safe initial state.
321  * This is also an indication that the current application state is undesired.
322  * ioevs[0].iv == 0, normal / "soft" (impl. defined) reset
323  * ioevs[0].iv == 1, hard reset (as close to initial state as possible)
324  * ioevs[0].iv == 2, recovery- reset, parent has lost tracking states
325  * ioevs[0].iv == 3, recovery- reconnect, connection was broken but has been
326  * re-established. This will still cause reset subsegments to terminate.
327  * In this state, a lot of the internals of the shmif- context
328  * has been modified. Most importantly, the epipe is no-longer
329  * the same. The old file-descriptor number (already closed at) this stage is
330  * returned in ioevs[1].iv in order to allow updates to polling structures.
331 */
332 	TARGET_COMMAND_RESET,
333 
334 /*
335  * Suspend operations, _EXIT, _PAUSE, _UNPAUSE, _DISPLAYHINT, _FONTHINT should
336  * be valid events in this state. If state management is left to the backend
337  * shmif implementation, the latest DISPLAYHINT, FONTHINT will be queued and
338  * appear on UNPAUSE. Indicates that the server does not want the client to
339  * consume any system- resources. Will be sent at user request or as part of
340  * power-save.
341  */
342 	TARGET_COMMAND_PAUSE,
343 	TARGET_COMMAND_UNPAUSE,
344 
345 /*
346  * For connections that have a fine-grained perception of time, both absolute
347  * and relative in terms of some internal timebase, request a seek to a
348  * specific point in time (or as close as possible).
349  * ioevs[0].iv != 1 indicates relative,
350  * ioevs[1].fv = contains the actual timeslot.
351  */
352 	TARGET_COMMAND_SEEKTIME,
353 
354 /*
355  * ioev[0].iv : 0 = seek_relative, 1 = seek_absolute
356  * if (seek_relative)
357  *  ioevs[1].iv = y-axis: step 'n' logic steps (impl. defined size)
358  *  ioevs[2].iv = x-axis: step 'n' logic steps (impl. defined size)
359  *  ioevs[3].fv = z-axis: step magnification (for 'zooming')
360  *
361  * if (seek_absolute)
362  *  ioevs[1].fv = y-axis: set content position (ignore : 0 <= n <= 1)
363  *  ioevs[2].fv = x-axis: set content position (ignore : 0 <= n <= 1)
364  *  ioevs[3].fv = z-axis: set content magnification (for 'zooming')
365  */
366 	TARGET_COMMAND_SEEKCONTENT,
367 
368 /* [PREROLL/UNIQUE/AGGREGATE]
369  * This event hints towards current display properties or desired display
370  * properties.
371  *
372  * Changes in width / height from the current segment size is
373  * a hint to call shmif_resize if the client can handle drawing in different
374  * resolutions without unecessary scaling UNLESS the specified dimensions
375  * are 0, 0 (indication that only hintflags are to be changed). These will
376  * all be aggregated to the last displahint in queue.
377  *
378  * Changes to the hintflag indicate more abstract states: e.g.
379  * more displayhint events to come shortly, segment not being used or shown,
380  * etc.
381  *
382  * Changes to the RGB layout or the density are hints to improve rendering
383  * quality in regard to a physical display (having things displayed at a
384  * known physical size and layout)
385  *
386  * ioevs[0].iv = width,
387  * ioevs[1].iv = height,
388  * ioevs[2].iv = bitmask hintflags: 0: normal, 1: drag resize,
389  *               2: invisible, 4: unfocused, 8: maximized, 16: fullscreen
390  * ioevs[3].iv = RGB layout (0 RGB, 1 BGR, 2 VRGB, 3 VBGR)
391  * ioevs[4].fv = ppcm (pixels per centimeter, square assumed), < 0 ignored.
392  * ioevs[5].iv = cell_width (rpack- feedback)
393  * ioevs[6].iv = cell_height (rpack- feedback)
394  *
395  * There are subtle side-effects from the UNIQUE/AGGREGATE approach,
396  * some other events may be relative to current display dimensions (typically
397  * analog input). In the cases where there is a queue like:
398  * (DH : displayhint, AIO : analog IOev.)
399  * DH, AIO, AIO, AIO, DH this will be 'optimized' into
400  * AIO, AIO, AIO, DH possibly changing the effect of the AIO. If this corner
401  * case is an actual risk, it should be taken into consideration by the ARCAN-
402  * APPL side.
403  */
404 	TARGET_COMMAND_DISPLAYHINT,
405 
406 /* Hint input/device mapping (device-type, input-port),
407  * primarily used for gaming / legacy applications.
408  * ioevs[0].iv = device_type,
409  * ioevs[1].iv = input_port
410  */
411 	TARGET_COMMAND_SETIODEV,
412 
413 /*
414  * [UNIQUE]
415  * Request substream switch.
416  * ioev[0].iv - Streamid, should match previously provided STREAMINFO data
417  *              (or be ignored!)
418  */
419 	TARGET_COMMAND_STREAMSET,
420 
421 /*
422  * Used when audio playback is controlled by the frameserver, e.g. clients that
423  * do not use the shmif to playback audio for quality- or latency- reasons.
424  * This is sent transparently when a script changes the gain for an audio
425  * source.
426  * ioevs[0].fv = gain_value
427  */
428 	TARGET_COMMAND_ATTENUATE,
429 
430 /*
431  * This indicates that A/V synch is not quite right and the client, if
432  * possible, should try to adjust internal buffering.
433  * ioevs[0].iv = relative audio-skew (ms)
434  * ioevs[1].iv = relative video-skew (ms)
435  */
436 	TARGET_COMMAND_AUDDELAY,
437 
438 /*
439  * Signals that a new subsegment has arrived, either as the reply to a previous
440  * user request, or as an explicit feature announce when there is no matching
441  * request cookie.
442  *
443  * ioev[0].iv carries the file descriptor used to build the new segment
444  * connection. This can safely be ignored as the cleanup or handover is
445  * managed by the next event command or by the acquire call.
446  *
447  * ioev[1].iv is set to !0 if the segment is used to receive rather than send
448  * data.
449  *
450  * ioev[2].iv carries the current segment type, which should pair the request
451  * (or if the request is unknown, hint what it should be used for).
452  *
453  * ioev[3].iv carries the client- provided request cookie -- or as an explicit
454  * request from the parent that a new window of a certain type should be
455  * created (used for image- transfers, debug windows, ...)
456  *
457  * ioev[4].uiv carries the segment token for the new segment, this is used
458  * for a handover situation where the parent process wants to reference the
459  * new window without knowing it
460  *
461  * ioev[5].iv is set to !0 if a default handler of the segment should be run
462  * instead of any client handled option
463  *
464  * To access this segment, call arcan_shmif_acquire with a NULL key. This can
465  * only be called once for each NEWSEGMENT event and the user accepts
466  * responsibility for the segment. Future calls to _poll or _wait with a
467  * pending NEWSEGMENT without accept will drop the segment negotiation.
468  */
469 	TARGET_COMMAND_NEWSEGMENT,
470 
471 /*
472  * The running application in the server explicitly prohibited the client from
473  * getting access to new segments due to UX restrictions or resource
474  * limitations.
475  * ioev[0].iv = cookie (submitted in request)
476  */
477 	TARGET_COMMAND_REQFAIL,
478 
479 /*
480  * There is a whole slew of reasons why a buffer handled provided could not be
481  * used. This event is returned when such a case has been detected in order to
482  * try and provide a graceful fallback to regular shm- copying.
483  */
484 	TARGET_COMMAND_BUFFER_FAIL,
485 
486 /*
487  * [PREROLL/DESCRIPTOR_PASSING]
488  * Provide a handle to a specific device node, the [1].iv determines type and
489  * intended use.
490  * ioev[0].iv = handle (or BADFD)
491  * ioev[1].iv =
492  *              1: device hardware descriptor, if provided (-1 means 2..5)
493  *              2: switch local connection:
494  *                 message field will contain new _CONNPATH otherwise
495  *                 connection primitive will be passed as handle.
496  *              3: [DEPRECATED]
497  *              4: hint alternative connection, will not be forwarded but
498  *                 tracked internally to use as a different connection path
499  *                 on parent failure. Uses message field.
500  *              5: reply to a request for privileged device access,
501  *                 this is special magic used for bridging DRI2 and will
502  *                 weaken security.
503  *
504  * Note: for the [1].iv == 2, 4 cases, the remote address (keyid:host:port) may
505  * be longer than the permitted message length. In such cases, the code field
506  * of the target event structure is used to indicate continuation (=1).
507  *
508  * [for [1].iv == 1]
509  * ioev[2].iv = 0: indirect-, output handles for buffer passing will be used
510  *                 for internal processing and do not need scanout capable
511  *                 memory
512  *              1: direct, output handles should be of a type that can be used
513  *                 as display scanout type (e.g. GBM_BO_USE_SCANOUT),
514  *              2; disabled, hardware acceleration is entirely lost
515  *
516  * ioev[3].iv = 0: device type is render-node-GBM
517  *              1: device type is render-node-Streams
518  *              2: device type is usb descriptor
519  *
520  * [for [1].iv == 2..4]
521  * 128-bit guid is packed in [2..5] as 64bit little-endian,
522  * (low-32, high-32), (low-32, high-32)
523  *
524  * [for [1].iv == 5]
525  * ioev[2].iv = 0: (unsigned) corresponds to a drm authentication token
526  */
527 	TARGET_COMMAND_DEVICE_NODE,
528 
529 /*
530  * Graph- mode is a special case for tuning drawing for a specific segment, for
531  * most cases this means a basic semantic and legacy palette. The meaning has
532  * drifted some over time and its format is mainly due to legacy.
533  *
534  * See the definition for target_graphmode.lua and the corresponding tuisym.h
535  * entries as well as the 'initial' structure in the control.h header.
536  *
537  * ioev[0].iv = mode (bit 1..7 = group, bit 8 == background)
538  * ioev[1..3].fv = (0..255) linear-RGB color, packed [0:R, 1:G, 2:B].
539  */
540 	TARGET_COMMAND_GRAPHMODE,
541 
542 /*
543  * Primarily used on clipboards ("pasteboards") that are sent as recordtargets,
544  * and comes with a possibly multipart UTF-8 encoded message at a fixed limit
545  * per message. Each individual message MUST be valid UTF-8 even in multipart.
546  * ioev[0].iv = !0, multipart continued
547  * ioev.message = utf-8 valid byte sequence
548  *
549  * For TUI clients, it is used as a complement to _ALERT to convey additional
550  * sideband data. If prefixed by '>' it is treated as a prompt, otherwise it is
551  * used as a notification.
552  */
553 	TARGET_COMMAND_MESSAGE,
554 
555 /*
556  * [PREROLL/DESCRIPTOR_PASSING]
557  * A hint in regards to how text rendering should be managed in relation to
558  * the display regarding filtering, font, and sizing decision.
559  * ioev[0].iv = BADFD or descriptor of font to use
560  * ioev[1].iv = (internal, signifies a font presence)
561  * ioev[2].fv = desired normal font size in mm, <= 0, unchanged from current
562  * ioev[3].iv = hinting: 0, off. 1, monochromatic, 2. light, 3. medium,
563  *  -1 (unchanged), 0: off, 1..16 (implementation defined, recommendation
564  *  is to range from light to strong). DISPLAYHINT should also be considered
565  *  when configuring font rendering.
566  *  ioev[4].iv = group:
567  *  <= 0 : ignore.
568  *  1 : continuation, append as a chain to the last fonthint.
569  *  (other values are reserved)
570  */
571 	TARGET_COMMAND_FONTHINT,
572 
573 /*
574  * [PREROLL]
575  * A hint to active positioning and localization settings
576  * ioev[0].fv = GPS(lat)
577  * ioev[1].fv = GPS(long)
578  * ioev[2].fv = GPS(elev)
579  * ioev[3].cv = ISO-3166-1 Alpha 3 code for country + \'0'
580  * ioev[4].cv = ISO-639-2, Alpha 3 code for language (spoken) + \'0'
581  * ioev[5].cv = ISO-639-2, Alpha 3 code for language (written) + \'0'
582  * ioev[6].iv = timezone as gm_offset
583  */
584 	TARGET_COMMAND_GEOHINT,
585 
586 /*
587  * [PREROLL]
588  * geometrical constraints, while-as DISPLAYHINT events convey how the
589  * target will be presented, the OUTPUT hints provide an estimate of the
590  * capabilities. Shmif will track these properties internally and use
591  * it to limit _resize commands (but server does not assume that the client
592  * is cooperating).
593  *
594  * ioev[0].iv = max_width,
595  * ioev[1].iv = max_height,
596  * ioev[2].iv = rate (hz)
597  * ieov[3].iv = min_width,
598  * ioev[4].iv = min_height,
599  * ioev[5].iv = output_id,
600  * ioev[6].fv = vrr_min
601  * ioev[7].fv = vrr_step
602  */
603 	TARGET_COMMAND_OUTPUTHINT,
604 
605 /*
606  * [ACTIVATION/INTERNAL]
607  * Used to indicate the end of the preroll state. _open (and only _open) is
608  * blocking until this command has been received. It is used to populate the
609  * shmif_cont with strong UI dominant properties, like density, font, ...
610  *
611  * It is also used as part of a transition to an extended context request,
612  * i.e. shmifext_open(...) where device access is privileged. This is needed
613  * for some platforms when we can't operate from a lesser-privileged device
614  * access ('render-node').
615  *
616  * ioev[0].iv = lower 32-bit of user access token
617  * ioev[1].iv = higher 32-bit of user access token
618  * This token can be used to re-authenticate in the event of a server crash
619  */
620 	TARGET_COMMAND_ACTIVATE,
621 
622 /*
623  * Modifies the current DEVICE_NODE for shmifext - provides context state.
624  * [0].iv == 0 : indirect
625  *           1 : direct (scanout capable)
626  *           2 : reset-metadata
627  *           3 : define_metadata (dependent on device-type)
628  *
629  * for [0].iv == 3
630  * [1].iv    modifier_hi
631  * [2].iv    modifier_lo
632  * [3].iv    modifier_hint (1 : preferred)
633  */
634 	TARGET_COMMAND_DEVICESTATE,
635 
636 
637 	TARGET_COMMAND_LIMIT = INT_MAX
638 };
639 
640 /*
641  * These events map from a connected client to an arcan server, the namespacing
642  * is transitional and it is recommended that the indirection macro,
643  * ARCAN_EVENT(X) is used. Those marked UNIQUE _may_ lead to the queue window
644  * being scanned for newer events of the same time, discarding previous ones.
645  */
646 #define _INT_SHMIF_TMERGE(X, Y) X ## Y
647 #define _INT_SHMIF_TEVAL(X, Y) _INT_SHMIF_TMERGE(X, Y)
648 #define ARCAN_EVENT(X)_INT_SHMIF_TEVAL(EVENT_EXTERNAL_, X)
649 enum ARCAN_EVENT_EXTERNAL {
650 /*
651  * Custom string message, used as some user- directed hint, or in the case
652  * of a clipboard segid, UTF-8 sequence to inject.
653  * Uses the message field.
654  */
655 	EVENT_EXTERNAL_MESSAGE = 0,
656 
657 /*
658  * Specify that there is a possible key=value argument that could be set.
659  * uses the message field to encode key and value pair.
660  */
661 	EVENT_EXTERNAL_COREOPT = 1,
662 
663 /*
664  * [UNIQUE]
665  * Dynamic data source identification string, similar to message but is
666  * expected to come when something has changed radically, (streaming external
667  * video sources redirecting to new url for instance).
668  * uses the message field.
669  */
670 	EVENT_EXTERNAL_IDENT = 2,
671 
672 /*
673  * Hint that the previous I/O operation failed (for FDTRANSFER related
674  * operations).
675  */
676 	EVENT_EXTERNAL_FAILURE = 3,
677 
678 /*
679  * Similar to FDTRANSFER in that the server is expected to take responsibility
680  * for a descriptor on the pipe that should be used for rendering instead of
681  * the .vidp buffer. This is for accelerated transfers when using an AGP
682  * platform and GPU setup that supports such sharing. Note that this is a
683  * rather young interface with possible security complications. Block this
684  * operation in sensitive contexts.
685  *
686  * This is managed by arcan_shmif_control.
687  */
688 	EVENT_EXTERNAL_BUFFERSTREAM = 4,
689 
690 /* [UNIQUE]
691  * Contains additional timing information about a delivered videoframe.
692  * Uses framestatus substructure.
693  */
694 	EVENT_EXTERNAL_FRAMESTATUS = 5,
695 
696 /*
697  * Decode playback discovered additional substreams that can be selected or
698  * switched between. Uses the streaminf substructure.
699  */
700 	EVENT_EXTERNAL_STREAMINFO = 6,
701 
702 /*
703  * [UNIQUE]
704  * Playback information regarding completion, current time, estimated length
705  * etc. Uses the streamstat substructure. Media windows uses it to indicate
706  * playback state, Other clients uses it to indicate action completion.
707  */
708 	EVENT_EXTERNAL_STREAMSTATUS = 7,
709 
710 /*
711  * [UNIQUE]
712  * hint that serialization operations (STORE / RESTORE) are possible and how
713  * much buffer data / which transfer limits that apply.
714  * Uses the stateinf substructure.
715  */
716 	EVENT_EXTERNAL_STATESIZE = 8,
717 
718 /*
719  * [UNIQUE]
720  * hint that any pending buffers on the audio device should be discarded.
721  * used primarily for A/V synchronization.
722  */
723 	EVENT_EXTERNAL_FLUSHAUD = 9,
724 
725 /*
726  * Request an additional shm-if connection to be allocated, only one segment is
727  * guaranteed per process. Tag with an ID for the parent to be able to accept-
728  * or reject properly.  Uses the segreq- substructure.
729  */
730 	EVENT_EXTERNAL_SEGREQ = 10,
731 
732 /*
733  * [UNIQUE]
734  * Hint which cursor representation to use; This complements the CURSOR
735  * subsegment type (for entirely custom drawn cursors). If a CURSOR subsegment
736  * exist, CURSORHINTs should be routed through that, otherwise it is valid to
737  * switch cursors on any segment.
738  *
739  * For legacy reasons, this uses the message field though the cursor name is
740  * implementation defined. Suggested labels are:
741  *
742  * [wait, select-inv, select, up, down, left-right, up-down, drag-up-down,
743  * drag-up, drag-down, drag-left, drag-right, drag-left-right, rotate-cw,
744  * rotate-ccw, normal-tag, diag-ur, diag-ll, drag-diag, datafield, move,
745  * typefield, forbidden, help, hand, vertical-datafield, drag-drop,
746  * drag-reject]
747  *
748  * The reserved/special names are:
749  * 'default' : revert to CURSOR subsegment contents or system default
750  * 'tag'     : the cursor isegment is a tag to the current cursor
751  * 'hidden'  : don't show/draw the cursor at all
752  * 'hidden-rel' : no visual change, but try to provide/bias relative samples
753  * 'hidden-abs' : no visual change, but try to provide/bias absolute samples
754  * 'hidden-hot:x:y' : for CURSOR subsegment, define the hotspot
755  * 'input:x:y' : for textual input, define the current cursor position
756  * 'warp:x:y' : for mouse cursor motion suggestions
757  */
758 	EVENT_EXTERNAL_CURSORHINT = 12,
759 
760 /*
761  * Indicate spatial relationship and visibility details relative to some
762  * fictive world anchor point or to an explicit relative parent.
763  */
764 	EVENT_EXTERNAL_VIEWPORT = 13,
765 
766 /*
767  * [UNIQUE]
768  * Hints that indicate there is scrolling/panning contents and the estimated
769  * range and position of the currently active viewport.
770  * Uses the content substructure.
771  */
772 	EVENT_EXTERNAL_CONTENT = 14,
773 
774 /*
775  * Hint that a specific input label is supported. Uses the labelhint
776  * substructure and label is subject to A-Z,0-9_ normalization with * used
777  * as wildchar character for incremental indexing.
778  *
779  * Multiple labels can be exposed, and it is up to the appl- layer to track
780  * these accordingly and tag outgoing input events. Sending an empty labelhint
781  * resets the tracked set.
782  *
783  */
784 	EVENT_EXTERNAL_LABELHINT = 15,
785 
786 /* [ONCE]
787  * Specify the requested subtype of a segment, along with a descriptive UTF-8
788  * string (application title or similar) and a caller- selected 128-bit UUID.
789 
790  * The UUID is an unmanaged identifier namespace where the caller or
791  * surrounding system tries to avoid collsions. The ID is primarily intended
792  * for recalling user-interface (not security- related) properties (window
793  * dimensions, ...).
794  *
795  * Although possible to call this multiple times, attempts at switching SEGID
796  * from the established type will be ignored.
797  */
798 	EVENT_EXTERNAL_REGISTER = 16,
799 
800 /*
801  * Request attention to the segment or subsegment, uses the message substr
802  * and multipart messages need to be properly terminated.
803  */
804 	EVENT_EXTERNAL_ALERT = 17,
805 
806 /*
807  * Request that the frameserver provide a monotonic update clock for events,
808  * can be used both to drive the _shmif_signal calls and as a crude timer.
809  * Uses the 'clock' substructure.
810  */
811 	EVENT_EXTERNAL_CLOCKREQ = 18,
812 
813 /*
814  * Update an estimate on how the connection will hand bchunk transfers.  Uses
815  * the 'bchunk' substructure.  This MAY prompt actions in the running appl,
816  * e.g. showing a file- open/ /save dialog.
817  */
818 	EVENT_EXTERNAL_BCHUNKSTATE = 19,
819 
820 /*
821  * Signal that the context operates in a lower level of trust
822  * that possible rule separation on the UI level should treat accordingly.
823  * Uses the privdrop substructure.
824  */
825 	EVENT_EXTERNAL_PRIVDROP = 20,
826 
827 /*
828  * Signal that the surface is not capable of processing inputs of a specific
829  * sample type and/or device type and can therefore be ignored / masked earlier.
830  * Uses the inputmask substructure.
831  */
832 	EVENT_EXTERNAL_INPUTMASK = 21,
833 
834 	EVENT_EXTERNAL_ULIM = INT_MAX
835 };
836 
837 	/*
838 	 * Skipmode are synchronization hints for how A/V/I synch
839 	 * should be compensated for (if possible), uses ioval[0].iv
840 	 */
841 enum ARCAN_TARGET_SKIPMODE {
842 	/* Discard V frames if the period time will be overshot */
843 		TARGET_SKIP_AUTO =  0,
844 	/* Never discard frames, prefer period to (period*2) time oscillation */
845 		TARGET_SKIP_NONE = -1,
846 	/* Reverse- playback state */
847 		TARGET_SKIP_REVERSE  = -2,
848 	/* Rollback video to (abs(v+TARGET_SKIP_ROLLBACK)+1) frames, apply
849 	 * input then simulate forward */
850 		TARGET_SKIP_ROLLBACK = -3,
851 	/* Single- stepping clock, stepframe events drive transfers */
852 		TARGET_SKIP_STEP = 1,
853 	/* Only process every v-TARGET_SKIP_FASTWD+1 frames */
854 		TARGET_SKIP_FASTFWD  = 10,
855 		TARGET_SKIP_ULIM = INT_MAX
856 	};
857 
858 	/*
859 	 * Basic input event type grouping,
860 	 * CATEGORY  => IO (used for masking, queuetransfer etc.)
861 	 * KIND      => determines substructure
862 	 * IDEVKIND  => hints at device origin (should rarely matter)
863 	 * IDATATYPE => usually redundant against KIND, reserved for future tuning
864 	 */
865 	enum ARCAN_EVENT_IO {
866 		EVENT_IO_BUTTON = 0,
867 		EVENT_IO_AXIS_MOVE,
868 		EVENT_IO_TOUCH,
869 		EVENT_IO_STATUS,
870 		EVENT_IO_EYES,
871 		EVENT_IO_ULIM = INT_MAX
872 	};
873 
874 	/* subid on a IDATATYPE = DIGITAL on IDEVKIND = MOUSE */
875 	enum ARCAN_MBTN_IMAP {
876 		MBTN_LEFT_IND = 1,
877 		MBTN_RIGHT_IND,
878 		MBTN_MIDDLE_IND,
879 		MBTN_WHEEL_UP_IND,
880 		MBTN_WHEEL_DOWN_IND
881 	};
882 
883 /* can also be used as values for an inputmask command */
884 	enum ARCAN_EVENT_IDEVKIND {
885 		EVENT_IDEVKIND_KEYBOARD    = 1,
886 		EVENT_IDEVKIND_MOUSE       = 2,
887 		EVENT_IDEVKIND_GAMEDEV     = 4,
888 		EVENT_IDEVKIND_TOUCHDISP   = 8,
889 		EVENT_IDEVKIND_LEDCTRL     = 16,
890 		EVENT_IDEVKIND_EYETRACKER  = 32,
891 		EVENT_IDEVKIND_STATUS      = 64,
892 		EVENT_IDEVKIND_ULIM        = INT_MAX
893 	};
894 
895 	enum ARCAN_IDEV_STATUS {
896 		EVENT_IDEV_ADDED = 0,
897 		EVENT_IDEV_REMOVED,
898 		EVENT_IDEV_BLOCKED
899 	};
900 
901 	enum ARCAN_EVENT_IDATATYPE {
902 		EVENT_IDATATYPE_ANALOG     = 1,
903 		EVENT_IDATATYPE_DIGITAL    = 2,
904 		EVENT_IDATATYPE_TRANSLATED = 4,
905 		EVENT_IDATATYPE_TOUCH      = 8,
906 		EVENT_IDATATYPE_EYES       = 16,
907 		EVENT_IDATATYPE_ULIM       = INT_MAX
908 	};
909 
910 	/*
911 	 * The following enumerations and subtypes are slated for removal here as they
912 	 * only refer to engine- internal events. Currently, the structures and types
913 	 * are re-used with an explicit filter-copy step (frameserver_queuetransfer).
914 	 * Attempting to use them from an external source will get the connection
915 	 * terminated.
916 	 *
917 	 * -- begin internal --
918 	 */
919 	enum ARCAN_EVENT_VIDEO {
920 		EVENT_VIDEO_EXPIRE,
921 		EVENT_VIDEO_CHAIN_OVER,
922 		EVENT_VIDEO_DISPLAY_RESET,
923 		EVENT_VIDEO_DISPLAY_ADDED,
924 		EVENT_VIDEO_DISPLAY_REMOVED,
925 		EVENT_VIDEO_DISPLAY_CHANGED,
926 		EVENT_VIDEO_ASYNCHIMAGE_LOADED,
927 		EVENT_VIDEO_ASYNCHIMAGE_FAILED
928 	};
929 
930 	enum ARCAN_EVENT_SYSTEM {
931 		EVENT_SYSTEM_EXIT = 0,
932 		EVENT_SYSTEM_DATA_IN = 1,
933 		EVENT_SYSTEM_DATA_OUT = 2
934 	};
935 
936 	enum ARCAN_EVENT_AUDIO {
937 		EVENT_AUDIO_PLAYBACK_FINISHED = 0,
938 		EVENT_AUDIO_PLAYBACK_ABORTED,
939 		EVENT_AUDIO_BUFFER_UNDERRUN,
940 		EVENT_AUDIO_PITCH_TRANSFORMATION_FINISHED,
941 		EVENT_AUDIO_GAIN_TRANSFORMATION_FINISHED,
942 		EVENT_AUDIO_OBJECT_GONE,
943 		EVENT_AUDIO_INVALID_OBJECT_REFERENCED
944 	};
945 
946 /*
947  * Meta- events concerning a single frameserver connection
948  */
949 	enum ARCAN_EVENT_FSRV
950 {
951 /* External connection established but not yet active */
952 		EVENT_FSRV_EXTCONN,
953 
954 /* Backing store dimensions has changed */
955 		EVENT_FSRV_RESIZED,
956 
957 /* External process has shut down */
958 		EVENT_FSRV_TERMINATED,
959 
960 /* Deadline- exceeded threshold, discarded */
961 		EVENT_FSRV_DROPPEDFRAME,
962 
963 /* Emitted in extended reporting mode for better server-side statistics */
964 		EVENT_FSRV_DELIVEREDFRAME,
965 
966 /* Event-buffer synch- stage, follows extcon */
967 		EVENT_FSRV_PREROLL,
968 
969 /* Protocol mask has been renegotiated */
970 		EVENT_FSRV_APROTO,
971 
972 /* Gamma ramp synchronization provided */
973 		EVENT_FSRV_GAMMARAMP,
974 
975 /* VR subsystem events */
976 		EVENT_FSRV_ADDVRLIMB,
977 		EVENT_FSRV_LOSTVRLIMB,
978 
979 /* Nested, contains an arcan_ioevent from an external source */
980 		EVENT_FSRV_IONESTED
981 	};
982 	/* -- end internal -- */
983 
984 	typedef union arcan_ioevent_data {
985 		struct {
986 			uint8_t active;
987 		} digital;
988 
989 	/*
990 	 * Packing in this field is poor due to legacy.
991 	 * axisval[] works on the basis of 'just forwarding whatever we can find' where
992 	 * [nvalues] determine the number of values used, with ordering manipulated
993 	 * with the [gotrel] field.
994 	 *
995 	 * [if gotrel is set]
996 	 * nvalues = 1: [0] relative sample
997 	 * nvalues = 2: [0] relative sample, [1] absolute sample
998 	 * nvalues = 3; same as [2], with 'unknown' sample data in [3]
999 	 * nvalues = 4; same as [2] but an extra axis (2D sources) in [3,4]
1000 	 *
1001 	 * [if gotrel is not set, the order between relative and absolute are changed]
1002 	 *
1003 	 * A convention for mouse cursors is to EITHER split into two samples on subid
1004 	 * 0 (x) and 1 (y), or use subid (2) with all 4 samples filled out. The point
1005 	 * of that is that we still lack serialization and force a 'largest struct wins'
1006 	 * scenario, meaning that a sample consumes unreasonable memory sizes. There is
1007 	 * also the option for ONE mouse device to be mapped directly into the shmif
1008 	 * page directly without going through the event queue.
1009 	 */
1010 		struct {
1011 			int8_t gotrel;
1012 			uint8_t nvalues;
1013 			int16_t axisval[4];
1014 		} analog;
1015 
1016 		struct {
1017 			uint8_t active;
1018 			int16_t x, y;
1019 			float pressure, size;
1020 			uint16_t tilt_x, tilt_y;
1021 			uint8_t tool;
1022 		} touch;
1023 
1024 /* presence indicates the presence of a user in front of the screen */
1025 /* head describes the detected head position and angle to the tracker as origo */
1026 /* gaze indicates the possible gaze-points */
1027 		struct {
1028 			float head_pos[3];
1029 			float head_ang[3];
1030 			float gaze_x1, gaze_y1, gaze_x2, gaze_y2;
1031 			uint8_t blink_left, blink_right;
1032 			uint8_t present;
1033 		} eyes;
1034 
1035 		struct {
1036 	/* match ARCAN_IDEV_STATUS */
1037 			uint8_t action;
1038 			uint8_t devkind;
1039 			uint16_t devref;
1040 			uint8_t domain;
1041 		} status;
1042 
1043 		struct {
1044 	/* possible utf8- match, if known, received events should
1045 	 * prefer these, if set. "waste" 1 byte to protect cascade from
1046 	 * missing \0 */
1047 			uint8_t utf8[5];
1048 	/* pressed or not */
1049 			uint8_t active;
1050 	/* propagated device code, for identification and troubleshooting */
1051 			uint8_t scancode;
1052 	/* depending on devid, SDL or X keysym */
1053 			uint32_t keysym;
1054 	/* bitmask of key_modifiers */
1055 			uint16_t modifiers;
1056 		} translated;
1057 
1058 	} arcan_ioevent_data;
1059 
1060 	enum ARCAN_EVENT_IOFLAG {
1061 	/* Possibly used by mouse, touch, gamedev  etc. where some implementation
1062 	 * defined gesture descriptions comes in label, suggested values follow
1063 	 * the google terminology (gestures-touch-mechanics):
1064 	 * touch, dbltouch, click, dblclick, drag, swipe, fling, press, release,
1065 	 * drag, drop, openpinch, closepinch, rotate.
1066 	 * n- finger variations will fire an event each, subid gives index.
1067 	 */
1068 		ARCAN_IOFL_GESTURE = 1,
1069 		ARCAN_IOFL_ENTER = 2,
1070 		ARCAN_IOFL_LEAVE = 4,
1071 	};
1072 
1073 	typedef struct {
1074 		enum ARCAN_EVENT_IO kind;
1075 		enum ARCAN_EVENT_IDEVKIND devkind;
1076 		enum ARCAN_EVENT_IDATATYPE datatype;
1077 		char label[16];
1078 		uint8_t flags;
1079 
1080 		union{
1081 		struct {
1082 			uint16_t devid;
1083 			uint16_t subid;
1084 		};
1085 		uint16_t id[2];
1086 		uint32_t iid;
1087 		};
1088 
1089 	/* relative to connection start, for scheduling future I/O without
1090 	 * risking a saturated event-queue or latency blocks from signal */
1091 		uint64_t pts;
1092 		arcan_ioevent_data input;
1093 	} arcan_ioevent;
1094 
1095 	/*
1096 	 * internal engine only
1097 	 */
1098 	typedef struct {
1099 		enum ARCAN_EVENT_VIDEO kind;
1100 
1101 		int64_t source;
1102 
1103 		union {
1104 			struct {
1105 				int16_t width;
1106 				int16_t height;
1107 				int flags;
1108 				float vppcm;
1109 				int displayid;
1110 				int ledctrl;
1111 				int ledid;
1112 				int cardid;
1113 			};
1114 			int slot;
1115 		};
1116 
1117 		intptr_t data;
1118 	} arcan_vevent;
1119 
1120 	/*
1121 	 * internal engine only
1122 	 */
1123 	typedef struct {
1124 		enum ARCAN_EVENT_FSRV kind;
1125 
1126 		union {
1127 			struct {
1128 				int32_t audio;
1129 				size_t width, height;
1130 				size_t xofs, yofs;
1131 				int8_t glsource;
1132 				uint64_t pts;
1133 				uint64_t counter;
1134 				uint8_t message[32];
1135 			};
1136 			struct {
1137 				char ident[32];
1138 				int64_t descriptor;
1139 			};
1140 			struct {
1141 				int aproto;
1142 			};
1143 			struct {
1144 				unsigned limb;
1145 			};
1146 			arcan_ioevent input;
1147 		};
1148 
1149 		int64_t video;
1150 		intptr_t otag;
1151 	} arcan_fsrvevent;
1152 
1153 	/*
1154 	 * internal engine only
1155 	 */
1156 	typedef struct {
1157 		enum ARCAN_EVENT_AUDIO kind;
1158 
1159 		int32_t source;
1160 		union {
1161 			intptr_t otag;
1162 			uintptr_t* data;
1163 		};
1164 	} arcan_aevent;
1165 
1166 	/*
1167 	 * internal engine only
1168 	 */
1169 	typedef struct arcan_sevent {
1170 		enum ARCAN_EVENT_SYSTEM kind;
1171 		int errcode;
1172 
1173 		union {
1174 			struct {
1175 				uint32_t hitag, lotag;
1176 			} tagv;
1177 			struct {
1178 				char* dyneval_msg;
1179 			} mesg;
1180 
1181 /* used by EVENT_SYSTEM_DATA_IN/OUT and comes from arcan_event.c into the drain
1182  * function when the non-blocking I/O state of a pollable descriptor gets to
1183  * pollin or pollout. */
1184 			struct {
1185 				int fd;
1186 				intptr_t otag;
1187 			} data;
1188 			char message[64];
1189 		};
1190 	} arcan_sevent;
1191 
1192 	typedef struct arcan_tgtevent {
1193 		enum ARCAN_TARGET_COMMAND kind;
1194 
1195 /* questionable separation, it is quite some work changing the format at this
1196  * stage, but it would be possible to split up into multiple unions for each
1197  * type/pattern projected over the ioevs */
1198 		union {
1199 			uint32_t uiv;
1200 			int32_t iv;
1201 			float fv;
1202 			uint8_t cv[4];
1203 		} ioevs[8];
1204 
1205 		int code;
1206 		union {
1207 			char message[78];
1208 			uint8_t bmessage[78];
1209 
1210 /* events that don't use the message field MAY have the timestamp on when it
1211  * was enqueued added here, in local system monotonic click. the edge cases
1212  * where it typically matters is when trying to resolve displayhint conflicts */
1213 			uint64_t timestamp;
1214 		};
1215 	} arcan_tgtevent;
1216 
1217 	typedef struct arcan_extevent {
1218 		enum ARCAN_EVENT_EXTERNAL kind;
1219 		int64_t source;
1220 
1221 		union {
1222 /*
1223  * For events that set one or multiple short messages:
1224  * MESSAGE, IDENT, CURSORHINT, ALERT
1225  * Only MESSAGE and ALERT type has any multipart meaning
1226  * (data) - UTF-8 (complete, valid)
1227  * (multipart) - !0 (more to come, terminated with 0)
1228  */
1229 		struct {
1230 			uint8_t data[78];
1231 			uint8_t multipart;
1232 		} message;
1233 
1234 /*
1235  * For user-toggleable options that can be persistantly tracked,
1236  * per segment related key/value store.
1237  *
1238  * (index) - setting index
1239  * (type)  - setting type:
1240  *           0 - key,
1241  *           1 - description,
1242  *           2 - value
1243  *           3 - current value,
1244  *           4 - forget option
1245  *
1246  * (data)  - UTF-8 encoded, type specific value. Limitations on key are similar
1247  *           to arcan database key (see arcan_db man)
1248  */
1249 		struct {
1250 			uint8_t index;
1251 			uint8_t type;
1252 			uint8_t data[77];
1253 		} coreopt;
1254 
1255 /*
1256  * Hint the current active size of a possible statetransfer along with a
1257  * user-defined type identifer. Tuple(identifier, size) should match for doing
1258  * a fsrv-fsrv state transfer, disabled (initial state).
1259  *
1260  * (size) - size, in bytes, of the state (0 to disable)
1261  * (type) - application/segment identifier (spoofable, no strong identity)
1262  */
1263 		struct {
1264 			uint32_t size;
1265 			uint32_t type;
1266 		} stateinf;
1267 
1268 /* Used for remoting, indicate keyboard button state change:
1269  * (id)     - numeric key ID, for use when we have translation tables
1270  * (keysym) - currently horrible, XKeySym with SDL- related translation (legacy)
1271  * (active) - & !0 > 0 active (pressed)
1272  */
1273 		struct{
1274 			uint8_t id;
1275 			uint32_t keysym;
1276 			uint8_t active;
1277 		} key;
1278 
1279 /* Used with the CLOCKREQ event for hinting how the server should provide
1280  * STEPFRAME events. if once is set, it is interpreted as a hint to register as
1281  * a separate / independent timer.
1282  * (once) - & !0 > 0, fire once or use as periodic timer
1283  * (rate) - if once is set, relative to last tick otherwise every n ticks.
1284  * (id)   - caller specified ID that will be used in stepframe reply
1285  * (dynamic) - set to !0 if it should be hooked to video frame delivery rather
1286  *             than an approximate monotonic clock
1287  *
1288  * there is one automatic clock- slot per connection, and will always have
1289  * ID 1 in the reply.
1290  */
1291 		struct{
1292 			uint32_t rate;
1293 			uint8_t dynamic, once;
1294 			uint32_t id;
1295 		} clock;
1296 
1297 /*
1298  * Used with the BCHUNKSTATE event for hinting to the server that the
1299  * application wants to- or is capable of- receiving or writing bchunkdata.
1300  * (size)      - (input == 0, estimation of upper limit or 0 if unknown)
1301  * (input)     - set to !0 to indicate that the support is for open/read,
1302  * (hint)      - set bit 1 to indicate that the state- support it immediate,
1303  *               e.g. an open/save dialog. set to 1 to hint that the bchunk-
1304  *               support indicates capability.
1305  *               set bit 2 to indicate that all data is also accepted
1306  *               items are coming.
1307  *               set bit 3 to indicate that this is a multipart transfer.
1308  * (stream)    - !0 if a streaming data store is acceptable or it needs to be
1309  *               seekable / mappable
1310  * (extensions)- 7-bit ASCII filtered to alnum with ; separation between
1311  *               accepted extensions or empty [0]='\0' to indicate no-support
1312  *               for input/output.
1313   */
1314 	struct {
1315 		uint64_t size;
1316 		uint8_t input;
1317 		uint8_t hint;
1318 		uint8_t stream;
1319 		uint8_t extensions[68];
1320 	} bchunk;
1321 
1322 /*
1323  * (external) : The execution context has moved from authoritative/trusted to
1324  *              an external conection origin. This can happen on crash recovery
1325  *              and can only be switched on.
1326  *
1327  * (sandboxed) : The client indicates voluntarily that the context now comes
1328  *               from a reduced level of trust. This can only be switched on.
1329  *
1330  * (networked) : Some intermediate (such as a network proxy) indicates that
1331  *               the client maintains a communication path outside of the
1332  *               localhost. This can be switched on and off, and it is the
1333  *               responsibility of the intermediate to prevent external
1334  *               influence.
1335  */
1336 	struct {
1337 		uint8_t external;
1338 		uint8_t sandboxed;
1339 		uint8_t networked;
1340 	} privdrop;
1341 
1342 /*
1343  * (device) : bitmap of blocked input device types (enum ARCAN_EVENT_IDEVKIND).
1344  * (types)  : bitmap of blocked input data types   (enum ARCAN_EVENT_IDATATYPE).
1345  */
1346 	struct {
1347 		uint32_t device;
1348 		uint32_t types;
1349 	} inputmask;
1350 
1351 /*
1352  * Indicate that the connection supports abstract input labels, along
1353  * with the expected data type (match EVENT_IDATATYPE_*)
1354  *
1355  * Sending a labelhint without a description means to REMOVE a previosly
1356  * existing labelhint.
1357  *
1358  * (label)     - 7-bit ASCII filtered to alnum and _
1359  * (initial)   - suggested default sym from the table used in
1360  *               arcan_shmif_tuisym.
1361  * (descr)     - short 8-bit UTF description, if localization is avail.
1362  *               also follow the language from the last GEOHINT
1363  * (vsym)      - single utf8 encoded visual ID
1364  * (subv)      - > 0, use subid as pseudonym for this label (reduce string use)
1365  * (idatatype) - match IDATATYPE enum of expected data
1366  * (modifiers) - bitmap of desired modifiers (arkmod)
1367  */
1368 		struct {
1369 			char label[16];
1370 			uint16_t initial;
1371 			char descr[53];
1372 			uint8_t vsym[5];
1373 			uint16_t subv;
1374 			uint8_t idatatype;
1375 			uint16_t modifiers;
1376 		} labelhint;
1377 
1378 /*
1379  * Platform specific content needed for some platforms to map a buffer, used
1380  * internally by backend and user-defined values may cause the connection to be
1381  * terminated, check arcan_shmif_sighandle and corresponding platform code
1382  * (pitch) - row width in bytes
1383  * (format) - color format, also platform specific value
1384  * (modifiers) - metadata to describe the contents of the buffer
1385  * (gpuid) - source GPU as provided by a previous devicehint
1386  * (width/height) - width/height of the buffer
1387  * (left) - if there are multiple planes to the same transfer
1388  */
1389 		struct {
1390 			uint32_t stride;
1391 			uint32_t format;
1392 			uint32_t offset;
1393 			uint32_t mod_hi;
1394 			uint32_t mod_lo;
1395 			uint32_t gpuid;
1396 			uint32_t width;
1397 			uint32_t height;
1398 			uint8_t left;
1399 		} bstream;
1400 
1401 /*
1402  * Define the arrival of a new data stream (for decode),
1403  * (streamid) - caller specific identifier (to specify stream),
1404  *
1405  */
1406 		struct {
1407 			uint8_t streamid; /* key used to tell the decoder to switch */
1408 			uint8_t datakind; /* 0: audio, 1: video, 2: text, 3: overlay */
1409 			uint8_t langid[4]; /* country code */
1410 		} streaminf;
1411 
1412 /*
1413  * The viewport hint is used to provide additional information about
1414  * different regions of a segment, possible decorations, hierarchical
1415  * relations, visibility, anchoring and ordering.
1416  *
1417  *  (borderpx)[tlrd] - indicate a possible border/shadow/decoration area
1418  *                     that can be cropped away or ignored in position
1419  *                     calculations.
1420  *
1421  *  (parent) (tok)   - can be 0 or the window-id we are relative against,
1422  *                     useful for popup subsegments etc. tok comes from
1423  *                     shmif_page segment_token
1424  *
1425  *	(invisible)      - hint that the current content segment backing store
1426  *	                   contains no information that is visibly helpful,
1427  *	                   this is typically flipped back and forth in order
1428  *	                   to save connection setup overhead.
1429  *
1430  *	(focused)        - Hint that for all the hierarchies in the connection,
1431  *	                   this is the one that should have the input-focus grab.
1432  *
1433  *	(embedded)       - The segment will attach as a part of its parent.
1434  *	                   This forces the edge to be UL and the segment contents
1435  *	                   will be clipped against the parent surface.
1436  *
1437  *  (anchor-edge)    - enable anchoring to parent.
1438  *
1439  *  (anchor-pos)     - enable anchor positioning selection within an area
1440  *                     in a surface-relative coordinate space.
1441  *
1442  *	(edge)           - parent-relative anchoring edge:
1443  *	                   0 - doesn't matter
1444  *	                   1 - UL        2 - UC      3 - UR
1445  *	                   4 - CL        5 - C       6 - CR
1446  *	                   7 - LL        8 - LC      9 - LR
1447  *
1448  *  (x+w, y+h)       - positioning HINT relative to parent UL origo,
1449  *                     describing the possible anchor region.
1450  *
1451  *  (order)          - parent-relative drawing order (+- #segments)
1452  *
1453  *  (ext_id)         - Identifier used to specify virtual (tok) when nesting
1454  *                     windowing systems where it is not useful to have a 1:1
1455  *                     mapping between segments and 'windows' (x11, win32, ...).
1456  *
1457  * Since order is relative to 'parent', the embedding order may be that a
1458  * negative value will have the effect that 'the child' is visually/hierarchy
1459  * speaking 'the parent'. The edge case where such a relationship might be
1460  * expressed is when multiple processes combine to embed one within the other,
1461  * and the first process controls positioning relative to the second due to
1462  * a handover allocation.
1463  */
1464 		struct {
1465 			int32_t x, y;
1466 			uint32_t w, h;
1467 			uint32_t parent;
1468 			uint8_t border[4];
1469 			uint8_t edge;
1470 			int8_t order;
1471 			uint8_t embedded;
1472 			uint8_t invisible;
1473 			uint8_t focus;
1474 			uint8_t anchor_edge;
1475 			uint8_t anchor_pos;
1476 			uint32_t ext_id;
1477 		} viewport;
1478 
1479 /*
1480  * Used as hints for content which may be used to enable scrollbars.
1481  * SZ determines how much of the contents is being showed, x,y + sz
1482  * is therefore in the range 0.00 <= n <= 1.0
1483  * (x,y_pos) - < 0.000, disable, +x_sz > 1.0 invalid (bad value)
1484  * (x,y_sz ) - < 0.000, invalid, > 1.0 invalid
1485  * width, height is an estimate as to the relative size of the window
1486  * (x_pos + width <= 1.0, y_pos + height <= 1.0)
1487  * (cell_w, cell_h) - > 0 indicates that the contents has grid/tile
1488  * like constraints and that resize actions should try and align
1489  * accordingly
1490  */
1491 		struct {
1492 			float x_pos, x_sz;
1493 			float y_pos, y_sz;
1494 			float width, height;
1495 			uint8_t cell_w;
1496 			uint8_t cell_h;
1497 			uint32_t min_w, min_h;
1498 			uint32_t max_w, max_h;
1499 		} content;
1500 
1501 /*
1502  * (ID)     - user-specified cookie, will propagate with req/resp
1503  * (width)  - desired width, will be clamped to PP_SHMPAGE_MAXW
1504  * (height) - desired height, will be clamped to PP_SHMPAGE_MAXH
1505  * (xofs)   - suggested offset relative to parent segment (parent hint)
1506  * (yofs)   - suggested offset relative to parent segment (parent hint)
1507  * (kind)   - desired type of the segment request, can be UNKNOWN
1508  * (dir)    - 0: no hint (xofs, yofs applied)
1509  *            1: split-l : (ofs-ignore), split parent, new left
1510  *            2: split-r : (ofs-ignore), split parent, new right
1511  *            3: split-t : (ofs-ignore), split parent, new top
1512  *            4: split-b : (ofs-ignore), split parent, new bottom
1513  *            5: attach-l : (ofs-ignore), position left of parent
1514  *            6: attach-r : (ofs-ignore), position right of parent
1515  *            7: attach-t : (ofs-ignore), position top of parent
1516  *            8: attach-b : (ofs-ignore), position below parent
1517  *            9: tab : set-up as a tab to the parent
1518  *            10: embed : segment is intended to viewport- attach
1519  */
1520 		struct {
1521 			uint32_t id;
1522 			uint16_t width;
1523 			uint16_t height;
1524 			int16_t xofs;
1525 			int16_t yofs;
1526 			uint8_t dir;
1527 			uint8_t hints;
1528 			enum ARCAN_SEGID kind;
1529 		} segreq;
1530 
1531 /*
1532  * (title) - title-bar info or other short string to indicate state
1533  * (kind)  - only used for non-auth connection primary segments or
1534  *           for subseg requests that got accepted with an empty kind
1535  *           if called with the existing kind, titlebar is updated
1536  * (uid )  - numeric identifier (insecure, non-enforced unique ID)
1537  *           used for tracking settings etc. between session
1538  */
1539 		struct {
1540 			char title[64];
1541 			enum ARCAN_SEGID kind;
1542 			uint64_t guid[2];
1543 		} registr;
1544 
1545 /*
1546  * (timestr, timelim) - 7-bit ascii, isnum : describing HH:MM:SS\0
1547  * (completion)       - 0..1 (start, 1 finish)
1548  * (streaming)        - dynamic / unknown source [media]
1549  *                      type identifier [tui]
1550  * (frameno)          - frame counter [media]
1551  */
1552 		struct {
1553 			uint8_t timestr[9];
1554 			uint8_t timelim[9];
1555 			float completion;
1556 			uint8_t streaming;
1557 			uint32_t frameno;
1558 		} streamstat;
1559 
1560 /*
1561  * (framenumber) - incremental counter
1562  * (pts)         - presentation time stamp, ms (0 - source start)
1563  * (acquired)    - delievered time stamp, ms (0 - source start)
1564  * (fhint)       - float metadata used for quality, or similar indicator
1565  */
1566 		struct {
1567 			uint32_t framenumber;
1568 			uint64_t pts;
1569 			uint64_t acquired;
1570 			float fhint;
1571 		} framestatus;
1572 	};
1573 } arcan_extevent;
1574 
1575 typedef struct arcan_event {
1576 	union {
1577 		struct {
1578 			union {
1579 				arcan_ioevent io;
1580 				arcan_vevent vid;
1581 				arcan_aevent aud;
1582 				arcan_sevent sys;
1583 				arcan_tgtevent tgt;
1584 				arcan_fsrvevent fsrv;
1585 				arcan_extevent ext;
1586 			};
1587 			uint8_t category;
1588 		};
1589 		char pad[128];
1590 	};
1591 } arcan_event;
1592 
1593 _Static_assert(sizeof(arcan_event) == 128, "event struct size should be 128b");
1594 
1595 /* matches those that libraries such as SDL uses */
1596 typedef enum {
1597 	ARKMOD_NONE  = 0x0000,
1598 	ARKMOD_LSHIFT= 0x0001,
1599 	ARKMOD_RSHIFT= 0x0002,
1600 	ARKMOD_LCTRL = 0x0040,
1601 	ARKMOD_RCTRL = 0x0080,
1602 	ARKMOD_LALT  = 0x0100,
1603 	ARKMOD_RALT  = 0x0200,
1604 	ARKMOD_LMETA = 0x0400,
1605 	ARKMOD_RMETA = 0x0800,
1606 	ARKMOD_NUM   = 0x1000,
1607 	ARKMOD_CAPS  = 0x2000,
1608 	ARKMOD_MODE  = 0x4000,
1609 	ARKMOD_REPEAT= 0x8000,
1610 	ARKMOD_LIMIT = INT_MAX
1611 } key_modifiers;
1612 
1613 #ifdef PLATFORM_HEADER
1614 #include PLATFORM_HEADER
1615 #endif
1616 
1617 struct arcan_event_trigger {
1618 	union {
1619 		int fd;
1620 	};
1621 	int type;
1622 	bool in, out;
1623 	uint64_t tag;
1624 };
1625 
1626 struct arcan_evctx {
1627 /* time and mask- tracking, only used parent-side */
1628 	int32_t c_ticks;
1629 	uint32_t mask_cat_inp;
1630 
1631 /* only used for local queues */
1632 	uint32_t state_fl;
1633 	int exit_code;
1634 	bool (*drain)(arcan_event*, int);
1635 	uint8_t eventbuf_sz;
1636 
1637 	arcan_event* eventbuf;
1638 
1639 /* offsets into the eventbuf queue, parent will always % ARCAN_SHMPAGE_QUEUE_SZ
1640  * to prevent nasty surprises. these were set before we had access to _Atomic
1641  * in the standard fashion, and the codebase should be refactored to take that
1642  * into account */
1643 	volatile uint8_t* volatile front;
1644 	volatile uint8_t* volatile back;
1645 
1646 	int8_t local;
1647 
1648 /*
1649  * When the child (!local flag) wants the parent to wake it up,
1650  * the sem_handle (by default, 1) is set to 0 and calls sem_wait.
1651  *
1652  * When the parent pushes data on the event-queue it checks the
1653  * state if this sem_handle. If it's 0, and some internal
1654  * dynamic heuristic (if the parent knows multiple- connected
1655  * events are enqueued, it can wait a bit before waking the child)
1656  * and if that heuristic is triggered, the semaphore is posted.
1657  *
1658  * This is also used by the guardthread (that periodically checks
1659  * if the parent is still alive, and if not, unlocks a batch
1660  * of semaphores).
1661  */
1662 	struct {
1663 		volatile uint8_t* killswitch;
1664 		sem_handle handle;
1665 	} synch;
1666 
1667 };
1668 
1669 typedef struct arcan_evctx arcan_evctx;
1670 
1671 #endif
1672