"> ]> LibGII API Manual LibGII API Steve Cheng Steve Cheng (steve@ggi-project.org) likes to hack GGI. This document describes the application programming interface for LibGII, a flexible library for input. It is used by LibGGI. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. There should not be any more changes to the LibGII/LibGGI API until the next major version. Unfortunately, implementation and documentation do not always match; if you encounter any such differences or have any other questions or comments on this documentation, please mail us at <Email/steve@ggi-project.org/, or the GGI mailing list. Thank you. </Para> <Para> For other developers: if you want to change this manual and do not know DocBook/SGML, just mail me the ASCII version and I will gladly format and include it for you. </Para> <Para> This manual is primarily written as a reference to the user-visible API of LibGII. However, it is being expanded to cover basic graphics concepts as well. It will not be a full tutorial, as actual working code serves that function better. This manual is also not intended to be an LibGII internals guide, although implementation hints are dropped throughout the manual :) </Para> <Para> This documentation is written in DocBook. The SGML source can be used to generate Unix manpages, HTML and text formats automatically. </Para> </Preface> <Chapter> <Title/Introduction/ <Para> <Application/LibGII/ (General Input Interface Library) is a flexible library for handling input from a variety of sources, including keyboards, mice, joysticks, etc. </Para> <Para> LibGII consists of a main library (<Filename/libgii.so/) and a multitude of dynamic drivers. The library then loads the necessary "drivers" for the requested input. </Para> </Chapter> <Chapter> <Title/General/ <Para>To use LibGII, #include <Filename>ggi/gii.h</FileName> in a C program. </Para> <Para> Most LibGII functions return <ReturnValue/0/ to indicate success, and a negative error code to indicate errors. <ReturnValue/Return codes greater than 0/ are usually additional hints or other non-negative integer data. </Para> <Para> A list of error codes and descriptions can be found in the <Filename>ggi/errors.h</Filename> file, which is part of the <Application>LibGGI/LibGG</Application> package. </Para> </Chapter> <Chapter> <Title/Library control/ <RefEntry ID="giiInit"> <RefMeta> <RefEntryTitle>giiInit </RefEntryTitle><ManVolNum>3gii </ManVolNum><RefMiscInfo/GGI/ </RefMeta> <RefNameDiv> <RefName/giiInit/ <RefName/giiExit/ <RefPurpose/Initialize and uninitialize LibGII/ </RefNameDiv> <RefSynopsisDiv><FuncSynopsis> <FuncSynopsisInfo>#include <ggi/gii.h></FuncSynopsisInfo> <FuncPrototype> <FuncDef>int <Function/giiInit/</FuncDef> <Void> </FuncPrototype> <FuncPrototype> <FuncDef>int <Function/giiExit/</FuncDef> <Void> </FuncPrototype> </FuncSynopsis></RefSynopsisDiv> <RefSect1> <Title/Description/ <Para> <Function/giiInit/ initalizes the library. This function must be called before using other LibGII functions; otherwise the results will be undefined. </Para> <Para> <Function/giiExit/ uninitializes the library (after being initalized by <Function/giiInit/) and automatically cleanup if necessary. This should be called after an application is finished with the library. If any GGI functions are called after the library has been uninitialized, the results will be undefined. </Para> <Para> <Function/giiInit/ allows multiple invocations. A reference count is maintained, and to completely uninitialize the library, <Function/giiExit/ must be called as many times as <Function/giiInit/ has been called beforehand. </Para> </RefSect1> <RefSect1> <Title/Return value/ <Para> <Function/giiInit/ returns <ReturnValue/0/ for OK, otherwise an error code. </Para> <Para> <Function/giiExit/ returns: <VariableList> <VarListEntry> <Term><ReturnValue/0/</Term> <ListItem><Para> after successfully cleaning up, </Para></ListItem> </VarListEntry> <VarListEntry> <Term><ReturnValue/> 0/</Term> <ListItem><Para> the number of 'open' <Function/giiInit/ calls, if there has been more than one call to <Function/giiInit/. As <Function/giiInit/ and <Function/giiExit/ must be used in properly nested pairs, e.g. the first <Function/giiExit/ after two <Function/giiInit/s will return 1. </Para></ListItem> </VarListEntry> <VarListEntry> <Term><ReturnValue/< 0/</Term> <ListItem><Para> error, especially if more <Function/giiExit/ calls have been done than <Function/giiInit/ calls. </Para></ListItem> </VarListEntry> </VariableList> </Para> </RefSect1> <RefSect1> <Title/Examples/ <Example> <Title/Initialize and uninitialize LibGII/ <ProgramListing> if (!giiInit()) { exit(EXIT_FAILURE); /* can't start! */ } <Replaceable>/* Do some libgii stuff */</Replaceable> giiExit(); </ProgramListing> </Example> </RefSect1> </RefEntry> <RefEntry> <BeginPage> <RefMeta> <RefEntryTitle>giiPanic</RefEntryTitle> <ManVolNum>3gii</ManVolNum> <RefMiscInfo>GGI</RefMiscInfo> </RefMeta> <RefNameDiv> <RefName/giiPanic/ <RefPurpose/Exit LibGII programs for fatal errors/ </RefNameDiv> <RefSynopsisDiv> <FuncSynopsis> <FuncSynopsisInfo>#include <ggi/gii.h></FuncSynopsisInfo> <FuncPrototype> <FuncDef>int <Function/giiPanic/</FuncDef> <ParamDef>const char *<Parameter/format/, <Replaceable/.../</ParamDef> </FuncPrototype> </FuncSynopsis> </RefSynopsisDiv> <RefSect1> <Title/Description/ <Para> <Function/giiPanic/ does a graceful shutdown, with <CiteRefEntry><RefEntryTitle><Function/printf/</RefEntryTitle><ManVolNum/3/</CiteRefEntry>-style reporting, taking a format string and any additional variables. It will close all inputs, print the given error message to stderr, and then exit the application. </Para> <Para> <Function/giiPanic/ should only be used by usermode programs when something is really screwed, and they do not know what to do. The same applies for libraries, but might be used in rare situations such as corruption of critical data structures. </Para> </RefSect1> <RefSect1> <Title/Return value/ <Para>Never returns. </Para> </RefSect1> <RefSect1> <Title/Examples/ <Example> <Title/An unrecoverable error/ <ProgramListing> if (my_important_struct->magic != MAGIC) { giiPanic("Fatal error: magic corrupted\n"); } </ProgramListing> </Example> </RefSect1> </RefEntry> </Chapter> <Chapter> <Title/Input management/ <RefEntry> <RefMeta> <RefEntryTitle>giiOpen</RefEntryTitle> <ManVolNum>3gii</ManVolNum> <RefMiscInfo/GGI</RefMiscInfo> </RefMeta> <RefNameDiv> <RefName/giiOpen/ <RefName/giiJoinInputs/ <RefName/giiClose/ <RefPurpose/Open, join and close inputs/ </RefNameDiv> <RefSynopsisDiv><FuncSynopsis> <FuncSynopsisInfo>#include <ggi/gii.h></FuncSynopsisInfo> <FuncPrototype> <FuncDef>gii_input_t <Function/giiOpen/</FuncDef> <ParamDef>const char *<Parameter/input/, <Replaceable/.../</ParamDef> </FuncPrototype> <FuncPrototype> <FuncDef>gii_input_t <Function/giiJoinInputs/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/, gii_input_t <Parameter/inp2/</ParamDef> </FuncPrototype> <FuncPrototype> <FuncDef>int <Function/giiClose/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/</ParamDef> </FuncPrototype> </FuncSynopsis> </RefSynopsisDiv> <RefSect1> <Title/Description/ <Para> <Function/giiOpen/ opens an input. This function is given the name of an input driver to load. Passing <Symbol/NULL/ here results in an auto-select mechanism, which currently means examining the contents of <EnVar/GII_INPUT/. </Para> <Para> The optional arguments are a <Symbol/NULL/-terminated list of pointers, which are used to give additional information to the targets. Currently only the first pointer is specified: <Type/void*/ <Parameter/argptr/, a pointer to a library-specific struct. It is used to pass parameters that are not easily transferable in textual form. </Para> <Para> Parameters which can be represented in text format are usually transfered in the <Parameter/input/ parameter, in the format: <Literal> <Token><Replaceable>library_name</Replaceable></Token>: <Token><Replaceable>arguments</Replaceable></Token> </Literal> </Para> <Para> <Function/giiJoinInputs/ joins two inputs into one. From a programmers' point of view, this closes both <Parameter/inp/ and <Parameter/inp2/ and opens an new input that combines both inputs into one. That is, after <Function/giiJoinInputs/ has completed, there is no need to <Function/giiClose/ <Parameter/inp/ and <Parameter/inp2/ any more. When cleaning up, you need to close the returned input instead. See the example for details. However the inputs are not actually closed or reopened internally. That is, you will not get any startup-events or similar the driver generates, though pending events of both old inputs are transferred to the newly created input. </Para> <Para> <Function/giiClose/ releases and destroys an open input and its associated internal control structures. This will put back input streams to their default modes, etc. </Para> <important> <para>If you want to handle input while also using LibGGI, using LibGII functions such as <function/giiOpen/ is almost certainly <emphasis/not/ what you want. Use LibGGI functions such as <citerefentry><refentrytitle><function/ggiEventRead/</refentrytitle> <manvolnum/3/</citerefentry> with the LibGGI visual instead.</para> </important> </RefSect1> <RefSect1> <Title/Return value/ <Para> <Function/giiOpen/ and <Function/giiJoin/ return the opened or joined input (<Type/gii_input_t/), or <Symbol/NULL/ for error. </Para> <Para> <Function/giiClose/ returns <ReturnValue/0/ for OK, otherwise an error code. </Para> </RefSect1> <RefSect1> <Title/Examples/ <InformalExample> <ProgramListing> gii_input_t inp,inp2; /* Initialize the GII library. This must be called before any other * GII function. */ if (giiInit() != 0) exit(1); /* Open the nulldevice for testing ... */ if ((inp=giiOpen("input-null",NULL)) == NULL) { giiExit(); exit(1); } /* Open stdin for testing ... */ if ((inp2=giiOpen("input-stdin",NULL)) == NULL) { giiExit(); exit(1); } /* Now join them. Note the usage of _i_n_p_=_giiJoin(inp,inp2); * This is the recommended way to do this. */ inp=giiJoinInputs(inp,inp2); /* Note that this mends inp2 into inp. That is you may not call giiClose(inp2) - this happens together with giiClose(inp) ! */ <Replaceable>... do the real work here ...</Replaceable> /* Close the joined input */ giiClose(inp); /* Now close down LibGII. */ giiExit(); </ProgramListing> </InformalExample> </RefSect1> <RefSect1> <Title/See Also/ <SimpleList TYPE=inline> <Member> <XRef LinkEnd="giiInit"> </Member> </SimpleList> </RefSect1> </RefEntry> <RefEntry> <BeginPage> <RefMeta> <RefEntryTitle>giiSetEventMask</RefEntryTitle> <ManVolNum>3gii</ManVolNum> <RefMiscInfo/GGI</RefMiscInfo> </RefMeta> <RefNameDiv> <RefName/giiSetEventMask/ <RefName/giiGetEventMask/ <RefName/giiAddEventMask/ <RefName/giiRemoveEventMask/ <RefPurpose/set the types of events you want to see/ </RefNameDiv> <RefSynopsisDiv><FuncSynopsis> <FuncSynopsisInfo>#include <ggi/gii.h></FuncSynopsisInfo> <FuncPrototype> <FuncDef>int <Function/giiSetEventMask/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/, gii_event_mask <Parameter/evm/</ParamDef> </FuncPrototype> <FuncPrototype> <FuncDef>gii_event_mask <Function/giiGetEventMask/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/</ParamDef> </FuncPrototype> <FuncPrototype> <FuncDef>int <Function/giiAddEventMask/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/, gii_event_mask <Parameter/mask/</ParamDef> </FuncPrototype> <FuncPrototype> <FuncDef>int <Function/giiRemoveEventMask/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/, gii_event_mask <Parameter/mask/</ParamDef> </FuncPrototype> </FuncSynopsis> </RefSynopsisDiv> <RefSect1> <Title/Description/ <Para> <Function/giiSetEventMask/ sets the mask of events you want to receive. Keep that down to those you really handle, as this allows to save time and memory by skipping checks and not allocating queues for events you will never read out. </Para> <Para> <Function/giiGetEventMask/ lets you query the currently set mask. </Para> <Para> <Function/giiAddEventMask/ and <Function/giiRemoveEventMask/ are macros that set or delete individual bits in the bitmask. </Para> </RefSect1> <RefSect1> <Title/Return value/ <Para><Function/giiSetEventMask/, <Function/giiAddEventMask/ and <Function/giiRemoveEventMask/ return <ReturnValue/0/ on success or an error code otherwise. </Para> <Para><Function/giiGetEventMask/ returns the currently set mask. </Para> </RefSect1> </RefEntry> <RefEntry ID="giiEventPoll"> <BeginPage> <RefMeta> <RefEntryTitle>giiEventPoll</RefEntryTitle> <ManVolNum>3gii</ManVolNum> <RefMiscInfo/GGI/ </RefMeta> <RefNameDiv> <RefName/giiEventPoll/ <RefName/giiEventSelect/ <RefName/giiEventsQueued/ <RefName/giiEventRead/ <RefPurpose/wait for and receive events/ </RefNameDiv> <RefSynopsisDiv><FuncSynopsis> <FuncSynopsisInfo>#include <ggi/gii.h></FuncSynopsisInfo> <FuncPrototype> <FuncDef>gii_event_mask <Function/giiEventPoll/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/, gii_event_mask <Parameter/mask/, struct timeval *<Parameter/t/</ParamDef> </FuncPrototype> <FuncPrototype> <FuncDef>int <Function/giiEventSelect/</FuncDef> <ParamDef> gii_input *<Parameter/inp/, gii_event_mask *<Parameter/mask/, int <Parameter/n/, fd_set *<Parameter/readfds/, fd_set *<Parameter/writefds/, fd_set *<Parameter/exceptfds/, struct timeval *<Parameter/timeout/ </ParamDef> </FuncPrototype> <FuncPrototype> <FuncDef>int <Function/giiEventsQueued/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/, gii_event_mask <Parameter/mask/</ParamDef> </FuncPrototype> <FuncPrototype> <FuncDef>int <Function/giiEventRead/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/, gii_event *<Parameter/ev/, gii_event_mask <Parameter/mask/</ParamDef> </FuncPrototype> </FuncSynopsis> </RefSynopsisDiv> <RefSect1> <Title/Description/ <Para> <Function/giiEventPoll/ waits for specific events to become available on an input. This call somewhat resembles the Unix &select; call, but only for LibGII events and is more portable. This function is given the input to wait on, a mask of events, any of which will terminate the waiting, and a timeout <Parameter/t/, after which the waiting will cease anyway. In case an event arrives, the timeout value is updated to the time that would have been remaining. So make sure to re-setup this value, when calling <Function/giiEventPoll/ in a loop. </Para> <Para> <Function/giiEventSelect/ is the combination of <Function/giiEventPoll/ and &select; allowing to wait for both LibGII events and arbitrary file descriptors in any of the three states. However, this function is <Emphasis/not/ available if the operating system does not support the &select; call, not even as a stub. </Para> <Para> <Function/giiEventsQueued/ returns the number of events matching the specified event mask that are currently queued in the input. </Para> <Para> <Function/giiEventRead/ blocks for and transfers an event from the given input to the location pointed to by <Parameter/ev/. The event with the earliest timestamp that matches the given mask is returned to the application. </Para> </RefSect1> <RefSect1> <Title/Return value/ <Para> <Function/giiEventPoll/ returns a mask of available events (constrained by the given mask). It is <ReturnValue/0/ if no events are available. On error, a negative error code is returned. </Para> <Para> <Function/giiEventSelect/ returns the same values as &select;. Unlike other LibGGI/LibGII functions, it also uses <Symbol/errno/. It will update the timeout regardless of whether or not the system call does so. </Para> <Para> <Function/giiEventsQueued/ returns the number of events. </Para> <Para> <Function/giiEventRead/ returns the size of event on success, and <ReturnValue/0/ on error. </Para> </RefSect1> </RefEntry> <RefEntry> <BeginPage> <RefMeta> <RefEntryTitle>giiEventSend</RefEntryTitle> <ManVolNum>3gii</ManVolNum> <RefMiscInfo/GGI/ </RefMeta> <RefNameDiv> <RefName/giiEventSend/ <RefPurpose>inject an event into the input</RefPurpose> </RefNameDiv> <RefSynopsisDiv><FuncSynopsis> <FuncSynopsisInfo>#include <ggi/gii.h></FuncSynopsisInfo> <FuncPrototype> <FuncDef>int <Function/giiEventSend/</FuncDef> <ParamDef>gii_input_t <Parameter/inp/, gii_event *<Parameter/ev/</ParamDef> </FuncPrototype> </FuncSynopsis> </RefSynopsisDiv> <RefSect1> <Title/Description/ <Para> <Function/giiEventSend/ injects an event into the queue. Such events can be identified by <Literal>(event->any.origin == GII_EV_ORIGIN_SENDEVENT)</Literal>. There are three main uses for this function: <ItemizedList> <ListItem><Para>"Simulating" input for independent subprograms.</Para></ListItem> <ListItem><Para>Sending events to externally attached programs via specialized "inputs", that are actually rather "outputs".</Para></ListItem> <ListItem><Para>Sending command events to inputs, like querying the axis of a valuator device.</Para></ListItem> </ItemizedList> </Para> </RefSect1> <RefSect1> <Title/Return value/ <Para> <Function/giiEventSend/ returns <ReturnValue/0/ on success, or an error code otherwise. </Para> </RefSect1> <RefSect1> <Title/See Also/ <SimpleList Type=inline> <Member><XRef LinkEnd="giiEventPoll"></Member> </SimpleList> </RefSect1> </RefEntry> </Chapter> <Chapter> <Title/Event Structures/ <Para> All of the event structures are included by <Filename>ggi/events.h</Filename>. </Para> <Para> Events are of type <StructName/gii_event/. It is a union of all of the LibGII event structures: <ProgramListing> typedef union gii_event { uint8 size; /* size of this event */ gii_any_event any; /* access COMMON_DATA */ gii_cmd_event cmd; /* command/information */ gii_expose_event expose; /* exposure event */ gii_val_event val; /* valuator change */ gii_key_event key; /* key press/release */ gii_pmove_event pmove; /* pointer move */ gii_pbutton_event pbutton; /* pointer buttons */ } gii_event; </ProgramListing> </Para> <Para>All of the event structures begin with <Symbol/COMMON_DATA/, which contains housekeeping information: <ProgramListing> #define COMMON_DATA \ uint8 size; /* size of event in bytes */\ uint8 type; /* type of this event */\ sint16 error; /* error (for replies) */\ uint32 origin; /* origin device (etc) */\ uint32 target; /* target device (etc) */\ struct timeval time /* timestamp */ </ProgramListing> <VariableList> <VarListEntry> <Term><StructField/size/</Term> <ListItem> <Para> specifies the size of the given event (in bytes). Note that <StructField/size/ is also accessable as the first member of <StructName/gii_event/ as well. </Para> </ListItem> </VarListEntry> <VarListEntry> <Term><StructField/type/</Term> <ListItem> <Para> is an enumeration of the possible types of LibGII events: <ProgramListing> typedef enum gii_event_type { evNothing = 0, /* event is not valid. (must be zero) */ evCommand, /* report command/do action */ evInformation, /* notification of new information */ evExpose, /* exposure event */ /* empty slot */ evKeyPress=5, /* key has been pressed */ evKeyRelease, /* key has been released */ evKeyRepeat, /* automatically repeated keypress */ evPtrRelative, /* pointer movements reported relative */ evPtrAbsolute, /* pointer movements reported absolute */ evPtrButtonPress, /* pointer button pressed */ evPtrButtonRelease, /* pointer button released */ evValRelative, /* valuator change (reported relative) */ evValAbsolute, /* valuator change (reported absolute) */ evLast /* must be less than 33 */ } gii_event_type; </ProgramListing> </Para> <Para> Thus, by analyzing the contents of <StructField/any.type/, you can determine what the given event is, and select the appropriate member of the <StructName/gii_event/ union to access to get at the event data. </Para> </ListItem> </VarListEntry> <VarListEntry> <Term><StructField/error/</Term> <ListItem> <Para> is mainly there to round things up to a 32 bit boundary, but could be used to signal an error in a send-reply sequence. </Para> </ListItem> </VarListEntry> <VarListEntry> <Term><StructField/origin/</Term> <ListItem><Para> is a device handle; it distinguishes one input device from another, other than that there's no real meaning to the number. </Para> </ListItem> </VarListEntry> <VarListEntry> <Term><StructField/target/</Term> <ListItem><Para> is also a device handle, but for distinguishes input devices when sending events <Emphasis/to/ an input device (e.g. via <Function/giiEventSend/). </Para> </ListItem></VarListEntry> <VarListEntry> <Term><StructField/time/</Term> <ListItem><Para> indicates when the event in question has been generated. </Para> </ListItem> </VarListEntry> </VariableList> </Para> <Sect1> <Title/Key events/ <Para> The <StructName/gii_key_event/ structure represents key/button events from keyboards and other devices. </Para> <Para>Event types: <SimpleList TYPE=Horiz> <Member><Symbol/evKeyPress/</Member> <Member><Symbol/evKeyRepeat/<Member> <Member><Symbol/evKeyRelease/</Member> </SimpleList> <ProgramListing> /* key events should be used to report events obtained from keys and ** other switches. */ typedef struct gii_key_event { COMMON_DATA; uint32 modifiers; /* current modifiers in effect */ uint32 sym; /* meaning of key */ uint32 label; /* label on key */ uint32 button; /* button number */ } gii_key_event; </ProgramListing> <VariableList> <VarListEntry> <Term><StructField/effect/</Term> <ListItem><Para> specifies the modifiers currently in effect, for example, the shift keys on a keyboard. </Para> </ListItem> </VarListEntry> <VarListEntry> <Term><StructField/sym/</Term> <ListItem><Para> is the 'symbol' of the key, describing the resultant character produced by the key. This is roughly the '<StructField/label/' on the key (described below) combined with the <StructField/effect/. </Para> </ListItem></VarListEntry> <VarListEntry> <Term><StructField/label/</Term> <ListItem><Para> is the actual label which is present on the key in question, and the main '<StructField/sym/bol' on the key. <StructField/label/ can be used as a generalized, portable keycode or scancode of the key. </Para> </ListItem> </VarListEntry> <VarListEntry> <Term><StructField/button/</Term> <ListItem><Para> is the button number distinguishing between the different buttons on the device. For example, on a keyboard it is a number from 0 to 127 (i.e. a 'scancode'), on a joystick it might be 1 to 4, and on a spaceorb it will be 1 to 8. </Para> </ListItem> </VarListEntry> </VariableList> </Para> <Para> In GGI, key values and characters are specified in accordance to <Filename>ggi/keyboard.h</Filename>. They are organized in a similar way to Linux keysyms (but without the braindamage) and Unicode. However, in the GGI system, no key is guaranteed to exist; the key values are for identification only. Particularly, applications should <Emphasis/not/ rely on their presence. Also, because not all keyboards are configured in the same way, GGI application are encouraged to allow user configuration of the keys used and not hardcode them. </Para> <Sect2> <Title/GGI keysym system/ <Para> A list of GGI keysyms and some macros for manipulating them are found in <Filename>gii/keyboard.h</Filename>. </Para> <Para>To be done.</Para> </Sect2> </Sect1> <Sect1> <Title/Pointer movement events/ <ProgramListing> /* This is used to report change of pointer position. ** Depending on the event type, the values are either absolute ** or relative. */ typedef struct gii_pmove_event { COMMON_DATA; sint32 x, y; /* absolute/relative position */ sint32 z, wheel; } gii_pmove_event; </ProgramListing> <Para> The <StructName/gii_pmove_event/ structure describes pointer motion in terms of the x, y, z coordinates and the 'wheel'. The motion described may be relative (offset from the current location) or absolute (a specific location on the 'screen'), depending on whether the event is of type <Symbol/evPtrRelative/ or <Symbol/evPtrAbsolute/, respectively. </Para> </Sect1> <Sect1> <Title/Pointer button events/ <ProgramListing> /* Button events are sent to report a change in pointer button ** state. Depending on the event type, the button is either being ** pressed or released. */ typedef struct gii_pbutton_event { COMMON_DATA; uint32 button; /* button number. This is a number, NOT a mask */ } gii_pbutton_event; </ProgramListing> <Para> <StructName/gii_pbutton_event/ simply specifies that the <StructField/button/ is being pressed (type <Symbol/evPtrButtonPress/) or released (type <Symbol/evPtrButtonRelease/). </Para> <Para> Pointer buttons are specified in order of common usage, with 1 being the primary button: <ProgramListing> #define GII_PBUTTON_LEFT 1 /* Left or primary button */ #define GII_PBUTTON_PRIMARY 1 #define GII_PBUTTON_FIRST 1 #define GII_PBUTTON_RIGHT 2 /* Right/Secondary button */ #define GII_PBUTTON_SECONDARY 2 #define GII_PBUTTON_SECOND 2 #define GII_PBUTTON_MIDDLE 3 /* Middle or tertiary */ #define GII_PBUTTON_TERTIARY 3 #define GII_PBUTTON_THIRD 3 </ProgramListing> </Para> <Para> Of course, applications should avoid hardcoding mouse button values. </Para> </Sect1> <Sect1> <Title/Commands and information/ <Para> <StructName/gii_cmd_event/ is the basic structure for <Symbol/evCommand/ and <Symbol/evInformation/ events. It may need to be casted to some other structure (depending on <StructField/code/) to access the data. <ProgramListing> #define GII_CMD_DATA_MAX (248-sizeof(gii_cmd_nodata_event)) /* These are used internally either to the application or the * kernel. The same event is used for both Command and Information * events. The recipient must not store references to the data. If * the data information is needed afterwards, copy it! */ typedef struct gii_cmd_event { COMMON_DATA; uint32 code; /* command/request code */ uint8 data[GII_CMD_DATA_MAX]; /* command related data */ } gii_cmd_event; </ProgramListing> </Para> <Sect2> <Title/Device information One use of /* This event is sent/received to require/get the capabilities of a device * as specified in target/origin. * An event stating num_buttons=num_axes=0 says, that the device is inactive, * unplugged, whatever. Devices automatically report (detectable) state * changes via devinfo. But you need to re-query the valinfo records. */ #define GII_CMDCODE_GETDEVINFO (0x01) typedef struct gii_cmddata_getdevinfo { char longname[75]; char shortname[5]; gii_event_mask can_generate; int num_buttons; /* Maximum number of buttons. */ int num_axes; /* Maximum number of axes. */ } gii_cmddata_getdevinfo; This event is guaranteed to be generated immediately after opening an input source. To be done. </Para> </Sect1> <Sect1> <Title/Expose events/ <Para> If an application loses the focus and is not physically displayed (e.g. console switching, iconifying), it may be stopped. Some targets may implement a backbuffer and allow continuing, though. </Para> <Para> After reactivation, the application will receive a redraw event, <Symbol/evExpose/. This is its structure, describing the region which needs to be redrawn: <ProgramListing> typedef struct gii_expose_event { COMMON_DATA; uint32 x,y; uint32 h,w; } gii_expose_event; </ProgramListing> <Example> <Title/How to use/ <ProgramListing> ggi_event ev; <Replaceable>/* ... wait and get the event... */</Replaceable> if (ev.any.type == evExpose) { /* redraw part of screen... */ redraw_screen(ev.expose.x, ev.expose.y, ev.expose.w, ev.expose.h); } <Replaceable>/* ... etc ... */</Replaceable> </ProgramListing> </Example> </Para> <!-- <InformalExample> <ProgramListing> gii_event ev; /* ... get the event... */ switch(ev.any.type) { case evKeyPress: case evKeyRepeat: printf("Received key symbol: %x\n", ev.key.sym); break; case evKeyRelease: /* ... ignore ... */ break; case evPtrRelative: case evPtrAbsolute: printf("Moved the mouse! x: %d, y: %d\n", ev.pmove.x, ev.pmove.y); /* ... etc ... */ </ProgramListing> </InformalExample> <Para> There is also <Type/gii_event_mask/ which may be passed to various event handling functions to indicate which types of events the program is interested in. They are similar to event types, but have a different prefix. See <Filename>gii/gii.h</> for possible masks. --> </Sect1> </Chapter> </Book>