예제 #1
0
파일: widget.c 프로젝트: scanlime/picogui
g_error widget_create(struct widget **w, handle *h, int type, 
		      struct divtree *dt, handle container, int owner) {

   g_error e;

   DBG("type %d, container %d, owner %d\n",type,container,owner);

   type = appmgr_widget_map(type);

   if (!dt)
     dt = DT_NIL;

   /* Check the type.
    */
   if ( type > PG_WIDGETMAX )
      return mkerror(PG_ERRT_BADPARAM, 20);

   /* Check if it's supported
    */
   if (!widgettab[type].install)
     return (g_error) (long) widgettab[type].remove;

#ifdef DEBUG_KEYS
  num_widgets++;
#endif

  /* Allocate new widget memory and zero it out.
   */
  e = g_malloc((void **)w, sizeof(struct widget));
  errorcheck;
  memset(*w, 0, sizeof(struct widget));

  /* Initialize the elements we can.  Since this widget is unattached.
   */
  (*w)->owner = owner;
  (*w)->type = type;
  (*w)->def = widgettab + type;
  (*w)->dt = dt;
  (*w)->container = container;

  /* Allocate data pointers for this widget and everythign it's subclassed from */
  e = g_malloc((void**)&(*w)->subclasses, sizeof(struct widget_subclass) * 
	       ((*w)->def->subclass_num + 1));
  errorcheck;

  /* Allocate a handle for this widget before calling install, so that it may
   * use the handle when setting up subwidgets.
   */
  e = mkhandle(h,PG_TYPE_WIDGET,owner,*w);
  errorcheck;
  (*w)->h = *h;

  /* Initialize this instance of the widget. This install function should initialize
   * the widget it's subclassed from first, if any
   */
  (*(*w)->def->install)(*w);

  return success;
}
예제 #2
0
void textedit_build ( struct gropctxt *c,
                      unsigned short state,
                      struct widget *self ) {
    s16 w, h, tw;
    g_error e;
    
    w = self->in->div->r.w - theme_lookup(PGTH_O_SCROLL_V,PGTH_P_WIDTH);
    h = self->in->div->r.h;

    self->in->div->preferred.h = h;
    self->in->div->preferred.w = w;

    if (!DATA->fd){
        /* FIXME: Theme lookup foreground, background colors, border */
        e = textedit_set_font (self, theme_lookup (state, PGTH_P_FONT));
//        errorcheck;
    }
    assert (DATA->fd);

    /*
     * The general rule is that once you create a handle you should never
     * delete the object it refers to, only delete the handle
     */
    handle_free(self->owner,DATA->bit_h);

    e = VID(bitmap_new) (&(DATA->bit), w, h, vid->bpp);
//    errorcheck;

    /* the handle should be owned by the application not by pgserver itself */
    e = mkhandle(&DATA->bit_h, PG_TYPE_BITMAP, self->owner, DATA->bit);
//    errorcheck;

    /* Size and add the bitmap itself */
    e = addgropsz(c, PG_GROP_BITMAP, 0, 0, w, h);
//    errorcheck;

    c->current->param[0] = DATA->bit_h;

    /* Create cursor */
    e = addgropsz(c,PG_GROP_RECT, 0, 0, 0, 0);
//    errorcheck;
    
    c->current->flags |= PG_GROPF_COLORED;
    DATA->cursor_grop = c->current;
    DATA->cursor_state = 1;
    DATA->cursor_grop->param[0] = VID(color_pgtohwr)(CURSORCOLOR_ON);

    /* Set cursor height to that of typical char */
    textedit_str_size(self, NULL, 0, &tw, &DATA->cursor_grop->r.h); 
    DATA->cursor_grop->r.x = DATA->border_h;
    DATA->cursor_grop->r.y = DATA->border_v;

    e = text_backend_build( DATA, w, h);
//    errorcheck;

//    return success;
}
예제 #3
0
파일: handle.c 프로젝트: scanlime/picogui
/*
 * Duplicate a handle and it's associated object.
 * (if it can be duplicated. Widgets, drivers,
 * and themes currently can't be duplicated)
 */
