Skip to content

Instantly share code, notes, and snippets.

@dvdhrm
Created February 27, 2013 20:44
Show Gist options
  • Select an option

  • Save dvdhrm/5051547 to your computer and use it in GitHub Desktop.

Select an option

Save dvdhrm/5051547 to your computer and use it in GitHub Desktop.
kmscon IM integration
/*
* uterm-input Input Method API Proposal
* This API extends the uterm library to handle input methods. An input method
* shall implement this API to be easily integrated into libuterm and all
* programs that depend on it.
* Note that this depends on the uterm-input and uterm-video parts. The
* important pieces are appended to the end of the file so you don't have to
* look it up.
*
* An IM backend shall provide a static constant "uterm_im_ops" object. kmscon
* will then pick an IM backend and use the provided function-pointers.
* "struct uterm_im" and "struct uterm_im_session" should be provided by the IM
* engine and they can be opaque. They're not accessed outside of the IM
* backend, anyway.
*
* The uterm_im object is the context object. It shall provide any global data
* for the IM engine. For each running session in kmscon, a uterm_im_session
* object is created based on the uterm_im object. For instance if you need to
* communicate with dbus, you can store the dbus-socket in "uterm_im" and each
* "uterm_im_session" can use it.
* A single uterm_im context and all sessions that were created by it are never
* accessed from multiple threads simultaneously. However, multiple uterm_im
* contexts should not depend on each other, nor should they require any static
* global data or locking. This _must_ not be handled in libraries. Let the
* application care for it.
*
* new():
* This should allocate a new context and store a pointer to it in \out. It
* should return 0 on success or a negative error code (like -EINVAL) on
* failure.
* Initial ref-count shall be 1.
*
* ref() / unref():
* Increase/decrease reference-count of the given context. If it drops to 0, the
* context shall be destroyed.
*
* get_fd():
* Return an internal file-descriptor or <0 if no file-descriptor is used. This
* allows the IM to be integrated into the main-loop. Whenever the given FD is
* readable, the main loop will call dispatch() on the context.
* You should use epoll internally if you need multiple file-descriptors or if
* you need other events than READABLE-events.
* This fd _must not_ change during runtime. This function is only called once.
* Use epoll if your fd may change.
* This can be NULL if you don't use file-descriptors.
*
* dispatch():
* Called whenever the fd returned by get_fd() is readable. Can be NULL if
* get_fd() is NULL.
*
* start():
* Start a new session with the given context. This shall store a pointer to the
* new session in \out. If the session depends on the context, the session
* _must_ take a reference via \ref of the context.
*
* stop():
* Stop a session an clean it up. Drop the reference to the context.
*
* event():
* Pass an input event to the IM handler. The input event contains keycode,
* keysym and any other data that you might need.
* Return "true" if you handled the event. Return "false" if you didn't handle
* it. (You might always return true here)
* Note that you will not get events that have been previously handled. These
* events include global keyboard-shortcuts and events that weren't targeted at
* the input region where the session is attached to.
*
*
* The start() function gets a callback and a data pointer during setup. Store
* this in your uterm_im_session and use it to notify the application of any
* events.
* Currently supported events are:
* UTERM_IM_INPUT: Contains an arbitrary UTF8 string (may contain binary 0)
* with a given length that will be used by the application
* as input.
* This contains the "result" of a single input-selection.
* UTERM_IM_SHOW: Show an arbitrary overlay. The overlay is a 2D buffer that
* is blitted under/over the current cursor-position.
* Use the provided render-pipeline to create this buffer.
*
* Render-Pipeline:
* TBD!
*/
struct uterm_im;
struct uterm_im_session;
enum uterm_im_event_type {
UTERM_IM_INPUT,
UTERM_IM_SHOW,
};
struct uterm_im_event {
unsigned int type;
union {
struct {
const char *utf8;
size_t len;
} input;
struct {
const struct uterm_video_buffer *overlay;
} show;
};
};
typedef void (*uterm_im_cb) (struct uterm_im *im, struct uterm_im_event *ev,
void *data);
struct uterm_im_ops {
int (*new) (struct uterm_im **out);
void (*ref) (struct uterm_im *im);
void (*unref) (struct uterm_im *im);
int (*get_fd) (struct uterm_im *im);
void (*dispatch) (struct uterm_im *im);
int (*start) (struct uterm_im *im, struct uterm_im_session **out,
uterm_im_cb cb, void *data);
void (*stop) (struct uterm_im_session *session);
bool (*event) (struct uterm_im_session *session,
const struct uterm_input_event *ev);
};
/*
* uterm-input
* This is copied from uterm_input.h and provides the key-events to the IM
* sessions.
*/
enum uterm_input_modifier {
UTERM_SHIFT_MASK = (1 << 0),
UTERM_LOCK_MASK = (1 << 1),
UTERM_CONTROL_MASK = (1 << 2),
UTERM_ALT_MASK = (1 << 3),
UTERM_LOGO_MASK = (1 << 4),
};
#define UTERM_INPUT_INVALID 0xffffffff
struct uterm_input_event {
bool handled; /* user-controlled, default is false */
uint16_t keycode; /* linux keycode - KEY_* - linux/input.h */
uint32_t ascii; /* ascii keysym for @keycode */
unsigned int mods; /* active modifiers - uterm_modifier mask */
unsigned int num_syms; /* number of keysyms */
uint32_t *keysyms; /* XKB-common keysym-array - XKB_KEY_* */
uint32_t *codepoints; /* ucs4 unicode value or UTERM_INPUT_INVALID */
};
/*
* uterm-video
* This is copied from uterm_video.h. It provides the video buffers so IMs can
* do their own rendering.
*/
enum uterm_video_format {
UTERM_FORMAT_GREY = 0x01,
UTERM_FORMAT_XRGB32 = 0x02,
UTERM_FORMAT_RGB16 = 0x04,
/* UTERM_FORMAT_ARGB32 will be added soon */
};
struct uterm_video_buffer {
unsigned int width;
unsigned int height;
unsigned int stride;
unsigned int format;
uint8_t *data;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment