/* _xdga2_fetch_mode_list: * Creates list of available DGA2 video modes. */ static GFX_MODE_LIST *_xdga2_private_fetch_mode_list(void) { XDGAMode *mode; int bpp, num_modes, stored_modes, i, j, already_there; GFX_MODE_LIST *mode_list; GFX_MODE *tmp; mode = XDGAQueryModes(_xwin.display, _xwin.screen, &num_modes); if (!mode) return NULL; mode_list = _AL_MALLOC(sizeof(GFX_MODE_LIST)); if (!mode_list) goto error; mode_list->mode = NULL; stored_modes = 0; for (i=0; i<num_modes; i++) { bpp = (mode[i].depth == 24) ? mode[i].bitsPerPixel : mode[i].depth; already_there = FALSE; for (j=0; j<stored_modes; j++) { if ((mode_list->mode[j].width == mode[i].viewportWidth) && (mode_list->mode[j].height == mode[i].viewportHeight) && (mode_list->mode[j].bpp == bpp)) { already_there = TRUE; break; } } if (!already_there) { tmp = _AL_REALLOC(mode_list->mode, sizeof(GFX_MODE) * (stored_modes + 1)); if (!tmp) goto error; mode_list->mode = tmp; mode_list->mode[stored_modes].width = mode[i].viewportWidth; mode_list->mode[stored_modes].height = mode[i].viewportHeight; mode_list->mode[stored_modes].bpp = bpp; stored_modes++; } } tmp = _AL_REALLOC(mode_list->mode, sizeof(GFX_MODE) * (stored_modes + 1)); if (!tmp) goto error; mode_list->mode = tmp; mode_list->mode[stored_modes].width = 0; mode_list->mode[stored_modes].height = 0; mode_list->mode[stored_modes].bpp = 0; mode_list->num_modes = stored_modes; XFree(mode); return mode_list; error: if (mode_list) { _AL_FREE(mode_list->mode); _AL_FREE(mode_list); } XFree(mode); return NULL; }
/* 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); } }
/* Internal function: _al_vector_alloc_back * * Allocate a block of memory at the back 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. * * Example: * _AL_VECTOR vec = _AL_VECTOR_INITIALIZER(struct boo); * struct boo *thing = _al_vector_alloc_back(&vec); * thing->aaa = 100; * thing->bbb = "a string"; */ void* _al_vector_alloc_back(_AL_VECTOR *vec) { ASSERT(vec); ASSERT(vec->_itemsize > 0); { if (vec->_items == NULL) { ASSERT(vec->_size == 0); ASSERT(vec->_unused == 0); vec->_items = _AL_MALLOC(vec->_itemsize); ASSERT(vec->_items); if (!vec->_items) return NULL; vec->_unused = 1; } else 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; } vec->_size++; vec->_unused--; return ITEM_START(vec, vec->_size-1); } }
/* _al_sane_realloc: * _AL_REALLOC() substitution with guaranteed behaviour. */ void *_al_sane_realloc(void *ptr, size_t size) { void *tmp_ptr; tmp_ptr = NULL; if (ptr && size) { tmp_ptr = _AL_REALLOC(ptr, size); if (!tmp_ptr && ptr) _AL_FREE(ptr); } else if (!size) { tmp_ptr = NULL; if (ptr) _AL_FREE(ptr); } else if (!ptr) { tmp_ptr = _AL_MALLOC(size); } return tmp_ptr; }
/* _WinMain: * Entry point for Windows GUI programs, hooked by a macro in alwin.h, * which makes it look as if the application can still have a normal * main() function. */ int _WinMain(void *_main, void *hInst, void *hPrev, char *Cmd, int nShow) { int (*mainfunc) (int argc, char *argv[]) = (int (*)(int, char *[]))_main; char *argbuf; char *cmdline; char **argv; int argc; int argc_max; int i, q; /* can't use parameter because it doesn't include the executable name */ cmdline = GetCommandLine(); i = strlen(cmdline) + 1; argbuf = _AL_MALLOC(i); memcpy(argbuf, cmdline, i); argc = 0; argc_max = 64; argv = _AL_MALLOC(sizeof(char *) * argc_max); if (!argv) { _AL_FREE(argbuf); return 1; } i = 0; /* parse commandline into argc/argv format */ while (argbuf[i]) { while ((argbuf[i]) && (uisspace(argbuf[i]))) i++; if (argbuf[i]) { if ((argbuf[i] == '\'') || (argbuf[i] == '"')) { q = argbuf[i++]; if (!argbuf[i]) break; } else q = 0; argv[argc++] = &argbuf[i]; if (argc >= argc_max) { argc_max += 64; argv = _AL_REALLOC(argv, sizeof(char *) * argc_max); if (!argv) { _AL_FREE(argbuf); return 1; } } while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (!uisspace(argbuf[i])))) i++; if (argbuf[i]) { argbuf[i] = 0; i++; } } } argv[argc] = NULL; /* call the application entry point */ i = mainfunc(argc, argv); _AL_FREE(argv); _AL_FREE(argbuf); return i; }
/* _find_executable_file: * Helper function: searches path and current directory for executable. * Returns 1 on succes, 0 on failure. */ static int _find_executable_file(const char *filename, char *output, int size) { char *path; /* If filename has an explicit path, search current directory */ if (strchr (filename, '/')) { if (filename[0] == '/') { /* Full path; done */ do_uconvert (filename, U_ASCII, output, U_CURRENT, size); return 1; } else { struct stat finfo; char pathname[1024]; int len; /* Prepend current directory */ getcwd(pathname, sizeof(pathname)); len = strlen(pathname); pathname[len] = '/'; _al_sane_strncpy (pathname+len+1, filename, strlen(filename)); if ((stat(pathname, &finfo)==0) && (!S_ISDIR (finfo.st_mode))) { do_uconvert (pathname, U_ASCII, output, U_CURRENT, size); return 1; } } } /* If filename has no explicit path, but we do have $PATH, search there */ else if ((path = getenv("PATH"))) { char *start = path, *end = path, *buffer = NULL, *temp; struct stat finfo; while (*end) { end = strchr (start, ':'); if (!end) end = strchr (start, '\0'); /* Resize `buffer' for path component, slash, filename and a '\0' */ temp = _AL_REALLOC (buffer, end - start + 1 + strlen (filename) + 1); if (temp) { buffer = temp; _al_sane_strncpy (buffer, start, end - start); *(buffer + (end - start)) = '/'; _al_sane_strncpy (buffer + (end - start) + 1, filename, end - start + 1 + strlen (filename) + 1); if ((stat(buffer, &finfo)==0) && (!S_ISDIR (finfo.st_mode))) { do_uconvert (buffer, U_ASCII, output, U_CURRENT, size); _AL_FREE (buffer); return 1; } } /* else... ignore the failure; `buffer' is still valid anyway. */ start = end + 1; } /* Path search failed */ _AL_FREE (buffer); } return 0; }
/* _make_bitmap: * Helper function for creating the screen bitmap. Sets up a bitmap * structure for addressing video memory at addr, and fills the bank * switching table using bank size/granularity information from the * specified graphics driver. */ BITMAP *_make_bitmap(int w, int h, uintptr_t addr, GFX_DRIVER *driver, int color_depth, int bpl) { GFX_VTABLE *vtable = _get_vtable(color_depth); int i, bank, size; BITMAP *b; if (!vtable) return NULL; size = sizeof(BITMAP) + sizeof(char *) * h; b = (BITMAP *)_AL_MALLOC(size); if (!b) return NULL; _gfx_bank = _AL_REALLOC(_gfx_bank, h * sizeof(int)); if (!_gfx_bank) { _AL_FREE(b); return NULL; } LOCK_DATA(b, size); LOCK_DATA(_gfx_bank, h * sizeof(int)); b->w = b->cr = w; b->h = b->cb = h; b->clip = TRUE; b->cl = b->ct = 0; b->vtable = &_screen_vtable; b->write_bank = b->read_bank = _stub_bank_switch; b->dat = NULL; b->id = BMP_ID_VIDEO; b->extra = NULL; b->x_ofs = 0; b->y_ofs = 0; b->seg = _video_ds(); memcpy(&_screen_vtable, vtable, sizeof(GFX_VTABLE)); LOCK_DATA(&_screen_vtable, sizeof(GFX_VTABLE)); _last_bank_1 = _last_bank_2 = -1; driver->vid_phys_base = addr; b->line[0] = (unsigned char *)addr; _gfx_bank[0] = 0; if (driver->linear) { for (i=1; i<h; i++) { b->line[i] = b->line[i-1] + bpl; _gfx_bank[i] = 0; } } else { bank = 0; for (i=1; i<h; i++) { b->line[i] = b->line[i-1] + bpl; if (b->line[i]+bpl-1 >= (unsigned char *)addr + driver->bank_size) { while (b->line[i] >= (unsigned char *)addr + driver->bank_gran) { b->line[i] -= driver->bank_gran; bank++; } } _gfx_bank[i] = bank; } } return b; }