/* A widget has requested focus... Send out the ACTIVATE and DEACTIVATE triggers, and update necessary vars */ void request_focus(struct widget *self) { handle hself = hlookup(self,NULL); struct widget *kbdfocus; /* Already focused? */ if (dts->top->focus==hself) return; kbdfocus = NULL; rdhandle((void**)&kbdfocus,PG_TYPE_WIDGET,-1,dts->top->focus); /* Deactivate the old widget, activate the new */ send_trigger(kbdfocus,PG_TRIGGER_DEACTIVATE,NULL); dts->top->focus = hself; appmgr_focus(appmgr_findapp(self)); send_trigger(self,PG_TRIGGER_ACTIVATE,NULL); /* Scroll in */ scroll_to_divnode(self->in->div); /* If there's an active hotspot cursor, move it to this widget */ if (dts->top->hotspot_cursor) { int x,y; divnode_hotspot_position(self->in->div, &x, &y); cursor_move(dts->top->hotspot_cursor,x,y,dts->top); } }
static int hammer_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { (void) offset; (void) fi; ino_t ino = hlookup(&hfs, path); if(ino == (ino_t)-1) { return -ENOENT; } struct stat st; if(hstat(&hfs, ino, &st)) { return -ENOENT; } if(!S_ISDIR(st.st_mode)) { return -ENOENT; } if(offset == 0) { filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); } struct dirent de; while(hreaddir(&hfs, ino, &offset, &de) == 0) { if(filler(buf, de.d_name, NULL, 0)) { return 0; } } return 0; }
static int hammer_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { (void) fi; ino_t ino = hlookup(&hfs, path); if(ino == (ino_t)-1) { return -ENOENT; } struct stat st; if(hstat(&hfs, ino, &st)) { return -ENOENT; } if(S_ISDIR(st.st_mode)) { return -EISDIR; } if (offset < st.st_size) { if (offset + size > st.st_size) size = st.st_size - offset; hreadf(&hfs, ino, offset, size, buf); } else size = 0; return size; }
int vmfree(void *addr, unsigned long size, int type) { struct filemap *fm = NULL; int pages = PAGES(size); int i, rc; char *vaddr; if (size == 0) return 0; addr = (void *) PAGEADDR(addr); if (!valid_range(addr, size)) return -EINVAL; if (type & (MEM_DECOMMIT | MEM_RELEASE)) { vaddr = (char *) addr; for (i = 0; i < pages; i++) { if (page_directory_mapped(vaddr)) { pte_t flags = get_page_flags(vaddr); unsigned long pfn = BTOP(virt2phys(vaddr)); if (flags & PT_FILE) { handle_t h = (flags & PT_PRESENT) ? pfdb[pfn].owner : pfn; struct filemap *newfm = (struct filemap *) hlookup(h); if (newfm != fm) { if (fm) { if (fm->pages == 0) { rc = free_filemap(fm); } else { rc = unlock_filemap(fm); } if (rc < 0) return rc; } fm = newfm; rc = wait_for_object(fm, INFINITE); if (rc < 0) return rc; } fm->pages--; unmap_page(vaddr); if (flags & PT_PRESENT) free_pageframe(pfn); } else if (flags & PT_PRESENT) { unmap_page(vaddr); free_pageframe(pfn); } } vaddr += PAGESIZE; } } if (fm) { if (fm->pages == 0) { rc = free_filemap(fm); } else { rc = unlock_filemap(fm); } if (rc < 0) return rc; } else if (type & MEM_RELEASE) { rmap_free(vmap, BTOP(addr), pages); } return 0; }
struct object *olock(handle_t h, int type) { struct object *o; o = hlookup(h); if (!o) return NULL; if (o->type != type && type != OBJECT_ANY) return NULL; if (o->handle_count == 0) return NULL; o->lock_count++; return o; }
void infilter_client_adaptor_handler(struct infilter *self, u32 trigger, union trigparam *param) { union pg_client_trigger cli_trig; int i; memset(&cli_trig,0,sizeof(cli_trig)); /* Fill in the easy bits */ cli_trig.content.type = trigger; cli_trig.content.infilter_from = hlookup(self,NULL); /* Fill in trigger-specific params */ if (trigger & PG_TRIGGERS_KEY) { cli_trig.content.u.kbd.key = param->kbd.key; cli_trig.content.u.kbd.mods = param->kbd.mods; cli_trig.content.u.kbd.flags = param->kbd.flags; cli_trig.content.u.kbd.consume = param->kbd.consume; cli_trig.content.u.kbd.divtree = param->kbd.divtree; } else if (trigger & PG_TRIGGERS_MOUSE) { cli_trig.content.u.mouse.x = param->mouse.x; cli_trig.content.u.mouse.y = param->mouse.y; cli_trig.content.u.mouse.btn = param->mouse.btn; cli_trig.content.u.mouse.chbtn = param->mouse.chbtn; cli_trig.content.u.mouse.pressure = param->mouse.pressure; cli_trig.content.u.mouse.is_logical = param->mouse.is_logical; cli_trig.content.u.mouse.cursor_handle = hlookup(param->mouse.cursor,NULL); cli_trig.content.u.mouse.ts_calibration = param->mouse.ts_calibration; cli_trig.content.u.mouse.divtree = param->mouse.divtree; } else if (trigger & PG_TRIGGER_MOTIONTRACKER) { memcpy(&cli_trig.content.u.motion, ¶m->motion, sizeof(param->motion)); } /* Convert it to network byte order */ for (i=0;i<(sizeof(cli_trig.array)/sizeof(cli_trig.array[0]));i++) cli_trig.array[i] = htonl(cli_trig.array[i]); /* Send to the client's event queue */ post_event(PG_NWE_INFILTER, NULL, sizeof(cli_trig), self->owner, &cli_trig); }
static int hammer_getattr(const char *path, struct stat *stbuf) { memset(stbuf, 0, sizeof(struct stat)); ino_t ino = hlookup(&hfs, path); if(ino == (ino_t)-1) { return -ENOENT; } if(hstat(&hfs, ino, stbuf)) { return -ENOENT; } return 0; }
static int hammer_readlink(const char *path, char *buf, size_t size) { int res; ino_t ino = hlookup(&hfs, path); if(ino == (ino_t)-1) { return -ENOENT; } res = hreadlink(&hfs, ino, buf, size); if(res < 0) return -EINVAL; return res; }
static int hammer_open(const char *path, struct fuse_file_info *fi) { ino_t ino = hlookup(&hfs, path); if(ino == (ino_t)-1) { return -ENOENT; } struct stat st; if(hstat(&hfs, ino, &st)) { return -ENOENT; } if((fi->flags & 3) != O_RDONLY) return -EACCES; return 0; }
/* Sprite helper functions */ g_error new_sprite(struct sprite **ps,struct divtree *dt,s16 w,s16 h) { g_error e; e = g_malloc((void**)ps,sizeof(struct sprite)); errorcheck; memset(*ps,0,sizeof(struct sprite)); (*ps)->ox = -1; (*ps)->w = w; (*ps)->h = h; VID(bitmap_new) (&(*ps)->backbuffer,w,h,vid->bpp); (*ps)->next = spritelist; (*ps)->visible = 1; (*ps)->lgop = PG_LGOP_NONE; (*ps)->dt = hlookup(dt,NULL); spritelist = *ps; return success; }
void cursor_widgetunder(struct cursor *crsr) { int x,y; struct divnode *div; struct divtree *dt; cursor_getposition(crsr, &x, &y, &dt); div = dt->head; /* If there are popups and they're all in the nontoolbar area, * we can pass toolbar's events through to the bottom layer in the dtstack */ if (popup_toolbar_passthrough()) { struct divnode *ntb = appmgr_nontoolbar_area(); if (ntb) { if (x < ntb->r.x || y < ntb->r.y || x >= ntb->r.x+ntb->r.w || y >= ntb->r.y+ntb->r.h) { /* Get a widget from the bottom layer, with the toolbars */ div = dts->root->head; } } } /* recursively determine the widget/divnode under the cursor */ crsr->ctx.div_under = NULL; crsr->ctx.deepest_div = NULL; r_cursor_widgetunder(crsr,div,x,y); /* Save the widget associated with the divnode we're under */ if (crsr->ctx.div_under) { crsr->ctx.widget_under = hlookup(crsr->ctx.div_under->owner,NULL); /* Also change the cursor theme */ cursor_set_theme(crsr, widget_get(crsr->ctx.div_under->owner,PG_WP_THOBJ)); } else { crsr->ctx.widget_under = 0; /* Default cursor theme */ cursor_set_theme(crsr, PGTH_O_DEFAULT); } }
int hfree(handle_t h) { struct object *o; int rc; o = hlookup(h); if (!o) return -EBADF; if (HPROT(htab[h])) return -EACCES; htab[h] = hfreelist; hfreelist = h; if (--o->handle_count > 0) return 0; rc = close_object(o); if (o->lock_count == 0) destroy_object(o); return rc; }
int vmsync(void *addr, unsigned long size) { struct filemap *fm = NULL; int pages = PAGES(size); int i, rc; char *vaddr; if (size == 0) return 0; addr = (void *) PAGEADDR(addr); if (!valid_range(addr, size)) return -EINVAL; vaddr = (char *) addr; for (i = 0; i < pages; i++) { if (page_directory_mapped(vaddr)) { pte_t flags = get_page_flags(vaddr); if ((flags & (PT_FILE | PT_PRESENT | PT_DIRTY)) == (PT_FILE | PT_PRESENT | PT_DIRTY)) { unsigned long pfn = BTOP(virt2phys(vaddr)); struct filemap *newfm = (struct filemap *) hlookup(pfdb[pfn].owner); if (newfm != fm) { if (fm) { rc = unlock_filemap(fm); if (rc < 0) return rc; } fm = newfm; rc = wait_for_object(fm, INFINITE); if (rc < 0) return rc; } rc = save_file_page(fm, vaddr); if (rc < 0) return rc; } } vaddr += PAGESIZE; } if (fm) { rc = unlock_filemap(fm); if (rc < 0) return rc; } return 0; }
/* Look up the handle associated with the pointer, and delete it safely */ g_error pointer_free(int owner, void *ptr) { return handle_free(owner, hlookup(ptr,NULL)); }
int hunprotect(handle_t h) { if (!hlookup(h)) return -EBADF; htab[h] &= ~HPROTECT; return 0; }
/* Fillstyle interpreter- generates/refreshes a gropnode list */ g_error exec_fillstyle_inner(struct gropctxt *ctx,u16 state, u16 property) { g_error e; u32 fssize; /* Fillstyle size */ unsigned char *fs; /* Pointer to the actual fillstyle data */ unsigned char *p,*plimit; unsigned char op; int r,g,b; /* For color arithmetic */ struct widget *w; int stackframe = fsstkpos-4; /* Look up the fillstyle */ e = rdhandle((void**)&fs,PG_TYPE_FILLSTYLE,-1,theme_lookup(state,property)); errorcheck; if (!fs) { /* When our best just isn't good enough... */ if (property == PGTH_P_BACKDROP || property == PGTH_P_BORDER_FILL) return success; /* The default fillstyle, if no theme is loaded or no theme has defined the property*/ addgrop(ctx,PG_GROP_SETCOLOR); ctx->current->param[0] = VID(color_pgtohwr) (0x000000); switch (state) { case PGTH_O_BUTTON_ON: /* 2 borders */ addgropsz(ctx,PG_GROP_FRAME,ctx->r.x,ctx->r.y,ctx->r.w,ctx->r.h); ctx->r.x += 1; ctx->r.y += 1; ctx->r.w -= 2; ctx->r.h -= 2; default: /* 1 border */ addgropsz(ctx,PG_GROP_FRAME,ctx->r.x,ctx->r.y,ctx->r.w,ctx->r.h); ctx->r.x += 1; ctx->r.y += 1; ctx->r.w -= 2; ctx->r.h -= 2; case PGTH_O_LABEL_SCROLL: /* No border */ addgrop(ctx,PG_GROP_SETCOLOR); ctx->current->param[0] = VID(color_pgtohwr) (theme_lookup(state,PGTH_P_BGCOLOR)); addgropsz(ctx,PG_GROP_RECT,ctx->r.x,ctx->r.y,ctx->r.w,ctx->r.h); } return success; } /* Process the opcodes */ fssize = *(((u32 *)fs)++); p = fs; plimit = fs+fssize; while (p<plimit) { op = *(p++); /* These must occur in MSB to LSB order! (see constants.h) */ if (op & PGTH_OPSIMPLE_GROP) { /* 1-byte gropnode */ e = fsgrop(ctx,op & (PGTH_OPSIMPLE_GROP-1)); errorcheck; } else if (op & PGTH_OPSIMPLE_LITERAL) { /* 1-byte literal */ fsstack[fsstkpos++] = op & (PGTH_OPSIMPLE_LITERAL-1); } else if (op & PGTH_OPSIMPLE_CMDCODE) { /* Command code */ switch (op) { case PGTH_OPCMD_LONGLITERAL: if ((plimit-p)<4) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsstack[fsstkpos++] = NEXTLONG; p += 4; break; case PGTH_OPCMD_LONGGROP: if ((plimit-p)<2) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ e = fsgrop(ctx,NEXTSHORT); p += 2; errorcheck; break; case PGTH_OPCMD_LONGGET: if (plimit<=p) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ e = fsget(*(p++)+stackframe); errorcheck; break; case PGTH_OPCMD_LONGSET: if (plimit<=p) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ e = fsset(*(p++)+stackframe); errorcheck; break; case PGTH_OPCMD_PROPERTY: if ((plimit-p)<4) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsa = NEXTSHORT; p += 2; fsb = NEXTSHORT; p += 2; fsstack[fsstkpos++] = theme_lookup(fsa,fsb); #ifdef CONFIG_ANIMATION /* If it depends on time or randomness, turn on the animated flag in the divnode */ if ((fsb==PGTH_P_TICKS || fsb==PGTH_P_RANDOM) && ctx->owner) ctx->owner->flags |= DIVNODE_ANIMATED; #endif break; case PGTH_OPCMD_LOCALPROP: if ((plimit-p)<2) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsa = NEXTSHORT; p += 2; #ifdef DEBUG_THEME printf("Local theme lookup, property %d\n",(int)fsa); #endif fsstack[fsstkpos++] = theme_lookup(state,fsa); #ifdef CONFIG_ANIMATION /* If it depends on time or randomness, turn on the animated flag in the divnode */ if ((fsa==PGTH_P_TICKS || fsa==PGTH_P_RANDOM) && ctx->owner) ctx->owner->flags |= DIVNODE_ANIMATED; #endif break; case PGTH_OPCMD_PLUS: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa + fsb; break; case PGTH_OPCMD_MINUS: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa - fsb; break; case PGTH_OPCMD_MULTIPLY: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa * fsb; break; case PGTH_OPCMD_SHIFTL: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa << fsb; break; case PGTH_OPCMD_SHIFTR: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa >> fsb; break; case PGTH_OPCMD_OR: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa | fsb; break; case PGTH_OPCMD_AND: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa & fsb; break; case PGTH_OPCMD_EQ: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa == fsb; break; case PGTH_OPCMD_LT: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa < fsb; break; case PGTH_OPCMD_GT: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa > fsb; break; case PGTH_OPCMD_LOGICAL_OR: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa || fsb; break; case PGTH_OPCMD_LOGICAL_AND: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa && fsb; break; case PGTH_OPCMD_LOGICAL_NOT: fsstack[fsstkpos-1] = !fsstack[fsstkpos-1]; break; case PGTH_OPCMD_DIVIDE: e = fspopargs(); errorcheck; if (fsb) fsstack[fsstkpos++] = fsa / fsb; else fsstack[fsstkpos++] = 0xFFFFFFFF; /* limit of fsa/fsb as fsb approaches 0 */ break; case PGTH_OPCMD_COLORADD: e = fspopargs(); errorcheck; r = getred(fsa); g = getgreen(fsa); b = getblue(fsa); r += getred(fsb); g += getgreen(fsb); b += getblue(fsb); if (r>255) r = 255; if (g>255) g = 255; if (b>255) b = 255; fsstack[fsstkpos++] = mkcolor(r,g,b); break; case PGTH_OPCMD_COLORSUB: e = fspopargs(); errorcheck; r = getred(fsa); g = getgreen(fsa); b = getblue(fsa); r -= getred(fsb); g -= getgreen(fsb); b -= getblue(fsb); if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0; fsstack[fsstkpos++] = mkcolor(r,g,b); break; case PGTH_OPCMD_COLORDIV: e = fspopargs(); errorcheck; r = getred(fsa); g = getgreen(fsa); b = getblue(fsa); r = getred(fsb) ? (r/getred(fsb)) : 0xFF; /* Avoid divide by zero */ g = getgreen(fsb) ? (g/getgreen(fsb)) : 0xFF; b = getred(fsb) ? (b/getblue(fsb)) : 0xFF; fsstack[fsstkpos++] = mkcolor(r,g,b); break; case PGTH_OPCMD_COLORMULT: e = fspopargs(); errorcheck; r = getred(fsa); g = getgreen(fsa); b = getblue(fsa); r *= getred(fsb); g *= getgreen(fsb); b *= getblue(fsb); if (r>255) r = 255; if (g>255) g = 255; if (b>255) b = 255; fsstack[fsstkpos++] = mkcolor(r,g,b); break; case PGTH_OPCMD_QUESTIONCOLON: if (fsstkpos<3) return mkerror(PG_ERRT_BADPARAM,88); /* Stack underflow */ fsstkpos -= 2; fsstack[fsstkpos-1] = fsstack[fsstkpos+1] ? fsstack[fsstkpos] : fsstack[fsstkpos-1]; break; case PGTH_OPCMD_WIDGET: if (ctx->owner && ctx->owner->owner) fsstack[fsstkpos++] = hlookup(ctx->owner->owner,NULL); else fsstack[fsstkpos++] = 0; break; case PGTH_OPCMD_TRAVERSEWGT: if (fsstkpos<3) return mkerror(PG_ERRT_BADPARAM,88); /* Stack underflow */ fsstkpos -= 2; e = rdhandle((void**)&w, PG_TYPE_WIDGET, -1, fsstack[fsstkpos+1]); errorcheck; if (w) fsstack[fsstkpos-1] = hlookup(widget_traverse(w,fsstack[fsstkpos],fsstack[fsstkpos-1]),NULL); else fsstack[fsstkpos-1] = 0; break; case PGTH_OPCMD_GETWIDGET: e = fspopargs(); errorcheck; e = rdhandle((void**)&w, PG_TYPE_WIDGET, -1, fsa); errorcheck; if (w) fsstack[fsstkpos++] = widget_get(w,fsb); else fsstack[fsstkpos++] = 0; break; case PGTH_OPCMD_CALL: if ((plimit-p)<4) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsa = NEXTSHORT; p += 2; fsb = NEXTSHORT; p += 2; e = exec_fillstyle_inner(ctx,fsa,fsb); errorcheck; break; case PGTH_OPCMD_LOCALCALL: if ((plimit-p)<2) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsb = NEXTSHORT; p += 2; e = exec_fillstyle_inner(ctx,state,fsb); errorcheck; break; case PGTH_OPCMD_EXTENDED: /* extended command */ op = *(p++); switch (op) { case PGTH_EXCMD_SKIP_IF: if (!fsstack[--fsstkpos]) { --fsstkpos; break; } /* else proceed to EXCMD_SKIP */ case PGTH_EXCMD_SKIP: p += (s32)fsstack[--fsstkpos]; break; } break; } } else if (op & PGTH_OPSIMPLE_GET) { /* 1-byte get */ e = fsget((op & (PGTH_OPSIMPLE_GET-1)) + stackframe); errorcheck; } else { /* 1-byte set */ e = fsset(op + stackframe); errorcheck; } #ifdef DEBUG_THEME /* trace */ printf("FILLSTYLE --- Op: 0x%02X Stk:",op); for (fsa=0;fsa<fsstkpos;fsa++) printf(" %d",(int)fsstack[fsa]); printf("\n"); #endif /* check for stack over/underflow */ if (fsstkpos<0) return mkerror(PG_ERRT_BADPARAM,88); /* Stack underflow */ if (fsstkpos>=FSSTACKSIZE) return mkerror(PG_ERRT_BADPARAM,89); /* Stack overflow */ }