symbian-qemu-0.9.1-12/qemu-symbian-svp/sdl.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * QEMU SDL display driver
       
     3  *
       
     4  * Copyright (c) 2003 Fabrice Bellard
       
     5  *
       
     6  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     7  * of this software and associated documentation files (the "Software"), to deal
       
     8  * in the Software without restriction, including without limitation the rights
       
     9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
    10  * copies of the Software, and to permit persons to whom the Software is
       
    11  * furnished to do so, subject to the following conditions:
       
    12  *
       
    13  * The above copyright notice and this permission notice shall be included in
       
    14  * all copies or substantial portions of the Software.
       
    15  *
       
    16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
       
    19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    22  * THE SOFTWARE.
       
    23  */
       
    24 #include "qemu-common.h"
       
    25 #include "console.h"
       
    26 #include "sysemu.h"
       
    27 #include "gui_host.h"
       
    28 
       
    29 #include <SDL.h>
       
    30 
       
    31 #ifndef _WIN32
       
    32 #include <signal.h>
       
    33 #endif
       
    34 
       
    35 static SDL_Surface *screen;
       
    36 static int gui_noframe;
       
    37 static int gui_key_modifier_pressed;
       
    38 static int special_key_combination;
       
    39 static int kbd_in_terminal_mode;
       
    40 static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
       
    41 static uint8_t modifiers_state[256];
       
    42 static int width, height;
       
    43 static SDL_Cursor *sdl_cursor_normal;
       
    44 static SDL_Cursor *sdl_cursor_hidden;
       
    45 static SDL_Cursor *guest_sprite = 0;
       
    46 
       
    47 static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
       
    48 {
       
    49     //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
       
    50     SDL_UpdateRect(screen, ds->x0 + x, ds->y0 + y, w, h);
       
    51 }
       
    52 
       
    53 static void sdl_gui_set_screen_size(int w, int h, int fullscreen_on)
       
    54 {
       
    55     int flags;
       
    56 
       
    57     //    printf("resizing to %d %d\n", w, h);
       
    58 
       
    59     flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
       
    60     if (fullscreen_on)
       
    61         flags |= SDL_FULLSCREEN;
       
    62     if (gui_noframe)
       
    63         flags |= SDL_NOFRAME;
       
    64 
       
    65     width = w;
       
    66     height = h;
       
    67 
       
    68  again:
       
    69     screen = SDL_SetVideoMode(width, height, 0, flags);
       
    70     if (!screen) {
       
    71         fprintf(stderr, "Could not open SDL display\n");
       
    72         exit(1);
       
    73     }
       
    74     if (!screen->pixels && (flags & SDL_HWSURFACE) && (flags & SDL_FULLSCREEN)) {
       
    75         flags &= ~SDL_HWSURFACE;
       
    76         goto again;
       
    77     }
       
    78 
       
    79     if (!screen->pixels) {
       
    80         fprintf(stderr, "Could not open SDL display\n");
       
    81         exit(1);
       
    82     }
       
    83 }
       
    84 
       
    85 static void sdl_gui_get_screen_data(screen_data_t *new_screen_data)
       
    86 {
       
    87     new_screen_data->data = screen->pixels;
       
    88     new_screen_data->linesize = screen->pitch;
       
    89     new_screen_data->width = screen->w;
       
    90     new_screen_data->height = screen->h;
       
    91     new_screen_data->depth = screen->format->BitsPerPixel;
       
    92     /* SDL BitsPerPixel never indicates any values other than
       
    93        multiples of 8, so we need to check for strange depths. */
       
    94     if (new_screen_data->depth == 16) {
       
    95         uint32_t mask;
       
    96 
       
    97         mask = screen->format->Rmask;
       
    98         mask |= screen->format->Gmask;
       
    99         mask |= screen->format->Bmask;
       
   100         if ((mask & 0x8000) == 0)
       
   101             new_screen_data->depth = 15;
       
   102     }
       
   103     if (new_screen_data->depth == 32 && screen->format->Rshift == 0) {
       
   104         new_screen_data->bgr = 1;
       
   105     } else {
       
   106         new_screen_data->bgr = 0;
       
   107     }
       
   108 }
       
   109 
       
   110 
       
   111 /* generic keyboard conversion */
       
   112 
       
   113 #include "sdl_keysym.h"
       
   114 #include "keymaps.c"
       
   115 
       
   116 static kbd_layout_t *kbd_layout = NULL;
       
   117 
       
   118 static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev)
       
   119 {
       
   120     int keysym;
       
   121     /* workaround for X11+SDL bug with AltGR */
       
   122     keysym = ev->keysym.sym;
       
   123     if (keysym == 0 && ev->keysym.scancode == 113)
       
   124         keysym = SDLK_MODE;
       
   125     /* For Japanese key '\' and '|' */
       
   126     if (keysym == 92 && ev->keysym.scancode == 133) {
       
   127         keysym = 0xa5;
       
   128     }
       
   129     return keysym2scancode(kbd_layout, keysym);
       
   130 }
       
   131 
       
   132 /* specific keyboard conversions from scan codes */
       
   133 
       
   134 #if defined(_WIN32)
       
   135 
       
   136 static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
       
   137 {
       
   138     return ev->keysym.scancode;
       
   139 }
       
   140 
       
   141 #else
       
   142 
       
   143 static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
       
   144 {
       
   145     int keycode;
       
   146 
       
   147     keycode = ev->keysym.scancode;
       
   148 
       
   149     if (keycode < 9) {
       
   150         keycode = 0;
       
   151     } else if (keycode < 97) {
       
   152         keycode -= 8; /* just an offset */
       
   153     } else if (keycode < 212) {
       
   154         /* use conversion table */
       
   155         keycode = _translate_keycode(keycode - 97);
       
   156     } else {
       
   157         keycode = 0;
       
   158     }
       
   159     return keycode;
       
   160 }
       
   161 
       
   162 #endif
       
   163 
       
   164 static void reset_keys(void)
       
   165 {
       
   166     int i;
       
   167     for(i = 0; i < 256; i++) {
       
   168         if (modifiers_state[i]) {
       
   169             if (i & 0x80)
       
   170                 gui_notify_dev_key(0xe0);
       
   171             gui_notify_dev_key(i | 0x80);
       
   172             modifiers_state[i] = 0;
       
   173         }
       
   174     }
       
   175 }
       
   176 
       
   177 static void sdl_process_key(SDL_KeyboardEvent *ev)
       
   178 {
       
   179     int keycode, v;
       
   180 
       
   181     if (ev->keysym.sym == SDLK_PAUSE) {
       
   182         /* specific case */
       
   183         v = 0;
       
   184         if (ev->type == SDL_KEYUP)
       
   185             v |= 0x80;
       
   186         gui_notify_dev_key(0xe1);
       
   187         gui_notify_dev_key(0x1d | v);
       
   188         gui_notify_dev_key(0x45 | v);
       
   189         return;
       
   190     }
       
   191 
       
   192     if (kbd_layout) {
       
   193         keycode = sdl_keyevent_to_keycode_generic(ev);
       
   194     } else {
       
   195         keycode = sdl_keyevent_to_keycode(ev);
       
   196     }
       
   197 
       
   198     switch(keycode) {
       
   199     case 0x00:
       
   200         /* sent when leaving window: reset the modifiers state */
       
   201         reset_keys();
       
   202         return;
       
   203     case 0x2a:                          /* Left Shift */
       
   204     case 0x36:                          /* Right Shift */
       
   205     case 0x1d:                          /* Left CTRL */
       
   206     case 0x9d:                          /* Right CTRL */
       
   207     case 0x38:                          /* Left ALT */
       
   208     case 0xb8:                         /* Right ALT */
       
   209         if (ev->type == SDL_KEYUP)
       
   210             modifiers_state[keycode] = 0;
       
   211         else
       
   212             modifiers_state[keycode] = 1;
       
   213         break;
       
   214     case 0x45: /* num lock */
       
   215     case 0x3a: /* caps lock */
       
   216         /* SDL does not send the key up event, so we generate it */
       
   217         gui_notify_dev_key(keycode);
       
   218         gui_notify_dev_key(keycode | 0x80);
       
   219         return;
       
   220     }
       
   221 
       
   222     /* now send the key code */
       
   223     if (keycode & 0x80)
       
   224         gui_notify_dev_key(0xe0);
       
   225     if (ev->type == SDL_KEYUP)
       
   226         gui_notify_dev_key(keycode | 0x80);
       
   227     else
       
   228         gui_notify_dev_key(keycode & 0x7f);
       
   229 }
       
   230 
       
   231 static int sdl_state_to_qemu(int sdl_state)
       
   232 {
       
   233     int buttons = 0;
       
   234     if (sdl_state & SDL_BUTTON(SDL_BUTTON_LEFT))
       
   235         buttons |= MOUSE_EVENT_LBUTTON;
       
   236     if (sdl_state & SDL_BUTTON(SDL_BUTTON_RIGHT))
       
   237         buttons |= MOUSE_EVENT_RBUTTON;
       
   238     if (sdl_state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
       
   239         buttons |= MOUSE_EVENT_MBUTTON;
       
   240 
       
   241     return buttons;
       
   242 }
       
   243 
       
   244 static void sdl_gui_process_events(void)
       
   245 {
       
   246     SDL_Event ev1, *ev = &ev1;
       
   247     int mod_state;
       
   248     int buttonstate = SDL_GetMouseState(NULL, NULL);
       
   249 
       
   250     gui_refresh_caption();
       
   251 
       
   252     /*vga_hw_update();*/
       
   253     SDL_EnableUNICODE(kbd_in_terminal_mode);
       
   254 
       
   255     while (SDL_PollEvent(ev)) {
       
   256         switch (ev->type) {
       
   257         case SDL_VIDEOEXPOSE:
       
   258             gui_notify_repaint_screen();
       
   259             break;
       
   260         case SDL_KEYDOWN:
       
   261         case SDL_KEYUP:
       
   262             if (ev->type == SDL_KEYDOWN) {
       
   263                 if (!alt_grab) {
       
   264                     mod_state = (SDL_GetModState() & gui_grab_code) ==
       
   265                                 gui_grab_code;
       
   266                 } else {
       
   267                     mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
       
   268                                 (gui_grab_code | KMOD_LSHIFT);
       
   269                 }
       
   270                 gui_key_modifier_pressed = mod_state;
       
   271                 if (gui_key_modifier_pressed) {
       
   272                     int keycode;
       
   273                     keycode = sdl_keyevent_to_keycode(&ev->key);
       
   274                     switch(keycode) {
       
   275                     case 0x21: /* 'f' key on US keyboard */
       
   276                         if (gui_allows_fullscreen()) {
       
   277                             gui_notify_toggle_fullscreen();
       
   278                             special_key_combination = 1;
       
   279                         }
       
   280                         break;
       
   281                     case 0x02 ... 0x0a: /* '1' to '9' keys */
       
   282                         /* Reset the modifiers sent to the current console */
       
   283                         reset_keys();
       
   284                         gui_notify_console_select(keycode - 0x02);
       
   285                         special_key_combination = 1;
       
   286                         break;
       
   287                     default:
       
   288                         break;
       
   289                     }
       
   290                 } else if (kbd_in_terminal_mode) {
       
   291                     int keysym;
       
   292                     keysym = 0;
       
   293                     if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
       
   294                         switch(ev->key.keysym.sym) {
       
   295                         case SDLK_UP: keysym = QEMU_KEY_CTRL_UP; break;
       
   296                         case SDLK_DOWN: keysym = QEMU_KEY_CTRL_DOWN; break;
       
   297                         case SDLK_LEFT: keysym = QEMU_KEY_CTRL_LEFT; break;
       
   298                         case SDLK_RIGHT: keysym = QEMU_KEY_CTRL_RIGHT; break;
       
   299                         case SDLK_HOME: keysym = QEMU_KEY_CTRL_HOME; break;
       
   300                         case SDLK_END: keysym = QEMU_KEY_CTRL_END; break;
       
   301                         case SDLK_PAGEUP: keysym = QEMU_KEY_CTRL_PAGEUP; break;
       
   302                         case SDLK_PAGEDOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
       
   303                         default: break;
       
   304                         }
       
   305                     } else {
       
   306                         switch(ev->key.keysym.sym) {
       
   307                         case SDLK_UP: keysym = QEMU_KEY_UP; break;
       
   308                         case SDLK_DOWN: keysym = QEMU_KEY_DOWN; break;
       
   309                         case SDLK_LEFT: keysym = QEMU_KEY_LEFT; break;
       
   310                         case SDLK_RIGHT: keysym = QEMU_KEY_RIGHT; break;
       
   311                         case SDLK_HOME: keysym = QEMU_KEY_HOME; break;
       
   312                         case SDLK_END: keysym = QEMU_KEY_END; break;
       
   313                         case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break;
       
   314                         case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break;
       
   315                         case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break;
       
   316                         case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break;
       
   317                         default: break;
       
   318                         }
       
   319                     }
       
   320                     if (keysym) {
       
   321                         gui_notify_term_key(keysym);
       
   322                     } else if (ev->key.keysym.unicode != 0) {
       
   323                         gui_notify_term_key(ev->key.keysym.unicode);
       
   324                     }
       
   325                 }
       
   326             } else if (ev->type == SDL_KEYUP) {
       
   327                 if (!alt_grab) {
       
   328                     mod_state = (ev->key.keysym.mod & gui_grab_code);
       
   329                 } else {
       
   330                     mod_state = (ev->key.keysym.mod &
       
   331                                  (gui_grab_code | KMOD_LSHIFT));
       
   332                 }
       
   333                 if (!mod_state) {
       
   334                     if (gui_key_modifier_pressed) {
       
   335                         gui_key_modifier_pressed = 0;
       
   336                         if (!special_key_combination) {
       
   337                             /* exit/enter grab if pressing Ctrl-Alt */
       
   338                             gui_notify_toggle_grabmode();
       
   339                             /* SDL does not send back all the
       
   340                                modifiers key, so we must correct it */
       
   341                             reset_keys();
       
   342                             break;
       
   343                         }
       
   344                         special_key_combination = 0;
       
   345                     }
       
   346                 }
       
   347             }
       
   348             if (!kbd_in_terminal_mode && !special_key_combination)
       
   349                 sdl_process_key(&ev->key);
       
   350             break;
       
   351         case SDL_QUIT:
       
   352             if (!no_quit)
       
   353                 qemu_system_shutdown_request();
       
   354             break;
       
   355         case SDL_MOUSEMOTION:
       
   356             gui_notify_mouse_motion(ev->motion.xrel, ev->motion.yrel, 0,
       
   357                                     ev->motion.x, ev->motion.y, 
       
   358                                     sdl_state_to_qemu(ev->motion.state));
       
   359             break;
       
   360         case SDL_MOUSEBUTTONDOWN:
       
   361         case SDL_MOUSEBUTTONUP:
       
   362             {
       
   363                 SDL_MouseButtonEvent *bev = &ev->button;
       
   364                 int dz = 0;
       
   365 
       
   366                 if (ev->type == SDL_MOUSEBUTTONDOWN) {
       
   367                     buttonstate |= SDL_BUTTON(bev->button);
       
   368                 } else {
       
   369                     buttonstate &= ~SDL_BUTTON(bev->button);
       
   370                 }
       
   371 #ifdef SDL_BUTTON_WHEELUP
       
   372                 if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) {
       
   373                     dz = -1;
       
   374                 } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) {
       
   375                     dz = 1;
       
   376                 }
       
   377 #endif
       
   378                 gui_notify_mouse_button(dz, bev->x, bev->y, sdl_state_to_qemu(buttonstate));
       
   379             }
       
   380             break;
       
   381         case SDL_ACTIVEEVENT:
       
   382             if (ev->active.state == SDL_APPINPUTFOCUS && !ev->active.gain) {
       
   383                 gui_notify_input_focus_lost();
       
   384             } else if (ev->active.state & SDL_APPACTIVE) {
       
   385                 gui_notify_app_focus(ev->active.gain);
       
   386             }
       
   387             break;
       
   388         default:
       
   389             break;
       
   390         }
       
   391     }
       
   392 }
       
   393 
       
   394 static void sdl_gui_set_kbd_terminal_mode(int on)
       
   395 {
       
   396     kbd_in_terminal_mode = on;
       
   397 }
       
   398 
       
   399 static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
       
   400 {
       
   401     SDL_Rect dst = { x, y, w, h };
       
   402     SDL_FillRect(screen, &dst, c);
       
   403 }
       
   404 
       
   405 static void sdl_mouse_warp(int x, int y, int on)
       
   406 {
       
   407     gui_notify_mouse_warp(x, y, on);
       
   408 }
       
   409 
       
   410 static void sdl_mouse_define(int width, int height, int bpp,
       
   411                              int hot_x, int hot_y,
       
   412                              uint8_t *image, uint8_t *mask)
       
   413 {
       
   414     uint8_t sprite[256], *line;
       
   415     int x, y, dst, bypl, src = 0;
       
   416     if (guest_sprite)
       
   417         SDL_FreeCursor(guest_sprite);
       
   418 
       
   419     memset(sprite, 0, 256);
       
   420     bypl = ((width * bpp + 31) >> 5) << 2;
       
   421     for (y = 0, dst = 0; y < height; y ++, image += bypl) {
       
   422         line = image;
       
   423         for (x = 0; x < width; x ++, dst ++) {
       
   424             switch (bpp) {
       
   425             case 24:
       
   426                 src = *(line ++); src |= *(line ++); src |= *(line ++);
       
   427                 break;
       
   428             case 16:
       
   429             case 15:
       
   430                 src = *(line ++); src |= *(line ++);
       
   431                 break;
       
   432             case 8:
       
   433                 src = *(line ++);
       
   434                 break;
       
   435             case 4:
       
   436                 src = 0xf & (line[x >> 1] >> ((x & 1)) << 2);
       
   437                 break;
       
   438             case 2:
       
   439                 src = 3 & (line[x >> 2] >> ((x & 3)) << 1);
       
   440                 break;
       
   441             case 1:
       
   442                 src = 1 & (line[x >> 3] >> (x & 7));
       
   443                 break;
       
   444             }
       
   445             if (!src)
       
   446                 sprite[dst >> 3] |= (1 << (~dst & 7)) & mask[dst >> 3];
       
   447         }
       
   448     }
       
   449     guest_sprite = SDL_CreateCursor(sprite, mask, width, height, hot_x, hot_y);
       
   450 
       
   451     gui_notify_new_guest_cursor();
       
   452 }
       
   453 
       
   454 static void sdl_cleanup(void)
       
   455 {
       
   456     if (guest_sprite)
       
   457         SDL_FreeCursor(guest_sprite);
       
   458     SDL_Quit();
       
   459 }
       
   460 
       
   461 /******** GUI CALLBACKS **********/
       
   462 static void sdl_gui_turn_cursor_on(gui_cursor_type_t cursor_type)
       
   463 {
       
   464     SDL_ShowCursor(1);
       
   465 
       
   466     switch(cursor_type) {
       
   467     case GUI_CURSOR_NORMAL:
       
   468         SDL_SetCursor(sdl_cursor_normal);
       
   469         break;
       
   470     case GUI_CURSOR_GUEST_SPRITE:
       
   471         SDL_SetCursor(guest_sprite);
       
   472         break;
       
   473     case GUI_CURSOR_HIDDEN:
       
   474         SDL_SetCursor(sdl_cursor_hidden);
       
   475         break;
       
   476     case GUI_CURSOR_GRABBING:
       
   477         if (guest_sprite)
       
   478             SDL_SetCursor(guest_sprite);
       
   479         else
       
   480             SDL_SetCursor(sdl_cursor_normal);
       
   481         break;
       
   482     }
       
   483 }
       
   484 
       
   485 static void sdl_gui_turn_cursor_off(void)
       
   486 {
       
   487     SDL_ShowCursor(0);
       
   488 }
       
   489 
       
   490 static void sdl_gui_mouse_warp(int x, int y)
       
   491 {
       
   492     SDL_WarpMouse(x, y);
       
   493 }
       
   494 
       
   495 static void sdl_gui_grab_input_on(void)
       
   496 {
       
   497     SDL_WM_GrabInput(SDL_GRAB_ON);
       
   498 }
       
   499 
       
   500 static void sdl_gui_grab_input_off(void)
       
   501 {
       
   502     SDL_WM_GrabInput(SDL_GRAB_OFF);
       
   503 }
       
   504 
       
   505 static void sdl_gui_set_caption(const char* title, const char* icon)
       
   506 {
       
   507     SDL_WM_SetCaption(title, icon);
       
   508 }
       
   509 
       
   510 static int sdl_gui_is_app_active(void)
       
   511 {
       
   512     return (SDL_GetAppState() & SDL_APPACTIVE);
       
   513 }
       
   514 
       
   515 static void sdl_init_ds(DisplayState *ds)
       
   516 {
       
   517     ds->dpy_update = sdl_update;
       
   518     ds->dpy_fill = sdl_fill;
       
   519     ds->mouse_set = sdl_mouse_warp;
       
   520     ds->cursor_define = sdl_mouse_define;
       
   521 }
       
   522 
       
   523 /*********************************/
       
   524 
       
   525 
       
   526 void sdl_display_init(int full_screen, int no_frame)
       
   527 {
       
   528     int flags;
       
   529     uint8_t data = 0;
       
   530     gui_host_callbacks_t gui_callbacks;
       
   531 
       
   532 #if defined(__APPLE__)
       
   533     /* always use generic keymaps */
       
   534     if (!keyboard_layout)
       
   535         keyboard_layout = "en-us";
       
   536 #endif
       
   537     if(keyboard_layout) {
       
   538         kbd_layout = init_keyboard_layout(keyboard_layout);
       
   539         if (!kbd_layout)
       
   540             exit(1);
       
   541     }
       
   542 
       
   543     if (no_frame)
       
   544         gui_noframe = 1;
       
   545 
       
   546     flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
       
   547     if (SDL_Init (flags)) {
       
   548         fprintf(stderr, "Could not initialize SDL - exiting\n");
       
   549         exit(1);
       
   550     }
       
   551 
       
   552     memset(&gui_callbacks, 0, sizeof(gui_host_callbacks_t));
       
   553     gui_callbacks.turn_cursor_on = &sdl_gui_turn_cursor_on;
       
   554     gui_callbacks.turn_cursor_off = &sdl_gui_turn_cursor_off;
       
   555     gui_callbacks.mouse_warp = &sdl_gui_mouse_warp;
       
   556     gui_callbacks.grab_input_on = &sdl_gui_grab_input_on;
       
   557     gui_callbacks.grab_input_off = &sdl_gui_grab_input_off;
       
   558     gui_callbacks.set_caption = &sdl_gui_set_caption;
       
   559     gui_callbacks.set_screen_size = &sdl_gui_set_screen_size;
       
   560     gui_callbacks.get_screen_data = &sdl_gui_get_screen_data;
       
   561     gui_callbacks.is_app_active = &sdl_gui_is_app_active;
       
   562     gui_callbacks.init_ds = &sdl_init_ds;
       
   563     gui_callbacks.process_events = &sdl_gui_process_events;
       
   564     gui_callbacks.set_kbd_terminal_mode = &sdl_gui_set_kbd_terminal_mode;
       
   565     gui_init(&gui_callbacks);
       
   566 
       
   567     if (full_screen && gui_allows_fullscreen()) {
       
   568         gui_notify_toggle_fullscreen();
       
   569     }
       
   570 
       
   571     SDL_EnableKeyRepeat(250, 50);
       
   572 
       
   573     sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
       
   574     sdl_cursor_normal = SDL_GetCursor();
       
   575 
       
   576     atexit(sdl_cleanup);
       
   577 
       
   578 }
       
   579