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; }
/* 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; }
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; }
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; }
/* 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; }
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; }
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; }
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()); }
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; }
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; }
/* 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)); }