Esempio n. 1
0
static rut_modifier_state_t
rut_headless_key_event_get_modifier_state(rut_input_event_t *event)
{
    rut_stream_event_t *stream_event = event->native;
    switch (stream_event->type) {
        case RUT_STREAM_EVENT_KEY_DOWN:
        case RUT_STREAM_EVENT_KEY_UP:
            return stream_event->key.mod_state;
        default:
            c_warn_if_reached();
            return 0;
    }
}
Esempio n. 2
0
static int32_t
rut_headless_key_event_get_keysym(rut_input_event_t *event)
{
    rut_stream_event_t *stream_event = event->native;

    switch (stream_event->type) {
        case RUT_STREAM_EVENT_KEY_UP:
        case RUT_STREAM_EVENT_KEY_DOWN:
            return stream_event->key.keysym;
        default:
            c_warn_if_reached();
            return 0;
    }
}
Esempio n. 3
0
static rut_button_state_t
rut_headless_motion_event_get_button(rut_input_event_t *event)
{
    rut_stream_event_t *stream_event = event->native;

    switch (stream_event->type) {
        case RUT_STREAM_EVENT_POINTER_DOWN:
            return stream_event->pointer_button.button;
        case RUT_STREAM_EVENT_POINTER_UP:
            return stream_event->pointer_button.button;
        default:
            c_warn_if_reached();
            return 0;
    }
}
Esempio n. 4
0
static rut_key_event_action_t
rut_headless_key_event_get_action(rut_input_event_t *event)
{
    rut_stream_event_t *stream_event = event->native;

    switch (stream_event->type) {
        case RUT_STREAM_EVENT_KEY_DOWN:
            return RUT_KEY_EVENT_ACTION_DOWN;
        case RUT_STREAM_EVENT_KEY_UP:
            return RUT_KEY_EVENT_ACTION_UP;
        default:
            c_warn_if_reached();
            return 0;
    }
}
Esempio n. 5
0
static rut_motion_event_action_t
rut_headless_motion_event_get_action(rut_input_event_t *event)
{
    rut_stream_event_t *stream_event = event->native;

    switch (stream_event->type) {
        case RUT_STREAM_EVENT_POINTER_DOWN:
            return RUT_MOTION_EVENT_ACTION_DOWN;
        case RUT_STREAM_EVENT_POINTER_UP:
            return RUT_MOTION_EVENT_ACTION_UP;
        case RUT_STREAM_EVENT_POINTER_MOVE:
            return RUT_MOTION_EVENT_ACTION_MOVE;
        default:
            c_warn_if_reached();
            return 0;
    }
}
Esempio n. 6
0
static cg_attribute_type_t
get_cg_attribute_type(rut_attribute_type_t type)
{
    switch (type) {
    case RUT_ATTRIBUTE_TYPE_BYTE:
        return CG_ATTRIBUTE_TYPE_BYTE;
    case RUT_ATTRIBUTE_TYPE_UNSIGNED_BYTE:
        return CG_ATTRIBUTE_TYPE_UNSIGNED_BYTE;
    case RUT_ATTRIBUTE_TYPE_SHORT:
        return CG_ATTRIBUTE_TYPE_SHORT;
    case RUT_ATTRIBUTE_TYPE_UNSIGNED_SHORT:
        return CG_ATTRIBUTE_TYPE_UNSIGNED_SHORT;
    case RUT_ATTRIBUTE_TYPE_FLOAT:
        return CG_ATTRIBUTE_TYPE_FLOAT;
    }

    c_warn_if_reached();
    return 0;
}
Esempio n. 7
0
static void
rut_headless_motion_event_get_transformed_xy(rut_input_event_t *event,
                                        float *x,
                                        float *y)
{
    rut_stream_event_t *stream_event = event->native;
    switch (stream_event->type) {
        case RUT_STREAM_EVENT_POINTER_MOVE:
            *x = stream_event->pointer_move.x;
            *y = stream_event->pointer_move.y;
            break;
        case RUT_STREAM_EVENT_POINTER_DOWN:
        case RUT_STREAM_EVENT_POINTER_UP:
            *x = stream_event->pointer_button.x;
            *y = stream_event->pointer_button.y;
            break;
        default:
            c_warn_if_reached();
    }
}
Esempio n. 8
0
void
rig_pb_stream_write(rig_pb_stream_t *stream,
                    rig_pb_stream_write_closure_t *closure)
{
    c_return_if_fail(stream->type != STREAM_TYPE_DISCONNECTED);

    switch (stream->type) {
    case STREAM_TYPE_BUFFER: {
        c_return_if_fail(stream->buffer.other_end != NULL);
        c_return_if_fail(stream->buffer.other_end->type == STREAM_TYPE_BUFFER);

        c_array_append_val(stream->buffer.other_end->buffer.incoming_write_closures, closure);

        queue_data_buffer_stream_read(stream->buffer.other_end);

        break;
    }

#ifdef USE_UV
    case STREAM_TYPE_FD:
    case STREAM_TYPE_TCP: {
        closure->write_req.data = closure;

        uv_write(&closure->write_req,
                 (uv_stream_t *)&stream->fd.uv_fd_pipe,
                 &closure->buf,
                 1, /* n buffers */
                 uv_write_done_cb);
        break;
    }
    case STREAM_TYPE_WEBSOCKET_SERVER: {
        struct wslay_event_fragmented_msg arg;

        memset(&arg, 0, sizeof(arg));
        arg.opcode = WSLAY_BINARY_FRAME;
        arg.source.data = closure;
        arg.read_callback = fragmented_wslay_read_cb;

        closure->current_offset = 0;

        wslay_event_queue_fragmented_msg(stream->websocket_server.ctx, &arg);
        wslay_event_send(stream->websocket_server.ctx);
        break;
    }
#endif

#ifdef __EMSCRIPTEN__
    case STREAM_TYPE_WORKER_IPC:
        if (stream->worker_ipc.in_worker)
            rig_emscripten_worker_post_to_main(closure->buf.base,
                                               closure->buf.len);
        else
            rig_emscripten_worker_post(stream->worker_ipc.worker,
                                       "rig_pb_stream_worker_onmessage",
                                       closure->buf.base,
                                       closure->buf.len);

        closure->done_callback(closure);
        break;

    case STREAM_TYPE_WEBSOCKET_CLIENT:
        c_debug("stream: websocket send() %d bytes", closure->buf.len);
        send(stream->websocket_client.socket,
             closure->buf.base,
             closure->buf.len,
             0 /* flags */);

        closure->done_callback(closure);
        break;
#endif

    case STREAM_TYPE_DISCONNECTED:
        c_warn_if_reached();
        break;
    }
}
Esempio n. 9
0
void
rut_mesh_foreach_triangle(rut_mesh_t *mesh,
                          rut_mesh_triangle_callback_t callback,
                          void *user_data,
                          const char *first_attribute,
                          ...)
{
    va_list ap;
    int n_vertices;
    int n_attributes = 0;
    uint8_t **bases;
    int *strides;
    void **data0;
    void **data1;
    void **data2;
    void **tri_v[3];
    int tri_i[3];
    bool ready;

    switch (mesh->mode) {
    case CG_VERTICES_MODE_LINES:
    case CG_VERTICES_MODE_LINE_STRIP:
    case CG_VERTICES_MODE_LINE_LOOP:
        return;
    default:
        break;
    }

    n_vertices = mesh->indices_buffer ? mesh->n_indices : mesh->n_vertices;
    if (n_vertices < 3)
        return;

    va_start(ap, first_attribute);
    do {
        n_attributes++;
    } while (va_arg(ap, const char *));
    va_end(ap);

    bases = c_alloca(sizeof(void *) * n_attributes);
    strides = c_alloca(sizeof(int) * n_attributes);
    data0 = c_alloca(sizeof(void *) * n_attributes);
    data1 = c_alloca(sizeof(void *) * n_attributes);
    data2 = c_alloca(sizeof(void *) * n_attributes);

    tri_v[0] = data0;
    tri_v[1] = data1;
    tri_v[2] = data2;

    va_start(ap, first_attribute);
    ready = collect_attribute_state(mesh, bases, strides, first_attribute, ap);
    va_end(ap);

    c_return_if_fail(ready);

#define SWAP_TRIANGLE_VERTICES(V0, V1)                                         \
    do {                                                                       \
        void **tmp_v;                                                          \
        int tmp_i;                                                             \
        tmp_v = tri_v[V0];                                                     \
        tri_v[V0] = tri_v[V1];                                                 \
        tri_v[V1] = tmp_v;                                                     \
                                                                               \
        tmp_i = tri_i[V0];                                                     \
        tri_i[V0] = tri_i[V1];                                                 \
        tri_i[V1] = tmp_i;                                                     \
    } while (1)

    /* Make sure we don't overrun the vertices if we don't have a
     * multiple of three vertices in triangle list mode */
    if (mesh->mode == CG_VERTICES_MODE_TRIANGLES)
        n_vertices -= 2;

    if (mesh->indices_buffer) {
        index_state_t state;
        cg_vertices_mode_t mode = mesh->mode;
        int i = 0;

        state.n_attributes = n_attributes;
        state.bases = bases;
        state.strides = strides;
        state.indices_type = mesh->indices_type;
        state.indices = mesh->indices_buffer->data;

        tri_i[0] = move_to_i(i++, &state, tri_v[0]);
        tri_i[1] = move_to_i(i++, &state, tri_v[1]);
        tri_i[2] = move_to_i(i++, &state, tri_v[2]);

        while (true) {
            if (!callback(tri_v[0],
                          tri_v[1],
                          tri_v[2],
                          tri_i[0],
                          tri_i[1],
                          tri_i[2],
                          user_data))
                return;

            if (i >= n_vertices)
                break;

            switch (mode) {
            case CG_VERTICES_MODE_TRIANGLES:
                tri_i[0] = move_to_i(i++, &state, tri_v[0]);
                tri_i[1] = move_to_i(i++, &state, tri_v[1]);
                tri_i[2] = move_to_i(i++, &state, tri_v[2]);
                break;
            case CG_VERTICES_MODE_TRIANGLE_FAN:
                SWAP_TRIANGLE_VERTICES(1, 2);
                tri_i[2] = move_to_i(i++, &state, tri_v[2]);
                break;
            case CG_VERTICES_MODE_TRIANGLE_STRIP:
                SWAP_TRIANGLE_VERTICES(0, 1);
                SWAP_TRIANGLE_VERTICES(1, 2);
                tri_i[2] = move_to_i(i++, &state, tri_v[2]);
                break;
            default:
                c_warn_if_reached();
            }
        }
    } else {
        cg_vertices_mode_t mode = mesh->mode;
        int i = 0;

        tri_i[0] = move_to(i++, n_attributes, bases, strides, tri_v[0]);
        tri_i[1] = move_to(i++, n_attributes, bases, strides, tri_v[1]);
        tri_i[2] = move_to(i++, n_attributes, bases, strides, tri_v[2]);

        while (true) {
            if (!callback(tri_v[0],
                          tri_v[1],
                          tri_v[2],
                          tri_i[0],
                          tri_i[1],
                          tri_i[2],
                          user_data))
                return;

            if (i >= n_vertices)
                break;

            switch (mode) {
            case CG_VERTICES_MODE_TRIANGLES:
                tri_i[0] = move_to(i++, n_attributes, bases, strides, tri_v[0]);
                tri_i[1] = move_to(i++, n_attributes, bases, strides, tri_v[1]);
                tri_i[2] = move_to(i++, n_attributes, bases, strides, tri_v[2]);
                break;
            case CG_VERTICES_MODE_TRIANGLE_FAN:
                SWAP_TRIANGLE_VERTICES(1, 2);
                tri_i[2] = move_to(i++, n_attributes, bases, strides, tri_v[2]);
                break;
            case CG_VERTICES_MODE_TRIANGLE_STRIP:
                SWAP_TRIANGLE_VERTICES(0, 1);
                SWAP_TRIANGLE_VERTICES(1, 2);
                tri_i[2] = move_to(i++, n_attributes, bases, strides, tri_v[2]);
                break;
            default:
                c_warn_if_reached();
            }
        }
    }
#undef SWAP_TRIANGLE_VERTICES
}
Esempio n. 10
0
int32_t
_rut_keysym_from_sdl_keysym(RutSDLKeycode sdl_keysym)
{
    switch (sdl_keysym) {
    /* ASCII mapped keysyms */
    case SDLK_BACKSPACE:
        return RUT_KEY_BackSpace;
    case SDLK_TAB:
        return RUT_KEY_Tab;
    case SDLK_CLEAR:
        return RUT_KEY_Clear;
    case SDLK_RETURN:
        return RUT_KEY_Return;
    case SDLK_PAUSE:
        return RUT_KEY_Pause;
    case SDLK_ESCAPE:
        return RUT_KEY_Escape;
    case SDLK_SPACE:
        return RUT_KEY_space;
    case SDLK_EXCLAIM:
        return RUT_KEY_exclam;
    case SDLK_QUOTEDBL:
        return RUT_KEY_quotedbl;
    case SDLK_HASH:
        return RUT_KEY_numbersign;
    case SDLK_DOLLAR:
        return RUT_KEY_dollar;
    case SDLK_AMPERSAND:
        return RUT_KEY_ampersand;
    case SDLK_QUOTE:
        return RUT_KEY_apostrophe;
    case SDLK_LEFTPAREN:
        return RUT_KEY_parenleft;
    case SDLK_RIGHTPAREN:
        return RUT_KEY_parenright;
    case SDLK_ASTERISK:
        return RUT_KEY_asterisk;
    case SDLK_PLUS:
        return RUT_KEY_plus;
    case SDLK_COMMA:
        return RUT_KEY_comma;
    case SDLK_MINUS:
        return RUT_KEY_minus;
    case SDLK_PERIOD:
        return RUT_KEY_period;
    case SDLK_SLASH:
        return RUT_KEY_slash;
    case SDLK_0:
        return RUT_KEY_0;
    case SDLK_1:
        return RUT_KEY_1;
    case SDLK_2:
        return RUT_KEY_2;
    case SDLK_3:
        return RUT_KEY_3;
    case SDLK_4:
        return RUT_KEY_4;
    case SDLK_5:
        return RUT_KEY_5;
    case SDLK_6:
        return RUT_KEY_6;
    case SDLK_7:
        return RUT_KEY_7;
    case SDLK_8:
        return RUT_KEY_8;
    case SDLK_9:
        return RUT_KEY_9;
    case SDLK_COLON:
        return RUT_KEY_colon;
    case SDLK_SEMICOLON:
        return RUT_KEY_semicolon;
    case SDLK_LESS:
        return RUT_KEY_less;
    case SDLK_EQUALS:
        return RUT_KEY_equal;
    case SDLK_GREATER:
        return RUT_KEY_greater;
    case SDLK_QUESTION:
        return RUT_KEY_question;
    case SDLK_AT:
        return RUT_KEY_at;

    /*
     * Skip uppercase letters
     */

    case SDLK_LEFTBRACKET:
        return RUT_KEY_bracketleft;
    case SDLK_BACKSLASH:
        return RUT_KEY_backslash;
    case SDLK_RIGHTBRACKET:
        return RUT_KEY_bracketright;
    case SDLK_CARET:
        return RUT_KEY_caret;
    case SDLK_UNDERSCORE:
        return RUT_KEY_underscore;
    case SDLK_BACKQUOTE:
        return RUT_KEY_quoteleft;
    case SDLK_a:
        return RUT_KEY_a;
    case SDLK_b:
        return RUT_KEY_b;
    case SDLK_c:
        return RUT_KEY_c;
    case SDLK_d:
        return RUT_KEY_d;
    case SDLK_e:
        return RUT_KEY_e;
    case SDLK_f:
        return RUT_KEY_f;
    case SDLK_g:
        return RUT_KEY_g;
    case SDLK_h:
        return RUT_KEY_h;
    case SDLK_i:
        return RUT_KEY_i;
    case SDLK_j:
        return RUT_KEY_j;
    case SDLK_k:
        return RUT_KEY_k;
    case SDLK_l:
        return RUT_KEY_l;
    case SDLK_m:
        return RUT_KEY_m;
    case SDLK_n:
        return RUT_KEY_n;
    case SDLK_o:
        return RUT_KEY_o;
    case SDLK_p:
        return RUT_KEY_p;
    case SDLK_q:
        return RUT_KEY_q;
    case SDLK_r:
        return RUT_KEY_r;
    case SDLK_s:
        return RUT_KEY_s;
    case SDLK_t:
        return RUT_KEY_t;
    case SDLK_u:
        return RUT_KEY_u;
    case SDLK_v:
        return RUT_KEY_v;
    case SDLK_w:
        return RUT_KEY_w;
    case SDLK_x:
        return RUT_KEY_x;
    case SDLK_y:
        return RUT_KEY_y;
    case SDLK_z:
        return RUT_KEY_z;
    case SDLK_DELETE:
        return RUT_KEY_Delete;

/* International keyboard keysyms */
#if SDL_MAJOR_VERSION < 2
    case SDLK_WORLD_0:
    case SDLK_WORLD_1:
    case SDLK_WORLD_2:
    case SDLK_WORLD_3:
    case SDLK_WORLD_4:
    case SDLK_WORLD_5:
    case SDLK_WORLD_6:
    case SDLK_WORLD_7:
    case SDLK_WORLD_8:
    case SDLK_WORLD_9:
    case SDLK_WORLD_10:
    case SDLK_WORLD_11:
    case SDLK_WORLD_12:
    case SDLK_WORLD_13:
    case SDLK_WORLD_14:
    case SDLK_WORLD_15:
    case SDLK_WORLD_16:
    case SDLK_WORLD_17:
    case SDLK_WORLD_18:
    case SDLK_WORLD_19:
    case SDLK_WORLD_20:
    case SDLK_WORLD_21:
    case SDLK_WORLD_22:
    case SDLK_WORLD_23:
    case SDLK_WORLD_24:
    case SDLK_WORLD_25:
    case SDLK_WORLD_26:
    case SDLK_WORLD_27:
    case SDLK_WORLD_28:
    case SDLK_WORLD_29:
    case SDLK_WORLD_30:
    case SDLK_WORLD_31:
    case SDLK_WORLD_32:
    case SDLK_WORLD_33:
    case SDLK_WORLD_34:
    case SDLK_WORLD_35:
    case SDLK_WORLD_36:
    case SDLK_WORLD_37:
    case SDLK_WORLD_38:
    case SDLK_WORLD_39:
    case SDLK_WORLD_40:
    case SDLK_WORLD_41:
    case SDLK_WORLD_42:
    case SDLK_WORLD_43:
    case SDLK_WORLD_44:
    case SDLK_WORLD_45:
    case SDLK_WORLD_46:
    case SDLK_WORLD_47:
    case SDLK_WORLD_48:
    case SDLK_WORLD_49:
    case SDLK_WORLD_50:
    case SDLK_WORLD_51:
    case SDLK_WORLD_52:
    case SDLK_WORLD_53:
    case SDLK_WORLD_54:
    case SDLK_WORLD_55:
    case SDLK_WORLD_56:
    case SDLK_WORLD_57:
    case SDLK_WORLD_58:
    case SDLK_WORLD_59:
    case SDLK_WORLD_60:
    case SDLK_WORLD_61:
    case SDLK_WORLD_62:
    case SDLK_WORLD_63:
    case SDLK_WORLD_64:
    case SDLK_WORLD_65:
    case SDLK_WORLD_66:
    case SDLK_WORLD_67:
    case SDLK_WORLD_68:
    case SDLK_WORLD_69:
    case SDLK_WORLD_70:
    case SDLK_WORLD_71:
    case SDLK_WORLD_72:
    case SDLK_WORLD_73:
    case SDLK_WORLD_74:
    case SDLK_WORLD_75:
    case SDLK_WORLD_76:
    case SDLK_WORLD_77:
    case SDLK_WORLD_78:
    case SDLK_WORLD_79:
    case SDLK_WORLD_80:
    case SDLK_WORLD_81:
    case SDLK_WORLD_82:
    case SDLK_WORLD_83:
    case SDLK_WORLD_84:
    case SDLK_WORLD_85:
    case SDLK_WORLD_86:
    case SDLK_WORLD_87:
    case SDLK_WORLD_88:
    case SDLK_WORLD_89:
    case SDLK_WORLD_90:
    case SDLK_WORLD_91:
    case SDLK_WORLD_92:
    case SDLK_WORLD_93:
    case SDLK_WORLD_94:
    case SDLK_WORLD_95:
        return sdl_keysym;
#endif /* SDL_MAJOR_VERSION < 2 */

/* Number Pad keysyms */
#if SDL_MAJOR_VERSION >= 2
#define KEYPAD_KEYSYM(digit) SDLK_KP_##digit
#else
#define KEYPAD_KEYSYM(digit) SDLK_KP##digit
#endif
    case KEYPAD_KEYSYM(0):
        return RUT_KEY_KP_0;
    case KEYPAD_KEYSYM(1):
        return RUT_KEY_KP_1;
    case KEYPAD_KEYSYM(2):
        return RUT_KEY_KP_2;
    case KEYPAD_KEYSYM(3):
        return RUT_KEY_KP_3;
    case KEYPAD_KEYSYM(4):
        return RUT_KEY_KP_4;
    case KEYPAD_KEYSYM(5):
        return RUT_KEY_KP_5;
    case KEYPAD_KEYSYM(6):
        return RUT_KEY_KP_6;
    case KEYPAD_KEYSYM(7):
        return RUT_KEY_KP_7;
    case KEYPAD_KEYSYM(8):
        return RUT_KEY_KP_8;
    case KEYPAD_KEYSYM(9):
        return RUT_KEY_KP_9;
#undef KEYPAD_KEYSYM
    case SDLK_KP_PERIOD:
        return RUT_KEY_KP_Decimal;
    case SDLK_KP_DIVIDE:
        return RUT_KEY_KP_Divide;
    case SDLK_KP_MULTIPLY:
        return RUT_KEY_KP_Multiply;
    case SDLK_KP_MINUS:
        return RUT_KEY_KP_Subtract;
    case SDLK_KP_PLUS:
        return RUT_KEY_KP_Add;
    case SDLK_KP_ENTER:
        return RUT_KEY_KP_Enter;
    case SDLK_KP_EQUALS:
        return RUT_KEY_KP_Equal;

    /* Arrows + Home/End keysyms */
    case SDLK_UP:
        return RUT_KEY_Up;
    case SDLK_DOWN:
        return RUT_KEY_Down;
    case SDLK_RIGHT:
        return RUT_KEY_Right;
    case SDLK_LEFT:
        return RUT_KEY_Left;
    case SDLK_INSERT:
        return RUT_KEY_Insert;
    case SDLK_HOME:
        return RUT_KEY_Home;
    case SDLK_END:
        return RUT_KEY_End;
    case SDLK_PAGEUP:
        return RUT_KEY_Page_Up;
    case SDLK_PAGEDOWN:
        return RUT_KEY_Page_Down;

    /* Function key keysyms */
    case SDLK_F1:
        return RUT_KEY_F1;
    case SDLK_F2:
        return RUT_KEY_F2;
    case SDLK_F3:
        return RUT_KEY_F3;
    case SDLK_F4:
        return RUT_KEY_F4;
    case SDLK_F5:
        return RUT_KEY_F5;
    case SDLK_F6:
        return RUT_KEY_F6;
    case SDLK_F7:
        return RUT_KEY_F7;
    case SDLK_F8:
        return RUT_KEY_F8;
    case SDLK_F9:
        return RUT_KEY_F9;
    case SDLK_F10:
        return RUT_KEY_F10;
    case SDLK_F11:
        return RUT_KEY_F11;
    case SDLK_F12:
        return RUT_KEY_F12;
    case SDLK_F13:
        return RUT_KEY_F13;
    case SDLK_F14:
        return RUT_KEY_F14;
    case SDLK_F15:
        return RUT_KEY_F15;

    /* Modifier keysyms */
    case SDLK_CAPSLOCK:
        return RUT_KEY_Caps_Lock;
    case SDLK_RSHIFT:
        return RUT_KEY_Shift_R;
    case SDLK_LSHIFT:
        return RUT_KEY_Shift_L;
    case SDLK_RCTRL:
        return RUT_KEY_Control_R;
    case SDLK_LCTRL:
        return RUT_KEY_Control_L;
    case SDLK_RALT:
        return RUT_KEY_Alt_R;
    case SDLK_LALT:
        return RUT_KEY_Alt_L;
    case SDLK_MODE:
        return RUT_KEY_Mode_switch;
#if SDL_MAJOR_VERSION < 2
    case SDLK_NUMLOCK:
        return RUT_KEY_Num_Lock;
    case SDLK_RMETA:
        return RUT_KEY_Meta_R;
    case SDLK_LMETA:
        return RUT_KEY_Meta_L;
    case SDLK_LSUPER:
        return RUT_KEY_Super_L;
    case SDLK_RSUPER:
        return RUT_KEY_Super_R;
    case SDLK_COMPOSE:
        return RUT_KEY_Multi_key;
    case SDLK_SCROLLOCK:
        return RUT_KEY_Scroll_Lock;
#else /* SDL_MAJOR_VERSION < 2 */
    case SDLK_SCROLLLOCK:
        return RUT_KEY_Scroll_Lock;
#endif /* SDL_MAJOR_VERSION < 2 */

    /* Miscellaneous keysyms */
    case SDLK_HELP:
        return RUT_KEY_Help;
    case SDLK_SYSREQ:
        return RUT_KEY_Sys_Req;
    case SDLK_MENU:
        return RUT_KEY_Menu;
    case SDLK_POWER:
        return RUT_KEY_PowerOff;
    case SDLK_UNDO:
        return RUT_KEY_Undo;
#if SDL_MAJOR_VERSION < 2
    case SDLK_PRINT:
        return RUT_KEY_Print;
    case SDLK_BREAK:
        return RUT_KEY_Break;
    case SDLK_EURO:
        return RUT_KEY_EuroSign;
#endif /* SDL_MAJOR_VERSION < 2 */
    }

    c_warn_if_reached();
    return RUT_KEY_VoidSymbol;
}