/* 
 * Thomas Pantzer: graphix.cc, v0.1b  23.9.97 22:29 
 * 
 * 
 * Copyright 1997 by Thomas Pantzer
 * 
 * Permission to use, copy, modify, and distribute this software for noncommercial 
 * use and without fee is hereby granted, provided that the above copyright notice 
 * appear in all copies and that both that copyright notice and this permission 
 * notice appear in supporting documentation, and that the name of the Author not be 
 * used in advertising or publicity pertaining to distribution of the software 
 * without specific, written prior permission. The Author makes no representations about
 * the suitability of this software for any purpose.  It is provided "as is" 
 * without expressed or implied warranty. 
 * 
 * 
 * pantec@aix520.informatik.uni-leipzig.de   (Thomas Pantzer) 
 * 
 */




#include "X11/xpm.h"
#include "graphix.h"
#include "forms.h"
#include "xfbgi.h"
#include "utils.h"


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

char XFonts[10][256] = {
        "vga",                                          /* default Font, 8x16, IBM charset */
        "-*-lucida-medium-r-*-*-10-*-75-*-*-*-iso8859-1",
/*	"-adobe-courier-bold-r-normal-*-14-*",      	   Small font */
        "-adobe-times-bold-r-normal-*-36-*",      	/* Triplex font */
        "-adobe-helvetica-medium-r-normal-*-24-*",      /* Sansserif font */
        "vga",                                 /* Gothic font,

                       give me a hint where to find a
                        Hershey or german gothic  X11 font */
                        
        // add custom fonts here

        "9x15",				       /* should be Script font */

        "10x20",
        "-adobe-courier-bold-o-normal-*-18-*",	      	
        "-adobe-times-medium-i-normal-*-25-*",
        "-misc-fixed-bold-r-normal-*-15-*"              /* other default Font */
};



#include "copyright.h"

// 8 Bit Display Support
typedef struct { int mode; char *name; } Gmode;                                 
               
#define VN(a) {a,#a}                                                            
               
static Gmode gmode[] =                                                          
{                                                                               
  VN(StaticGray), VN(GrayScale), VN(StaticColor),                               
  VN(PseudoColor), VN(TrueColor), VN(DirectColor),                              
};                                                                              



void t_screen::SetTextStyle(int font)
{
	if ((XFont_Info != NULL) && (dpy != NULL))
	   {
            XFreeFont(dpy,XFont_Info);
            XFont_Info = NULL; 
	   }

        if ((XFont_Info = XLoadQueryFont(dpy, XFonts[font])) == NULL) 
           {
#ifdef DEBUG
            fprintf(stdout, "Error opening font %d [%s]\n", 
                               font,XFonts[font]);
#endif                               
	    XFont_Info = NULL;
            return; 
           }

        XSetFont(dpy, gc, XFont_Info->fid);

}

int t_screen::GetWriteMode(void)
{
      XGCValues values;
      XGetGCValues(dpy, gc, GCFunction, &values);
  
      switch (values.function)
	{
	 case GXxor:
	   return XORPut;
	   
	 case GXor:
	   return OrPut;
	 
	 case GXand:
	   return AndPut;
	   
	 case GXcopyInverted:
	   return NotPut;  
	   
	 default:  
	 case GXcopy:  
	   return CopyPut;
	}
	
     return CopyPut;   
}

void t_screen::SetWriteMode(int mode)
{
	XGCValues values;

	switch (mode) {
		case CopyPut:
			values.function = GXcopy;
			break;
		case XORPut:
			values.function = GXxor;
			break;
		case OrPut:
			values.function = GXor;
			break;
		case AndPut:
			values.function = GXand;
			break;
		case NotPut:
			values.function = GXcopyInverted;
			break;
		default:
			return;
	}
	XChangeGC(dpy, gc, GCFunction, &values);
}


FL_OBJECT *t_screen::Init(int *argc, char *argv[])
{
	return Init(argc,argv,4,"ppxf_gc");
}


