Example #1
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;
}
Example #2
0
/* Create a new X11 display, which maps directly to a GLX window. */
static ALLEGRO_DISPLAY *gp2xwiz_create_display_fb(int w, int h)
{
   (void)w;
   (void)h;

   /* Only one display allowed at a time */
   if (set_gfx_mode)
      return NULL;

   lc_init_rest();

   ALLEGRO_DISPLAY_GP2XWIZ_FB *d = _AL_MALLOC(sizeof *d);
   ALLEGRO_DISPLAY *display = (void *)d;
   memset(d, 0, sizeof *d);

   ALLEGRO_SYSTEM_GP2XWIZ *system = (void *)al_get_system_driver();

   display->w = 320;
   display->h = 240;
   display->vt = _al_display_gp2xwiz_framebuffer_driver();
   display->refresh_rate = 60;
   display->flags = al_get_new_display_flags();

   display->flags |= ALLEGRO_FULLSCREEN;

   /* Add ourself to the list of displays. */
   ALLEGRO_DISPLAY_GP2XWIZ_FB **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 backbuffer and point it to the framebuffer */
   al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
   d->backbuffer = al_create_bitmap(320, 240);
   d->screen_mem = d->backbuffer->memory;
   d->backbuffer->memory = (unsigned char *)lc_fb1;

   set_gfx_mode = true;

   ALLEGRO_DEBUG("Display created successfully\n");

   return display;
}
Example #3
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;
}
Example #4
0
static ALLEGRO_DISPLAY* wgl_create_display(int w, int h)
{
   ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver();
   ALLEGRO_DISPLAY_WGL **add;
   ALLEGRO_DISPLAY_WGL *wgl_display = al_calloc(1, sizeof *wgl_display);
   ALLEGRO_DISPLAY *ogl_display = (void*)wgl_display;
   ALLEGRO_DISPLAY     *display     = (void*)ogl_display;
   ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)display;

   win_disp->adapter = _al_win_determine_adapter();

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

   display->ogl_extras = al_calloc(1, sizeof(ALLEGRO_OGL_EXTRAS));

   if (!create_display_internals(wgl_display)) {
      al_free(display->ogl_extras);
      al_free(display);
      return NULL;
   }

   /* 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\n", (const char*)glGetString(GL_RENDERER));

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

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

   _al_win_set_system_mouse_cursor(display, ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW);
   _al_win_show_mouse_cursor(display);

   return display;
}
Example #5
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 = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver();
   ALLEGRO_DISPLAY_XGLX *display;
   int flags;
   int 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;
   }

   flags = al_get_new_display_flags();
   if (flags & ALLEGRO_GTK_TOPLEVEL_INTERNAL) {
      if (gtk_override_vt == NULL) {
         ALLEGRO_ERROR("GTK requested but unavailable\n");
         return NULL;
      }
      if (flags & ALLEGRO_FULLSCREEN) {
         ALLEGRO_ERROR("GTK incompatible with fullscreen\n");
         return NULL;
      }
   }

   _al_mutex_lock(&system->lock);

   adapter = al_get_new_display_adapter();
   display = xdpy_create_display_locked(system, flags, w, h, adapter);

   _al_mutex_unlock(&system->lock);

   return (ALLEGRO_DISPLAY *)display;
}
Example #6
0
static ALLEGRO_DISPLAY_INTERFACE *win_get_display_driver(void)
{
    const int flags = al_get_new_display_flags();
    ALLEGRO_SYSTEM *sys = al_get_system_driver();
    ALLEGRO_CONFIG *sys_cfg = al_get_system_config();
    ALLEGRO_SYSTEM_WIN *syswin = (ALLEGRO_SYSTEM_WIN *)sys;
    const char *s;

    /* Look up the toggle_mouse_grab_key binding.  This isn't such a great place
     * to do it, but the config file is not available in win_initialize,
     * and this is neutral between the D3D and OpenGL display drivers.
     */
    if (!syswin->toggle_mouse_grab_keycode) {
        const char *binding = al_get_config_value(sys_cfg, "keyboard",
                              "toggle_mouse_grab_key");
        if (binding) {
            syswin->toggle_mouse_grab_keycode = _al_parse_key_binding(binding,
                                                &syswin->toggle_mouse_grab_modifiers);
            if (syswin->toggle_mouse_grab_keycode) {
                ALLEGRO_DEBUG("Toggle mouse grab key: '%s'\n", binding);
            }
            else {
                ALLEGRO_WARN("Cannot parse key binding '%s'\n", binding);
            }
        }
    }

    /* Programmatic selection. */
