Ejemplo n.º 1
0
void _al_iphone_update_visuals(void)
{
   ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref;
   ALLEGRO_SYSTEM_IPHONE *system = (void *)al_get_system_driver();
   
   ref = _al_get_new_display_settings();
   
   /* If we aren't called the first time, only updated scores. */
   if (system->visuals) {
      for (int i = 0; i < system->visuals_count; i++) {
         ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = system->visuals[i];
         eds->score = _al_score_display_settings(eds, ref);
      }
      return;
   }
   
   system->visuals = al_calloc(VISUALS_COUNT, sizeof(*system->visuals));
   system->visuals_count = VISUALS_COUNT;
   
   for (int i = 0; i < VISUALS_COUNT; i++) {
      ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = al_calloc(1, sizeof *eds);
      eds->settings[ALLEGRO_RENDER_METHOD] = 1;
      eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1;
      eds->settings[ALLEGRO_SWAP_METHOD] = 2;
      eds->settings[ALLEGRO_VSYNC] = 1;
      switch (i) {
         case 0:
            set_rgba8888(eds);
            break;
         case 1:
            set_rgb565(eds);
            break;
         case 2:
            set_rgba8888(eds);
            eds->settings[ALLEGRO_DEPTH_SIZE] = 16;
            break;
         case 3:
            set_rgb565(eds);
            eds->settings[ALLEGRO_DEPTH_SIZE] = 16;
            break;
         case 4:
            set_rgba8888(eds);
            eds->settings[ALLEGRO_DEPTH_SIZE] = 24;
            eds->settings[ALLEGRO_STENCIL_SIZE] = 8;
            break;
         case 5:
            set_rgb565(eds);
            eds->settings[ALLEGRO_DEPTH_SIZE] = 24;
            eds->settings[ALLEGRO_STENCIL_SIZE] = 8;
            break;
            
      }
      eds->score = _al_score_display_settings(eds, ref);
      eds->index = i;
      system->visuals[i] = eds;
   }   
}
Ejemplo n.º 2
0
/* Function: al_get_new_display_option
 */
int al_get_new_display_option(int option, int *importance)
{
   ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras;
   extras = _al_get_new_display_settings();
   if (extras->required & ((int64_t)1 << option)) {
      if (importance) *importance = ALLEGRO_REQUIRE;
      return extras->settings[option];
   }
   if (extras->suggested & ((int64_t)1 << option)) {
      if (importance) *importance = ALLEGRO_SUGGEST;
      return extras->settings[option];
   }
   if (importance) *importance = ALLEGRO_DONTCARE;
   return 0;
}
Ejemplo n.º 3
0
static int win_get_num_display_modes(void)
{
    int format = _al_deduce_color_format(_al_get_new_display_settings());
    int refresh_rate = al_get_new_display_refresh_rate();
    int flags = al_get_new_display_flags();

#if defined ALLEGRO_CFG_OPENGL
    if (flags & ALLEGRO_OPENGL) {
        return _al_wgl_get_num_display_modes(format, refresh_rate, flags);
    }
#endif
#if defined ALLEGRO_CFG_D3D
    return _al_d3d_get_num_display_modes(format, refresh_rate, flags);
#endif

    return 0;
}
Ejemplo n.º 4
0
static ALLEGRO_DISPLAY_MODE *win_get_display_mode(int index,
        ALLEGRO_DISPLAY_MODE *mode)
{
    int format = _al_deduce_color_format(_al_get_new_display_settings());
    int refresh_rate = al_get_new_display_refresh_rate();
    int flags = al_get_new_display_flags();

#if defined ALLEGRO_CFG_OPENGL
    if (flags & ALLEGRO_OPENGL) {
        return _al_wgl_get_display_mode(index, format, refresh_rate, flags, mode);
    }
#endif
#if defined ALLEGRO_CFG_D3D
    return _al_d3d_get_display_mode(index, format, refresh_rate, flags, mode);
#endif


    return NULL;
}
Ejemplo n.º 5
0
/* Function: al_set_new_display_option
 */
