1 /*         ______   ___    ___
2  *        /\  _  \ /\_ \  /\_ \
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *
11  *      SDL display implementation.
12  *
13  *      See LICENSE.txt for copyright information.
14  */
15 #include "allegro5/allegro.h"
16 #include "allegro5/allegro_opengl.h"
17 #include "allegro5/system.h"
18 #include "allegro5/internal/aintern.h"
19 #include "allegro5/internal/aintern_bitmap.h"
20 #include "allegro5/internal/aintern_opengl.h"
21 #include "allegro5/internal/aintern_vector.h"
22 #include "allegro5/internal/aintern_system.h"
23 #include "allegro5/internal/aintern_pixels.h"
24 #include "allegro5/internal/aintern_shader.h"
25 #include "allegro5/platform/allegro_internal_sdl.h"
26 
27 ALLEGRO_DEBUG_CHANNEL("display")
28 
29 int _al_win_determine_adapter(void);
30 
31 static ALLEGRO_DISPLAY_INTERFACE *vt;
32 
_al_sdl_get_display_pixel_ratio(ALLEGRO_DISPLAY * display)33 float _al_sdl_get_display_pixel_ratio(ALLEGRO_DISPLAY *display)
34 {
35    ALLEGRO_DISPLAY_SDL *sdl = (void *)display;
36    int window_width, drawable_width, h;
37    SDL_GetWindowSize(sdl->window, &window_width, &h);
38    SDL_GL_GetDrawableSize(sdl->window, &drawable_width, &h);
39    return drawable_width / (float)window_width;
40 }
41 
_al_sdl_find_display(uint32_t window_id)42 ALLEGRO_DISPLAY *_al_sdl_find_display(uint32_t window_id) {
43    unsigned int i;
44    ALLEGRO_SYSTEM *s = al_get_system_driver();
45    for (i = 0; i < _al_vector_size(&s->displays); i++) {
46       void **v = (void **)_al_vector_ref(&s->displays, i);
47       ALLEGRO_DISPLAY_SDL *d = *v;
48       if (SDL_GetWindowID(d->window) == window_id) {
49          return &d->display;
50          break;
51       }
52    }
53    return NULL;
54 }
55 
_al_sdl_display_event(SDL_Event * e)56 void _al_sdl_display_event(SDL_Event *e)
57 {
58    ALLEGRO_EVENT event;
59    event.display.timestamp = al_get_time();
60 
61    ALLEGRO_DISPLAY *d = NULL;
62 
63    if (e->type == SDL_WINDOWEVENT) {
64       d = _al_sdl_find_display(e->window.windowID);
65       if (e->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
66          event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN;
67       }
68       if (e->window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
69          event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT;
70       }
71       if (e->window.event == SDL_WINDOWEVENT_CLOSE) {
72          event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE;
73       }
74       if (e->window.event == SDL_WINDOWEVENT_RESIZED) {
75          float ratio = _al_sdl_get_display_pixel_ratio(d);
76          event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE;
77          event.display.width = e->window.data1 * ratio;
78          event.display.height = e->window.data2 * ratio;
79       }
80    }
81    if (e->type == SDL_QUIT) {
82       event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE;
83       /* Use the first display as event source if we have any displays. */
84       ALLEGRO_SYSTEM *s = al_get_system_driver();
85       if (_al_vector_size(&s->displays) > 0) {
86          void **v = (void **)_al_vector_ref(&s->displays, 0);
87          d = *v;
88       }
89    }
90 
91    if (!d)
92       return;
93    ALLEGRO_EVENT_SOURCE *es = &d->es;
94    _al_event_source_lock(es);
95    _al_event_source_emit_event(es, &event);
96    _al_event_source_unlock(es);
97 }
98 
GLoption(int allegro,int sdl)99 static void GLoption(int allegro, int sdl)
100 {
101    int i;
102    int x = al_get_new_display_option(allegro, &i);
103    if (i == ALLEGRO_DONTCARE)
104       return;
105    SDL_GL_SetAttribute(sdl, x);
106 }
107 
sdl_create_display_locked(int w,int h)108 static ALLEGRO_DISPLAY *sdl_create_display_locked(int w, int h)
109 {
110    ALLEGRO_DISPLAY_SDL *sdl = al_calloc(1, sizeof *sdl);
111    ALLEGRO_DISPLAY *d = (void *)sdl;
112    d->w = w;
113    d->h = h;
114    d->flags = al_get_new_display_flags();
115    d->flags |= ALLEGRO_OPENGL;
116 #ifdef ALLEGRO_CFG_OPENGLES2
117    d->flags |= ALLEGRO_PROGRAMMABLE_PIPELINE;
118 #endif
119 #ifdef ALLEGRO_CFG_OPENGLES
120    d->flags |= ALLEGRO_OPENGL_ES_PROFILE;
121 #endif
122    int flags = SDL_WINDOW_OPENGL;
123    if (d->flags & ALLEGRO_FULLSCREEN)
124       flags |= SDL_WINDOW_FULLSCREEN;
125    if (d->flags & ALLEGRO_FULLSCREEN_WINDOW)
126       flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
127    if (d->flags & ALLEGRO_FRAMELESS)
128       flags |= SDL_WINDOW_BORDERLESS;
129    if (d->flags & ALLEGRO_RESIZABLE)
130       flags |= SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
131 
132    if (d->flags & ALLEGRO_OPENGL_ES_PROFILE) {
133       SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
134 #ifdef ALLEGRO_CFG_OPENGLES1
135       SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
136 #else
137       SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
138 #endif
139       SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
140    }
141 
142    GLoption(ALLEGRO_COLOR_SIZE, SDL_GL_BUFFER_SIZE);
143    GLoption(ALLEGRO_RED_SIZE, SDL_GL_RED_SIZE);
144    GLoption(ALLEGRO_GREEN_SIZE, SDL_GL_GREEN_SIZE);
145    GLoption(ALLEGRO_BLUE_SIZE, SDL_GL_BLUE_SIZE);
146    GLoption(ALLEGRO_ALPHA_SIZE, SDL_GL_ALPHA_SIZE);
147    GLoption(ALLEGRO_ACC_RED_SIZE, SDL_GL_ACCUM_RED_SIZE);
148    GLoption(ALLEGRO_ACC_GREEN_SIZE, SDL_GL_ACCUM_GREEN_SIZE);
149    GLoption(ALLEGRO_ACC_BLUE_SIZE, SDL_GL_ACCUM_BLUE_SIZE);
150    GLoption(ALLEGRO_ACC_ALPHA_SIZE, SDL_GL_ACCUM_ALPHA_SIZE);
151    GLoption(ALLEGRO_STEREO, SDL_GL_STEREO);
152    GLoption(ALLEGRO_DEPTH_SIZE, SDL_GL_DEPTH_SIZE);
153    GLoption(ALLEGRO_STENCIL_SIZE, SDL_GL_STENCIL_SIZE);
154    GLoption(ALLEGRO_SAMPLE_BUFFERS, SDL_GL_MULTISAMPLEBUFFERS);
155    GLoption(ALLEGRO_SAMPLES, SDL_GL_MULTISAMPLESAMPLES);
156    GLoption(ALLEGRO_OPENGL_MAJOR_VERSION, SDL_GL_CONTEXT_MAJOR_VERSION);
157    GLoption(ALLEGRO_OPENGL_MINOR_VERSION, SDL_GL_CONTEXT_MINOR_VERSION);
158 
159    SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
160 
161    sdl->window = SDL_CreateWindow(al_get_new_window_title(), sdl->x, sdl->y,
162       d->w, d->h, flags);
163    if (!sdl->window) {
164       ALLEGRO_ERROR("SDL_CreateWindow failed: %s", SDL_GetError());
165       return NULL;
166    }
167 
168    sdl->context = SDL_GL_CreateContext(sdl->window);
169 
170    SDL_GL_GetDrawableSize(sdl->window, &d->w, &d->h);
171 
172    // there's no way to query pixel ratio before creating the window, so we
173    // have to compensate afterwards
174    if (d->flags & ALLEGRO_RESIZABLE &&
175         !(d->flags & ALLEGRO_FULLSCREEN || d->flags & ALLEGRO_FULLSCREEN_WINDOW)) {
176       int window_width, window_height;
177       SDL_GetWindowSize(sdl->window, &window_width, &window_height);
178       float ratio = _al_sdl_get_display_pixel_ratio(d);
179 
180       ALLEGRO_DEBUG("resizing the display to %dx%d to match the scaling factor %f\n", (int)(window_width / ratio), (int)(window_height / ratio), ratio);
181 
182       SDL_SetWindowSize(sdl->window, window_width / ratio, window_height / ratio);
183 
184       SDL_GL_GetDrawableSize(sdl->window, &d->w, &d->h);
185    }
186 
187    ALLEGRO_DISPLAY **add;
188    ALLEGRO_SYSTEM *system = al_get_system_driver();
189    add = _al_vector_alloc_back(&system->displays);
190    *add = d;
191 
192    _al_event_source_init(&d->es);
193    d->vt = vt;
194 
195    d->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = true;
196 
197    d->ogl_extras = al_calloc(1, sizeof *d->ogl_extras);
198    _al_ogl_manage_extensions(d);
199    _al_ogl_set_extensions(d->ogl_extras->extension_api);
200 
201    _al_ogl_setup_gl(d);
202 
203    /* Fill in opengl version */
204    const int v = d->ogl_extras->ogl_info.version;
205    d->extra_settings.settings[ALLEGRO_OPENGL_MAJOR_VERSION] = (v >> 24) & 0xFF;
206    d->extra_settings.settings[ALLEGRO_OPENGL_MINOR_VERSION] = (v >> 16) & 0xFF;
207 
208    return d;
209 }
210 
sdl_create_display(int w,int h)211 static ALLEGRO_DISPLAY *sdl_create_display(int w, int h)
212 {
213    ALLEGRO_SYSTEM_SDL *s = (void *)al_get_system_driver();
214    al_lock_mutex(s->mutex);
215    ALLEGRO_DISPLAY *d = sdl_create_display_locked(w, h);
216    al_unlock_mutex(s->mutex);
217    return d;
218 }
219 
convert_display_bitmaps_to_memory_bitmap(ALLEGRO_DISPLAY * d)220 static void convert_display_bitmaps_to_memory_bitmap(ALLEGRO_DISPLAY *d)
221 {
222    ALLEGRO_DEBUG("converting display bitmaps to memory bitmaps.\n");
223 
224    while (d->bitmaps._size > 0) {
225       ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps);
226       ALLEGRO_BITMAP *b = *bptr;
227       _al_convert_to_memory_bitmap(b);
228    }
229 }
230 
transfer_display_bitmaps_to_any_other_display(ALLEGRO_SYSTEM * s,ALLEGRO_DISPLAY * d)231 static void transfer_display_bitmaps_to_any_other_display(
232    ALLEGRO_SYSTEM *s, ALLEGRO_DISPLAY *d)
233 {
234    size_t i;
235    ALLEGRO_DISPLAY *living = NULL;
236    ASSERT(s->displays._size > 1);
237 
238    for (i = 0; i < s->displays._size; i++) {
239       ALLEGRO_DISPLAY **slot = _al_vector_ref(&s->displays, i);
240       living = *slot;
241       if (living != d)
242          break;
243    }
244 
245    ALLEGRO_DEBUG("transferring display bitmaps to other display.\n");
246 
247    for (i = 0; i < d->bitmaps._size; i++) {
248       ALLEGRO_BITMAP **add = _al_vector_alloc_back(&(living->bitmaps));
249       ALLEGRO_BITMAP **ref = _al_vector_ref(&d->bitmaps, i);
250       *add = *ref;
251       (*add)->_display = living;
252    }
253 }
254 
sdl_destroy_display_locked(ALLEGRO_DISPLAY * d)255 static void sdl_destroy_display_locked(ALLEGRO_DISPLAY *d)
256 {
257    ALLEGRO_DISPLAY_SDL *sdl = (void *)d;
258    ALLEGRO_SYSTEM *system = al_get_system_driver();
259    ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras;
260    bool is_last;
261 
262    ALLEGRO_DEBUG("destroying display.\n");
263 
264    /* If we're the last display, convert all bitmaps to display independent
265     * (memory) bitmaps. Otherwise, pass all bitmaps to any other living
266     * display. We assume all displays are compatible.)
267     */
268 
269    is_last = (system->displays._size == 1);
270    if (is_last)
271       convert_display_bitmaps_to_memory_bitmap(d);
272    else
273       transfer_display_bitmaps_to_any_other_display(system, d);
274 
275    _al_ogl_unmanage_extensions(d);
276    ALLEGRO_DEBUG("unmanaged extensions.\n");
277 
278    if (ogl->backbuffer) {
279       _al_ogl_destroy_backbuffer(ogl->backbuffer);
280       ogl->backbuffer = NULL;
281       ALLEGRO_DEBUG("destroy backbuffer.\n");
282    }
283 
284    _al_vector_free(&d->bitmaps);
285    _al_event_source_free(&d->es);
286 
287    al_free(d->ogl_extras);
288    al_free(d->vertex_cache);
289 
290    _al_event_source_free(&d->es);
291    _al_vector_find_and_delete(&system->displays, &d);
292 
293    SDL_GL_DeleteContext(sdl->context);
294    SDL_DestroyWindow(sdl->window);
295    al_free(sdl);
296 }
297 
sdl_destroy_display(ALLEGRO_DISPLAY * d)298 static void sdl_destroy_display(ALLEGRO_DISPLAY *d)
299 {
300    ALLEGRO_SYSTEM_SDL *s = (void *)al_get_system_driver();
301    al_lock_mutex(s->mutex);
302    sdl_destroy_display_locked(d);
303    al_unlock_mutex(s->mutex);
304 }
305 
sdl_set_current_display(ALLEGRO_DISPLAY * d)306 static bool sdl_set_current_display(ALLEGRO_DISPLAY *d)
307 {
308    ALLEGRO_DISPLAY_SDL *sdl = (void *)d;
309    SDL_GL_MakeCurrent(sdl->window, sdl->context);
310    return true;
311 }
312 
sdl_unset_current_display(ALLEGRO_DISPLAY * d)313 static void sdl_unset_current_display(ALLEGRO_DISPLAY *d)
314 {
315    (void)d;
316 }
317 
sdl_flip_display(ALLEGRO_DISPLAY * d)318 static void sdl_flip_display(ALLEGRO_DISPLAY *d)
319 {
320    ALLEGRO_DISPLAY_SDL *sdl = (void *)d;
321    SDL_GL_SwapWindow(sdl->window);
322 
323    // SDL loses texture contents, for example on resize.
324    al_backup_dirty_bitmaps(d);
325 }
326 
sdl_update_display_region(ALLEGRO_DISPLAY * d,int x,int y,int width,int height)327 static void sdl_update_display_region(ALLEGRO_DISPLAY *d, int x, int y,
328    	int width, int height)
329 {
330    ALLEGRO_DISPLAY_SDL *sdl = (void *)d;
331    (void)x;
332    (void)y;
333    (void)width;
334    (void)height;
335    SDL_GL_SwapWindow(sdl->window);
336 }
337 
sdl_is_compatible_bitmap(ALLEGRO_DISPLAY * display,ALLEGRO_BITMAP * bitmap)338 static bool sdl_is_compatible_bitmap(ALLEGRO_DISPLAY *display,
339       ALLEGRO_BITMAP *bitmap)
340 {
341    (void)display;
342    (void)bitmap;
343    return true;
344 }
345 
sdl_set_mouse_cursor(ALLEGRO_DISPLAY * display,ALLEGRO_MOUSE_CURSOR * cursor)346 static bool sdl_set_mouse_cursor(ALLEGRO_DISPLAY *display,
347       ALLEGRO_MOUSE_CURSOR *cursor)
348 {
349    (void)display;
350    (void)cursor;
351    return false;
352 }
353 
sdl_set_system_mouse_cursor(ALLEGRO_DISPLAY * display,ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id)354 static bool sdl_set_system_mouse_cursor(ALLEGRO_DISPLAY *display,
355       ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id)
356 {
357    (void)display;
358    (void)cursor_id;
359    return false;
360 }
361 
sdl_show_mouse_cursor(ALLEGRO_DISPLAY * display)362 static bool sdl_show_mouse_cursor(ALLEGRO_DISPLAY *display)
363 {
364    (void)display;
365    return SDL_ShowCursor(SDL_ENABLE) == SDL_ENABLE;
366 }
367 
sdl_hide_mouse_cursor(ALLEGRO_DISPLAY * display)368 static bool sdl_hide_mouse_cursor(ALLEGRO_DISPLAY *display)
369 {
370    (void)display;
371    return SDL_ShowCursor(SDL_DISABLE) == SDL_DISABLE;
372 }
373 
sdl_set_window_position(ALLEGRO_DISPLAY * display,int x,int y)374 static void sdl_set_window_position(ALLEGRO_DISPLAY *display, int x, int y)
375 {
376    ALLEGRO_DISPLAY_SDL *sdl = (void *)display;
377    SDL_SetWindowPosition(sdl->window, x, y);
378 }
379 
sdl_get_window_position(ALLEGRO_DISPLAY * display,int * x,int * y)380 static void sdl_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y)
381 {
382    ALLEGRO_DISPLAY_SDL *sdl = (void *)display;
383    SDL_GetWindowPosition(sdl->window, x, y);
384 }
385 
recreate_textures(ALLEGRO_DISPLAY * display)386 static void recreate_textures(ALLEGRO_DISPLAY *display)
387 {
388    unsigned int i;
389    for (i = 0; i < _al_vector_size(&display->bitmaps); i++) {
390       ALLEGRO_BITMAP **bptr = _al_vector_ref(&display->bitmaps, i);
391       ALLEGRO_BITMAP *bitmap = *bptr;
392       int bitmap_flags = al_get_bitmap_flags(bitmap);
393       if (bitmap->parent)
394          continue;
395       if (bitmap_flags & ALLEGRO_MEMORY_BITMAP)
396          continue;
397       if (bitmap_flags & ALLEGRO_NO_PRESERVE_TEXTURE)
398          continue;
399       _al_ogl_upload_bitmap_memory(bitmap, _al_get_bitmap_memory_format(
400          bitmap), bitmap->memory);
401    }
402 }
403 
sdl_acknowledge_resize(ALLEGRO_DISPLAY * display)404 static bool sdl_acknowledge_resize(ALLEGRO_DISPLAY *display)
405 {
406    ALLEGRO_DISPLAY_SDL *sdl = (void *)display;
407    SDL_GL_GetDrawableSize(sdl->window, &display->w, &display->h);
408 
409    _al_ogl_setup_gl(display);
410 
411    if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
412       display->default_shader = _al_create_default_shader(display->flags);
413       al_use_shader(display->default_shader);
414    }
415 
416    recreate_textures(display);
417 
418    _al_glsl_unuse_shaders();
419 
420    return true;
421 }
422 
sdl_set_window_title(ALLEGRO_DISPLAY * display,char const * title)423 static void sdl_set_window_title(ALLEGRO_DISPLAY *display, char const *title)
424 {
425    ALLEGRO_DISPLAY_SDL *sdl = (void *)display;
426    SDL_SetWindowTitle(sdl->window, title);
427 }
428 
sdl_resize_display(ALLEGRO_DISPLAY * display,int width,int height)429 static bool sdl_resize_display(ALLEGRO_DISPLAY *display, int width, int height)
430 {
431    ALLEGRO_DISPLAY_SDL *sdl = (void *)display;
432 
433    // Allegro uses pixels everywhere, while SDL uses screen space for window size
434    int window_width, drawable_width, h;
435    SDL_GetWindowSize(sdl->window, &window_width, &h);
436    SDL_GL_GetDrawableSize(sdl->window, &drawable_width, &h);
437    float ratio = drawable_width / (float)window_width;
438 
439    SDL_SetWindowSize(sdl->window, width / ratio, height / ratio);
440    sdl_acknowledge_resize(display);
441    return true;
442 }
443 
sdl_set_display_flag(ALLEGRO_DISPLAY * display,int flag,bool flag_onoff)444 static bool sdl_set_display_flag(ALLEGRO_DISPLAY *display, int flag,
445    bool flag_onoff)
446 {
447    ALLEGRO_DISPLAY_SDL *sdl = (void *)display;
448    switch (flag) {
449       case ALLEGRO_FRAMELESS:
450          /* The ALLEGRO_FRAMELESS flag is backwards. */
451          SDL_SetWindowBordered(sdl->window, !flag_onoff);
452          return true;
453       case ALLEGRO_FULLSCREEN_WINDOW:
454          SDL_SetWindowFullscreen(sdl->window, flag_onoff ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
455          return true;
456       case ALLEGRO_MAXIMIZED:
457           if (flag_onoff) {
458              SDL_MaximizeWindow(sdl->window);
459           } else {
460              SDL_RestoreWindow(sdl->window);
461           }
462          return true;
463    }
464    return false;
465 }
466 
sdl_set_icons(ALLEGRO_DISPLAY * display,int num_icons,ALLEGRO_BITMAP * bitmaps[])467 static void sdl_set_icons(ALLEGRO_DISPLAY *display, int num_icons, ALLEGRO_BITMAP *bitmaps[]) {
468    ALLEGRO_DISPLAY_SDL *sdl = (void *)display;
469    int w = al_get_bitmap_width(bitmaps[0]);
470    int h = al_get_bitmap_height(bitmaps[0]);
471    int data_size = w * h * 4;
472    (void)num_icons;
473 
474    unsigned char* data = al_malloc(data_size * sizeof(data[0]));
475 
476    Uint32 rmask, gmask, bmask, amask;
477 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
478    rmask = 0xff000000;
479    gmask = 0x00ff0000;
480    bmask = 0x0000ff00;
481    amask = 0x000000ff;
482 #else // little endian, like x86
483    rmask = 0x000000ff;
484    gmask = 0x0000ff00;
485    bmask = 0x00ff0000;
486    amask = 0xff000000;
487 #endif
488 
489    ALLEGRO_LOCKED_REGION *lock = al_lock_bitmap(bitmaps[0], ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_LOCK_READONLY);
490    if (lock) {
491       int i = 0, y = 0;
492       for (y = 0; y < h; y++) {
493          int x = 0;
494          for (x = 0; x < w; x++) {
495             ALLEGRO_COLOR c = al_get_pixel(bitmaps[0], x, y);
496             al_unmap_rgba(c, data+i, data+i+1, data+i+2, data+i+3);
497             i += 4;
498          }
499       }
500       al_unlock_bitmap(bitmaps[0]);
501 
502       SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(data, w, h, 4 * 8, w * 4, rmask, gmask, bmask, amask);
503       SDL_SetWindowIcon(sdl->window, icon);
504       SDL_FreeSurface(icon);
505    }
506 
507    al_free(data);
508 }
509 
_al_sdl_display_driver(void)510 ALLEGRO_DISPLAY_INTERFACE *_al_sdl_display_driver(void)
511 {
512    if (vt)
513       return vt;
514 
515    vt = al_calloc(1, sizeof *vt);
516    vt->id = AL_ID('S', 'D', 'L', '2');
517    vt->create_display = sdl_create_display;
518    vt->destroy_display = sdl_destroy_display;
519    vt->set_current_display = sdl_set_current_display;
520    vt->unset_current_display = sdl_unset_current_display;
521    //vt->clear = GL
522    //vt->draw_pixel = GL
523    vt->flip_display = sdl_flip_display;
524    vt->update_display_region = sdl_update_display_region;
525    vt->acknowledge_resize = sdl_acknowledge_resize;
526    vt->resize_display = sdl_resize_display;
527    /*vt->quick_size = sdl_quick_size;
528    vt->get_orientation = sdl_get_orientation;*/
529    vt->create_bitmap = _al_ogl_create_bitmap;
530    vt->set_target_bitmap = _al_ogl_set_target_bitmap;
531    vt->get_backbuffer = _al_ogl_get_backbuffer;
532    vt->is_compatible_bitmap = sdl_is_compatible_bitmap;
533    /*vt->switch_out = sdl_switch_out;
534    vt->switch_in = sdl_switch_in;
535    vt->draw_memory_bitmap_region = sdl_draw_memory_bitmap_region;
536    vt->wait_for_vsync = sdl_wait_for_vsync;*/
537    vt->set_mouse_cursor = sdl_set_mouse_cursor;
538    vt->set_system_mouse_cursor = sdl_set_system_mouse_cursor;
539    vt->show_mouse_cursor = sdl_show_mouse_cursor;
540    vt->hide_mouse_cursor = sdl_hide_mouse_cursor;
541    vt->set_icons = sdl_set_icons;
542    vt->set_window_position = sdl_set_window_position;
543    vt->get_window_position = sdl_get_window_position;
544    /*vt->set_window_constraints = sdl_set_window_constraints;
545    vt->get_window_constraints = sdl_get_window_constraints;*/
546    vt->set_display_flag = sdl_set_display_flag;
547    vt->set_window_title = sdl_set_window_title;
548    //vt->flush_vertex_cache = GL
549    //vt->prepare_vertex_cache = GL
550    //vt->update_transformation = GL
551    //vt->set_projection = GL
552    /*vt->shutdown = sdl_shutdown;
553    vt->acknowledge_drawing_halt = sdl_acknowledge_drawing_halt;
554    vt->acknowledge_drawing_resume = sdl_acknowledge_drawing_resume;
555    vt->set_display_option = sdl_set_display_option;*/
556    //vt->clear_depth_buffer = GL
557    vt->update_render_state = _al_ogl_update_render_state;
558 
559    _al_ogl_add_drawing_functions(vt);
560 
561    return vt;
562 }
563