Handle Screen events

The window manager needs to handle any events of interest.

Events that require action by your window manager include the creation and destruction of application windows as well as some input events.

To set up your window manager to handle Screen events, you need to:
  1. Create a thread in your window manager.
  2. Create a Screen event.
  3. Handle any Screen event of interest to your window manager.

Create a thread in your window manager

You can create a thread in 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);
if (rc = pthread_create(NULL, NULL, pps_thread, (void*)win_mgr) < 0)
{ /* error-handling code goes here */ }
pthread_setname_np(screen_tid = pthread_self(), "screen_monitor");

Create a Screen event

Create a Screen event to store the 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 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 of interest to your window manager

Create an event-handling routine within your thread. This routine will retrieve the most recent event from the queue and then extract 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 event type, by querying the SCREEN_PROPERTY_TYPE property. Handle the events 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;
    }
}
Note: See the Screen Graphics Subsystem Developer's Guide for a complete list of all Screen event types.