示例#1
0
/* _al_run_destructors:
 *  Run all the destructors on the list in reverse order.
 */
void _al_run_destructors(_AL_DTOR_LIST *dtors)
{
   if (!dtors) {
      return;
   }

   /* call the destructors in reverse order */
   _al_mutex_lock(&dtors->mutex);
   {
      while (!_al_vector_is_empty(&dtors->dtors)) {
         DTOR *dtor = _al_vector_ref_back(&dtors->dtors);
         void *object = dtor->object;
         void (*func)(void *) = dtor->func;

         ALLEGRO_DEBUG("calling dtor for %s %p, func %p\n",
            dtor->name, object, func);
         _al_mutex_unlock(&dtors->mutex);
         {
            (*func)(object);
         }
         _al_mutex_lock(&dtors->mutex);
      }
   }
   _al_mutex_unlock(&dtors->mutex);
}
示例#2
0
/* Destroys all bitmaps created for this display.
 */
void _al_destroy_display_bitmaps(ALLEGRO_DISPLAY *d)
{
   while (_al_vector_size(&d->bitmaps) > 0) {
      ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps);
      ALLEGRO_BITMAP *b = *bptr;
      al_destroy_bitmap(b);
   }
}
示例#3
0
static void unlock_current_page(ALLEGRO_TTF_FONT_DATA *data)
{
   if (data->page_lr) {
      ALLEGRO_BITMAP **back = _al_vector_ref_back(&data->page_bitmaps);
      ASSERT(al_is_bitmap_locked(*back));
      al_unlock_bitmap(*back);
      data->page_lr = NULL;
   }
}
示例#4
0
static void convert_display_bitmaps_to_memory_bitmap(ALLEGRO_DISPLAY *d)
{
   ALLEGRO_DEBUG("converting display bitmaps to memory bitmaps.\n");

   while (d->bitmaps._size > 0) {
      ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps);
      ALLEGRO_BITMAP *b = *bptr;
      _al_convert_to_memory_bitmap(b);
   }
}
/* Internal function: _al_event_source_free
 *  Free the resources using by an event source structure.  It
 *  automatically unregisters the event source from all the event
 *  queues it is currently registered with.
 */
void _al_event_source_free(ALLEGRO_EVENT_SOURCE *es)
{
   ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es;

   /* Unregister from all queues. */
   while (!_al_vector_is_empty(&this->queues)) {
      ALLEGRO_EVENT_QUEUE **slot = _al_vector_ref_back(&this->queues);
      al_unregister_event_source(*slot, es);
   }

   _al_vector_free(&this->queues);

   _al_mutex_destroy(&this->mutex);
}
示例#6
0
static void destroy_display_internals(ALLEGRO_DISPLAY_WGL *wgl_disp)
{
   ALLEGRO_DISPLAY *disp = (ALLEGRO_DISPLAY *)wgl_disp;
   ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)wgl_disp;

   /* We need to convert all our bitmaps to display independent (memory)
    * bitmaps because WGL driver doesn't support sharing of resources. */
   while (disp->bitmaps._size > 0) {
      ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&disp->bitmaps);
      ALLEGRO_BITMAP *bmp = *bptr;
      _al_convert_to_memory_bitmap(bmp);
   }

   if (disp->ogl_extras->backbuffer)
      _al_ogl_destroy_backbuffer(disp->ogl_extras->backbuffer);
   disp->ogl_extras->backbuffer = NULL;

   _al_ogl_unmanage_extensions(disp);

   PostMessage(win_disp->window, _al_win_msg_suicide, (WPARAM)win_disp, 0);

   while (!win_disp->thread_ended)
      al_rest(0.001);

   if (wgl_disp->glrc) {
      wglDeleteContext(wgl_disp->glrc);
      wgl_disp->glrc = NULL;
   }
   if (wgl_disp->dc) {
      ReleaseDC(win_disp->window, wgl_disp->dc);
      wgl_disp->dc = NULL;
   }

   if (disp->flags & ALLEGRO_FULLSCREEN && !_wgl_do_not_change_display_mode) {
      ChangeDisplaySettings(NULL, 0);
   }

   if (win_disp->window) {
      DestroyWindow(win_disp->window);
      win_disp->window = NULL;
   }
}
示例#7
0
文件: menu.c 项目: allefant/allegro5
/* Function: al_destroy_menu
 */
