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