char *heap_create(const char *description, size_t size_limit) { heapcb *cb; int page_size; /* Get a new heapcb and link it into the start of the chain */ cb = malloc(sizeof(heapcb)); if (cb == NULL) return NULL; /* failed - unable to allocate space for control block */ cb->next = first_cb; first_cb = cb; /* Create a dynamic area at least one page in size and set it up as a heap */ _swi(OS_ReadMemMapInfo, _OUT(0), &page_size); if (EC(_swix(OS_DynamicArea, _INR(0,8)|_OUT(1)|_OUT(3), 0, -1, page_size, -1, 0x80, size_limit, NULL, -1, description, &cb->area, &cb->base))) { free(cb); return NULL; } /* page_size must be enough to hold the default heap structure */ _swi(OS_Heap, _INR(0,1)|_IN(3), 0, cb->base, page_size); return cb->base; }
char *heap_claim(char *base, size_t required_size) { _kernel_oserror *e; int largest; unsigned int actual_change; void *block; heapcb *cb; if (required_size == 0) return NULL; cb = getcb(base); if (cb == NULL) return NULL; /* unknown heap */ /* Repeatedly attempt to claim a block of the required size */ while ((e = _swix(OS_Heap, _INR(0,1)|_IN(3)|_OUT(2), 2, base, required_size, &block)) != NULL) { int errnum; /* MemCheck_RegisterMiscBlock(e, sizeof(e->errnum)); */ errnum = e->errnum; /* MemCheck_UnRegisterMiscBlock(e); */ if (errnum != 0x184 /* Heap Full */) { #ifndef NDEBUG EC(e); #endif return NULL; /* unknown error */ } /* Read largest free space */ _swi(OS_Heap, _INR(0,1)|_OUT(2), 1, base, &largest); /* Increase the dynamic area by at least the difference between what we * want and what we have spare */ if (EC(_swix(OS_ChangeDynamicArea, _INR(0,1)|_OUT(1), cb->area, required_size - largest, &actual_change)) != NULL) return NULL; /* (most likely) out of memory */ /* Resize the heap itself */ _swi(OS_Heap, _INR(0,1)|_IN(3), 5, base, actual_change); } /* MemCheck_RegisterMiscBlock(block, required_size); */ return block; }
void heap_release(char *base, char *block) { _kernel_oserror *e; heapcb *cb; int errnum; int change; unsigned int actual_change; cb = getcb(base); if (cb == NULL) return; /* unknown heap */ /* MemCheck_UnRegisterMiscBlock(block); */ /* Release the block */ _swi(OS_Heap, _INR(0,2), 3, base, block); /* Current SWI methods don't let us easily get at the returned R3, so we * use our own assembler veneer */ e = xosheap_resize_r3(base, INT_MIN, &change); /* MemCheck_RegisterMiscBlock(e, sizeof(e->errnum)); */ errnum = e->errnum; /* MemCheck_UnRegisterMiscBlock(e); */ if (errnum != 0x187 /* Can't shrink heap any further */) _swi(OS_GenerateError, _IN(0), e); /* Shrink the dynamic area (note this needs to occur before the shrink of * the heap itself, since we need the actual size change) */ _swi(OS_ChangeDynamicArea, _INR(0,1)|_OUT(1), cb->area, -change, &actual_change); /* Shrink the heap by the actual size change */ _swi(OS_Heap, _INR(0,1)|_IN(3), 5, base, change - actual_change); }
_kernel_oserror *SWI_OS_File_5(const char *filename, int *objtype, unsigned int *loadaddr, unsigned int *execaddr, int *length, int *attrib) { /* read file info */ int _objtype,_length,_attrib; unsigned int _loadaddr,_execaddr; _kernel_oserror *err = _swix(OS_File,_INR(0,1)|_OUT(0)|_OUTR(2,5),5, filename, &_objtype,&_loadaddr,&_execaddr,&_length, &_attrib); if (err) return err; if (objtype) *objtype = _objtype; if (loadaddr) *loadaddr = _loadaddr; if (execaddr) *execaddr = _execaddr; if (length) *length = _length; if (attrib) *attrib = _attrib; return NULL; }
int SWI_Read_Timezone(void) { /* returns the timezone offset (centiseconds) */ int ofs; _kernel_oserror *err = _swix(Territory_ReadCurrentTimeZone,_OUT(0),&ofs); if (err) return 0; return ofs; }
bool OSystem_RISCOS::openUrl(const Common::String &url) { int flags; if (_swix(URI_Dispatch, _INR(0,2)|_OUT(0), 0, url.c_str(), 0, &flags) != NULL) { warning("openUrl() (RISCOS) failed to open URL"); return false; } if ((flags & 1) == 1) { warning("openUrl() (RISCOS) failed to open URL"); return false; } return true; }
_kernel_oserror *SWI_OS_ReadVarVal(const char *var, char *buf, int len, int *bytesused) { /* reads an OS varibale */ int _bytesused; _kernel_oserror *err = _swix(OS_ReadVarVal,_INR(0,4)|_OUT(2),var,buf,len, 0,0,&_bytesused); if (err) return err; if (bytesused) *bytesused = _bytesused; return NULL; }
bool artworks_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { static const ns_os_vdu_var_list vars = { os_MODEVAR_XEIG_FACTOR, { os_MODEVAR_YEIG_FACTOR, os_MODEVAR_LOG2_BPP, os_VDUVAR_END_LIST } }; artworks_content *aw = (artworks_content *) c; struct awinfo_block info; const char *source_data; unsigned long source_size; os_error *error; os_trfm matrix; int vals[24]; int clip_x0 = clip->x0; int clip_y0 = clip->y0; int clip_x1 = clip->x1; int clip_y1 = clip->y1; if (ctx->plot->flush && !ctx->plot->flush()) return false; /* pick up render addresses again in case they've changed (eg. newer AWRender module loaded since we first loaded this file) */ (void)_swix(AWRender_RenderAddress, _OUT(0) | _OUT(1), &aw->render_routine, &aw->render_workspace); /* Scaled image. Transform units (65536*OS units) */ matrix.entries[0][0] = data->width * 65536 / c->width; matrix.entries[0][1] = 0; matrix.entries[1][0] = 0; matrix.entries[1][1] = data->height * 65536 / c->height; /* Draw units. (x,y) = bottom left */ matrix.entries[2][0] = ro_plot_origin_x * 256 + data->x * 512 - aw->x0 * data->width / c->width; matrix.entries[2][1] = ro_plot_origin_y * 256 - (data->y + data->height) * 512 - aw->y0 * data->height / c->height; info.ditherx = ro_plot_origin_x; info.dithery = ro_plot_origin_y; clip_x0 -= data->x; clip_y0 -= data->y; clip_x1 -= data->x; clip_y1 -= data->y; if (data->scale == 1.0) { info.clip_x0 = (clip_x0 * 512) + aw->x0 - 511; info.clip_y0 = ((c->height - clip_y1) * 512) + aw->y0 - 511; info.clip_x1 = (clip_x1 * 512) + aw->x0 + 511; info.clip_y1 = ((c->height - clip_y0) * 512) + aw->y0 + 511; } else { info.clip_x0 = (clip_x0 * 512 / data->scale) + aw->x0 - 511; info.clip_y0 = ((c->height - (clip_y1 / data->scale)) * 512) + aw->y0 - 511; info.clip_x1 = (clip_x1 * 512 / data->scale) + aw->x0 + 511; info.clip_y1 = ((c->height - (clip_y0 / data->scale)) * 512) + aw->y0 + 511; } info.print_lowx = 0; info.print_lowy = 0; info.print_handle = 0; info.bgcolour = 0x20000000 | data->background_colour; error = xos_read_vdu_variables(PTR_OS_VDU_VAR_LIST(&vars), vals); if (error) { LOG("xos_read_vdu_variables: 0x%x: %s", error->errnum, error->errmess); return false; } error = xwimp_read_palette((os_palette*)&vals[3]); if (error) { LOG("xwimp_read_palette: 0x%x: %s", error->errnum, error->errmess); return false; } source_data = content__get_source_data(c, &source_size); error = awrender_render(source_data, &info, &matrix, vals, &aw->block, &aw->size, 110, /* fully anti-aliased */ 0, source_size, aw->render_routine, aw->render_workspace); if (error) { LOG("awrender_render: 0x%x: %s", error->errnum, error->errmess); return false; } return true; }
bool artworks_convert(struct content *c) { artworks_content *aw = (artworks_content *) c; union content_msg_data msg_data; const char *source_data; unsigned long source_size; void *init_workspace; void *init_routine; os_error *error; int used = -1; /* slightly better with older OSLib versions */ char *title; /* check whether AWViewer has been seen and we can therefore locate the ArtWorks rendering modules */ xos_read_var_val_size("Alias$LoadArtWorksModules", 0, os_VARTYPE_STRING, &used, NULL, NULL); if (used >= 0) { LOG("Alias$LoadArtWorksModules not defined"); msg_data.error = messages_get("AWNotSeen"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } /* load the modules, or do nothing if they're already loaded */ error = xos_cli("LoadArtWorksModules"); if (error) { LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess); msg_data.error = error->errmess; content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } /* lookup the addresses of the init and render routines */ error = (os_error*)_swix(AWRender_FileInitAddress, _OUT(0) | _OUT(1), &init_routine, &init_workspace); if (error) { LOG("AWRender_FileInitAddress: 0x%x: %s", error->errnum, error->errmess); msg_data.error = error->errmess; content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } error = (os_error*)_swix(AWRender_RenderAddress, _OUT(0) | _OUT(1), &aw->render_routine, &aw->render_workspace); if (error) { LOG("AWRender_RenderAddress: 0x%x: %s", error->errnum, error->errmess); msg_data.error = error->errmess; content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } source_data = content__get_source_data(c, &source_size); /* initialise (convert file to new format if required) */ error = awrender_init(&source_data, &source_size, init_routine, init_workspace); if (error) { LOG("awrender_init: 0x%x : %s", error->errnum, error->errmess); msg_data.error = error->errmess; content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } error = (os_error*)_swix(AWRender_DocBounds, _IN(0) | _OUT(2) | _OUT(3) | _OUT(4) | _OUT(5), source_data, &aw->x0, &aw->y0, &aw->x1, &aw->y1); if (error) { LOG("AWRender_DocBounds: 0x%x: %s", error->errnum, error->errmess); msg_data.error = error->errmess; content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } LOG("bounding box: %d,%d,%d,%d", aw->x0, aw->y0, aw->x1, aw->y1); /* create the resizable workspace required by the ArtWorksRenderer rendering routine */ aw->size = INITIAL_BLOCK_SIZE; aw->block = malloc(INITIAL_BLOCK_SIZE); if (!aw->block) { LOG("failed to create block for ArtworksRenderer"); msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } c->width = (aw->x1 - aw->x0) / 512; c->height = (aw->y1 - aw->y0) / 512; title = messages_get_buff("ArtWorksTitle", nsurl_access_leaf(llcache_handle_get_url(c->llcache)), c->width, c->height); if (title != NULL) { content__set_title(c, title); free(title); } content_set_ready(c); content_set_done(c); /* Done: update status bar */ content_set_status(c, ""); return true; }
int SWI_OS_ReadC(void) { /* get a key from the keyboard buffer */ int key; _swix(OS_ReadC,_OUT(0),&key); return key; }
_kernel_oserror *SWI_OS_FSControl_37(const char *pathname, char *buffer, int *size) { /* canonicalise path */ return _swix(OS_FSControl,_INR(0,5)|_OUT(5),37,pathname,buffer,0,0,*size, size); }