g_error handle_dup(handle *dest, int owner, handle src) {
  struct handlenode *n;
  void *newobj;
  g_error e;
  u32 sz;

  /* Find the handle */
  n = htree_find(src);
  /* make sure it exists */
  if (!n) return mkerror(PG_ERRT_HANDLE,26);
  /* Same permissions as rdhandle() */
  if (owner>=0 && n->owner>=0 && n->owner != owner) 
    return mkerror(PG_ERRT_HANDLE,27);
  
  /* Check the type */
  switch (n->type & PG_TYPEMASK) {

  case PG_TYPE_PGSTRING:
    e = pgstring_dup((struct pgstring **)&newobj, (struct pgstring *) n->obj);
    errorcheck;
    e = mkhandle(dest,n->type & PG_TYPEMASK,owner,newobj);
    errorcheck;
    break;

  case PG_TYPE_WT:
    e = wt_instantiate(dest, (struct pgmemwt *) n->obj, src, owner);
    errorcheck;
    break;

  case PG_TYPE_ARRAY:
  case PG_TYPE_PALETTE:
    e = g_malloc(&newobj, (((u32*)n->obj)[0] + 1) * sizeof(u32));
    errorcheck;
    e = mkhandle(dest,n->type & PG_TYPEMASK,owner,newobj);
    errorcheck;
    memcpy(newobj, n->obj, (((u32*)n->obj)[0] + 1) * sizeof(u32));
    break;

  default:
    return mkerror(PG_ERRT_BADPARAM,45);   /* Can't duplicate object */
  }
 
  return success;
}
예제 #4
0
/* Create a paragraph and divnode tied to each other */
g_error textbox_new_par_div(struct paragraph **par, struct divnode **div,
			    struct divnode *background) {
  g_error e;
  handle hpar;
  struct gropctxt c;
  struct paragraph *old_par = *par;
  struct divnode *old_div = *div;

  /* Top-level divnode for this paragraph is used for formatting, it's
   * child is where the paragraph renders to.
   */
  e = newdiv(div,background->owner);
  errorcheck;
  (*div)->flags |= DIVNODE_SPLIT_TOP;
  (*div)->flags &= ~DIVNODE_UNDERCONSTRUCTION;

  /* We want to prevent the normal groplist clearing in div_rebuild
   * because the only way our build function has to know the
   * paragraph handle is by reading the previous groplist.
   */
  e = newdiv(&(*div)->div,background->owner);
  errorcheck;
  (*div)->div->build = &textbox_build_par_div;
  (*div)->div->flags |= DIVNODE_RAW_BUILD;
  (*div)->div->flags &= ~DIVNODE_UNDERCONSTRUCTION;

  /* New paragraph with associated handle */
  e = paragraph_new(par, *div);
  errorcheck;
  e = mkhandle(&hpar, PG_TYPE_PARAGRAPH, -1, *par);
  errorcheck;
  (*par)->background = background;

  /* build the initial groplist-
   * one incremental paragraph divnode, one normal one.
   * The size and theme related params will be filled in later.
   */
  gropctxt_init(&c,(*div)->div);
  addgrop(&c,PG_GROP_SETCOLOR);
  addgrop(&c,PG_GROP_PARAGRAPH);
  c.current->param[0] = hpar;
  addgrop(&c,PG_GROP_PARAGRAPH_INC);
  c.current->param[0] = hpar;
  c.current->flags |= PG_GROPF_INCREMENTAL;

  /* Relink the portion of the paragraph and divnode lists after this node */
  (*par)->next = old_par;
  (*div)->next = old_div;

  return success;
}
예제 #5
0
파일: cursor.c 프로젝트: UIKit0/picogui
g_error cursor_new(struct cursor **crsr, handle *h, int owner) {
  g_error e;
  struct cursor *c;
  handle c_h;

  /* Allocate cursor */
  e = g_malloc((void**)&c, sizeof(struct cursor));
  errorcheck;
  memset(c,0,sizeof(struct cursor));

  /* Default at the screen center */
  cursor_getposition(NULL,&c->x, &c->y,NULL);

  /* Add to list */
  c->next = cursor_list;
  cursor_list = c;

  /* Allocate the sprite */
  e = cursor_set_theme(c, PGTH_O_DEFAULT);
  errorcheck;

  /* Give the cursor a handle. We always use pointers to
   * reference cursors internal to pgserver, but when passing
   * events to and from a client we must refer to the cursor
   * using only this handle.
   */
  e = mkhandle(&c_h, PG_TYPE_CURSOR, owner, c);
  errorcheck;

  if (crsr)
    *crsr = c;
  if (h)
    *h = c_h;

  return success;
}
예제 #6
0
/* Set the video mode using the current driver. This is the implementation
 * of the setmode client request */