void al_destroy_menu(ALLEGRO_MENU *menu)
{
   ALLEGRO_MENU_ITEM **slot;
   size_t i;
   ASSERT(menu);

   if (menu->parent) {
      /* If the menu is attached to a menu item, then this is equivelant to
         removing that menu item. */
      ALLEGRO_MENU *parent = menu->parent->parent;
      ASSERT(parent);

      for (i = 0; i < _al_vector_size(&parent->items); ++i) {
         slot = _al_vector_ref(&parent->items, i);
         if (*slot == menu->parent) {
            al_remove_menu_item(parent, 0 - (int) i);
            return;
         }
      }

      /* Should never get here. */
      ASSERT(false);
      return;
   }
   else if (menu->display && !menu->is_popup_menu) {
      /* This is an active, top-level menu. */
      al_remove_display_menu(menu->display);
   }

   /* Destroy each item associated with the menu. */
   while (_al_vector_size(&menu->items)) {
      slot = _al_vector_ref_back(&menu->items);
      destroy_menu_item(*slot);
   }

   _al_vector_free(&menu->items);

   al_disable_menu_event_source(menu);
   al_free(menu);
}
示例#8
0
static void destroy_display_internals(ALLEGRO_DISPLAY_WGL *wgl_disp)
{
   ALLEGRO_DISPLAY *disp = (ALLEGRO_DISPLAY *)wgl_disp;
   ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)wgl_disp;

   /* We need to convert all our bitmaps to display independent (memory)
    * bitmaps because WGL driver doesn't support sharing of resources. */
   while (disp->bitmaps._size > 0) {
      ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&disp->bitmaps);
      ALLEGRO_BITMAP *bmp = *bptr;
      _al_convert_to_memory_bitmap(bmp);
   }

   if (disp->ogl_extras->backbuffer)
      _al_ogl_destroy_backbuffer(disp->ogl_extras->backbuffer);
   disp->ogl_extras->backbuffer = NULL;

   _al_ogl_unmanage_extensions(disp);

   PostMessage(win_disp->window, _al_win_msg_suicide, (WPARAM)win_disp, 0);
   while (!win_disp->thread_ended)
      al_rest(0.001);
}
示例#9
0
/* Function: al_destroy_event_queue
 */