void al_set_new_display_option(int option, int value, int importance)
{
   ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras;
   extras = _al_get_new_display_settings();
   switch (importance) {
      case ALLEGRO_REQUIRE:
         extras->required |= (int64_t)1 << option;
         extras->suggested &= ~((int64_t)1 << option);
         break;
      case ALLEGRO_SUGGEST:
         extras->suggested |= (int64_t)1 << option;
         extras->required &= ~((int64_t)1 << option);
         break;
      case ALLEGRO_DONTCARE:
         extras->required &= ~((int64_t)1 << option);
         extras->suggested &= ~((int64_t)1 << option);
         break;
   }
   extras->settings[option] = value;
}
Ejemplo n.º 6
0
static bool create_display_internals(ALLEGRO_DISPLAY_WGL *wgl_disp)
{
   ALLEGRO_DISPLAY     *disp     = (void*)wgl_disp;
   ALLEGRO_DISPLAY_WIN *win_disp = (void*)wgl_disp;
   WGL_DISPLAY_PARAMETERS ndp;
   int window_x, window_y;

   /* The window is created in a separate thread so we need to pass this
    * TLS on
    */
   al_get_new_window_position(&window_x, &window_y);
   ndp.window_x = window_x;
   ndp.window_y = window_y;

   /* _beginthread closes the handle automatically. */
   ndp.display = wgl_disp;
   ndp.init_failed = true;
   ndp.AckEvent = CreateEvent(NULL, false, false, NULL);
   _beginthread(display_thread_proc, 0, &ndp);

   /* Wait some _finite_ time (10 secs or so) for display thread to init, and
    * give up if something horrible happened to it, unless we're in debug mode
    * and we may have intentionally stopped the execution to analyze the code.
    */
#ifdef DEBUGMODE
   WaitForSingleObject(ndp.AckEvent, INFINITE);
#else
   WaitForSingleObject(ndp.AckEvent, 10*1000);
#endif

   CloseHandle(ndp.AckEvent);

   if (ndp.init_failed) {
      ALLEGRO_ERROR("Failed to create display.\n");
      return false;
   }

   /* WGL display lists cannot be shared with the API currently in use. */
   disp->ogl_extras->is_shared = false;
   
   if (!select_pixel_format(wgl_disp, wgl_disp->dc)) {
      destroy_display_internals(wgl_disp);
      return false;
   }

   if (disp->flags & ALLEGRO_OPENGL_3_0) {
      bool fc = (disp->flags & ALLEGRO_OPENGL_FORWARD_COMPATIBLE) != 0;
      wgl_disp->glrc = init_ogl_context_ex(wgl_disp->dc, fc, 3, 0);
   }
   else {
      wgl_disp->glrc = wglCreateContext(wgl_disp->dc);
   }

   if (!wgl_disp->glrc) {
      ALLEGRO_ERROR("Unable to create a render context! %s\n",
                     get_error_desc(GetLastError()));
      destroy_display_internals(wgl_disp);
      return false;
   }

   /* make the context the current one */
   if (!wglMakeCurrent(wgl_disp->dc, wgl_disp->glrc)) {
      ALLEGRO_ERROR("Unable to make the context current! %s\n",
                     get_error_desc(GetLastError()));
      destroy_display_internals(wgl_disp);
      return false;
   }

   _al_ogl_manage_extensions(disp);
   _al_ogl_set_extensions(disp->ogl_extras->extension_api);

   if (disp->ogl_extras->ogl_info.version < _ALLEGRO_OPENGL_VERSION_1_2) {
      ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings();
      if (eds->required & (1<<ALLEGRO_COMPATIBLE_DISPLAY)) {
         ALLEGRO_WARN("Allegro requires at least OpenGL version 1.2 to work.\n");
         destroy_display_internals(wgl_disp);
         return false;
      }
      disp->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0;
   }

   disp->ogl_extras->backbuffer = _al_ogl_create_backbuffer(disp);
   if (!disp->ogl_extras->backbuffer) {
      ALLEGRO_ERROR("Failed to create a backbuffer.\n");
      destroy_display_internals(wgl_disp);
      return false;
   }

   /* Try to enable or disable vsync as requested */
   /* NOTE: my drivers claim I don't have WGL_EXT_swap_control
    * (according to al_have_opengl_extension), but wglSwapIntervalEXT
    * does get loaded, so just check for that.
    */
   if (wglSwapIntervalEXT) {
      if (disp->extra_settings.settings[ALLEGRO_VSYNC] == 1) {
         wglSwapIntervalEXT(1);
      }
      else if (disp->extra_settings.settings[ALLEGRO_VSYNC] == 2) {
         wglSwapIntervalEXT(0);
      }
   }
 
   win_disp->mouse_selected_hcursor = 0;
   win_disp->mouse_cursor_shown = false;
   win_disp->can_acknowledge = false;

   _al_win_grab_input(win_disp);

   if (disp->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY])
      setup_gl(disp);

   return true;
}
Ejemplo n.º 7
0
/* Function: al_create_display
 */
ALLEGRO_DISPLAY *al_create_display(int w, int h)
{
   ALLEGRO_SYSTEM *system;
   ALLEGRO_DISPLAY_INTERFACE *driver;
   ALLEGRO_DISPLAY *display;
   ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds;

   eds = _al_get_new_display_settings();
   /* We cannot depend on al_reset_new_display_options() having been called
    * anywhere because al_create_display() may be called from new threads.
    */
   if (!eds)
      al_reset_new_display_options();
   else
      _al_fill_display_settings(eds);

   system = al_get_system_driver();
   driver = system->vt->get_display_driver();
   display = driver->create_display(w, h);
   
   if (!display) {
      ALLEGRO_DEBUG("Failed to create display (NULL)\n");
      return NULL;
   }
   
   display->vertex_cache = 0;
   display->num_cache_vertices = 0;
   display->cache_enabled = false;
   display->vertex_cache_size = 0;
   display->cache_texture = 0;
   
   al_identity_transform(&display->cur_transform);
   _al_initialize_blender(&display->cur_blender);

   _al_vector_init(&display->bitmaps, sizeof(ALLEGRO_BITMAP*));

   al_set_current_display(display);

   /* Clear the screen */
#ifndef ALLEGRO_GP2XWIZ
   if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY])
      al_clear_to_color(al_map_rgb(0, 0, 0));
#else
   al_clear_to_color(al_map_rgb(0, 0, 0));
#endif

   /* on iphone, don't kill the initial splashscreen */
#ifndef ALLEGRO_IPHONE
   al_flip_display();
#endif

   /* Clear the backbuffer */
