
#ifndef thread_h_INCLUDED
#define thread_h_INCLUDED

#include <X11/Xlib.h>
#include "squid.h"

#define SQUID_STACK_SIZE 50
#define MAXARGS 20

enum o_type {
  o_window,
  o_bitmap,
  o_mouse,
};

typedef struct object {
  enum o_type type;
  int x, y;
  int newx, newy;
  int width, height;
  int newwidth, newheight;
  Bitmap bitmap;			/* For objects that are bitmaps */
  Bitmap newbitmap;
  Window win;				/* For objects that are windows */
  Window newwin;
  GC gc;
  int refcnt;				/* How many threads know about me? */
  int oid;
  int dirty;				/* Already in the dirty list? */
  int loc_known;			/* For mice and windows--- how confident are we we know where this is? */
  struct object *next_dirty;		/* link to next object in dirty list */
  struct object *next, *prev;		/* Doubly linked list of all objects */
} *Object;

enum b_type {
  b_unknown,
  b_void,
  b_integer,
  b_bitmap,				/* Produced by "bitmap" */
  b_sequence,				/* Produced by "sequence" */
  b_object,				/* Produced by "create" */
  b_thread,				/* Produced by "call" */
  b_zombie,				/* Zombie thread to hold exitted thread's code */
  b_window,
  b_cfunc,
  b_string,
};
    
typedef struct binding {
  enum b_type type;
  char *name;
  long value;
  struct binding *next;
} *Binding;

typedef struct thread {
  Squid sequence;			/* sequence that this thread is running (or NULL for main thread) */
  Squid statement;			/* next statement to be executed */
  Squid stack[SQUID_STACK_SIZE];
  int stack_pointer;
  Object object;
  Binding bindings;
  struct thread *parent;
  struct thread *children;
  struct thread *prev;			/* Doubly linked list of sibling threads */
  struct thread *next;			/* (for easy deletion) */
  int parent_waiting;			/* True if my parent is waiting for me */
  int ticks_left;			/* How many ticks before I can go on? */
  Squid waiting;			/* If waiting for a child, points to wait statement */
  long ret_val;				/* Return value for my parent */
  enum b_type ret_type;			/* Type of return value */
  int tid;
} *Thread;

typedef struct zombie {
  long ret_val;
  enum b_type ret_type;
} *Zombie;

typedef struct arglist {
  int nargs;
  long values[MAXARGS];
  enum b_type types[MAXARGS];
} *Arglist;

typedef struct cfunc {
  char *name;
  long (*func)();
} *Cfunc;

#endif
