Handle Screen events

The window manager needs to handle any events of interest.

Events that require action on the part of your window manage include the creation and destruction of new application windows as well as specific input events.

Set up your window manager to handle Screen events:
  1. Create a thread from your window manager.
  2. Create a Screen event.
  3. Handle any Screen event that is of interest to your window manager.

Create a thread from your window manager

You can create a thread from your window manager to handle Screen events.

window_manager_t window_manager;
memset(&window_manager, 0, sizeof(window_manager_t));
window_manager_t *winmgr = &window_manager;
...
int    screen_tid;                       /* Screen thread ID */
void *screen_thread(void *arg);
rc = (pthread_create(NULL, NULL, screen_thread, (void*)win_mgr) < 0)
pthread_setname_np(screen_tid = pthread_self(), "screen_monitor");

Create a Screen event

Create a Screen event to store the received event. After retrieving the event from the context's event queue, you can use Screen API functions to query the event's properties to determine whether or not additional action is required.

screen_event_t screen_ev;    /* handle used to retrieve events from our queue */
rc = screen_create_event(&screen_ev);

Handle any Screen event that is of interest to your window manager

Create an event-handling routine from within your thread. This routine consists of retrieving the most recent event from the queue and extracting data from the event.

Use the Screen API function screen_get_event() to retrieve the event. Then, use the screen_get_event_property_iv() function to retrieve the type of event by querying the SCREEN_PROPERTY_TYPE property. Apply logic to handle the events that are of interest to your window manager.

screen_window_t win;                 /* stores a window contained in an event */
int val;                             /* used for simple property queries */
screen_display_t *displays, disp;    /* used for display queries */ 
int display_count = 0, port;         /* used for display queries */
int pair[2];                         /* used to query pos, size */
void *ptr;                           /* used to query user handles */
char str[128];                       /* used to query string properties */
int size[2] = { 64, 64 };            /* size of the window on screen */

while (!screen_get_event(screen_ctx, screen_ev, ~0L)) {
    screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_TYPE, &val);
    switch (val) {
        case SCREEN_EVENT_DISPLAY:
            if ( screen_get_event_property_pv(screen_ev,
                                              SCREEN_PROPERTY_DISPLAY,
                                              (void *)&disp) == 0 ) {
            } else {
                break;
            }
            screen_get_display_property_iv(disp, SCREEN_PROPERTY_TYPE, &val);
            switch(val) {
               case SCREEN_DISPLAY_TYPE_HDMI:
                    screen_get_display_property_iv(disp, SCREEN_PROPERTY_ATTACHED, &val);
                    screen_get_display_property_iv(disp, SCREEN_PROPERTY_ID, &port);
                    break;
                default:
                    break;
            }
            break;
        case SCREEN_EVENT_IDLE:
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_IDLE_STATE, &val);
            screen_get_context_property_iv(screen_ctx, SCREEN_PROPERTY_IDLE_STATE, &val);
            screen_get_context_property_iv(screen_ctx,
                                           SCREEN_PROPERTY_DISPLAY_COUNT,
                                           &display_count);
            displays = malloc(display_count * sizeof(screen_display_t));
            screen_get_context_property_pv(screen_ctx,
                                           SCREEN_PROPERTY_DISPLAYS,
                                           (void *)displays);
            for (int i=0; i<display_count; i++) {
                screen_get_display_property_iv(displays[i], SCREEN_PROPERTY_KEEP_AWAKES, &val);
            }
            free(displays);
            break;
        case SCREEN_EVENT_CREATE:
            screen_get_event_property_pv(screen_ev, SCREEN_PROPERTY_WINDOW, (void **)&win);
            screen_get_window_property_iv(win, SCREEN_PROPERTY_OWNER_PID, &val);
            screen_get_window_property_pv(win, SCREEN_PROPERTY_USER_HANDLE, &ptr);
            break;
        case SCREEN_EVENT_PROPERTY:
            screen_get_event_property_pv(screen_ev, SCREEN_PROPERTY_WINDOW, (void **)&win);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_NAME, &val);
            break;
        case SCREEN_EVENT_CLOSE:
            screen_get_event_property_pv(screen_ev, SCREEN_PROPERTY_WINDOW, (void **)&win);
            screen_get_window_property_pv(win, SCREEN_PROPERTY_USER_HANDLE, &ptr);
            screen_destroy_window(win);
            break;
        case SCREEN_EVENT_POST:
            screen_get_event_property_pv(screen_ev, SCREEN_PROPERTY_WINDOW, (void **)&win);
            screen_get_window_property_pv(win, SCREEN_PROPERTY_USER_HANDLE, &ptr);
            set_window_properties(win);
            screen_flush_context(screen_ctx, 0);
            break;
        case SCREEN_EVENT_INPUT:
        case SCREEN_EVENT_JOG:
            break;
        case SCREEN_EVENT_POINTER:
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_DEVICE_INDEX, &val);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_POSITION, pair);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_BUTTONS, &val);
            if (val) {
                if (pair[0] >= size[0] - exit_area_size &&
                    pair[0] < size[0] &&
                    pair[1] >= 0 &&
                    pair[1] < exit_area_size) {
                    goto end;
                }
           }
           break;
        case SCREEN_EVENT_KEYBOARD:
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_DEVICE_INDEX, &val);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_KEY_CAP, &val);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_KEY_FLAGS, &val);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_KEY_MODIFIERS, &val);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_KEY_SCAN, &val);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_KEY_SYM, &val);
            switch (val) {
                case KEYCODE_ESCAPE:
                    goto end;
            }
            break;
        case SCREEN_EVENT_MTOUCH_TOUCH:
        case SCREEN_EVENT_MTOUCH_MOVE:
        case SCREEN_EVENT_MTOUCH_RELEASE:
            screen_get_event_property_pv(screen_ev, SCREEN_PROPERTY_WINDOW, (void **)&win);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_TOUCH_ID, &val);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_SEQUENCE_ID, &val);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_POSITION, pair);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_SIZE, pair);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_SOURCE_POSITION, pair);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_SOURCE_SIZE, pair);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_TOUCH_ORIENTATION, &val);
            screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_TOUCH_PRESSURE, &val);
            break;
        case SCREEN_EVENT_USER:
            break;
    }
}