cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_androidkeyboard.c (13371B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      4
      5  This software is provided 'as-is', without any express or implied
      6  warranty.  In no event will the authors be held liable for any damages
      7  arising from the use of this software.
      8
      9  Permission is granted to anyone to use this software for any purpose,
     10  including commercial applications, and to alter it and redistribute it
     11  freely, subject to the following restrictions:
     12
     13  1. The origin of this software must not be misrepresented; you must not
     14     claim that you wrote the original software. If you use this software
     15     in a product, an acknowledgment in the product documentation would be
     16     appreciated but is not required.
     17  2. Altered source versions must be plainly marked as such, and must not be
     18     misrepresented as being the original software.
     19  3. This notice may not be removed or altered from any source distribution.
     20*/
     21#include "../../SDL_internal.h"
     22
     23#if SDL_VIDEO_DRIVER_ANDROID
     24
     25#include <android/log.h>
     26
     27#include "../../events/SDL_events_c.h"
     28
     29#include "SDL_androidkeyboard.h"
     30
     31#include "../../core/android/SDL_android.h"
     32
     33void Android_InitKeyboard(void)
     34{
     35    SDL_Keycode keymap[SDL_NUM_SCANCODES];
     36
     37    /* Add default scancode to key mapping */
     38    SDL_GetDefaultKeymap(keymap);
     39    SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
     40}
     41
     42static SDL_Scancode Android_Keycodes[] = {
     43    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_UNKNOWN */
     44    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_LEFT */
     45    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_RIGHT */
     46    SDL_SCANCODE_AC_HOME, /* AKEYCODE_HOME */
     47    SDL_SCANCODE_AC_BACK, /* AKEYCODE_BACK */
     48    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CALL */
     49    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ENDCALL */
     50    SDL_SCANCODE_0, /* AKEYCODE_0 */
     51    SDL_SCANCODE_1, /* AKEYCODE_1 */
     52    SDL_SCANCODE_2, /* AKEYCODE_2 */
     53    SDL_SCANCODE_3, /* AKEYCODE_3 */
     54    SDL_SCANCODE_4, /* AKEYCODE_4 */
     55    SDL_SCANCODE_5, /* AKEYCODE_5 */
     56    SDL_SCANCODE_6, /* AKEYCODE_6 */
     57    SDL_SCANCODE_7, /* AKEYCODE_7 */
     58    SDL_SCANCODE_8, /* AKEYCODE_8 */
     59    SDL_SCANCODE_9, /* AKEYCODE_9 */
     60    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STAR */
     61    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_POUND */
     62    SDL_SCANCODE_UP, /* AKEYCODE_DPAD_UP */
     63    SDL_SCANCODE_DOWN, /* AKEYCODE_DPAD_DOWN */
     64    SDL_SCANCODE_LEFT, /* AKEYCODE_DPAD_LEFT */
     65    SDL_SCANCODE_RIGHT, /* AKEYCODE_DPAD_RIGHT */
     66    SDL_SCANCODE_SELECT, /* AKEYCODE_DPAD_CENTER */
     67    SDL_SCANCODE_VOLUMEUP, /* AKEYCODE_VOLUME_UP */
     68    SDL_SCANCODE_VOLUMEDOWN, /* AKEYCODE_VOLUME_DOWN */
     69    SDL_SCANCODE_POWER, /* AKEYCODE_POWER */
     70    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAMERA */
     71    SDL_SCANCODE_CLEAR, /* AKEYCODE_CLEAR */
     72    SDL_SCANCODE_A, /* AKEYCODE_A */
     73    SDL_SCANCODE_B, /* AKEYCODE_B */
     74    SDL_SCANCODE_C, /* AKEYCODE_C */
     75    SDL_SCANCODE_D, /* AKEYCODE_D */
     76    SDL_SCANCODE_E, /* AKEYCODE_E */
     77    SDL_SCANCODE_F, /* AKEYCODE_F */
     78    SDL_SCANCODE_G, /* AKEYCODE_G */
     79    SDL_SCANCODE_H, /* AKEYCODE_H */
     80    SDL_SCANCODE_I, /* AKEYCODE_I */
     81    SDL_SCANCODE_J, /* AKEYCODE_J */
     82    SDL_SCANCODE_K, /* AKEYCODE_K */
     83    SDL_SCANCODE_L, /* AKEYCODE_L */
     84    SDL_SCANCODE_M, /* AKEYCODE_M */
     85    SDL_SCANCODE_N, /* AKEYCODE_N */
     86    SDL_SCANCODE_O, /* AKEYCODE_O */
     87    SDL_SCANCODE_P, /* AKEYCODE_P */
     88    SDL_SCANCODE_Q, /* AKEYCODE_Q */
     89    SDL_SCANCODE_R, /* AKEYCODE_R */
     90    SDL_SCANCODE_S, /* AKEYCODE_S */
     91    SDL_SCANCODE_T, /* AKEYCODE_T */
     92    SDL_SCANCODE_U, /* AKEYCODE_U */
     93    SDL_SCANCODE_V, /* AKEYCODE_V */
     94    SDL_SCANCODE_W, /* AKEYCODE_W */
     95    SDL_SCANCODE_X, /* AKEYCODE_X */
     96    SDL_SCANCODE_Y, /* AKEYCODE_Y */
     97    SDL_SCANCODE_Z, /* AKEYCODE_Z */
     98    SDL_SCANCODE_COMMA, /* AKEYCODE_COMMA */
     99    SDL_SCANCODE_PERIOD, /* AKEYCODE_PERIOD */
    100    SDL_SCANCODE_LALT, /* AKEYCODE_ALT_LEFT */
    101    SDL_SCANCODE_RALT, /* AKEYCODE_ALT_RIGHT */
    102    SDL_SCANCODE_LSHIFT, /* AKEYCODE_SHIFT_LEFT */
    103    SDL_SCANCODE_RSHIFT, /* AKEYCODE_SHIFT_RIGHT */
    104    SDL_SCANCODE_TAB, /* AKEYCODE_TAB */
    105    SDL_SCANCODE_SPACE, /* AKEYCODE_SPACE */
    106    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SYM */
    107    SDL_SCANCODE_WWW, /* AKEYCODE_EXPLORER */
    108    SDL_SCANCODE_MAIL, /* AKEYCODE_ENVELOPE */
    109    SDL_SCANCODE_RETURN, /* AKEYCODE_ENTER */
    110    SDL_SCANCODE_BACKSPACE, /* AKEYCODE_DEL */
    111    SDL_SCANCODE_GRAVE, /* AKEYCODE_GRAVE */
    112    SDL_SCANCODE_MINUS, /* AKEYCODE_MINUS */
    113    SDL_SCANCODE_EQUALS, /* AKEYCODE_EQUALS */
    114    SDL_SCANCODE_LEFTBRACKET, /* AKEYCODE_LEFT_BRACKET */
    115    SDL_SCANCODE_RIGHTBRACKET, /* AKEYCODE_RIGHT_BRACKET */
    116    SDL_SCANCODE_BACKSLASH, /* AKEYCODE_BACKSLASH */
    117    SDL_SCANCODE_SEMICOLON, /* AKEYCODE_SEMICOLON */
    118    SDL_SCANCODE_APOSTROPHE, /* AKEYCODE_APOSTROPHE */
    119    SDL_SCANCODE_SLASH, /* AKEYCODE_SLASH */
    120    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AT */
    121    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM */
    122    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_HEADSETHOOK */
    123    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FOCUS */
    124    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PLUS */
    125    SDL_SCANCODE_MENU, /* AKEYCODE_MENU */
    126    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NOTIFICATION */
    127    SDL_SCANCODE_AC_SEARCH, /* AKEYCODE_SEARCH */
    128    SDL_SCANCODE_AUDIOPLAY, /* AKEYCODE_MEDIA_PLAY_PAUSE */
    129    SDL_SCANCODE_AUDIOSTOP, /* AKEYCODE_MEDIA_STOP */
    130    SDL_SCANCODE_AUDIONEXT, /* AKEYCODE_MEDIA_NEXT */
    131    SDL_SCANCODE_AUDIOPREV, /* AKEYCODE_MEDIA_PREVIOUS */
    132    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_REWIND */
    133    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_FAST_FORWARD */
    134    SDL_SCANCODE_MUTE, /* AKEYCODE_MUTE */
    135    SDL_SCANCODE_PAGEUP, /* AKEYCODE_PAGE_UP */
    136    SDL_SCANCODE_PAGEDOWN, /* AKEYCODE_PAGE_DOWN */
    137    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PICTSYMBOLS */
    138    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SWITCH_CHARSET */
    139    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_A */
    140    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_B */
    141    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_C */
    142    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_X */
    143    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Y */
    144    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Z */
    145    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L1 */
    146    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R1 */
    147    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L2 */
    148    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R2 */
    149    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBL */
    150    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBR */
    151    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_START */
    152    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_SELECT */
    153    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_MODE */
    154    SDL_SCANCODE_ESCAPE, /* AKEYCODE_ESCAPE */
    155    SDL_SCANCODE_DELETE, /* AKEYCODE_FORWARD_DEL */
    156    SDL_SCANCODE_LCTRL, /* AKEYCODE_CTRL_LEFT */
    157    SDL_SCANCODE_RCTRL, /* AKEYCODE_CTRL_RIGHT */
    158    SDL_SCANCODE_CAPSLOCK, /* AKEYCODE_CAPS_LOCK */
    159    SDL_SCANCODE_SCROLLLOCK, /* AKEYCODE_SCROLL_LOCK */
    160    SDL_SCANCODE_LGUI, /* AKEYCODE_META_LEFT */
    161    SDL_SCANCODE_RGUI, /* AKEYCODE_META_RIGHT */
    162    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FUNCTION */
    163    SDL_SCANCODE_PRINTSCREEN, /* AKEYCODE_SYSRQ */
    164    SDL_SCANCODE_PAUSE, /* AKEYCODE_BREAK */
    165    SDL_SCANCODE_HOME, /* AKEYCODE_MOVE_HOME */
    166    SDL_SCANCODE_END, /* AKEYCODE_MOVE_END */
    167    SDL_SCANCODE_INSERT, /* AKEYCODE_INSERT */
    168    SDL_SCANCODE_AC_FORWARD, /* AKEYCODE_FORWARD */
    169    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PLAY */
    170    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PAUSE */
    171    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_CLOSE */
    172    SDL_SCANCODE_EJECT, /* AKEYCODE_MEDIA_EJECT */
    173    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_RECORD */
    174    SDL_SCANCODE_F1, /* AKEYCODE_F1 */
    175    SDL_SCANCODE_F2, /* AKEYCODE_F2 */
    176    SDL_SCANCODE_F3, /* AKEYCODE_F3 */
    177    SDL_SCANCODE_F4, /* AKEYCODE_F4 */
    178    SDL_SCANCODE_F5, /* AKEYCODE_F5 */
    179    SDL_SCANCODE_F6, /* AKEYCODE_F6 */
    180    SDL_SCANCODE_F7, /* AKEYCODE_F7 */
    181    SDL_SCANCODE_F8, /* AKEYCODE_F8 */
    182    SDL_SCANCODE_F9, /* AKEYCODE_F9 */
    183    SDL_SCANCODE_F10, /* AKEYCODE_F10 */
    184    SDL_SCANCODE_F11, /* AKEYCODE_F11 */
    185    SDL_SCANCODE_F12, /* AKEYCODE_F12 */
    186    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM_LOCK */
    187    SDL_SCANCODE_KP_0, /* AKEYCODE_NUMPAD_0 */
    188    SDL_SCANCODE_KP_1, /* AKEYCODE_NUMPAD_1 */
    189    SDL_SCANCODE_KP_2, /* AKEYCODE_NUMPAD_2 */
    190    SDL_SCANCODE_KP_3, /* AKEYCODE_NUMPAD_3 */
    191    SDL_SCANCODE_KP_4, /* AKEYCODE_NUMPAD_4 */
    192    SDL_SCANCODE_KP_5, /* AKEYCODE_NUMPAD_5 */
    193    SDL_SCANCODE_KP_6, /* AKEYCODE_NUMPAD_6 */
    194    SDL_SCANCODE_KP_7, /* AKEYCODE_NUMPAD_7 */
    195    SDL_SCANCODE_KP_8, /* AKEYCODE_NUMPAD_8 */
    196    SDL_SCANCODE_KP_9, /* AKEYCODE_NUMPAD_9 */
    197    SDL_SCANCODE_KP_DIVIDE, /* AKEYCODE_NUMPAD_DIVIDE */
    198    SDL_SCANCODE_KP_MULTIPLY, /* AKEYCODE_NUMPAD_MULTIPLY */
    199    SDL_SCANCODE_KP_MINUS, /* AKEYCODE_NUMPAD_SUBTRACT */
    200    SDL_SCANCODE_KP_PLUS, /* AKEYCODE_NUMPAD_ADD */
    201    SDL_SCANCODE_KP_PERIOD, /* AKEYCODE_NUMPAD_DOT */
    202    SDL_SCANCODE_KP_COMMA, /* AKEYCODE_NUMPAD_COMMA */
    203    SDL_SCANCODE_KP_ENTER, /* AKEYCODE_NUMPAD_ENTER */
    204    SDL_SCANCODE_KP_EQUALS, /* AKEYCODE_NUMPAD_EQUALS */
    205    SDL_SCANCODE_KP_LEFTPAREN, /* AKEYCODE_NUMPAD_LEFT_PAREN */
    206    SDL_SCANCODE_KP_RIGHTPAREN, /* AKEYCODE_NUMPAD_RIGHT_PAREN */
    207    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_VOLUME_MUTE */
    208    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_INFO */
    209    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_UP */
    210    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_DOWN */
    211    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_IN */
    212    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_OUT */
    213    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV */
    214    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_WINDOW */
    215    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_GUIDE */
    216    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DVR */
    217    SDL_SCANCODE_AC_BOOKMARKS, /* AKEYCODE_BOOKMARK */
    218    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAPTIONS */
    219    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SETTINGS */
    220    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_POWER */
    221    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT */
    222    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_POWER */
    223    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_INPUT */
    224    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_POWER */
    225    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_INPUT */
    226    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_RED */
    227    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_GREEN */
    228    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_YELLOW */
    229    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_BLUE */
    230    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_APP_SWITCH */
    231    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_1 */
    232    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_2 */
    233    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_3 */
    234    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_4 */
    235    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_5 */
    236    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_6 */
    237    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_7 */
    238    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_8 */
    239    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_9 */
    240    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_10 */
    241    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_11 */
    242    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_12 */
    243    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_13 */
    244    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_14 */
    245    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_15 */
    246    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_16 */
    247    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_LANGUAGE_SWITCH */
    248    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MANNER_MODE */
    249    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_3D_MODE */
    250    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CONTACTS */
    251    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CALENDAR */
    252    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MUSIC */
    253    SDL_SCANCODE_CALCULATOR, /* AKEYCODE_CALCULATOR */
    254    SDL_SCANCODE_LANG5, /* AKEYCODE_ZENKAKU_HANKAKU */
    255    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_EISU */
    256    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MUHENKAN */
    257    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_HENKAN */
    258    SDL_SCANCODE_LANG3, /* AKEYCODE_KATAKANA_HIRAGANA */
    259    SDL_SCANCODE_INTERNATIONAL3, /* AKEYCODE_YEN */
    260    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_RO */
    261    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_KANA */
    262    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ASSIST */
    263    SDL_SCANCODE_BRIGHTNESSDOWN, /* AKEYCODE_BRIGHTNESS_DOWN */
    264    SDL_SCANCODE_BRIGHTNESSUP, /* AKEYCODE_BRIGHTNESS_UP */
    265    SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_AUDIO_TRACK */
    266};
    267
    268static SDL_Scancode
    269TranslateKeycode(int keycode)
    270{
    271    SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
    272
    273    if (keycode < SDL_arraysize(Android_Keycodes)) {
    274        scancode = Android_Keycodes[keycode];
    275    }
    276    if (scancode == SDL_SCANCODE_UNKNOWN) {
    277        __android_log_print(ANDROID_LOG_INFO, "SDL", "Unknown keycode %d", keycode);
    278    }
    279    return scancode;
    280}
    281
    282int
    283Android_OnKeyDown(int keycode)
    284{
    285    return SDL_SendKeyboardKey(SDL_PRESSED, TranslateKeycode(keycode));
    286}
    287
    288int
    289Android_OnKeyUp(int keycode)
    290{
    291    return SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode(keycode));
    292}
    293
    294SDL_bool
    295Android_HasScreenKeyboardSupport(_THIS)
    296{
    297    return SDL_TRUE;
    298}
    299
    300SDL_bool
    301Android_IsScreenKeyboardShown(_THIS, SDL_Window * window)
    302{
    303    return SDL_IsTextInputActive();
    304}
    305
    306void
    307Android_StartTextInput(_THIS)
    308{
    309    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
    310    Android_JNI_ShowTextInput(&videodata->textRect);
    311}
    312
    313void
    314Android_StopTextInput(_THIS)
    315{
    316    Android_JNI_HideTextInput();
    317}
    318
    319void
    320Android_SetTextInputRect(_THIS, SDL_Rect *rect)
    321{
    322    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
    323
    324    if (!rect) {
    325        SDL_InvalidParamError("rect");
    326        return;
    327    }
    328
    329    videodata->textRect = *rect;
    330}
    331
    332#endif /* SDL_VIDEO_DRIVER_ANDROID */
    333
    334/* vi: set ts=4 sw=4 expandtab: */