[Tizen] Support 32 bit window surface
[platform/upstream/SDL.git] / src / video / tizen / SDL_tizenwindow.c
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4   Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
5
6   This software is provided 'as-is', without any express or implied
7   warranty.  In no event will the authors be held liable for any damages
8   arising from the use of this software.
9
10   Permission is granted to anyone to use this software for any purpose,
11   including commercial applications, and to alter it and redistribute it
12   freely, subject to the following restrictions:
13
14   1. The origin of this software must not be misrepresented; you must not
15      claim that you wrote the original software. If you use this software
16      in a product, an acknowledgment in the product documentation would be
17      appreciated but is not required.
18   2. Altered source versions must be plainly marked as such, and must not be
19      misrepresented as being the original software.
20   3. This notice may not be removed or altered from any source distribution.
21 */
22
23 #include "../../SDL_internal.h"
24
25 #if SDL_VIDEO_DRIVER_TIZEN
26
27 #include "SDL_log.h"
28 #include "SDL_hints.h"
29 #include "SDL_loadso.h"
30
31 #include "SDL_tizenvideo.h"
32 #include "SDL_tizentouch.h"
33 #include "SDL_tizenkeyboard.h"
34 #include "SDL_tizenmouse.h"
35 #include "SDL_tizenevents_c.h"
36
37 #include "SDL_tizenwindow.h"
38
39 #include "../../events/SDL_mouse_c.h"
40 #include "../../joystick/tizen/SDL_sysjoystick_c.h"
41
42 #include "../SDL_egl_c.h"
43 #include "../SDL_vulkan_c.h"
44 #include "../SDL_sysvideo.h"
45 #include "../../events/SDL_windowevents_c.h"
46
47 enum {
48     ROTATION_TYPE_NORMAL_ROTATION = 0,
49     ROTATION_TYPE_PRE_ROTATION,      /* use pre-rotation */
50 };
51
52 #define LOAD_FUNC(NAME) \
53 _this->tizen_pre_rotation_data->NAME = SDL_LoadFunction(_this->tizen_pre_rotation_data->prerotation_dll_handle, #NAME); \
54 if (!_this->tizen_pre_rotation_data->NAME) \
55 { \
56     SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Could not retrieve pre-rotation function " #NAME); \
57     return SDL_FALSE; \
58 }
59
60 static int
61 _tizen_rotation_type_get()
62 {
63     static int type = ROTATION_TYPE_PRE_ROTATION;
64     static int checked = 0;
65     char *engine = NULL;
66
67     if (checked) return type;
68
69     engine = getenv("SDL_ROTATION");
70
71     if (engine)
72       {
73          if ((!strcasecmp(engine, "normal")))
74             type = ROTATION_TYPE_NORMAL_ROTATION;
75          else if ((!strcasecmp(engine, "pre_rotation")))
76             type = ROTATION_TYPE_PRE_ROTATION;
77          else
78             type = ROTATION_TYPE_PRE_ROTATION;
79       }
80     checked = 1;
81     return type;
82 }
83
84 int
85 _tizen_PreRotatotion_LoadLibrary(SDL_WindowData *_this, const char *lib_path)
86 {
87     void *lib_dll_handle = NULL;
88     char *path = NULL;
89
90     if (_this->isLoaded_pre_rotation)
91         return SDL_TRUE;
92
93     _this->tizen_pre_rotation_data = (Tizen_Prerotation_Data *) SDL_calloc(1, sizeof(Tizen_Prerotation_Data));
94     if (!_this->tizen_pre_rotation_data) {
95         return SDL_OutOfMemory();
96     }
97
98     if (!lib_path)
99         lib_dll_handle = SDL_LoadObject(lib_path);
100
101     if (!lib_dll_handle) {
102         path = "libwayland-egl.so";
103         lib_dll_handle = SDL_LoadObject(path);
104     }
105
106     _this->tizen_pre_rotation_data->prerotation_dll_handle = lib_dll_handle;
107
108     if (lib_dll_handle == NULL)
109         return SDL_FALSE;
110
111     LOAD_FUNC(wl_egl_window_set_rotation);
112     LOAD_FUNC(wl_egl_window_get_capabilities);
113     _this->isLoaded_pre_rotation = 1;
114
115     return SDL_TRUE;
116 }
117
118 SDL_bool
119 Tizen_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
120 {
121     SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
122     info->info.tizen.egl_display = NULL;
123     info->info.tizen.egl_surface = NULL;
124 #if SDL_VIDEO_OPENGL_EGL
125     if (_this->egl_data)
126     {
127        info->info.tizen.egl_display = (void*)_this->egl_data->egl_display;
128     }
129     info->info.tizen.egl_surface = (void*)wmdata->egl_surface;
130 #endif
131     info->subsystem = SDL_SYSWM_TIZEN;
132     return SDL_TRUE;
133 }
134
135 int
136 Tizen_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
137 {
138     return 0;  /* just succeed, the real work is done elsewhere. */
139 }
140
141 void
142 Tizen_ShowWindow(_THIS, SDL_Window *window)
143 {
144     SDL_WindowData *wind = window->driverdata;
145
146     if((window->flags & SDL_WINDOW_FULLSCREEN) || (window->flags & SDL_WINDOW_BORDERLESS))
147     {
148         ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_OFF);
149         ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_TRANSPARENT);
150         ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_HIDDEN);
151     }
152     else
153     {
154         ecore_wl_window_indicator_state_set(wind->window, ECORE_WL_INDICATOR_STATE_ON);
155         ecore_wl_window_indicator_opacity_set(wind->window, ECORE_WL_INDICATOR_OPAQUE);
156         ecore_wl_indicator_visible_type_set(wind->window, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
157     }
158     ecore_wl_window_show(wind->window);
159 }
160
161 void
162 Tizen_SetWindowFullscreen(_THIS, SDL_Window *window,
163                           SDL_VideoDisplay *_display, SDL_bool fullscreen)
164 {
165     /*DO NOTHING*/
166 }
167
168 void
169 Tizen_pre_rotation_set(SDL_WindowData *_this)
170 {
171     tizen_wl_egl_window_rotation rot;
172     if (!_this->egl_window) return;
173
174     switch (_this->rotation) {
175          case 90:
176             rot = TIZEN_ROTATION_270;
177             break;
178          case 180:
179             rot = TIZEN_ROTATION_180;
180             break;
181          case 270:
182             rot = TIZEN_ROTATION_90;
183             break;
184          case 0:
185             rot = TIZEN_ROTATION_0;
186             break;
187          default:
188             rot = TIZEN_ROTATION_0;
189             break;
190       }
191
192       _this->tizen_pre_rotation_data->wl_egl_window_set_rotation(_this->egl_window, rot);
193 }
194
195 void
196 _tizen_window_orientaiton_hint_callback(void *userdata, const char *name, const char *oldValue, const char *newValue)
197 {
198     char *p_str = NULL;
199     char orientation_type[4][20] = {"Portrait","LandscapeLeft","PortraitUpsideDown","LandscapeRight"};
200     int checked[4] = {0,};
201     int i;
202     unsigned int j = 0;
203     SDL_WindowData *wind = (SDL_WindowData*)userdata;
204     Ecore_Wl_Window *window = wind->window;
205
206     if (wind->rotation_supported == 0) {
207         return;
208     }
209
210     SDL_assert(SDL_strncmp(name, SDL_HINT_ORIENTATIONS, SDL_strlen(SDL_HINT_ORIENTATIONS)) == 0);
211
212     if ((oldValue == NULL) && (newValue == NULL)) {
213         return;
214     }
215
216     for (i=0;i<4;i++) {
217         p_str = SDL_strstr(newValue, orientation_type[i]);
218         if (p_str) {
219             if (p_str == newValue) {
220                 int rot = 0;
221                 if (i == 0) rot = 0;
222                 else if (i == 1) rot = 90;
223                 else if (i == 2) rot = 180;
224                 else if (i == 3) rot = 270;
225                 wind->rotation = rot;
226             }
227
228             if (i == 0) {
229                 checked[j] = 0;
230             }
231             else if (i == 1) {
232                 checked[j] = 90;
233             }
234             else if (i == 2) {
235                 checked[j] = 180;
236             }
237             else if (i == 3) {
238                 checked[j] = 270;
239             }
240             j++;
241         }
242     }
243
244     if (j > 0) {
245         if (j == 1) {
246             ecore_wl_window_rotation_preferred_rotation_set(window,wind->rotation);
247             if (wind->support_pre_rotation)
248                 Tizen_pre_rotation_set(wind);
249         }else {
250             ecore_wl_window_rotation_available_rotations_set(window, (const int*)checked, j);
251         }
252     }
253 }
254
255 void
256 _tizen_window_orientation_add_hint(void *data)
257 {
258     SDL_WindowData *wind = (SDL_WindowData*)data;
259     if (wind->rotation_supported == 0) {
260         return;
261     }
262
263     SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, _tizen_window_orientaiton_hint_callback, data);
264 }
265
266 int
267 Tizen_CreateWindow(_THIS, SDL_Window *window)
268 {
269     SDL_VideoData *data = _this->driverdata;
270     SDL_WindowData *wind;
271     Ecore_Wl_Global *global;
272     Eina_Inlist *globals;
273
274     wind = calloc(1, sizeof * wind);
275     if (!wind) {
276         return SDL_OutOfMemory();
277     }
278
279     window->driverdata = wind;
280     window->flags |= SDL_WINDOW_INPUT_FOCUS;    /* always has input focus */
281
282 #if SDL_VIDEO_OPENGL_EGL
283     if (window->flags & SDL_WINDOW_OPENGL) {
284         SDL_GL_LoadLibrary(NULL);
285     }
286 #endif
287
288 #if SDL_VIDEO_VULKAN
289     if (window->flags & SDL_WINDOW_VULKAN) {
290         if (!_this->vulkan_GetInstanceExtensions) {
291             SDL_SetError("No Vulkan support in video driver");
292         }
293
294         if (_this->vulkan_LoadLibrary(_this, NULL) < 0) {
295             SDL_SetError("Fail to load Vulkan Library");
296         }
297     }
298 #endif
299
300     if (window->x == SDL_WINDOWPOS_UNDEFINED) {
301         window->x = 0;
302     }
303     if (window->y == SDL_WINDOWPOS_UNDEFINED) {
304         window->y = 0;
305     }
306
307     if (!(globals = ecore_wl_globals_get()))
308       {
309          SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Failed to get wayland globals");
310          return -1;
311       }
312
313     wind->window = ecore_wl_window_new(NULL,
314                                        window->x, window->y, window->w, window->h,
315                                        ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
316     wind->surface = ecore_wl_window_surface_create(wind->window);
317     ecore_wl_window_type_set(wind->window, ECORE_WL_WINDOW_TYPE_UTILITY);
318
319     wind->rotation = 0;
320     wind->rotation_supported = 0;
321     wind->received_rotation = 0;
322
323 #if SDL_VIDEO_OPENGL_EGL
324     if (window->flags & SDL_WINDOW_OPENGL) {
325         wind->egl_window = wl_egl_window_create(ecore_wl_window_surface_get(wind->window), window->w, window->h);
326
327         /* Create the GLES window surface */
328         wind->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) wind->egl_window);
329         if (wind->egl_surface == EGL_NO_SURFACE) {
330             SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "failed to create a window surface");
331             return -1;
332         }
333
334         if (!Tizen_GLES_GetAlphaSize(_this)) {
335            ecore_wl_window_opaque_region_set(wind->window, window->x, window->y, window->w, window->h);
336         }
337         else {
338             wl_surface_set_opaque_region(ecore_wl_window_surface_get(wind->window), NULL);
339         }
340
341         //Support PreRotation
342         wind->support_pre_rotation = 0;
343         if (_tizen_rotation_type_get() && _tizen_PreRotatotion_LoadLibrary(wind, "libwayland-egl.so")) {
344             if (wind->tizen_pre_rotation_data->wl_egl_window_get_capabilities(wind->egl_window) == TIZEN_WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) {
345                 wind->support_pre_rotation = 1;
346             }
347         }
348     }
349 #endif
350
351     wind->id = ecore_wl_window_id_get(wind->window);
352     eina_hash_add(data->windows, &wind->id, window);
353
354     Tizen_InitKeyboard(_this);
355     SDL_SetMouseFocus(window);
356
357     if (window->flags & 0x00008000) {
358         ecore_wl_window_input_region_set(wind->window, -1, -1, 1, 1);
359         ecore_wl_window_focus_skip_set(wind->window, EINA_TRUE);
360     }
361
362     EINA_INLIST_FOREACH(globals, global) {
363          if (!strcmp(global->interface, "tizen_policy_ext")) {
364               wind->rotation_supported = 1;
365               break;
366            }
367       }
368     // Add orientaiton hint cb
369     _tizen_window_orientation_add_hint((void*)wind);
370
371
372     return 0;
373 }
374
375 void
376 Tizen_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
377 {
378 //Add setting window bordered.
379 }
380
381 void
382 _tizen_window_resize(SDL_Window *window)
383 {
384     SDL_WindowData *wind = window->driverdata;
385     if (!wind->egl_window) {
386         return;
387     }
388
389     if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
390         ecore_wl_window_update_size(wind->window, window->h, window->w);
391     else
392         ecore_wl_window_update_size(wind->window, window->w, window->h);
393
394     // TODO : consider to rotation status.
395 #if SDL_VIDEO_OPENGL_EGL
396     if (window->flags & SDL_WINDOW_OPENGL) {
397       if(wind->support_pre_rotation && (wind->rotation==90 || wind->rotation==270))
398           wl_egl_window_resize(wind->egl_window, window->h, window->w, 0, 0);
399       else
400           wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
401     }
402 #endif
403 }
404
405 void
406 _tizen_setwindowsize(SDL_Window *window)
407 {
408     SDL_WindowData *wind = window->driverdata;
409     if (!wind->window) {
410         return;
411     }
412 }
413
414 void
415 Tizen_SetWindowSize(_THIS, SDL_Window *window)
416 {
417     _tizen_window_resize(window);
418 }
419
420 void
421 Tizen_GetWindowSize(_THIS, SDL_Window *window, int *w, int *h)
422 {
423     SDL_WindowData *wind = window->driverdata;
424     if (!wind->window) {
425         return;
426     }
427
428     if (w) *w = window->w;
429     if (h) *h = window->h;
430 }
431
432 void
433 Tizen_SetWindowPosition(_THIS, SDL_Window * window)
434 {
435     SDL_WindowData *wind = window->driverdata;
436     if (!wind->window) {
437         return;
438     }
439
440     // TODO : consider to rotation status.
441    ecore_wl_window_position_set(wind->window, window->x, window->y);
442 }
443
444 void
445 Tizen_DestroyWindow(_THIS, SDL_Window *window)
446 {
447     SDL_VideoData *data = _this->driverdata;
448     SDL_WindowData *wind = window->driverdata;
449
450     if (data) {
451         eina_hash_del(data->windows, &wind->id, window);
452 #if SDL_VIDEO_OPENGL_EGL
453     if (window->flags & SDL_WINDOW_OPENGL) {
454         SDL_EGL_DestroySurface(_this, wind->egl_surface);
455         wl_egl_window_destroy(wind->egl_window);
456     }
457 #endif
458         ecore_wl_window_free(wind->window);
459         SDL_free(wind);
460     }
461
462     window->driverdata = NULL;
463 }
464
465 SDL_Window*
466 Tizen_FindWindow(_THIS, Ecore_Wl_Window *ewin)
467 {
468     SDL_VideoData *data = _this->driverdata;
469     int id;
470
471     id = ecore_wl_window_id_get(ewin);
472     return (SDL_Window*)eina_hash_find(data->windows, &id);
473 }
474
475 Eina_Bool
476 _tizen_cb_event_window_visibility_change(void *data, int type, void *event)
477 {
478     _THIS = data;
479     Ecore_Wl_Event_Window_Visibility_Change *ev;
480     Ecore_Wl_Window *ew;
481     SDL_Window *window;
482
483     ev = event;
484     ew = ecore_wl_window_find(ev->win);
485     window = Tizen_FindWindow(_this, ew);
486
487     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
488     SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
489     return ECORE_CALLBACK_PASS_ON;
490 }
491
492 Eina_Bool
493 _tizen_cb_window_configure(void *data, int type EINA_UNUSED, void *event)
494 {
495    _THIS = data;
496    Ecore_Wl_Window *ew;
497    SDL_Window *window;
498    SDL_WindowData *wind;
499    Ecore_Wl_Event_Window_Configure *ev;
500    ev = event;
501    ew = ecore_wl_window_find(ev->win);
502    window = Tizen_FindWindow(_this, ew);
503    wind = window->driverdata;
504
505    if (wind->rotation_supported == 0){
506       return ECORE_CALLBACK_PASS_ON;
507    }
508 /*
509    int nx = 0, ny = 0, nw = 0, nh = 0;
510   SDL_Log( "configure notify window: %p, ecore_wl_window: %p\n", window, ew);
511
512    ecore_wl_window_geometry_get(ew, &nx, &ny, &nw, &nh);
513    if (nw < 1) nw = 1;
514    if (nh < 1) nh = 1;
515    
516    SDL_Log("[SDL_Size] * _tizen_cb_window_configure :: w->w:%d, w->h:%d, nw:%d, nh:%d", window->w, window->h, nw, nh);
517    if ((window->x != nx) || (window->y != ny))
518      ecore_wl_window_position_set(ew, nx, ny);
519
520    if ((window->w != nw) || (window->h != nh)) {
521      _tizen_setwindowsize(window);
522    }
523    */
524    return ECORE_CALLBACK_PASS_ON;
525 }
526
527
528 void
529 _tizen_send_rotation_event(SDL_Window *window, unsigned int angle)
530 {
531     SDL_Event event;
532     SDL_WindowData *wind;
533     wind = window->driverdata;
534
535     SDL_memset(&event, 0, sizeof(event));
536     event.type = SDL_ROTATEEVENT;
537     event.user.code = 0;
538     if (wind->support_pre_rotation)
539         event.user.data1 = (void*)0;
540     else
541         event.user.data1 = (void*)angle;
542     event.user.data2 = (void*)-1;
543
544     SDL_PushEvent(&event);
545     return;
546 }
547
548 void
549 _tizen_set_window_size(SDL_Window * window, int w, int h)
550 {
551     if(!window)
552     {
553         SDL_SetError("Invalid window");
554         return;
555     }
556
557     SDL_VideoDevice *_this = SDL_GetVideoDevice();
558     if (!_this) {
559         SDL_SetError("Video subsystem has not been initialized");
560         return;
561     }
562
563     if (window->magic != &_this->window_magic) {
564         return;
565     }
566
567     if (w <= 0) {
568         SDL_InvalidParamError("w");
569         return;
570     }
571     if (h <= 0) {
572         SDL_InvalidParamError("h");
573         return;
574     }
575
576     /* Make sure we don't exceed any window size limits */
577     if (window->min_w && w < window->min_w)
578     {
579         w = window->min_w;
580     }
581     if (window->max_w && w > window->max_w)
582     {
583         w = window->max_w;
584     }
585     if (window->min_h && h < window->min_h)
586     {
587         h = window->min_h;
588     }
589     if (window->max_h && h > window->max_h)
590     {
591         h = window->max_h;
592     }
593
594     window->windowed.w = w;
595     window->windowed.h = h;
596
597     window->w = w;
598     window->h = h;
599 }
600
601 Eina_Bool
602 _tizen_cb_event_window_rotate(void *data, int type EINA_UNUSED, void *event)
603 {
604     _THIS = data;
605     Ecore_Wl_Event_Window_Rotate *ev;
606     Ecore_Wl_Window *ew;
607     SDL_Window *window;
608     SDL_WindowData *wind;
609
610     ev = event;
611     if (!ev) {
612         return ECORE_CALLBACK_PASS_ON;
613     }
614
615     ew = ecore_wl_window_find(ev->win);
616     window = Tizen_FindWindow(_this, ew);
617     wind = window->driverdata;
618
619     if (wind->rotation != ev->angle) {
620         /* set ecore_wayland window rotation */
621         wind->rotation = ev->angle;
622         ecore_wl_window_rotation_set(ew, ev->angle);
623         if(wind->support_pre_rotation) {
624             int window_w, window_h;
625             if(wind->rotation==90 || wind->rotation==270)
626                 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_h, &window_w);
627             else
628                 ecore_wl_window_geometry_get(wind->window, 0, 0, &window_w, &window_h);
629
630             _tizen_set_window_size(window, window_w, window_h);
631             Tizen_pre_rotation_set(wind);
632         }
633         _tizen_send_rotation_event(window, ev->angle);
634         SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
635         wind->received_rotation = 1;
636     }
637
638     return ECORE_CALLBACK_PASS_ON;
639 }
640
641 int
642 Tizen_InitWindow(_THIS)
643 {
644     SDL_VideoData *data = _this->driverdata;
645
646     data->windows = eina_hash_int32_new(NULL);
647
648     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
649                         _tizen_cb_event_window_visibility_change,_this);
650     ecore_event_handler_add(ECORE_EVENT_KEY_UP,
651                         _tizen_cb_event_keyup_change,_this);
652     ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
653                         _tizen_cb_event_keydown_change,_this);
654     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
655                         _tizen_cb_event_mousedown_change,_this);
656     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
657                         _tizen_cb_event_mouseup_change,_this);
658     ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
659                         _tizen_cb_event_mousemove_change,_this);
660     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_ROTATE,
661                         _tizen_cb_event_window_rotate,_this);
662     ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
663                         _tizen_cb_window_configure,_this);
664     ecore_event_handler_add(ECORE_EVENT_JOYSTICK,
665                         _tizen_cb_event_joystick_change,_this);
666     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
667                         _tizen_cb_event_focus_in,_this);
668     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
669                         _tizen_cb_event_focus_out,_this);
670     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
671                         _tizen_cb_event_mouse_in,_this);
672     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
673                         _tizen_cb_event_mouse_out,_this);
674
675     data->current_thread = SDL_GetThreadID(0);
676
677     return 0;
678 }
679
680 void
681 Tizen_DeinitWindow(_THIS)
682 {
683     SDL_VideoData *data = _this->driverdata;
684
685     eina_hash_free(data->windows);
686 }
687 #endif /* SDL_VIDEO_DRIVER_TIZEN */
688
689 /* vi: set ts=4 sw=4 expandtab: */