void t_screen::Done(void)
{
	rle_done();
}

FL_OBJECT *t_screen::Init(int *argc, char *argv[],int vis, char *name)
{
   fl_initialize(argc, argv, 0, 0, 0);
//   fd_xfbgi = create_form_xfbgi();

   /* fill-in form initialization code */
   Init(vis);
   
   /* show the first form */
   Show(name);

//   fl_set_object_dblbuffer(fd_xfbgi->canvas,true);
   fl_add_canvas_handler(fd_xfbgi->canvas, Expose, xfgc_canvas_expose, fd_xfbgi);

   fl_add_canvas_handler(fd_xfbgi->canvas, ButtonPress, xfgc_canvas_event, fd_xfbgi);
   fl_add_canvas_handler(fd_xfbgi->canvas, ButtonRelease, xfgc_canvas_event, fd_xfbgi);
   fl_add_canvas_handler(fd_xfbgi->canvas, KeyPress, xfgc_canvas_event, fd_xfbgi);
   fl_add_canvas_handler(fd_xfbgi->canvas, KeyRelease, xfgc_canvas_event, fd_xfbgi);
   // clear screen
   
//   fl_do_forms();
//   return 0;
//   MakeColormap(fd_xfbgi->canvas); 
   
   return fd_xfbgi->canvas;
}


void t_screen::Init(FL_OBJECT *canvas)
{
	colormap_canvas = canvas;
//	MakeColormap(canvas);
}

// pre-handler,  call before fl_show_form(...
void t_screen::Init(int _vis)
{
    char *host; 
/* create connection to display */                                              
        if ((host = getenv("DISPLAY")) == NULL) {                               
                fprintf(stderr, "Cannot open display \n");                      
                exit(-1);                                                       
        }                                                                       
                       
/* open connection to display */                                                
        if ((dpy = XOpenDisplay(host)) == NULL) {                         
             
                fprintf(stderr, "Cannot connect to X server \n");               
                exit(-1);                                                       
        }        

   visual = DefaultVisual(dpy,DefaultScreen(dpy));
   depth = fl_get_visual_depth(); 

//	fprintf(stderr,"visual: %d\tdepth:%d\n",visual->id,depth);
//   depth = 8;
  
   switch (depth)
      {
       case 24:
       case 16:
         break;
       
       case 8:  
         fl_set_graphics_mode (gmode[_vis].mode, 0);     
                             // truecolor, doublebuffer
                             
         // this is a quick and dirty hack
         // use gmode[1] and allocate a 9x5x5 color cube
         //               or better a 10x6x4 color cube                    
//	 MakeColormap(canvas);
         break;
        
       default:
         fprintf(stderr,"visual depth %d not supported\n",depth);
         break;  
      } 

   fd_xfbgi = create_form_xfbgi();

#ifdef DEBUG
   fprintf(stderr,"form x:%d, y:%d, w:%d, h:%d\n",
                fd_xfbgi->xfbgi->x,fd_xfbgi->xfbgi->y,
                fd_xfbgi->xfbgi->w,fd_xfbgi->xfbgi->h);

   fprintf(stderr,"canvas x:%d, y:%d, w:%d, h:%d\n",
                fd_xfbgi->canvas->x,fd_xfbgi->canvas->y,
                fd_xfbgi->canvas->w,fd_xfbgi->canvas->h);
#endif

   page = 0;
   win = 0;
   backpix = 0;
//   inhibit = 5;	
   backplane = true;
   ignore_expose = false;	
   gc = NULL;
   resize = true;
   XFont_Info = NULL;
   colormap_canvas = NULL;	

	fprintf(stderr,"init rle graphix\n");
	rle_init();
}


// int min(int a, int b)
// {
// 	if (a < b)
// 		return a;
// 
// 	return b;
// }			
// 
// int max(int a, int b)
// {
// 	if (a > b)
// 		return a;
// 
// 	return b;
// }			