#ifdef ALLEGRO_CFG_D3D
    if (flags & ALLEGRO_DIRECT3D_INTERNAL) {
        ALLEGRO_DISPLAY_INTERFACE* iface = _al_display_d3d_driver();
        if (iface == NULL)
            ALLEGRO_WARN("Direct3D graphics driver not available.\n");
        return iface;
    }
#endif
#ifdef ALLEGRO_CFG_OPENGL
    if (flags & ALLEGRO_OPENGL) {
        return _al_display_wgl_driver();
    }
#endif

    /* Selection by configuration file.  The configuration value is non-binding.
     * The user may unknowingly set a value which was configured out at compile
     * time.  The value should have no effect instead of causing a failure.
     */
    s = al_get_config_value(sys_cfg, "graphics", "driver");
    if (s) {
        ALLEGRO_DEBUG("Configuration value graphics.driver = %s\n", s);
        if (0 == _al_stricmp(s, "DIRECT3D") || 0 == _al_stricmp(s, "D3D")) {
#ifdef ALLEGRO_CFG_D3D
            ALLEGRO_DISPLAY_INTERFACE* iface = _al_display_d3d_driver();
            if (iface != NULL) {
                al_set_new_display_flags(flags | ALLEGRO_DIRECT3D_INTERNAL);
                return iface;
            }
#endif
        }
        else if (0 == _al_stricmp(s, "OPENGL")) {
#ifdef ALLEGRO_CFG_OPENGL
            al_set_new_display_flags(flags | ALLEGRO_OPENGL);
            return _al_display_wgl_driver();
#endif
        }
        else if (0 != _al_stricmp(s, "DEFAULT")) {
            ALLEGRO_WARN("Graphics driver selection unrecognised: %s\n", s);
        }
    }

    /* Automatic graphics driver selection. */
    /* XXX is implicitly setting new_display_flags the desired behaviour? */
#ifdef ALLEGRO_CFG_D3D
    {
        ALLEGRO_DISPLAY_INTERFACE* iface = _al_display_d3d_driver();
        if (iface != NULL) {
            al_set_new_display_flags(flags | ALLEGRO_DIRECT3D_INTERNAL);
            return iface;
        }
    }
#endif
#ifdef ALLEGRO_CFG_OPENGL
    {
        al_set_new_display_flags(flags | ALLEGRO_OPENGL);
        return _al_display_wgl_driver();
    }
