Esempio n. 1
0
/* Carefully destroy a menu item... If the item is part of a menu, it must be
 * removed from it.
 */
static void destroy_menu_item(ALLEGRO_MENU_ITEM *item)
{
   ASSERT(item);

   if (!item->parent) {
      /* This normally won't happen. */
      _al_destroy_menu_item_at(item, -1);
   }
   else {
      size_t i;
      for (i = 0; i < _al_vector_size(&item->parent->items); ++i) {
         if (*(ALLEGRO_MENU_ITEM **)_al_vector_ref(&item->parent->items, i) == item) {
            /* Notify the platform that the item is to be removed. */
            _al_destroy_menu_item_at(item, i);

            /* Remove the command from the look-up vector. */
            if (item->id != 0) {
               _AL_MENU_ID *menu_id;
               size_t j;

               for (j = 0; j < _al_vector_size(&menu_ids); ++j) {
                  menu_id = (_AL_MENU_ID *) _al_vector_ref(&menu_ids, j);
                  if (menu_id->menu == item->parent && menu_id->unique_id == item->unique_id) {
                     _al_vector_delete_at(&menu_ids, j);
                     break;
                  }
               }
            }

            /* Remove the menu from the parent's list. */
            _al_vector_delete_at(&item->parent->items, i);

            break;
         }
      }
   }

   if (item->caption)
      al_ustr_free(item->caption);

   if (item->popup) {
      /* Delete the sub-menu. Must set the parent/display to NULL ahead of time to
       * avoid recursing back here.
       */
      item->popup->parent = NULL;
      item->popup->display = NULL;
      al_destroy_menu(item->popup);
   }
   
   if (item->icon) {
      al_destroy_bitmap(item->icon);
   }

   al_free(item);
}
Esempio n. 2
0
/* Function: al_reserve_samples
 */
bool al_reserve_samples(int reserve_samples)
{
   int i;
   int current_samples_count = (int) _al_vector_size(&auto_samples);

   ASSERT(reserve_samples >= 0);

   /* If no default mixer has been set by the user, then create a voice
    * and a mixer, and set them to be the default one for use with
    * al_play_sample().
    */
   if (default_mixer == NULL) {
      if (!al_restore_default_mixer())
         goto Error;
   }

   if (current_samples_count < reserve_samples) {
      /* We need to reserve more samples than currently are reserved. */
      for (i = 0; i < reserve_samples - current_samples_count; i++) {
         ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_alloc_back(&auto_samples);
         int *id = _al_vector_alloc_back(&auto_sample_ids);
         *id = 0;
         *slot = al_create_sample_instance(NULL);
         if (!*slot) {
            ALLEGRO_ERROR("al_create_sample failed\n");
            goto Error;
         }
         if (!al_attach_sample_instance_to_mixer(*slot, default_mixer)) {
            ALLEGRO_ERROR("al_attach_mixer_to_sample failed\n");
            goto Error;
         }
      }
   }
   else if (current_samples_count > reserve_samples) {
      /* We need to reserve fewer samples than currently are reserved. */
      while (current_samples_count-- > reserve_samples) {
         _al_vector_delete_at(&auto_samples, current_samples_count);
         _al_vector_delete_at(&auto_sample_ids, current_samples_count);
      }
   }

   return true;

 Error:
   free_sample_vector();
   
   return false;
}
Esempio n. 3
0
void _al_d3d_bmp_destroy(void)
{
   while (!_al_vector_is_empty(&created_bitmaps))
      _al_vector_delete_at(&created_bitmaps, _al_vector_size(&created_bitmaps)-1);
   _al_vector_free(&created_bitmaps);
   _al_vector_init(&created_bitmaps, sizeof(ALLEGRO_SYSTEM_INTERFACE *));

   al_free(vt);
   vt = NULL;
}
Esempio n. 4
0
/* Internal function: _al_vector_find_and_delete
 *
 *  Similar to _al_vector_delete_at(_al_vector_find(vec, ptr_item)) but is
 *  lenient if the item is not found.  Returns true if the item was found and
 *  deleted.
 */
bool _al_vector_find_and_delete(_AL_VECTOR *vec, const void *ptr_item)
{
   int idx = _al_vector_find(vec, ptr_item);
   if (idx >= 0) {
      _al_vector_delete_at(vec, idx);
      return true;
   }
   else
      return false;
}
Esempio n. 5
0
/* Function: al_remove_path_component
 */
void al_remove_path_component(ALLEGRO_PATH *path, int i)
{
   ASSERT(path);
   ASSERT(i < (int)_al_vector_size(&path->segments));

   if (i < 0)
      i = _al_vector_size(&path->segments) + i;

   ASSERT(i >= 0);

   al_ustr_free(get_segment(path, i));
   _al_vector_delete_at(&path->segments, i);
}
Esempio n. 6
0
static void shutdown_system_driver(void)
{
   if (active_sysdrv) {
      if (active_sysdrv->user_exe_path)
         al_destroy_path(active_sysdrv->user_exe_path);
      if (active_sysdrv->vt && active_sysdrv->vt->shutdown_system)
         active_sysdrv->vt->shutdown_system();
      active_sysdrv = NULL;
 
      while (!_al_vector_is_empty(&_al_system_interfaces))
         _al_vector_delete_at(&_al_system_interfaces, _al_vector_size(&_al_system_interfaces)-1);
      _al_vector_free(&_al_system_interfaces);
      _al_vector_init(&_al_system_interfaces, sizeof(ALLEGRO_SYSTEM_INTERFACE *));
   }
   al_destroy_config(sys_config);
   sys_config = NULL;
}
Esempio n. 7
0
/* _al_kcm_detach_from_parent:
 *  This detaches the sample, stream, or mixer from anything it may be attached
 *  to.
 */