void t_screen::Refresh(void)
{

	if (fd_xfbgi->canvas->visible == false)
	   return;	

#ifdef DEBUG
   fprintf(stderr,"refresh dpy:0x%lx, bp:0x%lx, win:0x%lx, gc:0x%lx\n",
			(long int)dpy,backpix,win,(long int)gc);
#endif

   if ((backplane == true) && (backpix != 0))
       XCopyArea(dpy,backpix,win,gc,0,0,width,height,0,0);
//    else
//       Fill(FL_BLACK);   

//   XSync(dpy,false);
   XFlush(dpy);  
}


void t_screen::Store(void)
{
	if (fd_xfbgi->canvas->visible == false)
	   return;	


	if ((backplane == true) && (backpix != 0))
	   {
#ifdef DEBUG      
	    fprintf(stderr,"t_screen::Store() %dx%d\n",__min(width,bck_w),__min(height,bck_h));
#endif
	    XCopyArea(dpy,win,backpix,gc,0,0,__min(width,bck_w),__min(height,bck_h),0,0);
	   } 

//	XSync(dpy,false);
	XFlush(dpy);  
}



void t_screen::SetPage(int i)
{
   if (backplane == true)
      {
       page = (i%2);

       if (page == 0)
          Refresh();
      }
    else 
      {
       page = 0;  
       XFlush(dpy);
      } 
}

void t_screen::BackingStore(char b)
{
     if (backplane == b)
      	return;
      	
/*
     if (backplane == true)
        { 	 
         if (backpix != 0)
            XFreePixmap(dpy,backpix);
        }
*/
     
     // if someone switches backing store on 
     // after a former initialisation to false
     if ((b == true) && (backpix == 0))
	{ 
  	 backpix = XCreatePixmap(dpy,win,width,height,depth);
	 bck_w = width;
	 bck_h = height;
                       /*fl_state[fl_vmode].depth*/
#ifdef DEBUG
	 fprintf(stderr,"XCreatePixmap\n");
#endif
        }
     
     backplane = b;   
}


int get_color_component(unsigned int P, unsigned long Mask)
{
	unsigned int r = P;
	unsigned int m = (unsigned int)Mask;

	r &= m;

	int k = 0;
	while ((m & 0xffffff00) > 0) 
	  { 
	   r >>= 1;  
	   m >>= 1; 	
	   k++;
		
	   if (k > 32)
	      {	
	       fprintf(stderr,"down r:0x%04x, m:0x%04x\n",r,m);	
	       return 0;	 	
	      } 	
	  }    			

	int n = 0;
	while ((m & 0x80) == 0) 
	  { 
	   r <<= 1;  
	   m <<= 1; 

	   if (n > 8)
	      {	
	       fprintf(stderr,"up r:0x%04x, m:0x%04x\tk: %d P:0x%04x M:0x%04lx\n",r,m,k,P,Mask);	
	       return 0;	 	
	      } 	

	   n++;	
	  }    			

	return (int)r;
}