#endif
    ALLEGRO_WARN("No graphics driver available.\n");
    return NULL;
}
Example #7
0
int main() {
    //allegro stuff
    ALLEGRO_DISPLAY *al_display;
    ALLEGRO_EVENT_QUEUE *queue;
    ALLEGRO_EVENT event;    
    ALLEGRO_TIMER *loop_timer;
    int need_draw = 1;
    
    //widgets
    ALGUI_DISPLAY *display;
    
    //other
    ALGUI_SKIN *skin;
    
    /**** INIT ****/
    
    //init allegro
    al_init();
    al_install_keyboard();
    al_install_mouse();
    al_init_image_addon();
    al_init_font_addon();
    al_init_ttf_addon();
    al_init_primitives_addon();
    
    //init algui
    algui_init();
    
    /**** CREATE ALLEGRO RESOURCES ****/
    
    //set flags
    al_set_new_display_flags(al_get_new_display_flags() | ALLEGRO_GENERATE_EXPOSE_EVENTS | ALLEGRO_RESIZABLE | ALLEGRO_WINDOWED);
    
    //create a al_display
    al_display = al_create_display(640, 480);
    assert(al_display);        
    
    //create timers and events
    queue = al_create_event_queue();    
    loop_timer = al_create_timer(1.0 / 60.0);    
    al_register_event_source(queue, al_get_keyboard_event_source());
    al_register_event_source(queue, al_get_mouse_event_source());
    al_register_event_source(queue, al_get_display_event_source(al_display));
    al_register_event_source(queue, al_get_timer_event_source(loop_timer));    
    
    /**** CREATE WIDGETS ****/
    
    //create the display widget
    display = algui_create_display();
    algui_resize_widget(algui_get_display_widget(display), 640, 480);
    
    //skin widgets
    skin = algui_load_skin("test/test-skin/test-skin.txt");
    algui_skin_widget(algui_get_display_widget(display), skin);
        
    /**** MANAGE EVENTS ****/
    
    //event loop        
    al_start_timer(loop_timer);
    for(;;) {
        //wait for event
        al_wait_for_event(queue, &event);
        
        switch (event.type) {
            //close
            case ALLEGRO_EVENT_DISPLAY_CLOSE:
                goto END;
                
            //keydown                
            case ALLEGRO_EVENT_KEY_DOWN:
                if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) goto END;
                algui_dispatch_event(algui_get_display_widget(display), &event);
                break;                                

            //redraw
            case ALLEGRO_EVENT_DISPLAY_EXPOSE:
                need_draw = 1;
                break;            
                
            //remove the input focus                
            case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:
                algui_dispatch_event(algui_get_display_widget(display), &event);
                need_draw = 1;
                break;            
                        
            //handle timers
            case ALLEGRO_EVENT_TIMER:
                if (event.timer.source == loop_timer) need_draw = 1;
                else algui_dispatch_event(algui_get_display_widget(display), &event);
                break;
                
            //dispatch event to the widgets                
			default:                                
                algui_dispatch_event(algui_get_display_widget(display), &event);
                break;
        }

        if (need_draw && al_is_event_queue_empty(queue)) {
            algui_draw_widget(algui_get_display_widget(display));
            al_flip_display();
            need_draw = false;
        }                
    }
    
    /**** CLEANUP ****/
    
    END:

    //cleanup the gui
    algui_destroy_widget(algui_get_display_widget(display));
    algui_destroy_skin(skin);
    algui_cleanup();
    
    //cleanup allegro
    al_destroy_timer(loop_timer);
    al_destroy_event_queue(queue);  
    al_destroy_display(al_display);
   
    return 0;
}
Example #8
0
void GameEngine::initialise()
{
	if (!al_init())
	{
		THROW_GAME_EXCEPTION(EXCEP_ALLEG_ENGINE_FAILED);
	}	

	if (!al_init_font_addon())
	{
		THROW_GAME_EXCEPTION(EXCEP_ALLEG_FONT_FAILED);
	}

	if (!al_init_image_addon())
	{
		THROW_GAME_EXCEPTION(EXCEP_ALLEG_IMAGE_FAILED);
	}

	if (!al_install_keyboard())
	{
		THROW_GAME_EXCEPTION(EXCEP_ALLEG_KEYBOARD_FAILED);
	}

	if (!al_install_mouse())
	{
		THROW_GAME_EXCEPTION(EXCEP_ALLEG_MOUSE_FAILED);
	}

	//Temporary Display Options
	al_set_new_display_flags(ALLEGRO_OPENGL);
	al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
	al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST);
	al_set_new_display_option(ALLEGRO_RENDER_METHOD, 1, ALLEGRO_SUGGEST);
	al_set_new_display_option(ALLEGRO_VSYNC, 2, ALLEGRO_REQUIRE);
	al_set_new_display_option(ALLEGRO_CAN_DRAW_INTO_BITMAP, 1, ALLEGRO_SUGGEST);

	int originalDisplayFlags = al_get_new_display_flags();
	int displayFlags = 0;
	if (m_Config->getFullscreen())
	{
		displayFlags = displayFlags | ALLEGRO_FULLSCREEN_WINDOW | ALLEGRO_NOFRAME;
	}

	al_set_new_display_flags(displayFlags);
	al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR | ALLEGRO_VIDEO_BITMAP);

	if (m_Config->getResolutionWidth() < 0 || m_Config->getResolutionHeight() < 0)
	{
		ALLEGRO_DISPLAY_MODE largest_display_mode;
		al_get_display_mode(al_get_num_display_modes() - 1, &largest_display_mode);

		m_Config->setResolutionWidth(largest_display_mode.width);
		m_Config->setResolutionHeight(largest_display_mode.height);

		//std::cout << m_Config->getResolutionWidth() << " " << m_Config->getResolutionHeight() << endl;
	}

	m_Display = al_create_display(m_Config->getResolutionWidth(), m_Config->getResolutionHeight());
	if (!m_Display)
	{
		THROW_GAME_EXCEPTION(EXCEP_ALLEG_DISPLAY_FAILED);
	}
	al_set_new_display_flags(originalDisplayFlags);

	m_RedrawTimer = al_create_timer(ALLEGRO_BPS_TO_SECS(m_Config->getFrameSpeed()));
	if (!m_RedrawTimer)
	{
		THROW_GAME_EXCEPTION(EXCEP_ALLEG_TIMER_FAILED);
	}

	m_EventQueue = al_create_event_queue();
	if (!m_EventQueue)
	{
		THROW_GAME_EXCEPTION(EXCEP_ALLEG_EQUEUE_FAILED);
	}

	al_register_event_source(m_EventQueue, al_get_display_event_source(m_Display));
	al_register_event_source(m_EventQueue, al_get_timer_event_source(m_RedrawTimer));
	al_register_event_source(m_EventQueue, al_get_keyboard_event_source());
}
Example #9
0
static ALLEGRO_DISPLAY *raspberrypi_create_display(int w, int h)
{
    ALLEGRO_DISPLAY_RASPBERRYPI *d = al_calloc(1, sizeof *d);
    ALLEGRO_DISPLAY *display = (void*)d;
    ALLEGRO_OGL_EXTRAS *ogl = al_calloc(1, sizeof *ogl);
    display->ogl_extras = ogl;
    display->vt = _al_get_raspberrypi_display_interface();
    display->flags = al_get_new_display_flags();

    ALLEGRO_SYSTEM_RASPBERRYPI *system = (void *)al_get_system_driver();

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

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

    display->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1;

    display->w = w;
    display->h = h;

    if (!pi_create_display(display)) {
        // FIXME: cleanup
        return NULL;
    }

    if (getenv("DISPLAY")) {
        _al_mutex_lock(&system->lock);
        Window root = RootWindow(
                          system->x11display, DefaultScreen(system->x11display));
        XWindowAttributes attr;
        XGetWindowAttributes(system->x11display, root, &attr);
        d->window = XCreateWindow(
                        system->x11display,
                        root,
                        0,
                        0,
                        attr.width,
                        attr.height,
                        0, 0,
                        InputOnly,
                        DefaultVisual(system->x11display, 0),
                        0,
                        NULL
                    );
        XGetWindowAttributes(system->x11display, d->window, &attr);
        XSelectInput(
            system->x11display,
            d->window,
            PointerMotionMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask
        );
        XMapWindow(system->x11display, d->window);
        _al_xwin_reset_size_hints(display);
        _al_xwin_set_fullscreen_window(display, 2);
        _al_xwin_set_size_hints(display, INT_MAX, INT_MAX);
        d->wm_delete_window_atom = XInternAtom(system->x11display,
                                               "WM_DELETE_WINDOW", False);
        XSetWMProtocols(system->x11display, d->window, &d->wm_delete_window_atom, 1);
        _al_mutex_unlock(&system->lock);
    }

    al_grab_mouse(display);

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

    setup_gl(display);

    al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);

    display->flags |= ALLEGRO_OPENGL;

    if (al_is_mouse_installed() && !getenv("DISPLAY")) {
        _al_evdev_set_mouse_range(0, 0, display->w-1, display->h-1);
    }

    set_cursor_data(d, default_cursor, DEFAULT_CURSOR_WIDTH, DEFAULT_CURSOR_HEIGHT);

    return display;
}
Example #10
0
static ALLEGRO_DISPLAY *sdl_create_display_locked(int w, int h)
{
   ALLEGRO_DISPLAY_SDL *sdl = al_calloc(1, sizeof *sdl);
   ALLEGRO_DISPLAY *d = (void *)sdl;
   d->w = w;
   d->h = h;
   d->flags = al_get_new_display_flags();
   d->flags |= ALLEGRO_OPENGL;
   int flags = SDL_WINDOW_OPENGL;
   if (d->flags & ALLEGRO_FULLSCREEN)
      flags |= SDL_WINDOW_FULLSCREEN;
   if (d->flags & ALLEGRO_FULLSCREEN_WINDOW)
      flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
   if (d->flags & ALLEGRO_FRAMELESS)
      flags |= SDL_WINDOW_BORDERLESS;
   if (d->flags & ALLEGRO_RESIZABLE)
      flags |= SDL_WINDOW_RESIZABLE;

   GLoption(ALLEGRO_COLOR_SIZE, SDL_GL_BUFFER_SIZE);
   GLoption(ALLEGRO_RED_SIZE, SDL_GL_RED_SIZE);
   GLoption(ALLEGRO_GREEN_SIZE, SDL_GL_GREEN_SIZE);
   GLoption(ALLEGRO_BLUE_SIZE, SDL_GL_BLUE_SIZE);
   GLoption(ALLEGRO_ALPHA_SIZE, SDL_GL_ALPHA_SIZE);
   GLoption(ALLEGRO_ACC_RED_SIZE, SDL_GL_ACCUM_RED_SIZE);
   GLoption(ALLEGRO_ACC_GREEN_SIZE, SDL_GL_ACCUM_GREEN_SIZE);
   GLoption(ALLEGRO_ACC_BLUE_SIZE, SDL_GL_ACCUM_BLUE_SIZE);
   GLoption(ALLEGRO_ACC_ALPHA_SIZE, SDL_GL_ACCUM_ALPHA_SIZE);
   GLoption(ALLEGRO_STEREO, SDL_GL_STEREO);
   GLoption(ALLEGRO_DEPTH_SIZE, SDL_GL_DEPTH_SIZE);
   GLoption(ALLEGRO_STENCIL_SIZE, SDL_GL_STENCIL_SIZE);
   GLoption(ALLEGRO_SAMPLE_BUFFERS, SDL_GL_MULTISAMPLEBUFFERS);
   GLoption(ALLEGRO_SAMPLES, SDL_GL_MULTISAMPLESAMPLES);

   sdl->window = SDL_CreateWindow(sdl->title, sdl->x, sdl->y,
      d->w, d->h, flags);
   if (!sdl->window) {
      ALLEGRO_ERROR("SDL_CreateWindow failed: %s", SDL_GetError());
      return NULL;
   }
   flags =
      SDL_RENDERER_ACCELERATED |
      SDL_RENDERER_PRESENTVSYNC |
      SDL_RENDERER_TARGETTEXTURE;
   sdl->renderer = SDL_CreateRenderer(sdl->window, -1, flags);
   sdl->context = SDL_GL_CreateContext(sdl->window);
   ALLEGRO_DISPLAY **add;
   ALLEGRO_SYSTEM *system = al_get_system_driver();
   add = _al_vector_alloc_back(&system->displays);
   *add = d;

   _al_event_source_init(&d->es);
   d->vt = vt;

   d->extra_settings.settings[ALLEGRO_COMPATIBLE_DISPLAY] = true;

   d->ogl_extras = al_calloc(1, sizeof *d->ogl_extras);
   _al_ogl_manage_extensions(d);
   _al_ogl_set_extensions(d->ogl_extras->extension_api);

   _al_ogl_setup_gl(d);

   return d;
}
Example #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;
}
void _al_d3d_generate_display_format_list(void)
{
   static bool fullscreen = !(al_get_new_display_flags() & ALLEGRO_FULLSCREEN); /* stop warning */
   static int adapter = ~al_get_new_display_adapter(); /* stop warning */
   int i;

   if (!_al_vector_is_empty(&eds_list) && (fullscreen == (bool)(al_get_new_display_flags() & ALLEGRO_FULLSCREEN))
         && (adapter == al_get_new_display_adapter())) {
      return;
   }
   else if (!_al_vector_is_empty(&eds_list)) {
     _al_d3d_destroy_display_format_list();
   }

   fullscreen = (al_get_new_display_flags() & ALLEGRO_FULLSCREEN) != 0;
   adapter = al_get_new_display_adapter();
   if (adapter < 0)
      adapter = 0;

   _al_vector_init(&eds_list, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS *));

   /* Loop through each bit combination of:
    * bit 0: 16/32 bit
    * bit 1: single-buffer
    * bit 2: vsync
    */
   for (i = 0; i < 8; i++) {
      int format_num = !!(i & 1);
      int single_buffer = !!(i & 2);
      int vsync = !!(i & 4);
      int allegro_format = ALLEGRO_PIXEL_FORMAT_XRGB_8888;
      if (format_num == 1) allegro_format = ALLEGRO_PIXEL_FORMAT_RGB_565;
      D3DFORMAT d3d_format = (D3DFORMAT)_al_pixel_format_to_d3d(allegro_format);

     /* Count available multisample quality levels. */
      DWORD quality_levels = 0;

      if (_al_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, d3d_format,
         !fullscreen, D3DMULTISAMPLE_NONMASKABLE, &quality_levels) != D3D_OK) {
         _al_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_REF, d3d_format,
            !fullscreen, D3DMULTISAMPLE_NONMASKABLE, &quality_levels);
      }

      /* Loop through available depth/stencil formats. */
      for (int j = 0; j < D3D_DEPTH_FORMATS; j++) {
         if (j == 0 || IsDepthFormatExisting(
               depth_stencil_formats[j].format, d3d_format)) {
            DEPTH_STENCIL_DESC *ds = depth_stencil_formats + j;
            for (int k = 0; k < (int)quality_levels + 1; k++) {
               ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, **peds;
               peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS **)_al_vector_alloc_back(&eds_list);
               eds = *peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS *)al_malloc(sizeof *eds);               
               memset(eds->settings, 0, sizeof(int) * ALLEGRO_DISPLAY_OPTIONS_COUNT);

               eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1;

               if (format_num == 0) {
                  eds->settings[ALLEGRO_RED_SIZE] = 8;
                  eds->settings[ALLEGRO_GREEN_SIZE] = 8;
                  eds->settings[ALLEGRO_BLUE_SIZE] = 8;
                  eds->settings[ALLEGRO_RED_SHIFT] = 16;
                  eds->settings[ALLEGRO_GREEN_SHIFT] = 8;
                  eds->settings[ALLEGRO_BLUE_SHIFT] = 0;
                  eds->settings[ALLEGRO_COLOR_SIZE] = 32;
               }
               else if (format_num == 1) {
                  eds->settings[ALLEGRO_RED_SIZE] = 5;
                  eds->settings[ALLEGRO_GREEN_SIZE] = 6;
                  eds->settings[ALLEGRO_BLUE_SIZE] = 5;
                  eds->settings[ALLEGRO_RED_SHIFT] = 11;
                  eds->settings[ALLEGRO_GREEN_SHIFT] = 5;
                  eds->settings[ALLEGRO_BLUE_SHIFT] = 0;
                  eds->settings[ALLEGRO_COLOR_SIZE] = 16;
               }

               if (single_buffer) {
                  eds->settings[ALLEGRO_SINGLE_BUFFER] = 1;
                  eds->settings[ALLEGRO_UPDATE_DISPLAY_REGION] = 1;
               }

               if (vsync) {
                  eds->settings[ALLEGRO_VSYNC] = 1;
               }

               eds->settings[ALLEGRO_DEPTH_SIZE] = ds->d;
               eds->settings[ALLEGRO_STENCIL_SIZE] = ds->s;
               
               if (k > 1) {
                  eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 1;
                  // TODO: Is it ok to use the quality level here?
                  eds->settings[ALLEGRO_SAMPLES] = k;
               }
            }
         }
      }
      
   }
   ALLEGRO_INFO("found %d format combinations\n", _al_vector_size(&eds_list));
}