#ifndef ALLEGRO_GP2XWIZ
   if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY])
      al_clear_to_color(al_map_rgb(0, 0, 0));
#else
   al_clear_to_color(al_map_rgb(0, 0, 0));
#endif
   
#ifndef ALLEGRO_IPHONE
   al_flip_display();
#endif
   
   al_set_window_title(al_get_appname());

   return display;
}
Ejemplo n.º 8
0
static bool pi_create_display(ALLEGRO_DISPLAY *display)
{
    ALLEGRO_DISPLAY_RASPBERRYPI *d = (void *)display;
    ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings();

    egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (egl_display == EGL_NO_DISPLAY) {
        return false;
    }

    int major, minor;
    if (!eglInitialize(egl_display, &major, &minor)) {
        return false;
    }

    static EGLint attrib_list[] =
    {
        EGL_DEPTH_SIZE, 0,
        EGL_STENCIL_SIZE, 0,
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    attrib_list[1] = eds->settings[ALLEGRO_DEPTH_SIZE];
    attrib_list[3] = eds->settings[ALLEGRO_STENCIL_SIZE];

    if (eds->settings[ALLEGRO_RED_SIZE] || eds->settings[ALLEGRO_GREEN_SIZE] ||
            eds->settings[ALLEGRO_BLUE_SIZE] ||
            eds->settings[ALLEGRO_ALPHA_SIZE]) {
        attrib_list[5] = eds->settings[ALLEGRO_RED_SIZE];
        attrib_list[7] = eds->settings[ALLEGRO_GREEN_SIZE];
        attrib_list[9] = eds->settings[ALLEGRO_BLUE_SIZE];
        attrib_list[11] = eds->settings[ALLEGRO_ALPHA_SIZE];
    }
    else if (eds->settings[ALLEGRO_COLOR_SIZE] == 16) {
        attrib_list[5] = 5;
        attrib_list[7] = 6;
        attrib_list[9] = 5;
        attrib_list[11] = 0;
    }

    EGLConfig config;
    int num_configs;

    if (!eglChooseConfig(egl_display, attrib_list, &config, 1, &num_configs)) {
        return false;
    }

    eglBindAPI(EGL_OPENGL_ES_API);

    int es_ver = (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) ?
                 2 : 1;

    static EGLint ctxattr[3] = {
        EGL_CONTEXT_CLIENT_VERSION, 0xDEADBEEF,
        EGL_NONE
    };

    ctxattr[1] = es_ver;

    egl_context = eglCreateContext(egl_display, config, EGL_NO_CONTEXT, ctxattr);
    if (egl_context == EGL_NO_CONTEXT) {
        return false;
    }

    static EGL_DISPMANX_WINDOW_T nativewindow;
    DISPMANX_ELEMENT_HANDLE_T dispman_element;

    int dx, dy, screen_width, screen_height;
    _al_raspberrypi_get_screen_info(&dx, &dy, &screen_width, &screen_height);

    d->cursor_offset_x = dx;
    d->cursor_offset_y = dy;

    dst_rect.x = dx;
    dst_rect.y = dy;
    dst_rect.width = screen_width;
    dst_rect.height = screen_height;

    d->screen_width = screen_width;
    d->screen_height = screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = display->w << 16;
    src_rect.height = display->h << 16;

    dispman_display = vc_dispmanx_display_open(0 /* LCD */);
    dispman_update = vc_dispmanx_update_start(0);

    dispman_element = vc_dispmanx_element_add (
                          dispman_update,
                          dispman_display,
                          0/*layer*/,
                          &dst_rect,
                          0/*src*/,
                          &src_rect,
                          DISPMANX_PROTECTION_NONE,
                          0 /*alpha*/,
                          0/*clamp*/,
                          DISPMANX_NO_ROTATE/*transform*/
                      );

    nativewindow.element = dispman_element;
    nativewindow.width = display->w;
    nativewindow.height = display->h;
    vc_dispmanx_update_submit_sync(dispman_update);

    egl_window = eglCreateWindowSurface(
                     egl_display, config, &nativewindow, NULL);
    if (egl_window == EGL_NO_SURFACE) {
        return false;
    }

    if (!eglMakeCurrent(egl_display, egl_window, egl_window, egl_context)) {
        return false;
    }

    return true;
}
Ejemplo n.º 9
0
void _al_set_color_components(int format, ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds,
                              int importance)
{
   ALLEGRO_EXTRA_DISPLAY_SETTINGS old_eds;
   memcpy(&old_eds, _al_get_new_display_settings(), sizeof(old_eds));
   _al_set_new_display_settings(eds);

   al_set_new_display_option(ALLEGRO_RED_SIZE,    0, ALLEGRO_DONTCARE);
   al_set_new_display_option(ALLEGRO_RED_SHIFT,   0, ALLEGRO_DONTCARE);
   al_set_new_display_option(ALLEGRO_GREEN_SIZE,  0, ALLEGRO_DONTCARE);
   al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 0, ALLEGRO_DONTCARE);
   al_set_new_display_option(ALLEGRO_BLUE_SIZE,   0, ALLEGRO_DONTCARE);
   al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  0, ALLEGRO_DONTCARE);
   al_set_new_display_option(ALLEGRO_ALPHA_SIZE,  0, ALLEGRO_DONTCARE);
   al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, ALLEGRO_DONTCARE);
   al_set_new_display_option(ALLEGRO_COLOR_SIZE,  0, ALLEGRO_DONTCARE);

   switch (format) {
      case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE,   0, importance);
         break;
      case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE,   8, importance);
         break;
      case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE,   0, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE,   16, importance);
         break;
      case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE,   1, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE,   16, importance);
         break;
      case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE,   0, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE,   24, importance);
         break;
      case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA:
         /* With OpenGL drivers, we never "know" the actual pixel
          * format. We use glReadPixels when we lock the screen, so
          * we can always lock the screen in any format we want. There
          * is no "display format".
          * 
          * Therefore it makes no sense to fail display creation
          * if either an RGB or RGBX format was requested but the
          * other seems available only in WGL/GLX (those really report
          * the number of bits used for red/green/blue/alpha to us only.
          * They never report any "X bits".).
          */
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE,   0, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE,   32, ALLEGRO_SUGGEST);
         break;
      case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE,   8, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE,   32, importance);
         break;
   }

   switch (format) {
      case ALLEGRO_PIXEL_FORMAT_RGBA_8888:
      case ALLEGRO_PIXEL_FORMAT_ABGR_8888:
      case ALLEGRO_PIXEL_FORMAT_ARGB_8888:
      case ALLEGRO_PIXEL_FORMAT_RGB_888:
      case ALLEGRO_PIXEL_FORMAT_BGR_888:
      case ALLEGRO_PIXEL_FORMAT_RGBX_8888:
      case ALLEGRO_PIXEL_FORMAT_XRGB_8888:
      case ALLEGRO_PIXEL_FORMAT_XBGR_8888:
         al_set_new_display_option(ALLEGRO_RED_SIZE,   8, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SIZE, 8, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SIZE,  8, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_BGR_565:
      case ALLEGRO_PIXEL_FORMAT_RGB_565:
         al_set_new_display_option(ALLEGRO_RED_SIZE,   5, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SIZE, 6, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SIZE,  5, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_RGBA_5551:
      case ALLEGRO_PIXEL_FORMAT_ARGB_1555:
         al_set_new_display_option(ALLEGRO_RED_SIZE,   5, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SIZE, 5, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SIZE,  5, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_ARGB_4444:
      case ALLEGRO_PIXEL_FORMAT_RGBA_4444:
         al_set_new_display_option(ALLEGRO_RED_SIZE,   4, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SIZE, 4, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SIZE,  4, importance);
      break;
   }

   switch (format) {
      case ALLEGRO_PIXEL_FORMAT_RGBA_8888:
      case ALLEGRO_PIXEL_FORMAT_ABGR_8888:
      case ALLEGRO_PIXEL_FORMAT_ARGB_8888:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 8, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_RGB_888:
      case ALLEGRO_PIXEL_FORMAT_BGR_888:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE, 24, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_RGBX_8888:
      case ALLEGRO_PIXEL_FORMAT_XRGB_8888:
      case ALLEGRO_PIXEL_FORMAT_XBGR_8888:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE, 32, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_BGR_565:
      case ALLEGRO_PIXEL_FORMAT_RGB_565:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 0, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_RGBA_5551:
      case ALLEGRO_PIXEL_FORMAT_ARGB_1555:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 1, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_ARGB_4444:
      case ALLEGRO_PIXEL_FORMAT_RGBA_4444:
         al_set_new_display_option(ALLEGRO_ALPHA_SIZE, 4, importance);
         al_set_new_display_option(ALLEGRO_COLOR_SIZE, 16, importance);
      break;
   }

   switch (format) {
      case ALLEGRO_PIXEL_FORMAT_RGBA_8888:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  8, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 16, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   24, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_ABGR_8888:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 24, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  16, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   0, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_ARGB_8888:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 24, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  0, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   16, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_RGB_888:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  0, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   16, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_BGR_888:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  16, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   0, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_XRGB_8888:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  0, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   16, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_RGBX_8888:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  8, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 16, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   24, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_XBGR_8888:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  16, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 8, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   0, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_BGR_565:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  11, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 5, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   0, importance);
      break;
      case ALLEGRO_PIXEL_FORMAT_RGB_565:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  0, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 5, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   11, importance);      
      break;
      case ALLEGRO_PIXEL_FORMAT_RGBA_5551:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 0, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  1, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 6, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   11, importance);      
      break;
      case ALLEGRO_PIXEL_FORMAT_ARGB_1555:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 15, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  0, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 5, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   10, importance);      
      break;
      case ALLEGRO_PIXEL_FORMAT_ARGB_4444:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 12, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  8, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 4, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   0, importance);      
      case ALLEGRO_PIXEL_FORMAT_RGBA_4444:
         al_set_new_display_option(ALLEGRO_ALPHA_SHIFT, 12, importance);
         al_set_new_display_option(ALLEGRO_BLUE_SHIFT,  8, importance);
         al_set_new_display_option(ALLEGRO_GREEN_SHIFT, 4, importance);
         al_set_new_display_option(ALLEGRO_RED_SHIFT,   0, importance);      
      break;
   }

   memcpy(eds, _al_get_new_display_settings(), sizeof(*eds));
   _al_set_new_display_settings(&old_eds);
}
Ejemplo n.º 10
0
/* Function: al_reset_new_display_options
 */