void t_screen::Save(char *st)
{
     XImage *xi;
//     Pixmap pix;
	 char filename[256];
	int fd;
   
//   if (backplane == true)
//      pix = backpix;
//    else
//      pix = win;

   switch (depth)
     { 
      case 8:
//	fprintf(stderr,"XpmWriteFromPixmap:\n"); 
//	if (XpmWriteFileFromPixmap(fl_get_display(),filename,backpix,0,NULL) 
//        	   != XpmSuccess)
//	   {
//	    fprintf(stderr,"write to [%s] failed\n",filename);
//	   } 
	{
	 MakeColormap(colormap_canvas);
	 sprintf(filename,"%s.rle",st);   

	 fd = open(filename,O_RDWR|O_CREAT|O_TRUNC,0644);
	 if (fd < 1)	
	    return;

//	 rle_init();	
         rle_save_header(fd,bck_w,bck_h,MapColor); 
  	 xi = XGetImage(dpy,backpix,0,0,bck_w,bck_h,AllPlanes,ZPixmap);
         
         if (xi == NULL)
	    {
 	     close(fd);
	     return;
	    }	

         for (int i=0; i<bck_h; i++)
           for (int j=0; j<bck_w; j++)    
	      rle_save_pixel(fd,xi->data[j+(i*bck_w)]);

	 rle_sync(fd);

//	 rle_done();
//         close(fd);

         if (xi != NULL)
	    XDestroyImage(xi);  
	}

        break;

//	XPM_Save
//       case 16:
// // #ifdef DEBUG
// 	fprintf(stderr,"XpmWriteFromPixmap:\n"); 
// //#endif
// 	sprintf(filename,"%s.xpm",st);   
// 	if (XpmWriteFileFromPixmap(fl_get_display(),filename,backpix,0,NULL) 
//         	   != XpmSuccess)
// 	   {
// 	    fprintf(stderr,"write to [%s] failed\n",filename);
// 	   } 
// 	break;



//	RLE_Save
//    case 8: && visual == truecolor
      case 16: 	
      case 24:
	{
	 sprintf(filename,"%s.rle",st);   
	 fd = open(filename,O_RDWR|O_CREAT|O_TRUNC,0644);
	 if (fd < 1)	
	    return;

         rle_save_header(fd,bck_w,bck_h,NULL); 
  	 xi = XGetImage(dpy,backpix,0,0,bck_w,bck_h,AllPlanes,ZPixmap);
         
         if (xi == NULL)
	    {
 	     close(fd);
	     fprintf(stderr,"can't get XImage\n");	
	     return;
	    }	

	 long k = 0;
	 int bstep = xi->bits_per_pixel/8;


	if (xi->red_mask == xi->green_mask)
	   {
	    fprintf(stderr,"curious bitmasks: 0x%04lx,0x%04lx,0x%04lx\b",xi->red_mask,xi->green_mask,xi->blue_mask);

	    switch (depth)
	      {
#ifdef SunOS
	       case 8:   /* 8 bit color cube 9x5x5 */                                                     
	         xi->red_mask   = 0x07;                                                               
	         xi->green_mask = 0x38;                                                               
	         xi->blue_mask  = 0xc0;                                                             
	         break;                                                                                  

	       case 16:   /* 16 bit Display */                                                            
	         xi->red_mask   = 0x001f;                                                             
	         xi->green_mask = 0x07e0;                                                             
	         xi->blue_mask  = 0xf800;                                                             
	         break;                                                                                  

	       case 24:
		 xi->red_mask = 0xff;	 
		 xi->green_mask = 0xff00;	 
		 xi->blue_mask = 0xff0000;	 
		 break;
#else
#ifdef Linux
	       case 8:   /* 8 bit color cube 9x5x5 */                                                     
	         xi->red_mask   = 0xc0;                                                               
	         xi->green_mask = 0x38;                                                               
	         xi->blue_mask  = 0x07;                                                             
	         break;                                                                                  

	       case 16:   /* 16 bit Display */                                                            
	         xi->red_mask   = 0xf800;                                                             
	         xi->green_mask = 0x07e0;                                                             
	         xi->blue_mask  = 0x001f;                                                             
	         break;                                                                                  
                                                                                                
	       case 24:   /* 24 bit Display */                                                            
	         xi->red_mask   = 0xff0000;                                                           
	         xi->green_mask = 0x00ff00;                                                           
	         xi->blue_mask  = 0x0000ff;                                                           
	         break;                                                                                  
#else
	#ifdef DEBUG
	    #warning fix the bitmak fields for visual	
	    #error
	#endif
#endif
#endif
	       default:
		 fprintf(stderr,"save with visual depth %d not supported\n",depth);
		 break;	
	      }
	   } 

         for (int i=0; i<bck_h; i++)
           {
	    for (int j=0; j<bck_w; j++)
              {
	       t_color tc;

	       unsigned int *P = (unsigned int *)&(xi->data[((j+(i*bck_w))*bstep)+0]);		

	       tc.r = get_color_component(*P,xi->red_mask);
	       tc.g = get_color_component(*P,xi->green_mask);
	       tc.b = get_color_component(*P,xi->blue_mask);
	
	       rle_save_3dpixel(fd,&tc);			
	       k++;	 
              }
           } 

	 fprintf(stderr,"%ld pixel written\n",k);
	 rle_sync(fd);

         if (xi != NULL)
	    XDestroyImage(xi);  
	}
	break;

// 	PPM_Save
// 	xi = XGetImage(dpy,backpix,0,0,bck_w,bck_h,AllPlanes,ZPixmap);
// 	sprintf(filename,"%s.ppm",st);   
// 	fd = open(filename,O_RDWR|O_CREAT|O_TRUNC,0644); 
// 	if (fd > 0)
// 	   {
// 	    char st[256];
// 	    sprintf(st,"P6\n%d %d\n255\n",bck_w,bck_h);
// 	    write(fd,st,strlen(st));
// 
//             for (int i=0; i<bck_h; i++)
//               {
//                char line[1024*3];
// 	       for (int j=0; j<bck_w; j++)
//                  {
//                   for (int k=0; k<3; k++)
//                      line[(j*3)+k] = xi->data[((j+(i*bck_w))*4)+k];
//                  }
//                write(fd,line,bck_w*3);
//               } 
// 	    close(fd);
// 	   }	
// 
//         if (xi != NULL)
// 	   XDestroyImage(xi);  
//         break;

      default:	
	fprintf(stderr,"save not implemented for color depth %d\n",depth);
	break;
     } // end switch(bpp) 
//
//   if (XpmWriteFileFromImage(fl_get_display(),filename,xi,0,NULL) !=
//     
}


