void x11_window_set_title(hwrbitmap window, const struct pgstring *title) { struct x11bitmap *xb = XB(window)->frontbuffer ? XB(window)->frontbuffer : XB(window); struct pgstring *s; struct pgstr_iterator i; /* Make a null-terminated UTF-8 string */ if (!iserror(pgstring_convert(&s, PGSTR_ENCODE_UTF8, title))) { pgstring_seek(s, &i, 1, PGSEEK_END); if (!iserror(pgstring_insert_char(s, &i, 0, NULL))) XStoreName(x11_display, xb->d, s->buffer); pgstring_delete(s); } }
/* Loads an input driver, and puts a pointer to it in 'inl' */ g_error load_inlib(g_error (*regfunc)(struct inlib *i), struct inlib **inl) { struct inlib *newnode,*p; g_error e; if (!regfunc) return mkerror(PG_ERRT_BADPARAM,75); /* Avoid duplicates */ p = inlib_list; while (p) { if (p->regfunc == regfunc) { if (inl) * inl = p; return success; } p = p->next; } /* Allocate... */ e = g_malloc((void**)&newnode,sizeof(struct inlib)); errorcheck; memset(newnode,0,sizeof(struct inlib)); /* Register it */ e = (*regfunc)(newnode); if (iserror(e)) { g_free(newnode); return e; } newnode->regfunc = regfunc; /* Insert */ newnode->next = inlib_list; inlib_list = newnode; /* Init */ if (newnode->init) e = (*newnode->init)(); if (iserror(e)) { g_free(newnode); return e; } /* Return stuff */ if (inl) *inl = newnode; return success; }
void def_sprite_hide(struct sprite *spr) { static struct pgquad cr; struct divtree *dt; if (disable_output) return; if (iserror(rdhandle((void**)&dt, PG_TYPE_DIVTREE, -1, spr->dt))) return; if ( (!spr->onscreen) || (spr->ox == -1) ) return; cr.x1 = spr->x; cr.y1 = spr->y; cr.x2 = spr->x+spr->w-1; cr.y2 = spr->y+spr->h-1; /* Remove sprites above this one too */ def_sprite_hide_above(spr); /* Put back the old image */ VID(blit) (dt->display,spr->ox,spr->oy,spr->ow,spr->oh, spr->backbuffer,0,0,PG_LGOP_NONE); add_updarea(dt,spr->ox,spr->oy,spr->ow,spr->oh); spr->onscreen = 0; }
g_error tabpage_set(struct widget *self,int property, glob data) { struct widget *w; g_error e; /* Redirect applicable properties to the tab */ if (is_tab_property(property)) if (!iserror(rdhandle((void**)&w, PG_TYPE_WIDGET, self->owner, DATA->htab)) && w) return widget_set(w, property, data); /* Redirect applicable properties to the tab bar */ if (is_tab_bar_property(property)) if (!iserror(rdhandle((void**)&w, PG_TYPE_WIDGET, self->owner, DATA->htab_bar)) && w) return widget_set(w, property, data); return WIDGET_PARENT->set(self,property,data); }
/* Rebuild function for paragraph divnodes, issued by textbox_new_par_div */ void textbox_build_par_div(struct gropctxt *c, u16 state, struct widget *self) { struct paragraph *par; struct gropnode *grops = *c->headpp; /* Retrieve the paragraph pointer from the existing gropnodes */ if (iserror(rdhandle((void**)&par,PG_TYPE_PARAGRAPH,-1,grops->next->param[0])) || !par) return; /* Text color, cursor color, cursor width */ grops->param[0] = VID(color_pgtohwr)(theme_lookup(state,PGTH_P_FGCOLOR)); par->cursor.color = grops->param[0]; par->cursor.width = theme_lookup(state,PGTH_P_CURSOR_WIDTH); /* If we're displaying to a different width, rewrap it */ if (par->width != c->r.w) { par->width = c->r.w; paragraph_wrap(par,1); } /* Set gropnode sizes */ grops->next->r.x = c->r.x; grops->next->r.y = c->r.y; grops->next->r.w = c->r.w; grops->next->r.h = c->r.h; grops->next->next->r = grops->next->r; DBG("Build, size: %d,%d,%d,%d preferred: %d,%d\n", c->r.x,c->r.y,c->r.w,c->r.h,c->owner->preferred.w,c->owner->preferred.h); }
int geterror(const char *error_str) { int errnum; if (!__errorstr_lookup) { // initialize lookup table for (errnum = 1; errnum < EUNK; errnum++) { __errorstr_lookup = s_table_set(__errorstr_lookup, __errorstr_table[errnum], (void*) errnum); } } if (!error_str) { return EUNK; } if (!iserror(error_str)) { return ENONE; } errnum = (int) s_table_get(__errorstr_lookup, error_str); if (!errnum) { errnum = EUNK; } return errnum; }
g_error widget_derive(struct widget **w, handle *h, int type,struct widget *parent, handle hparent,int rship,int owner) { g_error e; DBG("type %d, rship %d, parent %p, owner %d\n",type,rship,parent,owner); /* Allow using this to detach widgets too. Makes sense, since this is called * by the attachwidget request handler. */ if (!parent) return widget_attach(*w, NULL, NULL, 0); switch (rship) { case PG_DERIVE_INSIDE: if (*w == NULL ) { e = widget_create(w,h, type, parent->dt, hparent, owner); errorcheck; } e = widget_attach(*w, parent->dt,parent->sub,hparent); break; case PG_DERIVE_AFTER: if ( *w == NULL ) { e = widget_create(w,h, type, parent->dt, parent->container, owner); errorcheck; } e = widget_attach(*w,parent->dt,parent->out,parent->container); break; case PG_DERIVE_BEFORE: case PG_DERIVE_BEFORE_OLD: if ( *w == NULL ) { e = widget_create(w,h, type, parent->dt, parent->container, owner); errorcheck; } e = widget_attach(*w,parent->dt,parent->where,parent->container); break; default: return mkerror(PG_ERRT_BADPARAM,22); } /* Error checking code common to all cases */ if (iserror(e)) { widget_remove(*w); errorcheck; } if ((*w)->def->post_attach) { e = (*w)->def->post_attach(*w,parent,rship); errorcheck; } return success; }
g_error textedit_set ( struct widget *self, int property, glob data ) { struct pgstring *text; switch (property) { case PG_WP_TEXT: if (iserror(rdhandle((void **) &text, PG_TYPE_PGSTRING, -1, (handle) data))) text = NULL; if (text) { text_backend_set_text(DATA, text); } break; case PG_WP_FONT: if (iserror(rdhandle((void **)&DATA->fd, PG_TYPE_FONTDESC,-1,data)) || !DATA->fd) return mkerror(PG_ERRT_HANDLE,44); text_backend_build(DATA, DATA->width, DATA->height); break; case PG_WP_SELECTION: if (iserror(rdhandle((void **) &text, PG_TYPE_PGSTRING, -1, (handle) data))) text = NULL; if (text) text_backend_set_selection(DATA, text); break; case PG_WP_READONLY: if (data) { SET_FLAG(DATA->flags, TEXT_WIDGET_READONLY); UNSET_FLAG(DATA->flags, TEXT_WIDGET_FLASH_ON); } else { UNSET_FLAG(DATA->flags, TEXT_WIDGET_READONLY); SET_FLAG(DATA->flags, TEXT_WIDGET_FLASH_ON); DATA->cursor_state = 1; install_timer(self, FLASHTIME_ON); } break; } return success; }
void def_sprite_update(struct sprite *spr) { struct divtree *dt; if (iserror(rdhandle((void**)&dt, PG_TYPE_DIVTREE, -1, spr->dt))) return; (*vid->sprite_hide) (spr); def_sprite_showall(); /* Also re-show the sprites we hid with protectarea */ /* Redraw */ realize_updareas(dt); }
/* Iterator function for widget_find */ g_error widget_find_iterator(const void **p, void *extra) { struct widget *w = (struct widget *) (*p); const struct pgstring *str; struct widget_find_data *data = (struct widget_find_data *) extra; if (iserror(rdhandle((void**)&str,PG_TYPE_PGSTRING,-1,w->name)) || !str) return success; if (!pgstring_cmp(data->string,str)) data->result = w; return success; }
/* Get the window the cursor is in, falling back on the debug window */ static hwrbitmap magic_cursor_display(void) { struct cursor *c = cursor_get_default(); struct divtree *dt; if (!c) return VID(window_debug)(); if (iserror(rdhandle((void**)&dt, PG_TYPE_DIVTREE, -1, c->divtree))) return VID(window_debug)(); return dt->display; }
/* Retrieve the paragraph associated with a divnode */ struct paragraph *document_get_div_par(struct divnode *div) { struct paragraph *par; /* The second gropnode refers to the paragraph, extract the handle from it */ if (!div->grop) return NULL; if (!div->grop->next) return NULL; if (iserror(rdhandle((void**)&par,PG_TYPE_PARAGRAPH,-1,div->grop->next->param[0]))) return NULL; return par; }
int main(int argc, char **argv) { char *path, *args, *reply; uint64_t ctrl; int i; if (argc < 2) { fprintf(stderr, "%s: missing operand\n", argv[0]); return 1; } if (argv[1][0] == '/') { path = strdup(argv[1]); } else if (argv[1][0] == '@') { path = strdup(argv[1]); } else { path = strvcat("/sys/", argv[1]); } ctrl = fs_find(path); if (!ctrl) { fprintf(stderr, "%s: %s: control file not accessible\n", argv[0], path); return 1; } args = malloc(1000); args[0] = '\0'; for (i = 2; i < argc; i++) { strlcat(args, argv[i], 1000); strlcat(args, " ", 1000); } if (args[0]) args[strlen(args)-1] = '\0'; reply = rcall(ctrl, args); if (!reply) { printf("! nosys (not implemented)\n"); return 1; } if (iserror(reply)) { printf("%s (%s)\n", reply, strerror(geterror(reply))); } else { printf("%s\n", reply); } return 0; }
/* Let the driver register itself, and initialize things */ g_error load_vidlib(g_error (*regfunc)(struct vidlib *v), s16 xres,s16 yres,s16 bpp,u32 flags) { g_error e; /* Unload */ if (vid) VID(close) (); /* Clear it */ vid = &vidlib_static; vidwrap = vid; /* No transforms */ memset(vid,0,sizeof(struct vidlib)); vid->close = &emulate_dos; vid->update = &def_update; vid->setmode = &def_setmode; /* Device registration */ e = (*regfunc)(vid); if (iserror(e)) { vid = NULL; return e; } inlib_main = NULL; /* By default use a static vid->display */ vid->display = (hwrbitmap) &static_display; /* Load new driver */ e = VID(init)(); if (iserror(e)) { vid = NULL; return e; } /* Set the initial mode */ return video_setmode(xres,yres,bpp,PG_FM_SET,flags); }
glob tabpage_get(struct widget *self,int property) { struct widget *w; /* Redirect applicable properties to the tab */ if (is_tab_property(property)) if (!iserror(rdhandle((void**)&w, PG_TYPE_WIDGET, self->owner, DATA->htab)) && w) return widget_get(w, property); /* Redirect applicable properties to the tab bar */ if (is_tab_bar_property(property)) if (!iserror(rdhandle((void**)&w, PG_TYPE_WIDGET, self->owner, DATA->htab_bar)) && w) return widget_get(w, property); switch (property) { case PG_WP_TAB: return DATA->htab; case PG_WP_TAB_BAR: return DATA->htab_bar; } return WIDGET_PARENT->get(self,property); }
g_error rdhandle(void **p,unsigned char reqtype,int owner,handle h) { void **x; g_error e; e = rdhandlep(&x,reqtype,owner,h); #ifdef DEBUG_MEMORY if (iserror(e)) printf("rdhandle error (0x%08X)\n",h); #endif errorcheck; if (x) *p = *x; else *p = NULL; return success; }
/* This is the 'high level' hotspot function that will usually be called * by the widget code. * * It rebuilds the hotspot graph from the current divtree if necessary, finds * the hotspot closest to the mouse pointer, traverses the hotspot graph in * the indicated direction, and finds the new mouse pointer position. * * The direction is a HOTSPOT_* constant */ void hotspot_traverse(short direction) { struct hotspot *p; int x,y; struct divtree *dt; /* rebuild the graph */ if (!hotspotlist) { hotspot_build(dts->top->head,NULL); if (popup_toolbar_passthrough()) hotspot_build(dts->root->head,appmgr_nontoolbar_area()); hotspot_graph(); } /* Create the hotspotnav cursor if it doesn't exist */ if (!dts->top->hotspot_cursor) if (iserror(cursor_new(&dts->top->hotspot_cursor,NULL,-1))) return; /* Find the current node */ cursor_getposition(dts->top->hotspot_cursor,&x,&y,&dt); p = hotspot_closest(x,y); if (!p) return; /* If the closest node isn't really that close, just warp to * that closest node. Otherwise, traverse. * * NOTE: We used to test whether the hotspot cursor was within * the same divnode as the hotspot, but now that the hotspot cursor * is separate from all driver-controlled cursors we can do an * exact match. */ if (x==p->x && y==p->y) { /* traverse */ p = p->graph[direction]; if (!p) return; } /* Make sure the divnode is scrolled in and focused now */ if (p->div) request_focus(p->div->owner); /* Warp the hotspot cursor to the new hotspot location */ cursor_move(dts->top->hotspot_cursor,p->x,p->y,dt); }
int rp_admin(rp_t rp, uint32_t user, int access) { char *reply; if (!rp) { return 1; } reply = rcall(rp, "set-access %d %d", user, access); if (iserror(reply)) { errno = geterror(reply); free(reply); return 1; } free(reply); return 0; }
int rp_ulink(rp_t dir, const char *name) { char *reply; if (!name) { return 1; } reply = rcall(dir, rp_getkey(dir, AC_ALTER), "unlink %s", name); if (iserror(reply)) { errno = geterror(reply); free(reply); return 1; } free(reply); return 0; }
/* This is used in transparent widgets - it propagates a redraw through the container the widget is in, in order to redraw the background */ void redraw_bg(struct widget *self) { struct widget *container; /* Dereference the handle */ if (iserror(rdhandle((void **)&container,PG_TYPE_WIDGET,-1, self->container)) || ! container) return; /* Flags! Redraws automatically propagate through all child nodes of the container's div. */ #ifndef CONFIG_NOPANELBAR if (container->type == PG_WIDGET_PANEL) /* Optimize for panels: don't redraw panelbar */ container->in->div->div->next->flags |= DIVNODE_NEED_REDRAW; else #endif container->in->flags |= DIVNODE_NEED_REDRAW; if ( container->dt ) container->dt->flags |= DIVTREE_NEED_REDRAW; }
/* Exception handling wrapper for main */ int main(int argc, char **argv) { g_error e; /* pgserver has an exception handling mechanism based on the g_error * data type and the 'errorcheck' macro. See pgserver/g_error.h * for info on this system. */ e = protected_main(argc,argv); if (iserror(e)) { /* This will print a possibly OS-specific error message. Right now this just * dumps it to stderr, but in a future Win32 port for example it may make a dialog. */ os_show_error(e); return 1; } return 0; }
void scroll_to_divnode(struct divnode *div) { s16 dx = 0,dy = 0; struct divnode *ds = div->divscroll; struct widget *w; if (!ds) return; /* If the divnode is larger or equal size to the scrolled * container, no need to scroll it in. * This fixes some confusing scroll behavior when focusing the textbox widget. */ if ( (div->r.x <= ds->calc.x && (div->r.x + div->r.w) > (ds->calc.x + ds->calc.w)) || (div->r.y <= ds->calc.y && (div->r.y + div->r.h) > (ds->calc.y + ds->calc.h)) ) return; /* Figure out how much to scroll, if any. */ if (div->r.x < ds->calc.x) dx = div->r.x - ds->calc.x; else if ( (div->r.x + div->r.w) > (ds->calc.x + ds->calc.w) ) dx = (div->r.x + div->r.w) - (ds->calc.x + ds->calc.w); if (div->r.y < ds->calc.y) dy = div->r.y - ds->calc.y; else if ( (div->r.y + div->r.h) > (ds->calc.y + ds->calc.h) ) dy = (div->r.y + div->r.h) - (ds->calc.y + ds->calc.h); /* No scrolling? */ if (!(dx || dy)) return; /* Get a pointer to the scroll bar */ if (!iserror(rdhandle((void **)&w,PG_TYPE_WIDGET,-1, ds->owner->scrollbind)) && w) { if (dx) widget_set(w,PG_WP_SCROLL_X,widget_get(w,PG_WP_SCROLL_X) + dx); if (dy) widget_set(w,PG_WP_SCROLL_Y,widget_get(w,PG_WP_SCROLL_Y) + dy); update(NULL,1); } }
void cursor_getposition(struct cursor *crsr, int *x, int *y, struct divtree **dt) { if (!crsr) crsr = cursor_get_default(); if (!crsr) { /* Start cursors out near the top-left corner */ *x = 16; *y = 16; if (dt) *dt = dts->top; } else { *x = crsr->x; *y = crsr->y; if (dt) { if (iserror(rdhandle((void**)dt, PG_TYPE_DIVTREE, -1, crsr->divtree)) || !*dt) *dt = dts->top; } } }
/* Sends a trigger to all of a widget's children */ void r_send_trigger(struct widget *w, s32 type, union trigparam *param, int *stop,int forward) { struct widget *bar; if (!w || (*stop) > 0) return; send_trigger(w,type,param); /* Also traverse the panelbar if there is one */ if (!iserror(rdhandle((void**)&bar, PG_TYPE_WIDGET, w->owner, widget_get(w,PG_WP_PANELBAR))) && bar) { r_send_trigger(bar, type, param, stop,0); if ((*stop) > 0) return; } r_send_trigger(widget_traverse(w,PG_TRAVERSE_CHILDREN,0),type,param,stop,1); if (forward) r_send_trigger(widget_traverse(w,PG_TRAVERSE_FORWARD,1),type,param,stop,1); }
g_error prerror(g_error e) { if (!iserror(e)) return e; #ifdef CONFIG_TEXT fprintf(stderr, "*** ERROR ("); switch (errtype(e)) { case PG_ERRT_MEMORY: fprintf(stderr, "MEMORY"); break; case PG_ERRT_IO: fprintf(stderr, "IO"); break; case PG_ERRT_NETWORK: fprintf(stderr, "NETWORK"); break; case PG_ERRT_BADPARAM: fprintf(stderr, "BADPARAM"); break; case PG_ERRT_HANDLE: fprintf(stderr, "HANDLE"); break; case PG_ERRT_INTERNAL: fprintf(stderr, "INTERNAL"); break; case PG_ERRT_BUSY: fprintf(stderr, "BUSY"); break; case PG_ERRT_FILEFMT: fprintf(stderr, "FILEFMT"); break; default: fprintf(stderr, "UNKNOWN"); } fprintf(stderr, ") : %s\n",errortext(e)); #else puts(errortext(e)); #endif return e; }
/* Get the section, creating it if it doesn't exist */ struct cfg_section *configfile_makesection(const char *section) { size_t len; struct cfg_section *sect; g_error e; /* Find the proper section, create one if it doesn't exist */ sect = configfile_getsection(section); if (!sect) { len=strlen(section)+1; /* create the section and section name */ e = g_malloc((void**) §, sizeof(struct cfg_section) + len); if (iserror(e)) return NULL; memset(sect,0,sizeof(struct cfg_section)); sect->next = sections; sections = sect; sect->name = ((char*)sect) + sizeof(struct cfg_section); memcpy(sect->name,section,len); } return sect; }
int rp_link(uint64_t dir, const char *name, uint64_t link) { char *reply; if (!name) { return 1; } if (link && RP_PID(dir) != RP_PID(link)) { return 1; } reply = rcall(dir, rp_getkey(dir, AC_ALTER), "link %s %r", name, link); if (iserror(reply)) { errno = geterror(reply); free(reply); return 1; } free(reply); return 0; }
int rp_type(rp_t rp, const char *type) { char *reply; if (!rp) { return 0; } reply = rcall(rp, 0, "type"); if (iserror(reply)) { errno = geterror(reply); free(reply); return 0; } if (strstr(reply, type)) { free(reply); return 1; } else { free(reply); return 0; } }
/* Traverse to other widgets in a given direction (PG_TRAVERSE_*) */ struct widget *widget_traverse(struct widget *w, int direction, int count) { struct widget *p; struct divnode *d; struct app_info **appinfo_p, *appinfo; switch (direction) { /* Traverse to the first child, then go forward */ case PG_TRAVERSE_CHILDREN: if (!w) return NULL; /* Make sure not only that this widget has an occupied child * attachment point, but make sure that the thing attached to it is * really the "in" connector on another widget. This is necessary to avoid * an improper result when this is called with a widget used inside another * widget as a container. */ if (!w->sub || !*w->sub || (*w->sub)->owner->in != *w->sub) return NULL; return widget_traverse((*w->sub)->owner,PG_TRAVERSE_FORWARD,count); /* Go forward by 'count' widgets */ case PG_TRAVERSE_FORWARD: for (;w && count;count--) { if (!w->out || !*w->out || (*w->out)->owner->in != *w->out) return NULL; w = (*w->out)->owner; } break; /* Go up by 'count' container levels */ case PG_TRAVERSE_CONTAINER: for (;w && count;count--) { if (iserror(rdhandle((void**) &w, PG_TYPE_WIDGET, -1, w->container))) return NULL; } break; /* Traversing backwards is harder, since there's no 'parent' pointer in the divnode */ case PG_TRAVERSE_BACKWARD: for (;w && count;count--) { /* Find a suitable subtree */ if (iserror(rdhandle((void**) &p, PG_TYPE_WIDGET, -1, w->container))) return NULL; if (p) d = p->in; else d = w->dt->head; /* Find parent divnode */ d = divnode_findparent(d, w->in); if (!d) return NULL; if (d->next != w->in) /* div child doesn't count */ return NULL; w = d->owner; } break; /* Traverse through the application list */ case PG_TRAVERSE_APP: if (w) { /* Find the appinfo structure associated with this widget */ appinfo_p = appmgr_findapp(w); if (!appinfo_p) return NULL; /* Traverse the appinfo list */ for (appinfo=*appinfo_p;appinfo && count;count--) appinfo = appinfo->next; } else { /* If they passed a 0 widget, start them off with the first app */ appinfo = applist; } /* Return the root widget */ if (!appinfo) return NULL; if (iserror(rdhandle((void**) &w, PG_TYPE_WIDGET, -1, appinfo->rootw))) return NULL; break; } return w; }
g_error widget_base_set(struct widget *w, int property, glob data) { char *str; struct divnode *maindiv = w->in->div ? w->in->div : w->in; switch (property) { /* Set the size, assuming initial split at w->in. * Calls resize handler if it exists, and sets the * appropriate flags. */ case PG_WP_SIDE: if (!VALID_SIDE(data)) return mkerror(PG_ERRT_BADPARAM,2); w->in->flags &= SIDEMASK; w->in->flags |= ((sidet)data) | DIVNODE_NEED_RECALC; resizewidget(w); w->dt->flags |= DIVTREE_NEED_RECALC; redraw_bg(w); if (w->auto_orientation) { /* Set orientation on all child widgets */ struct widget *p; p = widget_traverse(w, PG_TRAVERSE_CHILDREN, 0); while (p) { switch (data) { case PG_S_LEFT: case PG_S_RIGHT: if (w->auto_orientation & PG_AUTO_DIRECTION) widget_set(p, PG_WP_DIRECTION, PG_DIR_VERTICAL); if (w->auto_orientation & PG_AUTO_SIDE) switch (widget_get(p, PG_WP_SIDE)) { case PG_S_LEFT: widget_set(p, PG_WP_SIDE, PG_S_TOP); break; case PG_S_RIGHT: widget_set(p, PG_WP_SIDE, PG_S_BOTTOM); break; } break; case PG_S_TOP: case PG_S_BOTTOM: if (w->auto_orientation & PG_AUTO_DIRECTION) widget_set(p, PG_WP_DIRECTION, PG_DIR_HORIZONTAL); if (w->auto_orientation & PG_AUTO_SIDE) switch (widget_get(p, PG_WP_SIDE)) { case PG_S_TOP: widget_set(p, PG_WP_SIDE, PG_S_LEFT); break; case PG_S_BOTTOM: widget_set(p, PG_WP_SIDE, PG_S_RIGHT); break; } break; } p = widget_traverse(p, PG_TRAVERSE_FORWARD,1); } } break; case PG_WP_SIZE: if (data<0) { /* Automatic sizing */ w->in->flags |= DIVNODE_SIZE_AUTOSPLIT; w->dt->flags |= DIVTREE_NEED_RESIZE; } else { w->in->split = data; w->in->flags &= ~DIVNODE_SIZE_AUTOSPLIT; /* No auto resizing */ } w->in->flags |= DIVNODE_NEED_RECALC; w->dt->flags |= DIVTREE_NEED_RECALC; redraw_bg(w); break; case PG_WP_SIZEMODE: w->in->flags &= ~DIVNODE_SIZE_AUTOSPLIT; /* No auto resizing */ w->in->flags &= ~PG_SZMODEMASK; w->in->flags |= data & PG_SZMODEMASK; redraw_bg(w); break; case PG_WP_SCROLL_X: if (data > w->in->child.w - w->in->r.w) data = w->in->child.w - w->in->r.w; if (data < 0) data = 0; if (maindiv->translation.x != -data) { maindiv->translation.x = -data; maindiv->flags |= DIVNODE_SCROLL_ONLY | DIVNODE_NEED_RECALC; w->dt->flags |= DIVTREE_NEED_REDRAW; hotspot_free(); } maindiv->flags |= DIVNODE_DIVSCROLL | DIVNODE_EXTEND_WIDTH; break; case PG_WP_SCROLL_Y: if (data > w->in->child.h - w->in->r.h) data = w->in->child.h - w->in->r.h; if (data < 0) data = 0; if (maindiv->translation.y != -data) { maindiv->translation.y = -data; maindiv->flags |= DIVNODE_SCROLL_ONLY | DIVNODE_NEED_RECALC; w->dt->flags |= DIVTREE_NEED_REDRAW; hotspot_free(); } maindiv->flags |= DIVNODE_DIVSCROLL | DIVNODE_EXTEND_HEIGHT; break; case PG_WP_NAME: if (iserror(rdhandle((void **)&str,PG_TYPE_PGSTRING,-1,data))) return mkerror(PG_ERRT_HANDLE,18); w->name = handle_canonicalize((handle) data); break; case PG_WP_PUBLICBOX: w->publicbox = data; break; case PG_WP_BIND: w->scrollbind = data; break; case PG_WP_THOBJ: maindiv->state = data; resizewidget(w); w->in->flags |= DIVNODE_NEED_RECALC; w->dt->flags |= DIVTREE_NEED_RECALC; break; case PG_WP_TRIGGERMASK: w->trigger_mask = data; break; case PG_WP_HILIGHTED: { struct widget *p; // // Pass the message onto the other sub widgets // p = widget_traverse(w, PG_TRAVERSE_CHILDREN, 0); while (p) { widget_set(p, PG_WP_HILIGHTED, data); p = widget_traverse(p, PG_TRAVERSE_FORWARD,1); } } break; case PG_WP_AUTO_ORIENTATION: w->auto_orientation = data; break; default: return mkerror(PG_ERRT_BADPARAM,6); /* Unknown property */ } return success; }