void al_reset_new_display_options(void)
{
   ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras;
   extras = _al_get_new_display_settings();
   _al_fill_display_settings(extras);
}
Ejemplo n.º 11
0
/* Create a new X11 display, which maps directly to a GLX window. */
static ALLEGRO_DISPLAY *xdpy_create_display(int w, int h)
{
   ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
   int adapter = al_get_new_display_adapter();
   
   if (system->x11display == NULL) {
      ALLEGRO_WARN("Not connected to X server.\n");
      return NULL;
   }

   if (w <= 0 || h <= 0) {
      ALLEGRO_ERROR("Invalid window size %dx%d\n", w, h);
      return NULL;
   }

   _al_mutex_lock(&system->lock);

   ALLEGRO_DISPLAY_XGLX *d = al_calloc(1, sizeof *d);
   ALLEGRO_DISPLAY *display = (void*)d;
   ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl);
   display->ogl_extras = ogl;

   int major, minor;
   glXQueryVersion(system->x11display, &major, &minor);
   d->glx_version = major * 100 + minor * 10;
   ALLEGRO_INFO("GLX %.1f.\n", d->glx_version / 100.f);

   display->w = w;
   display->h = h;
   display->vt = _al_display_xglx_driver();
   display->refresh_rate = al_get_new_display_refresh_rate();
   display->flags = al_get_new_display_flags();

   // FIXME: default? Is this the right place to set this?
   display->flags |= ALLEGRO_OPENGL;

   // store our initial virtual adapter, used by fullscreen and positioning code
   d->adapter = adapter;
   ALLEGRO_DEBUG("selected adapter %i\n", adapter);
   if (d->adapter < 0) {
      d->adapter = _al_xglx_get_default_adapter(system);
   }

   _al_xglx_use_adapter(system, d->adapter);
   
   /* if we're in multi-head X mode, bail if we try to use more than one display
    * as there are bugs in X/glX that cause us to hang in X if we try to use more than one. */
   /* if we're in real xinerama mode, also bail, x makes mouse use evil */
   
   bool true_xinerama_active = false;
