Exemple #1
0
/*
  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);
  }
}
Exemple #2
0
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;
}
Exemple #3
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;
}
Exemple #4
0
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;
}
Exemple #5
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;
}
Exemple #6
0
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, &param->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);
}
Exemple #7
0
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;
}
Exemple #8
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;
}
Exemple #9
0
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;
}
Exemple #10
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;
}
Exemple #11
0
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);
  }
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
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));
}
Exemple #15
0
int hunprotect(handle_t h) {
  if (!hlookup(h)) return -EBADF;
  htab[h] &= ~HPROTECT;
  return 0;
}
Exemple #16
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 */
  }