g_error video_setmode(u16 xres,u16 yres,u16 bpp,u16 flagmode,u32 flags) {
   g_error e;
   struct divtree *tree;
   struct sprite *spr;
   u8 converting_mode,oldbpp;

   /* Must be done first */
   if (vidwrap->exitmode) {
      e = VID(exitmode)();
      errorcheck;
   }
   
   /* Default values, combine flags */
   if (!xres) xres = vid->xres;
   if (!yres) yres = vid->yres;
   if (!bpp)  bpp  = vid->bpp;
   switch (flagmode) {
    case PG_FM_ON:
      flags |= vid->flags;
      break;      
    case PG_FM_OFF:
      flags = vid->flags & (~flags);
      break;
    case PG_FM_TOGGLE:
      flags ^= vid->flags;
      break;
   }
   vid->flags = flags;

   /* If the new bpp is different, use modeconvert/modeunconvert */
   oldbpp = vid->bpp;
   converting_mode = (bpp != vid->bpp);
   if (converting_mode) {
      e = bitmap_iterate((handle_iterator)vid->bitmap_modeunconvert, NULL);
      errorcheck;
      e = handle_iterate(PG_TYPE_PALETTE,(handle_iterator)array_hwrtopg, NULL);
      errorcheck;
   }
      
   /* Might want to tell the driver! */
   e = (*vid->setmode) (xres,yres,bpp,flags);
   errorcheck;

   /* By default logical coordinates are also physical */
   vid->lxres = vid->xres;
   vid->lyres = vid->yres;
   
   /* Synchronize vid->display info automatically if we're using stdbitmap */
   if (vid->display && vid->bitmap_getsize==def_bitmap_getsize) {
     if (((struct stdbitmap *)vid->display)->rend)
       g_free(((struct stdbitmap *)vid->display)->rend);
     ((struct stdbitmap *)vid->display)->freebits = 0;
     ((struct stdbitmap *)vid->display)->w = vid->xres;
     ((struct stdbitmap *)vid->display)->h = vid->yres;
     ((struct stdbitmap *)vid->display)->bpp = vid->bpp;
   }
      
   /* Reset wrapper library (before using VID macro) */
   vidwrap_static = vidlib_static;
   vidwrap = &vidwrap_static;
   
   {
     /* Generate text colors table */

     u32 *tc;
     int i;

     /* Default VGA 16-color palette, copied from the Linux console */
     static const u32 default_palette[] = {
       0x000000, 0xaa0000, 0x00aa00, 0xaaaa00, 0x0000aa, 0xaa00aa, 0x00aaaa, 0xaaaaaa,
       0x555555, 0xff5555, 0x55ff55, 0xffff55, 0x5555ff, 0xff55ff, 0x55ffff, 0xffffff,
     };

     /* Allocate space for textcolors if we haven't already */
     if (!res[PGRES_DEFAULT_TEXTCOLORS]) {
       u32 *ptr;
       e = g_malloc((void**)&ptr,sizeof(u32)*17);
       errorcheck;
       ptr[0] = 16;
       e = mkhandle(&res[PGRES_DEFAULT_TEXTCOLORS],PG_TYPE_PALETTE,-1,(void*)ptr);
       errorcheck;
     }

     e = rdhandle((void **) &tc, PG_TYPE_PALETTE, -1, res[PGRES_DEFAULT_TEXTCOLORS]);
     errorcheck;
      
     /* Transcribe our static palette */
     memcpy(tc+1, default_palette, sizeof(default_palette));
     
     /* If we won't be doing it anyway later, go ahead and convert these to hwrcolors */
     if (!converting_mode) {
       e = array_pgtohwr(&tc);
       errorcheck;
     }
   }
     
   /* Add wrapper libraries if necessary. At compile-time, support adding
    * 90, 180, or 270 degrees as a hardware rotation
    */

#ifdef CONFIG_ROTATIONBASE_90                  /***** 90 degree default */
#ifdef CONFIG_ROTATE180
   if (vid->flags & PG_VID_ROTATE90) {
      vidwrap_rotate180(vidwrap);
      vid->lxres = vid->xres;
      vid->lyres = vid->yres;
   }
#endif   
#ifdef CONFIG_ROTATE270
   if (vid->flags & PG_VID_ROTATE180) {
      vidwrap_rotate270(vidwrap);
      vid->lxres = vid->yres;
      vid->lyres = vid->xres;
   }
#endif   
#ifdef CONFIG_ROTATE
   if (!(vid->flags & PG_VID_ROTATEMASK)) {
      vidwrap_rotate90(vidwrap);
      vid->lxres = vid->yres;
      vid->lyres = vid->xres;
   }
#endif
#else
#ifdef CONFIG_ROTATIONBASE_180                  /***** 180 degree default */
#ifdef CONFIG_ROTATE
   if (vid->flags & PG_VID_ROTATE270) {
      vidwrap_rotate90(vidwrap);
      vid->lxres = vid->yres;
      vid->lyres = vid->xres;
   }
#endif   
#ifdef CONFIG_ROTATE270
   if (vid->flags & PG_VID_ROTATE90) {
      vidwrap_rotate270(vidwrap);
      vid->lxres = vid->yres;
      vid->lyres = vid->xres;
   }
#endif   
#ifdef CONFIG_ROTATE180
   if (!(vid->flags & PG_VID_ROTATEMASK)) {
      vidwrap_rotate180(vidwrap);
      vid->lxres = vid->xres;
      vid->lyres = vid->yres;
   }
#endif
#else
#ifdef CONFIG_ROTATIONBASE_270                  /***** 270 degree default */
#ifdef CONFIG_ROTATE
   if (vid->flags & PG_VID_ROTATE180) {
      vidwrap_rotate90(vidwrap);
      vid->lxres = vid->yres;
      vid->lyres = vid->xres;
   }
#endif   
#ifdef CONFIG_ROTATE180
   if (vid->flags & PG_VID_ROTATE270) {
      vidwrap_rotate180(vidwrap);
      vid->lxres = vid->xres;
      vid->lyres = vid->yres;
   }
#endif   
#ifdef CONFIG_ROTATE270
   if (!(vid->flags & PG_VID_ROTATEMASK)) {
      vidwrap_rotate270(vidwrap);
      vid->lxres = vid->yres;
      vid->lyres = vid->xres;
   }
#endif
#else                                           /***** 0 degree default */
#ifdef CONFIG_ROTATE
   if (vid->flags & PG_VID_ROTATE90) {
      vidwrap_rotate90(vidwrap);
      vid->lxres = vid->yres;
      vid->lyres = vid->xres;
   }
#endif   
#ifdef CONFIG_ROTATE180
   if (vid->flags & PG_VID_ROTATE180) {
      vidwrap_rotate180(vidwrap);
      vid->lxres = vid->xres;
      vid->lyres = vid->yres;
   }
#endif   
#ifdef CONFIG_ROTATE270
   if (vid->flags & PG_VID_ROTATE270) {
      vidwrap_rotate270(vidwrap);
      vid->lxres = vid->yres;
      vid->lyres = vid->xres;
   }
#endif   
#endif
#endif
#endif

   /* Should we ignore the base screen rotation for keyboard events? */
#ifdef CONFIG_ROTATIONBASE_NOKEYS
   vidwrap->coord_keyrotate = &def_coord_keyrotate;
#ifdef CONFIG_ROTATE
   if (vid->flags & PG_VID_ROTATE90)
     vidwrap->coord_keyrotate = &rotate90_coord_keyrotate;
#endif   
#ifdef CONFIG_ROTATE180
   if (vid->flags & PG_VID_ROTATE180)
     vidwrap->coord_keyrotate = &rotate180_coord_keyrotate;
#endif   
#ifdef CONFIG_ROTATE270
   if (vid->flags & PG_VID_ROTATE270)
     vidwrap->coord_keyrotate = &rotate270_coord_keyrotate;
#endif
#endif /* CONFIG_ROTATIONBASE_NOKEYS */

   /* Ignore the base screen rotation for pointing events? */
#ifdef CONFIG_ROTATIONBASE_NOPOINTING
   vidwrap->coord_physicalize = &def_coord_logicalize;
   vidwrap->coord_logicalize = &def_coord_logicalize;
#ifdef CONFIG_ROTATE
   if (vid->flags & PG_VID_ROTATE90) {
     vidwrap->coord_physicalize = &rotate90_coord_physicalize;
     vidwrap->coord_logicalize = &rotate90_coord_logicalize;
   }
#endif   
#ifdef CONFIG_ROTATE180
   if (vid->flags & PG_VID_ROTATE180) {
     vidwrap->coord_physicalize = &rotate180_coord_logicalize;
     vidwrap->coord_logicalize = &rotate180_coord_logicalize;
   }
#endif   
#ifdef CONFIG_ROTATE270
   if (vid->flags & PG_VID_ROTATE270) {
     vidwrap->coord_physicalize = &rotate270_coord_physicalize;
     vidwrap->coord_logicalize = &rotate270_coord_logicalize;
   }
#endif
#endif /* CONFIG_ROTATIONBASE_NOPOINTING */

   /* Since changing video modes pretty much obliterates all onscreen
    * sprites, and the previous location might be offscreen now,
    * reset the backbuffer on all sprites */
   for (spr=spritelist;spr;spr=spr->next)
     spr->onscreen = 0;
   
   /* Resize the root divnodes of all divtrees in the dtstack */
   if (dts)   /* (if this is in early init, dtstack isn't here yet) */
     for (tree=dts->top;tree;tree=tree->next) {
	tree->head->r.w = vid->lxres;
	tree->head->r.h = vid->lyres;
	tree->head->calc.w = vid->lxres;
	tree->head->calc.h = vid->lyres;
	tree->head->flags |= DIVNODE_NEED_RECALC | DIVNODE_FORCE_CHILD_RECALC | DIVNODE_NEED_REBUILD;
	tree->flags |= DIVTREE_NEED_RECALC | DIVTREE_ALL_REDRAW | DIVTREE_CLIP_POPUP;
     }

   /* Convert to the new color depth if necessary */
   if (converting_mode) {
      e = bitmap_iterate((handle_iterator)vid->bitmap_modeconvert, NULL);
      errorcheck;
      e = handle_iterate(PG_TYPE_PALETTE,(handle_iterator)array_pgtohwr, NULL);
      errorcheck;
   }
   
   /* Done swtiching the mode, give the driver a shot at changing
    * things around */
   e = VID(entermode)();
   errorcheck;
   
   /* Reload things when increasing color depth */
   if (oldbpp < bpp) {
    
      /* Reload any themes the server is responsible for */
      e = reload_initial_themes();
      errorcheck;
      
      /* FIXME: notify all clients that they can reload here */    
   }
  
   return success;
}