void t_screen::Init(Display *d, GC g)
{
   dpy = d;
   gc = g;
   win = 0;
   resize = false;
   ignore_expose = false;	
}


// void t_screen::PutImage(XImage *image, int sx, int sy, int dx, int dy, unsigned int width, unsigned int height)
// {
// 	Window tw1,tw2;
// 	
// 	tw1 = fl_get_canvas_id(fd_xfbgi->canvas);
// 	tw2 = fl_get_real_object_window(fd_xfbgi->canvas);
// 	
// 	fprintf(stderr,"t_screen::PutImage(w:0x%lx/0x%lx/0x%lx\tdest:%dx%d\tw:%d,h:%d)\n",
// 				win,tw1,tw2,dx,dy,width,height);
// 
// //	if (win != fl_get_canvas_id(fd_xfbgi->canvas))
// //	   win = fl_get_canvas_id(fd_xfbgi->canvas);
// //	   Init(fl_get_canvas_id(fd_xfbgi->canvas),width,height);	
// //  XFlush(VScr.dpy);
// 
// 		
//  	XPutImage(dpy,win,gc,image,sx,sy,dx,dy,width,height);
// 
// 	if ((backplane == true) && (backpix != 0))
// 	   {
// 	    fprintf(stderr,"t_screen::PutImage(w:0x%lx\tdest:%dx%d\tw:%d,h:%d)\n",backpix,dx,dy,width,height);
// 
// 
// 	    XPutImage(dpy,backpix,gc,image,sx,sy,dx,dy,width,height);
// //  XFlush(VScr.dpy);
// 	   } 
// }



typedef struct {
		int A;
		int B;
		int C;	
		int D;
		int E;	
	       } t_guess_pixmap;

