Exemple #1
0
/* [user thread] */
static bool xgtk_create_display_hook(ALLEGRO_DISPLAY *display, int w, int h)
{
   ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display;
   ARGS_CREATE args;

   d->gtk = al_calloc(1, sizeof(*(d->gtk)));
   if (!d->gtk) {
      ALLEGRO_WARN("Out of memory\n");
      return false;
   }

   if (!_al_gtk_ensure_thread()) {
      al_free(d->gtk);
      d->gtk = NULL;
      return false;
   }

   if (!_al_gtk_init_args(&args, sizeof(args))) {
      al_free(d->gtk);
      d->gtk = NULL;
      return false;
   }

   args.display = d;
   args.w = w;
   args.h = h;
   args.title = al_get_new_window_title();

   return _al_gtk_wait_for_args(do_create_display_hook, &args);
}
Exemple #2
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 *settings;
   int flags;

   system = al_get_system_driver();
   driver = system->vt->get_display_driver();
   if (!driver) {
      ALLEGRO_ERROR("Failed to create display (no display driver)\n");
      return NULL;
   }

   display = driver->create_display(w, h);
   if (!display) {
      ALLEGRO_ERROR("Failed to create display (NULL)\n");
      return NULL;
   }

   ASSERT(display->vt);

   settings = &display->extra_settings;
   flags = settings->required | settings->suggested;
   if (!(flags & (1 << ALLEGRO_AUTO_CONVERT_BITMAPS))) {
      settings->settings[ALLEGRO_AUTO_CONVERT_BITMAPS] = 1;
   }

   display->min_w = 0;
   display->min_h = 0;
   display->max_w = 0;
   display->max_h = 0;

   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->projview_transform);

   display->default_shader = NULL;

   _al_vector_init(&display->display_invalidated_callbacks, sizeof(void *));
   _al_vector_init(&display->display_validated_callbacks, sizeof(void *));

   display->render_state.write_mask = ALLEGRO_MASK_RGBA | ALLEGRO_MASK_DEPTH;
   display->render_state.depth_test = false;
   display->render_state.depth_function = ALLEGRO_RENDER_LESS;
   display->render_state.alpha_test = false;
   display->render_state.alpha_function = ALLEGRO_RENDER_ALWAYS;
   display->render_state.alpha_test_value = 0;

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

   if (settings->settings[ALLEGRO_COMPATIBLE_DISPLAY]) {
      al_set_target_bitmap(al_get_backbuffer(display));
   }
   else {
      ALLEGRO_DEBUG("ALLEGRO_COMPATIBLE_DISPLAY not set\n");
      _al_set_current_display_only(display);
   }

   if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
      display->default_shader = _al_create_default_shader(display->flags);
      if (!display->default_shader) {
         al_destroy_display(display);
         return NULL;
      }
      al_use_shader(display->default_shader);
   }

   /* Clear the screen */
   if (settings->settings[ALLEGRO_COMPATIBLE_DISPLAY]) {
      al_clear_to_color(al_map_rgb(0, 0, 0));

      /* TODO:
       * on iphone, don't kill the initial splashscreen - in fact, it's also
       * annoying in linux to have an extra black frame as first frame and I
       * suppose we never really want it
       */
#if 0
      al_flip_display();
#endif
   }

   // TODO: Remove this once all the implementations set the title correctly themselves.
   // Issue #544.
   al_set_window_title(display, al_get_new_window_title());
   
   if (settings->settings[ALLEGRO_AUTO_CONVERT_BITMAPS]) {
      /* We convert video bitmaps to memory bitmaps when the display is
       * destroyed, so seems only fair to re-convertt hem when the
       * display is re-created again.
       */
      al_convert_memory_bitmaps();
   }

   return display;
}
Exemple #3
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;
}