void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue)
{
   ASSERT(queue);

   _al_unregister_destructor(_al_dtor_list, queue);

   /* Unregister any event sources registered with this queue.  */
   while (_al_vector_is_nonempty(&queue->sources)) {
      ALLEGRO_EVENT_SOURCE **slot = _al_vector_ref_back(&queue->sources);
      al_unregister_event_source(queue, *slot);
   }

   ASSERT(_al_vector_is_empty(&queue->sources));
   _al_vector_free(&queue->sources);

   ASSERT(queue->events_head == queue->events_tail);
   _al_vector_free(&queue->events);

   _al_cond_destroy(&queue->cond);
   _al_mutex_destroy(&queue->mutex);

   al_free(queue);
}
示例#10
0
static void raspberrypi_destroy_display(ALLEGRO_DISPLAY *d)
{
    ALLEGRO_DISPLAY_RASPBERRYPI *pidisplay = (ALLEGRO_DISPLAY_RASPBERRYPI *)d;

    hide_cursor(pidisplay);
    delete_cursor_data(pidisplay);

    _al_set_current_display_only(d);

    while (d->bitmaps._size > 0) {
        ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref_back(&d->bitmaps);
        ALLEGRO_BITMAP *b = *bptr;
        _al_convert_to_memory_bitmap(b);
    }

    _al_event_source_free(&d->es);

    ALLEGRO_SYSTEM_RASPBERRYPI *system = (void *)al_get_system_driver();
    _al_vector_find_and_delete(&system->system.displays, &d);

    eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglDestroySurface(egl_display, egl_window);
    eglDestroyContext(egl_display, egl_context);
    eglTerminate(egl_display);

    if (getenv("DISPLAY")) {
        _al_mutex_lock(&system->lock);
        XUnmapWindow(system->x11display, pidisplay->window);
        XDestroyWindow(system->x11display, pidisplay->window);
        _al_mutex_unlock(&system->lock);
    }

    if (system->mouse_grab_display == d) {
        system->mouse_grab_display = NULL;
    }
}
示例#11
0
static bool wgl_resize_helper(ALLEGRO_DISPLAY *d, int width, int height)
{
   ALLEGRO_DISPLAY_WGL *wgl_disp = (ALLEGRO_DISPLAY_WGL *)d;
   ALLEGRO_DISPLAY *ogl_disp = (ALLEGRO_DISPLAY *)d;
   ALLEGRO_DISPLAY_WIN *win_disp = (ALLEGRO_DISPLAY_WIN *)d;
   int full_w, full_h;
   ALLEGRO_MONITOR_INFO mi;
   int adapter = al_get_new_display_adapter();
   if (adapter < 0)
      adapter = 0;
   al_get_monitor_info(adapter, &mi);
   full_w = mi.x2 - mi.x1;
   full_h = mi.y2 - mi.y1;

   if ((d->flags & ALLEGRO_FULLSCREEN_WINDOW) && (full_w != width || full_h != height)) {
      win_disp->toggle_w = width;
      win_disp->toggle_h = height;
      return true;
   }

   win_disp->can_acknowledge = false;

   if (d->flags & ALLEGRO_FULLSCREEN) {
      ALLEGRO_BITMAP *target_bmp;
      _AL_VECTOR disp_bmps;
      bool was_backbuffer = false;
      size_t i;

      target_bmp = al_get_target_bitmap();
      if (target_bmp->vt)
         was_backbuffer = ((ALLEGRO_BITMAP_OGL*)target_bmp)->is_backbuffer;

      /* Remeber display bitmaps. */
      _al_vector_init(&disp_bmps, sizeof(ALLEGRO_BITMAP*));
      for (i = 0; i < _al_vector_size(&d->bitmaps); i++) {
         ALLEGRO_BITMAP **dis = _al_vector_ref(&d->bitmaps, i);
         ALLEGRO_BITMAP **mem = _al_vector_alloc_back(&disp_bmps);
         *mem = *dis;
      }

      /* This flag prevents from switching to desktop resolution in between. */
      _wgl_do_not_change_display_mode = true;
      destroy_display_internals(wgl_disp);
      _wgl_do_not_change_display_mode = false;

      d->w = width;
      d->h = height;
      if (!create_display_internals(wgl_disp))
         return false;

      /* Reupload bitmaps. */
      while (_al_vector_is_nonempty(&disp_bmps)) {
         ALLEGRO_BITMAP **back = _al_vector_ref_back(&disp_bmps);
         _al_convert_to_display_bitmap(*back);
         _al_vector_delete_at(&disp_bmps, _al_vector_size(&disp_bmps) - 1);
      }

      /* We have a new backbuffer now. */
      if (was_backbuffer)
         al_set_target_bitmap(al_get_backbuffer(d));
   }
   else {
      RECT win_size;
      WINDOWINFO wi;

      win_size.left = 0;
      win_size.top = 0;
      win_size.right = width;
      win_size.bottom = height;

      wi.cbSize = sizeof(WINDOWINFO);
      GetWindowInfo(win_disp->window, &wi);

      AdjustWindowRectEx(&win_size, wi.dwStyle, false, wi.dwExStyle);

      if (!SetWindowPos(win_disp->window, HWND_TOP,
         0, 0,
         win_size.right - win_size.left,
         win_size.bottom - win_size.top,
         SWP_NOMOVE|SWP_NOZORDER))
            return false;

      PostMessage(win_disp->window, WM_USER+0, 0, 0);

      d->w = width;
      d->h = height;
      if (!(d->flags & ALLEGRO_FULLSCREEN_WINDOW)) {
         win_disp->toggle_w = width;
         win_disp->toggle_h = height;
      }

      _al_ogl_resize_backbuffer(ogl_disp->ogl_extras->backbuffer, width, height);

      setup_gl(d);
   }

   return true;
}
示例#12
0
static void xdpy_destroy_display(ALLEGRO_DISPLAY *d)
{
   ALLEGRO_SYSTEM_XGLX *s = (void *)al_get_system_driver();
   ALLEGRO_DISPLAY_XGLX *glx = (void *)d;
   ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras;

   ALLEGRO_DEBUG("destroy display.\n");

   /* If we're the last display, convert all bitmpas to display independent
    * (memory) bitmaps. */
   if (s->system.displays._size == 1) {
      while (d->bitmaps._size > 0) {
         ALLEGRO_BITMAP **bptr = _al_vector_ref_back(&d->bitmaps);
         ALLEGRO_BITMAP *b = *bptr;
         _al_convert_to_memory_bitmap(b);
      }
   }
   else {
      /* Pass all bitmaps to any other living display. (We assume all displays
       * are compatible.) */
      size_t i;
      ALLEGRO_DISPLAY **living = NULL;
      ASSERT(s->system.displays._size > 1);

      for (i = 0; i < s->system.displays._size; i++) {
         living = _al_vector_ref(&s->system.displays, i);
         if (*living != d)
            break;
      }

      for (i = 0; i < d->bitmaps._size; i++) {
         ALLEGRO_BITMAP **add = _al_vector_alloc_back(&(*living)->bitmaps);
         ALLEGRO_BITMAP **ref = _al_vector_ref(&d->bitmaps, i);
         *add = *ref;
         (*add)->display = *living;
      }
   }

   _al_xglx_unuse_adapter(s, glx->adapter);
   
   _al_ogl_unmanage_extensions(d);
   ALLEGRO_DEBUG("unmanaged extensions.\n");

   _al_mutex_lock(&s->lock);
   _al_vector_find_and_delete(&s->system.displays, &d);
   XDestroyWindow(s->x11display, glx->window);

   if (s->mouse_grab_display == d) {
      s->mouse_grab_display = NULL;
   }

   ALLEGRO_DEBUG("destroy window.\n");

   if (d->flags & ALLEGRO_FULLSCREEN) {
      size_t i;
      ALLEGRO_DISPLAY **living = NULL;
      bool last_fullscreen = true;
      /* If any other fullscreen display is still active on the same adapter,
       * we must not touch the video mode.
       */
      for (i = 0; i < s->system.displays._size; i++) {
         living = _al_vector_ref(&s->system.displays, i);
         ALLEGRO_DISPLAY_XGLX *living_glx = (void*)*living;
         
         if (*living == d) continue;
         
         /* check for fullscreen displays on the same adapter */
         if (living_glx->adapter == glx->adapter &&
             al_get_display_flags(*living) & ALLEGRO_FULLSCREEN)
         {
            last_fullscreen = false;
         }
      }
      
      if (last_fullscreen) {
         ALLEGRO_DEBUG("restore modes.\n");
         _al_xglx_restore_video_mode(s, glx->adapter);
      }
      else {
         ALLEGRO_DEBUG("*not* restoring modes.\n");
      }
   }

   if (ogl->backbuffer) {
      _al_ogl_destroy_backbuffer(ogl->backbuffer);
      ogl->backbuffer = NULL;
      ALLEGRO_DEBUG("destroy backbuffer.\n");
   }

   if (glx->context) {
      glXDestroyContext(s->gfxdisplay, glx->context);
      glx->context = NULL;
      ALLEGRO_DEBUG("destroy context.\n");
   }

   /* XXX quick pre-release hack */
   /* In multi-window programs these result in a double-free bugs. */
#if 0
   if (glx->fbc) {
      al_free(glx->fbc);
      glx->fbc = NULL;
      XFree(glx->xvinfo);
      glx->xvinfo = NULL;
   }
   else if (glx->xvinfo) {
      al_free(glx->xvinfo);
      glx->xvinfo = NULL;
   }
#endif

   _al_cond_destroy(&glx->mapped);

   _al_vector_free(&d->bitmaps);
   _al_event_source_free(&d->es);

   al_free(d->ogl_extras);
   al_free(d->vertex_cache);
   al_free(d);

   _al_mutex_unlock(&s->lock);

   ALLEGRO_DEBUG("destroy display finished.\n");
}