void t_screen::Init(Window w, int x, int y)
{
  if (win == w)
     return;

  if (w == 0)
     return;

#ifdef DEBUG
  fprintf(stderr,"t_screen::Init(w:0x%lx->0x%lx\tx:%d->%d\ty:%d->%d)\n",win,w,width,x,height,y);
#endif

//	Store();

  win = w;
  width = x;
  height = y;
  page = 0;
  LineWidth = 1;
  XFont_Info = NULL;
  sync_often = false;
  
  if (width < height)
     size = width;
   else
     size = height;  
     
  center.x = width/2;
  center.y = height/2;
  Cursor.x = center.x;
  Cursor.y = center.y;

  if (gc != NULL)
     XFreeGC(dpy,gc);
     
  gc = XCreateGC(dpy,win,0,0); 

  Pixmap newpix = 0;
     
  if (backplane == true)
     {
      newpix = XCreatePixmap(dpy,win,width,height,depth);
                                /*fl_state[fl_vmode].depth*/
     }
	
  if ((backpix != 0) && (newpix != 0))
     {
      XCopyArea(dpy,backpix,newpix,gc,0,0,width,height,0,0);
      XFreePixmap(dpy,backpix);
     } 

  if (backplane == true)
     {
      backpix = newpix;
      bck_w = width;
      bck_h = height;		
     }	

  ColorMapSize = 0;
}

void t_screen::MakeColormap(FL_OBJECT *canvas)
{
  if (ColorMapSize != 0)
     return;
	
  for (int i=0; i<1024; i++)
    {
     unsigned long L = fl_state[fl_vmode].lut[i];	
     if (L < 256)
        hash[L] = i;		
    }

  for (int i=0; i<256; i++)
    {
     int R,G,B;	
     fl_get_icm_color(hash[i],&R,&G,&B);
     MapColor[i].r = (unsigned char)R; 
     MapColor[i].g = (unsigned char)G; 
     MapColor[i].b = (unsigned char)B; 
    } 	

//   rle_init();     
}


void t_screen::Show(const char *t)
{
      strcpy(title,t);

#ifdef DEBUG
      fprintf(stderr,"t_screen::Show(%s,%s)\n",t,title);
#endif

      if (VScr.fd_xfbgi->canvas->visible == true)
	 return;

      Show(FL_PLACE_FREE);    
      
      Fill(FL_BLACK);	 
}



void t_screen::Show(int where)
{
      fl_set_graphics_mode (gmode[4].mode, 0);     

      fl_show_form(VScr.fd_xfbgi->xfbgi,where,FL_FULLBORDER,title);
      fl_show_object(VScr.fd_xfbgi->canvas);

//    XFlush(VScr.dpy);

      Window w = fl_get_real_object_window(fd_xfbgi->canvas);
//    Window w = fl_get_canvas_id(fd_xfbgi->canvas);

      Init(w,fd_xfbgi->xfbgi->w,fd_xfbgi->xfbgi->h);

      fl_activate_form(fd_xfbgi->xfbgi);
}



void t_screen::Hide(void)
{
	if (VScr.fd_xfbgi->canvas->visible == false)
	   return;

	fl_hide_object(VScr.fd_xfbgi->canvas);
	fl_deactivate_form(VScr.fd_xfbgi->xfbgi);

	if (VScr.fd_xfbgi->xfbgi->visible == false)
	   return;

	fl_hide_form(VScr.fd_xfbgi->xfbgi);
}




int cvs_event[]= { Expose        ,	     
	           ButtonPress	 ,
	           ButtonRelease ,
	           MotionNotify  ,
	           KeyPress      ,
	           KeyRelease	 };

#define n_events (sizeof(cvs_event) / sizeof(int))

int xfgc_canvas_nop(FL_OBJECT *ob, Window _win, int w, int h, XEvent *ev, void *d)
{
	fprintf(stderr,"xfgc_canvas_NOP(0x%08lx,%d,%d)",_win,w,h);
	return 0;
}


