Exemplo n.º 1
0
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);
  }
}
Exemplo n.º 2
0
/* 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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
0
/* 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);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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);
}
Exemplo n.º 10
0
/* 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;
}
Exemplo n.º 11
0
/* 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;
}
Exemplo n.º 12
0
/* 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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
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);
}
Exemplo n.º 15
0
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);
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
/* 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);
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
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;
}
Exemplo n.º 21
0
/* 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;
}
Exemplo n.º 22
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);
  }
}
Exemplo n.º 23
0
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;
    }
  }
}
Exemplo n.º 24
0
/* 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);
}
Exemplo n.º 25
0
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;
}
Exemplo n.º 26
0
/* 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**) &sect,
		 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;
}
Exemplo n.º 27
0
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;
}
Exemplo n.º 28
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;
	}
}
Exemplo n.º 29
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;
}
Exemplo n.º 30
0
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;
}