#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA
   bool xrandr_active = false;

#ifdef ALLEGRO_XWINDOWS_WITH_XRANDR
   xrandr_active = system->xrandr_available;
#endif

   true_xinerama_active = !xrandr_active && system->xinerama_available;
#endif
   
   if ((true_xinerama_active || ScreenCount(system->x11display) > 1) && system->adapter_use_count) {
      uint32_t i, adapter_use_count = 0;
      for (i = 0; i < 32; i++) {
         if (system->adapter_map[i])
            adapter_use_count++;
      }
      
      if (adapter_use_count > 1) {
         ALLEGRO_ERROR("Use of more than one adapter at once in multi-head X or X with true Xinerama active is not possible.\n");
         al_free(d);
         al_free(ogl);
         _al_mutex_unlock(&system->lock);
         return NULL;
      }
   }
   ALLEGRO_DEBUG("xdpy: selected adapter %i\n", d->adapter);
   
   // store or initial X Screen, used by window creation, fullscreen, and glx visual code
   d->xscreen = _al_xglx_get_xscreen(system, d->adapter);
   
   ALLEGRO_DEBUG("xdpy: selected xscreen %i\n", d->xscreen);
   
   d->is_mapped = false;
   _al_cond_init(&d->mapped);

   d->resize_count = 0;
   d->programmatic_resize = false;

   _al_xglx_config_select_visual(d);

   if (!d->xvinfo) {
      ALLEGRO_ERROR("FIXME: Need better visual selection.\n");
      ALLEGRO_ERROR("No matching visual found.\n");
      al_free(d);
      al_free(ogl);
      _al_mutex_unlock(&system->lock);
      return NULL;
   }

   ALLEGRO_INFO("Selected X11 visual %lu.\n", d->xvinfo->visualid);

   /* Add ourself to the list of displays. */
   ALLEGRO_DISPLAY_XGLX **add;
   add = _al_vector_alloc_back(&system->system.displays);
   *add = d;

   /* Each display is an event source. */
   _al_event_source_init(&display->es);

   /* Create a colormap. */
   Colormap cmap = XCreateColormap(system->x11display,
      RootWindow(system->x11display, d->xvinfo->screen),
      d->xvinfo->visual, AllocNone);

   /* Create an X11 window */
   XSetWindowAttributes swa;
   int mask = CWBorderPixel | CWColormap | CWEventMask;
   swa.colormap = cmap;
   swa.border_pixel = 0;
   swa.event_mask =
      KeyPressMask |
      KeyReleaseMask |
      StructureNotifyMask |
      EnterWindowMask |
      LeaveWindowMask |
      FocusChangeMask |
      ExposureMask |
      PropertyChangeMask |
      ButtonPressMask |
      ButtonReleaseMask |
      PointerMotionMask;

   /* For a non-compositing window manager, a black background can look
    * less broken if the application doesn't react to expose events fast
    * enough. However in some cases like resizing, the black background
    * causes horrible flicker.
    */
   if (!(display->flags & ALLEGRO_RESIZABLE)) {
      mask |= CWBackPixel;
      swa.background_pixel = BlackPixel(system->x11display, d->xvinfo->screen);
   }

   int x_off = INT_MAX, y_off = INT_MAX;
   if (display->flags & ALLEGRO_FULLSCREEN) {
      _al_xglx_get_display_offset(system, d->adapter, &x_off, &y_off);
   }
   else {
      /* we want new_display_adapter's offset to add to the new_window_position */
      int xscr_x = 0, xscr_y = 0;

      al_get_new_window_position(&x_off, &y_off);
      
      if (adapter >= 0) {
         /* non default adapter. I'm assuming this means the user wants the window to be placed on the adapter offset by new display pos */
         _al_xglx_get_display_offset(system, d->adapter, &xscr_x, &xscr_y);
         if (x_off != INT_MAX)
            x_off += xscr_x;
         
         if (y_off != INT_MAX)
            y_off += xscr_y;
      }
   }

   d->window = XCreateWindow(system->x11display,
      RootWindow(system->x11display, d->xvinfo->screen),
      x_off != INT_MAX ? x_off : 0,
      y_off != INT_MAX ? y_off : 0,
      w, h, 0, d->xvinfo->depth,
      InputOutput, d->xvinfo->visual, mask, &swa);
      
   // Try to set full screen mode if requested, fail if we can't
   if (display->flags & ALLEGRO_FULLSCREEN) {
      /* According to the spec, the window manager is supposed to disable
       * window decorations when _NET_WM_STATE_FULLSCREEN is in effect.
       * However, some WMs may not be fully compliant, e.g. Fluxbox.
       */
      
      xdpy_set_frame(display, false);

      _al_xglx_set_above(display, 1);
      
      if (!_al_xglx_fullscreen_set_mode(system, d, w, h, 0, display->refresh_rate)) {
         ALLEGRO_DEBUG("xdpy: failed to set fullscreen mode.\n");
         xdpy_destroy_display(display);
         _al_mutex_unlock(&system->lock);
         return NULL;
      }
      //XSync(system->x11display, False);
   }

   if (display->flags & ALLEGRO_FRAMELESS) {
      xdpy_set_frame(display, false);
   }

   ALLEGRO_DEBUG("X11 window created.\n");
   
   _al_xwin_set_size_hints(display, x_off, y_off);
   
   XLockDisplay(system->x11display);
   
   d->wm_delete_window_atom = XInternAtom(system->x11display,
      "WM_DELETE_WINDOW", False);
   XSetWMProtocols(system->x11display, d->window, &d->wm_delete_window_atom, 1);

   XMapWindow(system->x11display, d->window);
   ALLEGRO_DEBUG("X11 window mapped.\n");
   
   XUnlockDisplay(system->x11display);

   /* Send the pending request to the X server. */
   XSync(system->x11display, False);
   
   /* To avoid race conditions where some X11 functions fail before the window
    * is mapped, we wait here until it is mapped. Note that the thread is
    * locked, so the event could not possibly have been processed yet in the
    * events thread. So as long as no other map events occur, the condition
    * should only be signalled when our window gets mapped.
    */
   while (!d->is_mapped) {
      _al_cond_wait(&d->mapped, &system->lock);
   }

   /* We can do this at any time, but if we already have a mapped
    * window when switching to fullscreen it will use the same
    * monitor (with the MetaCity version I'm using here right now).
    */
   if ((display->flags & ALLEGRO_FULLSCREEN_WINDOW)) {
      ALLEGRO_INFO("Toggling fullscreen flag for %d x %d window.\n",
         display->w, display->h);
      _al_xwin_reset_size_hints(display);
      _al_xwin_set_fullscreen_window(display, 2);
      _al_xwin_set_size_hints(display, INT_MAX, INT_MAX);

      XWindowAttributes xwa;
      XGetWindowAttributes(system->x11display, d->window, &xwa);
      display->w = xwa.width;
      display->h = xwa.height;
      ALLEGRO_INFO("Using ALLEGRO_FULLSCREEN_WINDOW of %d x %d\n",
         display->w, display->h);
   }

   if (display->flags & ALLEGRO_FULLSCREEN) {
      /* kwin wants these here */
      /* metacity wants these here too */
      /* XXX compiz is quiky, can't seem to find a combination of hints that
       * make sure we are layerd over panels, and are positioned properly */

      //_al_xwin_set_fullscreen_window(display, 1);
      _al_xglx_set_above(display, 1);

      _al_xglx_fullscreen_to_display(system, d);

      /* Grab mouse if we only have one display, ungrab it if we have more than
       * one.
       */
      if (_al_vector_size(&system->system.displays) == 1) {
         al_grab_mouse(display);
      }
      else if (_al_vector_size(&system->system.displays) > 1) {
         al_ungrab_mouse();
      }
   }
   
   if (!_al_xglx_config_create_context(d)) {
      xdpy_destroy_display(display);
      _al_mutex_unlock(&system->lock);
      return NULL;
   }

   /* Make our GLX context current for reading and writing in the current
    * thread.
    */
   if (d->fbc) {
      if (!glXMakeContextCurrent(system->gfxdisplay, d->glxwindow,
            d->glxwindow, d->context)) {
         ALLEGRO_ERROR("glXMakeContextCurrent failed\n");
      }
   }
   else {
      if (!glXMakeCurrent(system->gfxdisplay, d->glxwindow, d->context)) {
         ALLEGRO_ERROR("glXMakeCurrent failed\n");
      }
   }

   _al_ogl_manage_extensions(display);
   _al_ogl_set_extensions(ogl->extension_api);

   /* Print out OpenGL version info */
   ALLEGRO_INFO("OpenGL Version: %s\n", (const char*)glGetString(GL_VERSION));
   ALLEGRO_INFO("Vendor: %s\n", (const char*)glGetString(GL_VENDOR));
   ALLEGRO_INFO("Renderer: %s\n", (const char*)glGetString(GL_RENDERER));

   if (display->ogl_extras->ogl_info.version < _ALLEGRO_OPENGL_VERSION_1_2) {
      ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings();
      if (eds->required & (1<<ALLEGRO_COMPATIBLE_DISPLAY)) {
         ALLEGRO_ERROR("Allegro requires at least OpenGL version 1.2 to work.\n");
         xdpy_destroy_display(display);
         _al_mutex_unlock(&system->lock);
         return NULL;
      }
      display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0;
   }
