/* This is a function each platform must define to register all available * system drivers. */ void _al_register_system_interfaces(void) { ALLEGRO_SYSTEM_INTERFACE **add; #if defined ALLEGRO_WITH_XWINDOWS && !defined ALLEGRO_RASPBERRYPI add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_system_xglx_driver(); #elif defined ALLEGRO_RASPBERRYPI add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_system_raspberrypi_driver(); #endif }
/* 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; }
/* This is a function each platform must define to register all available * system drivers. */ void _al_register_system_interfaces(void) { ALLEGRO_SYSTEM_INTERFACE **add; add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_get_iphone_system_interface(); }
void _al_register_system_interfaces() { ALLEGRO_SYSTEM_INTERFACE **add; add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_system_win_driver(); }
/* Internal function: _al_vector_alloc_mid * * Allocate a block of memory in the middle of the vector of the vector's * item * size (see _AL_VECTOR_INITIALIZER and _al_vector_init). Returns a pointer * to the start of this block. This address should only be used while the * vector is not modified; after that it is invalid. You may fill the block * with whatever you want. */ void* _al_vector_alloc_mid(_AL_VECTOR *vec, unsigned int index) { ASSERT(vec); ASSERT(vec->_itemsize > 0); { if (vec->_items == NULL) { ASSERT(index == 0); return _al_vector_alloc_back(vec); } if (vec->_unused == 0) { char *new_items = _AL_REALLOC(vec->_items, 2 * vec->_size * vec->_itemsize); ASSERT(new_items); if (!new_items) return NULL; vec->_items = new_items; vec->_unused = vec->_size; } memmove(ITEM_START(vec, index + 1), ITEM_START(vec, index), vec->_itemsize * (vec->_size - index)); vec->_size++; vec->_unused--; return ITEM_START(vec, index); } }
/* Function: al_create_event_queue */ ALLEGRO_EVENT_QUEUE *al_create_event_queue(void) { ALLEGRO_EVENT_QUEUE *queue = al_malloc(sizeof *queue); ASSERT(queue); if (queue) { _al_vector_init(&queue->sources, sizeof(ALLEGRO_EVENT_SOURCE *)); _al_vector_init(&queue->events, sizeof(ALLEGRO_EVENT)); _al_vector_alloc_back(&queue->events); queue->events_head = 0; queue->events_tail = 0; queue->paused = false; _AL_MARK_MUTEX_UNINITED(queue->mutex); _al_mutex_init(&queue->mutex); _al_cond_init(&queue->cond); _al_register_destructor(_al_dtor_list, "queue", queue, (void (*)(void *)) al_destroy_event_queue); } return queue; }
static bool d3d_upload_bitmap(ALLEGRO_BITMAP *bitmap) { ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap; int w = bitmap->w; int h = bitmap->h; if (d3d_bmp->display->device_lost) return false; if (d3d_bmp->initialized != true) { bool non_pow2 = al_have_d3d_non_pow2_texture_support(); bool non_square = al_have_d3d_non_square_texture_support(); if (non_pow2 && non_square) { // Any shape and size d3d_bmp->texture_w = w; d3d_bmp->texture_h = h; } else if (non_pow2) { // Must be sqaure int max = _ALLEGRO_MAX(w, h); d3d_bmp->texture_w = max; d3d_bmp->texture_h = max; } else { // Must be POW2 d3d_bmp->texture_w = pot(w); d3d_bmp->texture_h = pot(h); } // Some cards/drivers don't like small textures if (d3d_bmp->texture_w < 16) d3d_bmp->texture_w = 16; if (d3d_bmp->texture_h < 16) d3d_bmp->texture_h = 16; if (d3d_bmp->video_texture == 0) if (!d3d_create_textures(d3d_bmp->display, d3d_bmp->texture_w, d3d_bmp->texture_h, d3d_bmp->bitmap.flags, &d3d_bmp->video_texture, &d3d_bmp->system_texture, bitmap->format)) { return false; } /* * Keep track of created bitmaps, in case the display is lost * or resized. */ *(ALLEGRO_BITMAP_D3D **)_al_vector_alloc_back(&created_bitmaps) = d3d_bmp; d3d_bmp->initialized = true; } d3d_do_upload(d3d_bmp, 0, 0, w, h, false); return true; }
/* This is a function each platform must define to register all available * system drivers. */ void _al_register_system_interfaces(void) { #ifdef ALLEGRO_WITH_XWINDOWS ALLEGRO_SYSTEM_INTERFACE **add; /* This is the only system driver right now */ add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_system_xglx_driver(); #endif }
/* This is a function each platform must define to register all available * system drivers. */ void _al_register_system_interfaces(void) { ALLEGRO_SYSTEM_INTERFACE **add; #if defined ALLEGRO_UNIX /* This is the only system driver right now */ add = _al_vector_alloc_back(&_al_system_interfaces); *add = _al_system_xglx_driver(); #endif }
void _al_add_display_validated_callback(ALLEGRO_DISPLAY* display, void (*display_validated)(ALLEGRO_DISPLAY*)) { if (_al_vector_find(&display->display_validated_callbacks, display_validated) >= 0) { return; } else { void (**callback)(ALLEGRO_DISPLAY *) = _al_vector_alloc_back(&display->display_validated_callbacks); *callback = display_validated; } }
/* Internal function: _al_event_source_on_registration_to_queue * This function is called by al_register_event_source() when an * event source is registered to an event queue. This gives the * event source a chance to remember which queues it is registered * to. */ void _al_event_source_on_registration_to_queue(ALLEGRO_EVENT_SOURCE *es, ALLEGRO_EVENT_QUEUE *queue) { _al_event_source_lock(es); { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; /* Add the queue to the source's list. */ ALLEGRO_EVENT_QUEUE **slot = _al_vector_alloc_back(&this->queues); *slot = queue; } _al_event_source_unlock(es); }
/* Function: al_register_event_source */ void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT_SOURCE *source) { ALLEGRO_EVENT_SOURCE **slot; ASSERT(queue); ASSERT(source); if (!_al_vector_contains(&queue->sources, &source)) { _al_event_source_on_registration_to_queue(source, queue); _al_mutex_lock(&queue->mutex); slot = _al_vector_alloc_back(&queue->sources); *slot = source; _al_mutex_unlock(&queue->mutex); } }
static ACODEC_TABLE *add_acodec_table_entry(const char *ext) { ACODEC_TABLE *ent; ent = _al_vector_alloc_back(&acodec_table); strcpy(ent->ext, ext); ent->loader = NULL; ent->saver = NULL; ent->stream_loader = NULL; ent->fs_loader = NULL; ent->fs_saver = NULL; ent->fs_stream_loader = NULL; return ent; }
/* Function: al_create_sub_bitmap */ ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent, int x, int y, int w, int h) { ALLEGRO_BITMAP *bitmap; if (parent->parent) { x += parent->xofs; y += parent->yofs; parent = parent->parent; } if (parent->display && parent->display->vt && parent->display->vt->create_sub_bitmap) { bitmap = parent->display->vt->create_sub_bitmap( parent->display, parent, x, y, w, h); } else { bitmap = al_calloc(1, sizeof *bitmap); bitmap->size = sizeof *bitmap; bitmap->vt = parent->vt; } bitmap->format = parent->format; bitmap->flags = parent->flags; bitmap->w = w; bitmap->h = h; bitmap->display = parent->display; bitmap->locked = false; bitmap->cl = bitmap->ct = 0; bitmap->cr_excl = w; bitmap->cb_excl = h; al_identity_transform(&bitmap->transform); bitmap->parent = parent; bitmap->xofs = x; bitmap->yofs = y; bitmap->memory = NULL; if (bitmap->display) { ALLEGRO_BITMAP **back; back = _al_vector_alloc_back(&bitmap->display->bitmaps); *back = bitmap; } return bitmap; }
static ALLEGRO_DISPLAY *iphone_create_display(int w, int h) { ALLEGRO_DISPLAY_IPHONE *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_iphone_display_interface(); display->flags = al_get_new_display_flags(); if (display->flags & ALLEGRO_FULLSCREEN_WINDOW) { _al_iphone_get_screen_size(&w, &h); } display->w = w; display->h = h; ALLEGRO_SYSTEM_IPHONE *system = (void *)al_get_system_driver(); /* Add ourself to the list of displays. */ ALLEGRO_DISPLAY_IPHONE **add; add = _al_vector_alloc_back(&system->system.displays); *add = d; /* Each display is an event source. */ _al_event_source_init(&display->es); _al_iphone_update_visuals(); ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds[system->visuals_count]; memcpy(eds, system->visuals, sizeof(*eds) * system->visuals_count); qsort(eds, system->visuals_count, sizeof(*eds), _al_display_settings_sorter); ALLEGRO_INFO("Chose visual no. %i\n", eds[0]->index); memcpy(&display->extra_settings, eds[0], sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS)); /* This will add an OpenGL view with an OpenGL context, then return. */ _al_iphone_add_view(display); _al_iphone_make_view_current(); _al_ogl_manage_extensions(display); _al_ogl_set_extensions(ogl->extension_api); setup_gl(display); display->flags |= ALLEGRO_OPENGL; return display; }
static ALLEGRO_BITMAP *push_new_page(ALLEGRO_TTF_FONT_DATA *data, int glyph_size) { ALLEGRO_BITMAP **back; ALLEGRO_BITMAP *page; ALLEGRO_STATE state; int page_size = 1; /* 16 seems to work well. A particular problem are fixed width fonts which * take an inordinate amount of space. */ while (page_size < 16 * glyph_size) { page_size *= 2; } if (page_size < data->min_page_size) { page_size = data->min_page_size; } if (page_size > data->max_page_size) { page_size = data->max_page_size; } if (glyph_size > page_size) { return NULL; } unlock_current_page(data); /* The bitmap will be destroyed when the parent font is destroyed so * it is not safe to register a destructor for it. */ _al_push_destructor_owner(); al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_format(data->bitmap_format); al_set_new_bitmap_flags(data->bitmap_flags); page = al_create_bitmap(page_size, page_size); al_restore_state(&state); _al_pop_destructor_owner(); if (page) { back = _al_vector_alloc_back(&data->page_bitmaps); *back = page; data->page_pos_x = 0; data->page_pos_y = 0; data->page_line_height = 0; } return page; }
/* 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; }
/* Internal function: _al_register_destructor * Register OBJECT to be destroyed by FUNC during Allegro shutdown. * This would be done in the object's constructor function. * * [thread-safe] */ void _al_register_destructor(_AL_DTOR_LIST *dtors, char const *name, void *object, void (*func)(void*)) { int *dtor_owner_count; ASSERT(object); ASSERT(func); dtor_owner_count = _al_tls_get_dtor_owner_count(); if (*dtor_owner_count > 0) return; _al_mutex_lock(&dtors->mutex); { #ifdef DEBUGMODE /* make sure the object is not registered twice */ { unsigned int i; for (i = 0; i < _al_vector_size(&dtors->dtors); i++) { DTOR *dtor = _al_vector_ref(&dtors->dtors, i); ASSERT(dtor->object != object); } } #endif /* DEBUGMODE */ /* add the destructor to the list */ { DTOR *new_dtor = _al_vector_alloc_back(&dtors->dtors); if (new_dtor) { new_dtor->object = object; new_dtor->func = func; new_dtor->name = name; ALLEGRO_DEBUG("added dtor for %s %p, func %p\n", name, object, func); } else { ALLEGRO_WARN("failed to add dtor for %s %p\n", name, object); } } } _al_mutex_unlock(&dtors->mutex); }
static ALLEGRO_JOYSTICK_LINUX *ljoy_allocate_structure(void) { ALLEGRO_JOYSTICK_LINUX **slot; ALLEGRO_JOYSTICK_LINUX *joy; unsigned i; for (i = 0; i < _al_vector_size(&joysticks); i++) { slot = _al_vector_ref(&joysticks, i); joy = *slot; if (joy->config_state == LJOY_STATE_UNUSED) return joy; } joy = al_calloc(1, sizeof *joy); slot = _al_vector_alloc_back(&joysticks); *slot = joy; return joy; }
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; }
ALLEGRO_SHADER *_al_create_shader_glsl(ALLEGRO_SHADER_PLATFORM platform) { ALLEGRO_SHADER_GLSL_S *shader = al_calloc(1, sizeof(ALLEGRO_SHADER_GLSL_S)); if (!shader) return NULL; shader->shader.platform = platform; shader->shader.vt = &shader_glsl_vt; _al_vector_init(&shader->shader.bitmaps, sizeof(ALLEGRO_BITMAP *)); al_lock_mutex(shaders_mutex); { ALLEGRO_SHADER **back = (ALLEGRO_SHADER **)_al_vector_alloc_back(&shaders); *back = (ALLEGRO_SHADER *)shader; } al_unlock_mutex(shaders_mutex); return (ALLEGRO_SHADER *)shader; }
/* Function: al_clone_path */ ALLEGRO_PATH *al_clone_path(const ALLEGRO_PATH *path) { ALLEGRO_PATH *clone; unsigned int i; ASSERT(path); clone = al_create_path(NULL); if (!clone) { return NULL; } al_ustr_assign(clone->drive, path->drive); al_ustr_assign(clone->filename, path->filename); for (i = 0; i < _al_vector_size(&path->segments); i++) { ALLEGRO_USTR **slot = _al_vector_alloc_back(&clone->segments); (*slot) = al_ustr_dup(get_segment(path, i)); } return clone; }
// FIXME: Add a special case for when a single glyph rendering won't fit // into 256x256 pixels. static ALLEGRO_BITMAP *push_new_page(ALLEGRO_TTF_FONT_DATA *data) { ALLEGRO_BITMAP **back; ALLEGRO_BITMAP *page; ALLEGRO_STATE state; unlock_current_page(data); /* The bitmap will be destroyed when the parent font is destroyed so * it is not safe to register a destructor for it. */ _al_push_destructor_owner(); al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_format(data->bitmap_format); al_set_new_bitmap_flags(data->bitmap_flags); page = al_create_bitmap(256, 256); al_restore_state(&state); _al_pop_destructor_owner(); back = _al_vector_alloc_back(&data->page_bitmaps); *back = page; /* Sometimes OpenGL will partly sample texels from the border of * glyphs. So we better clear the texture to transparency. * XXX This is very slow and avoidable with some effort. */ al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); al_hold_bitmap_drawing(false); al_set_target_bitmap(*back); al_clear_to_color(al_map_rgba_f(0, 0, 0, 0)); al_restore_state(&state); data->page_pos_x = 0; data->page_pos_y = 0; data->page_line_height = 0; return page; }
static void transfer_display_bitmaps_to_any_other_display( ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY *d) { size_t i; ALLEGRO_DISPLAY *living = NULL; ASSERT(s->system.displays._size > 1); for (i = 0; i < s->system.displays._size; i++) { ALLEGRO_DISPLAY **slot = _al_vector_ref(&s->system.displays, i); living = *slot; if (living != d) break; } ALLEGRO_DEBUG("transferring display bitmaps to other display.\n"); 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; } }
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; }
ALLEGRO_BITMAP *_al_create_bitmap_params(ALLEGRO_DISPLAY *current_display, int w, int h, int format, int flags) { ALLEGRO_SYSTEM *system = al_get_system_driver(); ALLEGRO_BITMAP *bitmap; ALLEGRO_BITMAP **back; int64_t mul; bool result; /* Reject bitmaps where a calculation pixel_size*w*h would overflow * int. Supporting such bitmaps would require a lot more work. */ mul = 4 * (int64_t) w * (int64_t) h; if (mul > (int64_t) INT_MAX) { ALLEGRO_WARN("Rejecting %dx%d bitmap\n", w, h); return NULL; } if ((flags & ALLEGRO_MEMORY_BITMAP) || !current_display || !current_display->vt || current_display->vt->create_bitmap == NULL || _al_vector_size(&system->displays) < 1) { if (flags & ALLEGRO_VIDEO_BITMAP) return NULL; return create_memory_bitmap(current_display, w, h, format, flags); } /* Else it's a display bitmap */ bitmap = current_display->vt->create_bitmap(current_display, w, h, format, flags); if (!bitmap) { ALLEGRO_ERROR("failed to create display bitmap\n"); return NULL; } bitmap->_display = current_display; bitmap->w = w; bitmap->h = h; bitmap->locked = false; bitmap->cl = 0; bitmap->ct = 0; bitmap->cr_excl = w; bitmap->cb_excl = h; al_identity_transform(&bitmap->transform); al_identity_transform(&bitmap->inverse_transform); bitmap->inverse_transform_dirty = false; al_identity_transform(&bitmap->proj_transform); al_orthographic_transform(&bitmap->proj_transform, 0, 0, -1.0, w, h, 1.0); bitmap->parent = NULL; bitmap->xofs = 0; bitmap->yofs = 0; bitmap->_flags |= ALLEGRO_VIDEO_BITMAP; bitmap->dirty = !(bitmap->_flags & ALLEGRO_NO_PRESERVE_TEXTURE); /* The display driver should have set the bitmap->memory field if * appropriate; video bitmaps may leave it NULL. */ ASSERT(bitmap->pitch >= w * al_get_pixel_size(bitmap->_format)); result = bitmap->vt->upload_bitmap(bitmap); if (!result) { al_destroy_bitmap(bitmap); if (flags & ALLEGRO_VIDEO_BITMAP) return NULL; /* With ALLEGRO_CONVERT_BITMAP, just use a memory bitmap instead if * video failed. */ return create_memory_bitmap(current_display, w, h, format, flags); } /* We keep a list of bitmaps depending on the current display so that we can * convert them to memory bimaps when the display is destroyed. */ back = _al_vector_alloc_back(¤t_display->bitmaps); *back = bitmap; return bitmap; }
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; }
/* Function: al_append_path_component */ void al_append_path_component(ALLEGRO_PATH *path, const char *s) { ALLEGRO_USTR **slot = _al_vector_alloc_back(&path->segments); (*slot) = al_ustr_new(s); }
/* Function: al_insert_menu_item */ int al_insert_menu_item(ALLEGRO_MENU *parent, int pos, char const *title, uint16_t id, int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu) { ALLEGRO_MENU_ITEM *item; ALLEGRO_MENU_ITEM **slot; _AL_MENU_ID *menu_id; size_t i; ASSERT(parent); /* If not found, then treat as an append. */ if (!interpret_menu_id_param(&parent, &pos)) pos = _al_vector_size(&parent->items); /* At this point pos == the _index_ of where to insert */ /* The sub-menu must not already be in use. */ if (submenu && (submenu->display || submenu->parent || submenu->is_popup_menu)) return -1; item = create_menu_item(title, id, flags, submenu); if (!item) return -1; item->parent = parent; set_item_icon(item, icon); i = (size_t) pos; if (i >= _al_vector_size(&parent->items)) { /* Append */ i = _al_vector_size(&parent->items); slot = _al_vector_alloc_back(&parent->items); } else { /* Insert */ slot = _al_vector_alloc_mid(&parent->items, i); } if (!slot) { destroy_menu_item(item); return -1; } *slot = item; if (submenu) { submenu->parent = item; if (parent->display) _al_walk_over_menu(submenu, set_menu_display_r, parent->display); } _al_insert_menu_item_at(item, (int) i); if (id) { /* Append the menu's ID to the search vector */ menu_id = (_AL_MENU_ID *) _al_vector_alloc_back(&menu_ids); menu_id->unique_id = item->unique_id; menu_id->id = id; menu_id->menu = parent; } return (int) i; }
/* 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; }