void _al_kcm_detach_from_parent(ALLEGRO_SAMPLE_INSTANCE *spl)
{
    ALLEGRO_MIXER *mixer;
    int i;

    if (!spl || !spl->parent.u.ptr)
        return;

    if (spl->parent.is_voice) {
        al_detach_voice(spl->parent.u.voice);
        return;
    }

    mixer = spl->parent.u.mixer;

    /* Search through the streams and check for this one */
    for (i = _al_vector_size(&mixer->streams) - 1; i >= 0; i--) {
        ALLEGRO_SAMPLE_INSTANCE **slot = _al_vector_ref(&mixer->streams, i);

        if (*slot == spl) {
            maybe_lock_mutex(mixer->ss.mutex);

            _al_vector_delete_at(&mixer->streams, i);
            spl->parent.u.mixer = NULL;
            _al_kcm_stream_set_mutex(spl, NULL);

            if (spl->spl_read != _al_kcm_mixer_read)
                spl->spl_read = NULL;

            maybe_unlock_mutex(mixer->ss.mutex);

            break;
        }
    }

    free(spl->matrix);
    spl->matrix = NULL;
}
/* Internal function: _al_unregister_destructor
 *  Unregister a previously registered object.  This must be called
 *  in the normal object destroyer routine, e.g. al_destroy_timer.
 *
 *  [thread-safe]
 */
void _al_unregister_destructor(_AL_DTOR_LIST *dtors, void *object)
{
   ASSERT(object);

   _al_mutex_lock(&dtors->mutex);
   {
      unsigned int i;

      for (i = 0; i < _al_vector_size(&dtors->dtors); i++) {
         DTOR *dtor = _al_vector_ref(&dtors->dtors, i);
         if (dtor->object == object) {
            _al_vector_delete_at(&dtors->dtors, i);
            ALLEGRO_DEBUG("removed dtor for object %p\n", object);
            break;
         }
      }

      /* We cannot assert that the destructor was found because it might not
       * have been registered if the owner count was non-zero at the time.
       */
   }
   _al_mutex_unlock(&dtors->mutex);
}
Esempio n. 9
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;
}
Esempio n. 10
0
/* Function: al_set_display_menu
 */
bool al_set_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu)
{
   DISPLAY_MENU *dm = NULL;
   size_t i;
   int menu_height = _al_get_menu_display_height();
   bool automatic_menu_display_resize = true;
   const char* automatic_menu_display_resize_value =
      al_get_config_value(al_get_system_config(), "compatibility", "automatic_menu_display_resize");
   if (automatic_menu_display_resize_value && strcmp(automatic_menu_display_resize_value, "false") == 0)
      automatic_menu_display_resize = false; 

   ASSERT(display);

   /* Check if this display has a menu associated with it */
   for (i = 0; i < _al_vector_size(&display_menus); ++i) {
      dm = (DISPLAY_MENU *) _al_vector_ref(&display_menus, i);
      if (dm->display == display)
         break;
   }

   /* If no display was found, reset dm to NULL */
   if (i == _al_vector_size(&display_menus))
      dm = NULL;

   if (!menu) {
      /* Removing the menu */

      if (!dm)
         return false;

      _al_hide_display_menu(display, dm->menu);
      _al_walk_over_menu(dm->menu, set_menu_display_r, NULL);
      _al_vector_delete_at(&display_menus, i);

      if (automatic_menu_display_resize && menu_height > 0) {
         display->extra_resize_height = 0;
         al_resize_display(display, al_get_display_width(display), al_get_display_height(display));
      }
   }
   else {
      /* Setting the menu. It must not currently be attached to any 
       * display, and it cannot have a parent menu. */
      if (menu->display || menu->parent)
         return false;

      if (dm) {
         /* hide the existing menu */
         _al_hide_display_menu(display, dm->menu);
         _al_walk_over_menu(dm->menu, set_menu_display_r, NULL);
      }

      if (!_al_show_display_menu(display, menu)) {
         /* Unable to set the new menu, but already have hidden the 
          * previous one, so delete the display_menus slot. */
         if (dm) 
            _al_vector_delete_at(&display_menus, i);
         return false;
      }

      /* Set the entire menu tree as owned by the display */
      _al_walk_over_menu(menu, set_menu_display_r, display);

      if (!dm)
         dm = _al_vector_alloc_back(&display_menus);

      if (automatic_menu_display_resize && menu_height > 0) {
         /* Temporarily disable the constraints so we don't send a RESIZE_EVENT. */
         bool old_constraints = display->use_constraints;
         display->use_constraints = false;
         display->extra_resize_height = menu_height;
         al_resize_display(display, al_get_display_width(display), al_get_display_height(display));
         display->use_constraints = old_constraints;
      }

      dm->display = display;
      dm->menu = menu;
   }

   return true;
}