#if 0
   // Apparently, you can get a OpenGL 3.0 context without specifically creating
   // it with glXCreateContextAttribsARB, and not every OpenGL 3.0 is evil, but we
   // can't tell the difference at this stage.
   else if (display->ogl_extras->ogl_info.version > _ALLEGRO_OPENGL_VERSION_2_1) {
      /* We don't have OpenGL3 a driver. */
      display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0;
   }
#endif

   if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY])
      _al_ogl_setup_gl(display);

   /* vsync */

   /* Fill in the user setting. */
   display->extra_settings.settings[ALLEGRO_VSYNC] =
      _al_get_new_display_settings()->settings[ALLEGRO_VSYNC];

   /* We set the swap interval to 0 if vsync is forced off, and to 1
    * if it is forced on.
    * http://www.opengl.org/registry/specs/SGI/swap_control.txt
    * If the option is set to 0, we simply use the system default. The
    * above extension specifies vsync on as default though, so in the
    * end with GLX we can't force vsync on, just off.
    */
   ALLEGRO_DEBUG("requested vsync=%d.\n",
      display->extra_settings.settings[ALLEGRO_VSYNC]);
   if (display->extra_settings.settings[ALLEGRO_VSYNC]) {
      if (display->ogl_extras->extension_list->ALLEGRO_GLX_SGI_swap_control) {
         int x = 1;
         if (display->extra_settings.settings[ALLEGRO_VSYNC] == 2)
            x = 0;
         if (glXSwapIntervalSGI(x)) {
            ALLEGRO_WARN("glXSwapIntervalSGI(%d) failed.\n", x);
         }
      }
      else {
         ALLEGRO_WARN("no vsync, GLX_SGI_swap_control missing.\n");
         /* According to the specification that means it's on, but
          * the driver might have disabled it. So we do not know.
          */
         display->extra_settings.settings[ALLEGRO_VSYNC] = 0;
      }
   }

   d->invisible_cursor = None; /* Will be created on demand. */
   d->current_cursor = None; /* Initially, we use the root cursor. */
   d->cursor_hidden = false;

   d->icon = None;
   d->icon_mask = None;

   _al_mutex_unlock(&system->lock);

   return display;
}
Ejemplo n.º 12
0
static ALLEGRO_DISPLAY_XGLX *xdpy_create_display_locked(
   ALLEGRO_SYSTEM_XGLX *system, int flags, int w, int h, int adapter)
{
   ALLEGRO_DISPLAY_XGLX *d = al_calloc(1, sizeof *d);
   ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)d;
   ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl);
   display->ogl_extras = ogl;

   d->glx_version = query_glx_version(system);

   display->w = w;
   display->h = h;
   display->vt = _al_display_xglx_driver();
   display->refresh_rate = al_get_new_display_refresh_rate();
   display->flags = flags;
   // FIXME: default? Is this the right place to set this?
   display->flags |= ALLEGRO_OPENGL;

   /* Store our initial virtual adapter, used by fullscreen and positioning
    * code.
    */
   ALLEGRO_DEBUG("selected adapter %i\n", adapter);
   if (adapter < 0)
      d->adapter = _al_xglx_get_default_adapter(system);
   else
      d->adapter = adapter;

   ALLEGRO_DEBUG("xdpy: selected adapter %i\n", d->adapter);
   _al_xglx_use_adapter(system, d->adapter);
   if (!check_adapter_use_count(system)) {
      goto EarlyError;
   }

   /* Store our initial X Screen, used by window creation, fullscreen, and glx
    * visual code.
    */
   d->xscreen = _al_xglx_get_xscreen(system, d->adapter);
   ALLEGRO_DEBUG("xdpy: selected xscreen %i\n", d->xscreen);

   d->wm_delete_window_atom = None;

   d->is_mapped = false;
   _al_cond_init(&d->mapped);
   
   d->is_selectioned = false;
   _al_cond_init(&d->selectioned);


   d->resize_count = 0;
   d->programmatic_resize = false;

   _al_xglx_config_select_visual(d);

   if (!d->xvinfo) {
      ALLEGRO_ERROR("FIXME: Need better visual selection.\n");
      ALLEGRO_ERROR("No matching visual found.\n");
      goto EarlyError;
   }

   ALLEGRO_INFO("Selected X11 visual %lu.\n", d->xvinfo->visualid);

   /* Add ourself to the list of displays. */
   ALLEGRO_DISPLAY_XGLX **add;
   add = _al_vector_alloc_back(&system->system.displays);
   *add = d;

   /* Each display is an event source. */
   _al_event_source_init(&display->es);

   if (!xdpy_create_display_window(system, d, w, h, adapter)) {
      goto LateError;
   }

   /* Send any pending requests to the X server.
    * This is necessary to make the window ID immediately valid
    * for a GtkSocket.
    */
   XSync(system->x11display, False);

   if (display->flags & ALLEGRO_GTK_TOPLEVEL_INTERNAL) {
      ASSERT(gtk_override_vt);
      if (!gtk_override_vt->create_display_hook(display, w, h)) {
         goto LateError;
      }
   }
   else {
      default_overridable_vt.set_window_title(display, al_get_new_window_title());
      if (!default_overridable_vt.create_display_hook(display, w, h)) {
         goto LateError;
      }
   }

   /* overridable_vt should be set by the create_display_hook. */
   ASSERT(d->overridable_vt);

   /* Send any pending requests to the X server. */
   XSync(system->x11display, False);

   /* To avoid race conditions where some X11 functions fail before the window
    * is mapped, we wait here until it is mapped. Note that the thread is
    * locked, so the event could not possibly have been processed yet in the
    * events thread. So as long as no other map events occur, the condition
    * should only be signalled when our window gets mapped.
    */
   while (!d->is_mapped) {
      _al_cond_wait(&d->mapped, &system->lock);
   }
   /* In tiling WMs, we might get resize events pretty much immediately after
    * Window creation. This location seems to catch them reliably, tested with
    * dwm, awesome, xmonad and i3. */
   if ((display->flags & ALLEGRO_RESIZABLE) && d->resize_count > 0) {
      xdpy_acknowledge_resize(display);
   }

   /* We can do this at any time, but if we already have a mapped
    * window when switching to fullscreen it will use the same
    * monitor (with the MetaCity version I'm using here right now).
    */
   if ((display->flags & ALLEGRO_FULLSCREEN_WINDOW)) {
      ALLEGRO_INFO("Toggling fullscreen flag for %d x %d window.\n",
         display->w, display->h);
      _al_xwin_reset_size_hints(display);
      _al_xwin_set_fullscreen_window(display, 2);
      _al_xwin_set_size_hints(display, INT_MAX, INT_MAX);

      XWindowAttributes xwa;
      XGetWindowAttributes(system->x11display, d->window, &xwa);
      display->w = xwa.width;
      display->h = xwa.height;
      ALLEGRO_INFO("Using ALLEGRO_FULLSCREEN_WINDOW of %d x %d\n",
         display->w, display->h);
   }

   if (display->flags & ALLEGRO_FULLSCREEN) {
      /* kwin wants these here */
      /* metacity wants these here too */
      /* XXX compiz is quiky, can't seem to find a combination of hints that
       * make sure we are layerd over panels, and are positioned properly */

      //_al_xwin_set_fullscreen_window(display, 1);
      _al_xwin_set_above(display, 1);

      _al_xglx_fullscreen_to_display(system, d);

      /* Grab mouse if we only have one display, ungrab it if we have more than
       * one.
       */
      if (_al_vector_size(&system->system.displays) == 1) {
         al_grab_mouse(display);
      }
      else if (_al_vector_size(&system->system.displays) > 1) {
         al_ungrab_mouse();
      }
   }

   if (flags & ALLEGRO_MAXIMIZED) {
      _al_xwin_maximize(display, true);
   }

   if (!_al_xglx_config_create_context(d)) {
      goto LateError;
   }

   /* Make our GLX context current for reading and writing in the current
    * thread.
    */
   if (d->fbc) {
      if (!glXMakeContextCurrent(system->gfxdisplay, d->glxwindow,
            d->glxwindow, d->context)) {
         ALLEGRO_ERROR("glXMakeContextCurrent failed\n");
      }
   }
   else {
      if (!glXMakeCurrent(system->gfxdisplay, d->glxwindow, d->context)) {
         ALLEGRO_ERROR("glXMakeCurrent failed\n");
      }
   }

   _al_ogl_manage_extensions(display);
   _al_ogl_set_extensions(ogl->extension_api);

   /* Print out OpenGL version info */
   ALLEGRO_INFO("OpenGL Version: %s\n", (const char*)glGetString(GL_VERSION));
   ALLEGRO_INFO("Vendor: %s\n", (const char*)glGetString(GL_VENDOR));
   ALLEGRO_INFO("Renderer: %s\n", (const char*)glGetString(GL_RENDERER));

   if (display->ogl_extras->ogl_info.version < _ALLEGRO_OPENGL_VERSION_1_2) {
      ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings();
      if (eds->required & (1<<ALLEGRO_COMPATIBLE_DISPLAY)) {
         ALLEGRO_ERROR("Allegro requires at least OpenGL version 1.2 to work.\n");
         goto LateError;
      }
      display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 0;
   }

   if (display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY])
      _al_ogl_setup_gl(display);

   /* vsync */
   int vsync_setting = _al_get_new_display_settings()->settings[ALLEGRO_VSYNC];
   vsync_setting = xdpy_swap_control(display, vsync_setting);
   display->extra_settings.settings[ALLEGRO_VSYNC] = vsync_setting;

   d->invisible_cursor = None; /* Will be created on demand. */
   d->current_cursor = None; /* Initially, we use the root cursor. */
   d->cursor_hidden = false;

   d->icon = None;
   d->icon_mask = None;

   return d;

EarlyError:
   al_free(d);
   al_free(ogl);
   return NULL;

LateError:
   xdpy_destroy_display(display);
   return NULL;
}