void t_screen::Resize(int w,  int h)
{
	if (resize == false)
	   return;

	Store();
	fl_set_idle_callback(Dummy_cb,0);
       
	FL_HANDLE_CANVAS cvs_handler[6];
// 	fprintf(stderr,"n_events: %d\n",n_events);
	for (unsigned int i=0; i<n_events; i++)	
   	  cvs_handler[i] = fl_add_canvas_handler(fd_xfbgi->canvas, 
						cvs_event[i], xfgc_canvas_nop, 
						fd_xfbgi);
//	Store();
	Hide();

#ifdef DEBUG       
      fprintf(stderr,"t_screen::Resize(): setting canvas to %d,%d\n",w,h);
#endif
           
        fl_set_form_geometry(fd_xfbgi->xfbgi,160,20,w,h);

// show begin
	Show(FL_PLACE_CENTER);
	
	for (unsigned int i=0; i<n_events; i++)	
	   fl_add_canvas_handler(fd_xfbgi->canvas, cvs_event[i], cvs_handler[i], fd_xfbgi);

//	fl_activate_form(fd_xfbgi->xfbgi);
//	Fill(FL_BLACK);    
	Refresh();
}






void t_screen::MoveTo(int x,int y)
{
   Cursor.x = x;
   Cursor.y = y;
}

void t_screen::LineTo(int x,int y)
{
   DrawLine(Cursor.x,Cursor.y,x,y);
   MoveTo(x,y); 
}


int t_screen::TextWidth(char *st)
{
   if (XFont_Info == NULL)
      return 1;
      
   return XTextWidth(XFont_Info,st,strlen(st));
}

int t_screen::TextHeight(char *st)
{
   return 25;  	
//   if (XFont_Info == NULL)
//      return 1;
      
//   return XTextHeight(XFont_Info,st,strlen(st));

}

void t_screen::OutText(char *st)
{
   char *s = strchr(st,'\n');
   
   if (s != NULL)
      *s = '\0';
      
   OutTextXY(Cursor.x,Cursor.y,st);

   if (s != NULL)
      MoveTo(Cursor.x,Cursor.y+TextHeight(st));	
    else 
      MoveTo(Cursor.x+TextWidth(st),Cursor.y);	
}

void t_screen::Fill(int color)
{
   SetColor(color);
   FillRectangle(0,0,width,height);
}

/*   

int t_screen::LineWidth(int w)
{
   if (w != 0)
      linewidth = w;
      
   return linewidth;	
}
*/

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   
// low level drawing
//_____________________________________________________________
/*   
void t_screen::DrawLine(int x1,int y1,int x2,int y2)  
{
   if (page == 0)
      XDrawLine(dpy,win,gc,x1,y1,x2,y2);

   if ((backplane == true) && (backpix != 0))
      XDrawLine(dpy,backpix,gc,x1,y1,x2,y2);
}
*

#define DrawLine(x1,y1,x2,y2) \
            {\
             if (VScr.page == 0) \
              	 XDrawLine(VScr.dpy,VScr-win,VScr.gc,x1,y1,x2,y2); \
             \
             if ((VScr.backplane == true) && (VScr.backpix != 0)) \
                XDrawLine(VScr.dpy,VScr.backpix,VScr.gc,x1,y1,x2,y2);\
            }
 */
  
void t_screen::DrawLine(int x1,int y1,int x2,int y2)
{
   if (LineWidth > 1)
      {
       for (int i=0; i<LineWidth; i++)
        for (int j=0; j<LineWidth; j++)
         for (int k=0; k<LineWidth; k++)
          for (int l=0; l<LineWidth; l++)
	   drawline(x1+i,y1+j,x2+k,y2+l); 
      }
    else
      drawline(x1,y1,x2,y2);	
}
 
              


/* callbacks for form xfbgi */
void canvas_cb(FL_OBJECT *ob, long data)
{
  /* fill-in code for callback */
}

int Dummy_cb(XEvent *,void *)
{
   usleep(1);
   return 0;
}

int xfgc_canvas_expose(FL_OBJECT *ob, Window _win, int w, int h, XEvent *ev, void *d)
{
	if (VScr.ignore_expose == true)
	   return 0;	

#ifdef DEBUG    
	fprintf(stderr,"expose\n");
#endif
	VScr.Init(_win,w,h);
//    VScr.MakeColormap(ob);	
	VScr.Refresh();
    
	return 0;
}

