/*******************************************************************/
//              "Меркурий"-"Правда" - open source переводчик
//          распространяется в соответсвии с лицензией GNU v 2.0
//
//     библиотека интерфейса с текстовым терминалом (X-Window)
//     Анисимов Д.В.                               сегодня
/*******************************************************************/

# include <malloc.h>
# include <string.h>
# include <stdlib.h>
# include <locale.h>
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/Xos.h>
# include <X11/keysym.h>
# include <X11/Intrinsic.h>
# include <X11/StringDefs.h>

# include <mylib.h>
# include <s_defkey.h>
# include <video.h>
# include "slowo.xbm"

long  *Symbol ;
uchar *Color ;
short  max_x,max_y ;
short  size_x,size_y ;
int    Symbol_W,Symbol_H;      /* Ширина и высота буковки */
int    Shiftstatus ;           /* Какие нажаты спецклавиши  */
char        *FontName ;
Display     *Dis ;
int          i_Scr ;
Window       Win ;
Colormap     Colormap1 ;
XColor       xColor[16] ;
XFontStruct *FontInfo ;

// -------------------- графический контекст -------------------------------

class t_GC
{
public :
   GC     GC1 ;

	  t_GC( Window Win );
	  t_GC( Window Win, ulong Color1, ulong Color2 );
	 ~t_GC( void );
   void   SetForeground( ulong Color );
   void   SetBackground( ulong Color );
   void   DrawImageString( short x, short y, char *Text );
};

class t_Save_Screen
{  long   *stek ;   // запоминание областей экрана
   short   l_stek ; // длинна массива Stek
   short   j_stek ; // указатель последнего свободного байта
public:
   t_Save_Screen( short l );
   ~t_Save_Screen( void );
   void   save   ( short y1, short x1, short y2, short x2 );
   void   save_rame( short y1, short x1, short y2, short x2 );
   void   restore( void );
} ;

short       Cur_X=0,Cur_Y=0 ;
short       n_Line,n_Col ;
static char    TextFont[100]="" ;
t_Save_Screen  Save( 10000 ) ;

void s_rame( short y1, short x1, short y2, short x2, uchar f );
void s_quadro( short y1, short x1, short y2, short x2, uchar f );

/* ----------------------------------------------------------------------- */
void   s_begin_schone( int argc, char *argv[] )
{  short i,f=0,Size_X,Size_Y ;

   setlocale( LC_ALL,"" );
   max_x=256 ; max_y=100 ;
   Symbol=(long  *)Calloc( max_x*max_y,sizeof(long) );
   Color =(uchar *)Calloc( max_x*max_y,1 );
   for( i=0 ; i<max_x*max_y ; i++ )
      Symbol[i]=' ';

   size_y=n_Line=50 ;
   size_x=n_Col =100 ;
   Shiftstatus  =0 ;

   XSizeHints    SizeHints ;
   XWMHints      WMHints ;
   XClassHint    ClassHint ;
   XTextProperty WinName ;

   // --------------- открыть дисплей ---------------------------

   Dis   = XOpenDisplay(NULL) ;
   if( Dis == NULL ) { printf("Can not open Display"); exit(-1) ; }
   i_Scr = DefaultScreen(Dis) ;

   // -------------- каким шрифтом писать будем ----------------
   for( i=0 ; i<argc-1 ; i++ )
      if( 0==strcmp( argv[i], "-fn" ) )
      {  FontName=(char *)Calloc( strlen(argv[i+1])+1,sizeof(char) );
	 strcpy( FontName,argv[i+1] );
	 f=1 ;
      }
   if( f==0 && TextFont[0]!=0 )
   {   FontName=TextFont ; f=1 ;  }
   if( f==0 ) FontName="-cronyx-fixed-medium-r-semicondensed--13-120-75-75-c-60-koi8-r" ;  

   if((FontInfo = XLoadQueryFont( Dis, FontName )) == NULL)
   {  printf( "\n Error load font:%s",FontName ); exit(-1);  }
   Symbol_W = FontInfo->max_bounds.width;
   Symbol_H = FontInfo->ascent + FontInfo->descent;
   Size_X=100*Symbol_W ; Size_Y=50*Symbol_H ;
   // --------------- открыть окошко --------------------------

   Win   = XCreateSimpleWindow( Dis,RootWindow( Dis,i_Scr),
	   0,0,Size_X,Size_Y,5, BlackPixel(Dis,i_Scr), BlackPixel(Dis,i_Scr) );

   // --------------- захватить цвета --------------------------

   Colormap1 = DefaultColormap( Dis,DefaultScreen(Dis) );
   for( i=0 ; i<16 ; i++ )
   {  XColor Color1 ;
      unsigned short V ;

      if( i>=8 ) V=0x8000 ; else V=0 ;
      if( (i&0x01)!=0 ) Color1.blue  = V+0x7FFF ; else Color1.blue  = 0 ;
      if( (i&0x02)!=0 ) Color1.green = V+0x7FFF ; else Color1.green = 0 ;
      if( (i&0x04)!=0 ) Color1.red   = V+0x7FFF ; else Color1.red   = 0 ;
      if( i==7 ) Color1.red=Color1.green=Color1.blue=0xBFFF ;
      if( i==8 ) Color1.red=Color1.green=Color1.blue=0xBFFF ;
      Color1.flags = DoRed|DoGreen|DoBlue ;
      XAllocColor( Dis,Colormap1,&Color1 );
      xColor[i] =Color1 ;
   }
   // ------------ сделать иконку чтоб красиво было --------------

   Pixmap Pix1 = XCreatePixmapFromBitmapData( Dis,RootWindow( Dis,i_Scr),
		 lingvo_bits,lingvo_width,lingvo_height,1,0,1 );

   char *sSlowo="Mercury" ;
   if( !XStringListToTextProperty( &sSlowo,1,&WinName ) ) exit(1);

   // -------------- назначить атрибуты окна -----------------------

   SizeHints.flags       = 0 ;

   WMHints.flags         = StateHint | IconPixmapHint | InputHint ;
   WMHints.initial_state = NormalState ;
   WMHints.input         = True ;
   WMHints.icon_pixmap   = Pix1 ;

   ClassHint.res_name    = argv[0] ;
   ClassHint.res_class   = "Mercury" ;

   XSetWMProperties ( Dis,Win, &WinName,&WinName, argv,argc,
		      &SizeHints, &WMHints, &ClassHint );

   XSelectInput( Dis,Win,ExposureMask | KeyPressMask | KeyReleaseMask );
   XMapWindow( Dis,Win );

}
/* ----------------------------------------------------------------------- */
void   s_begin_schone( void )
{  char *argv[1] ;
   argv[0]="mercury" ;
   s_begin_schone( 1,argv );
}
/* ----------------------------------------------------------------------- */
void   s_end_schone( void )
{  ;  }
/* ----------------------------------------------------------------------- */
void   s_nacht( void )
{  long i ;

   for( i=0 ; i<max_x*max_y ; i++ )
   {  Symbol[i]=' ' ; Color[i]=0 ;  }
}
/* ----------------------------------------------------------------------- */
void   s_get_size( short *sx, short *sy )
{
/*
   short size_y1, size_x1 ;
   
   getmaxyx( Win, size_y1, size_x1 );
   if( max_x<size_x1 ) size_x1=max_x ;
   if( max_y<size_y1 ) size_y1=max_y ;
   *sx=size_x1 ; *sy=size_y1 ;
   size_x=size_x1 ; size_y=size_y1 ;
*/
   size_x=100 ; size_y=50 ;
}
/* ----------------------------------------------------------------------- */
void   s_text_yxf(  short y, short x, uchar f, char *str )
{  short i,r1 ;

   r1=max_x*y+x ;
   for( i=0 ; str[i]!=0 && str[i]!='\r' && str[i]!='\n' ; i++ )
   {  Symbol[ r1+i ]=str[i] ;
      Color [ r1+i ]=f ;
   }
}
/* ----------------------------------------------------------------------- */
void   s_text_yxf1( short y, short x, uchar f, char *str )
{  short i,r ;

   r = max_x*y+x ;
   Symbol[ r ] = '\"' ; Color[ r ] = f ;
   for( i=0 ; str[i]!=0 ; i++ )
   {  r=max_x*y+x+i+1 ;
      Symbol[ r ] = str[i] ; Color[ r ] = f ;
   }
   r=r+1 ;
   Symbol[ r ] = '\"' ; Color[ r ] = f ;
}
/* ----------------------------------------------------------------------- */
void   s_text_yxfl( short y, short x, uchar f, short L, char *str )
{  short i,r1 ;

   r1=max_x*y+x ;
   for( i=0 ; str[i]!=0 && i<L ; i++ )
   {  Symbol[ r1+i ]=str[i] ;
      Color [ r1+i ]=f ;
   }
}
/* ----------------------------------------------------------------------- */
void   s_text_yx( short y, short x, char *str )
{  short i,r1 ;

   r1=max_x*y+x ;
   for( i=0 ; str[i]!=0 ; i++ )
      Symbol[ r1+i ]=str[i] ;
}
/* ----------------------------------------------------------------------- */
void   s_color_yxt( short y, short x, uchar *t, char *str )
{  short i,r1,r2,f ;

   r1=max_x*y+x ;
   for( i=0 ; str[i]!=0 ; i++ )
   {  f=0x07 ; r2=str[i] ;
      if( '0'<=r2 && r2<= '9' ) f=t[r2-'0'] ;
      if( 'a'<=r2 && r2<= 'z' ) f=t[r2-'a'+10] ;
      Color[ r1+i ]=f ;
   }
}
/* ----------------------------------------------------------------------- */
void   s_foreground_yxt( short y, short x, uchar *t, char *str )
{  short i,r1,r2,f ;

   r1=max_x*y+x ;
   for( i=0 ; str[i]!=0 ; i++ )
   {  f=0x07 ; r2=str[i] ;
      if( '0'<=r2 && r2<= '9' ) f=t[r2-'0'] ;
      if( 'a'<=r2 && r2<= 'z' ) f=t[r2-'a'+10] ;
      Color[ r1+i ] = (0xf0 & Color[ r1+i ]) + (0x0f & f) ;
   }
}
/* ----------------------------------------------------------------------- */
void   s_rame1_f( short y1, short x1, short y2, short x2, uchar f )
{
   s_rame( y1, x1, y2, x2, f );
}
/* ----------------------------------------------------------------------- */
void   s_rame1_F( short y1, short x1, short y2, short x2, uchar f )
{
   s_quadro( y1, x1, y2, x2, f );
   s_rame  ( y1, x1, y2, x2, f );
}
/* ----------------------------------------------------------------------- */
void   s_rame2_f( short y1, short x1, short y2, short x2, uchar f )
{
   s_rame  ( y1, x1, y2, x2, f );
}
/* ----------------------------------------------------------------------- */
void   s_rame2_F( short y1, short x1, short y2, short x2, uchar f )
{
   s_quadro( y1, x1, y2, x2, f );
   s_rame  ( y1, x1, y2, x2, f );
}
/* ----------------------------------------------------------------------- */
void s_rame( short y1, short x1, short y2, short x2, uchar f )
{  short i,r ;

   for( i=x1+1 ; i<x2 ; i++ )
   {  r=max_x*y1+i ; Symbol[ r ]='-' ; Color[ r ]=f ;
      r=max_x*y2+i ; Symbol[ r ]='-' ; Color[ r ]=f ;
   }
   for( i=y1+1 ; i<y2 ; i++ )
   {  r=max_x*i+x1 ; Symbol[ r ]='|' ; Color[ r ]=f ;
      r=max_x*i+x2 ; Symbol[ r ]='|' ; Color[ r ]=f ;
   }
   r=max_x*y1+x1 ; Symbol[ r ]='+' ; Color[ r ]=f ;
   r=max_x*y2+x1 ; Symbol[ r ]='+' ; Color[ r ]=f ;
   r=max_x*y1+x2 ; Symbol[ r ]='+' ; Color[ r ]=f ;
   r=max_x*y2+x2 ; Symbol[ r ]='+' ; Color[ r ]=f ;
}
/* ----------------------------------------------------------------------- */
void s_quadro( short y1, short x1, short y2, short x2, uchar f )
{  short i,j,r1 ;

   for( j=y1+1 ; j<y2 ; j++ )
   {  for( i=x1+1 ; i<x2 ; i++ )
      {   r1=max_x*j+i ;
	  Symbol[ r1 ]=' ' ;
	  Color [ r1 ]=f ;
      }
   }
}
/* ----------------------------------------------------------------------- */
void s_save_rame( short s1, short p1, short s2, short p2 )
{  Save.save_rame( s1, p1, s2, p2 );  }

void s_save( short s1, short p1, short s2, short p2 )
{  Save.save( s1, p1, s2, p2 );  }

void s_restore( void )
{  Save.restore( );  
}
/* ----------------------------------------------------------------------- */
t_Save_Screen :: t_Save_Screen( short L )
{
   stek=(long *)Calloc( L,sizeof(long) );
   j_stek=0 ;
   l_stek=L ;

}
/* ----------------------------------------------------------------------- */
t_Save_Screen :: ~t_Save_Screen( void )
{
   if( stek!=NULL ){  free( stek ); stek=NULL ;  }
   j_stek=0 ;
   l_stek=0 ;
}
/* ----------------------------------------------------------------------- */

void t_Save_Screen :: save( short y1, short x1, short y2, short x2 )
{  short i,j,r ;

   for( i=y1 ; i<=y2 ; i++ )
   {  for( j=x1 ; j<=x2 ; j++ )
      {   r=max_x*i+j ;
	  stek[j_stek++] = Color [ r ] ; /* атрибут */
	  stek[j_stek++] = Symbol[ r ] ;   /* символ  */
      }
   }
   stek[j_stek++]=(uchar )x1 ; stek[j_stek++]=(uchar )y1 ;
   stek[j_stek++]=(uchar )x2 ; stek[j_stek++]=(uchar )y2 ;
   stek[j_stek++]=0 ;
}
/* ----------------------------------------------------------------------- */

void t_Save_Screen :: save_rame( short s1, short p1, short s2, short p2 )
{  short i,r,r1,r2 ;

   r1=max_x*s1 ; r2=max_x*s2 ;
   for( i=p1 ; i<=p2 ; i++ )
   {  r=r1+i ;
      stek[j_stek++]=Symbol[ r ] ;
      stek[j_stek++]=Color [ r ] ;
      r=r2+i ;
      stek[j_stek++]=Symbol[ r ] ;
      stek[j_stek++]=Color [ r ] ;
   }
   for( i=s1 ; i<=s2 ; i++ )
   {  r1=max_x*i+p1 ;
      stek[j_stek++]=Symbol[ r1 ] ;
      stek[j_stek++]=Color [ r1 ] ;
      r2=max_x*i+p2 ;
      stek[j_stek++]=Symbol[ r2 ] ;
      stek[j_stek++]=Color [ r2 ] ;
   }
   stek[j_stek++]=(uchar )p1 ; stek[j_stek++]=(uchar )s1 ;
   stek[j_stek++]=(uchar )p2 ; stek[j_stek++]=(uchar )s2 ;
   stek[j_stek++]=1 ;
}
/* ----------------------------------------------------------------------- */

void t_Save_Screen :: restore( void )
{  short i,j,p1,p2,s1,s2,
	 r,r1,r2 ;
   uchar c,f ;

   f =stek[--j_stek] ;
   s2=stek[--j_stek] ; p2=stek[--j_stek] ;
   s1=stek[--j_stek] ; p1=stek[--j_stek] ;
   if( f==1 )
   {  for( i=s2 ; s1<=i ; i-- )
      {  r=max_x*i+p2 ;
	 f=Color [ r ] = stek[--j_stek] ;
	 c=Symbol[ r ] = stek[--j_stek] ;
	 r=max_x*i+p1 ;
	 f=Color [ r ] = stek[--j_stek] ;
	 c=Symbol[ r ] = stek[--j_stek] ;
      }
      r1=max_x*s1 ; r2=max_x*s2 ;
      for( i=p2 ; p1<=i ; i-- )
      {  r=r2+i ;
	 f=Color [ r ] = stek[--j_stek] ;
	 c=Symbol[ r ] = stek[--j_stek] ;
	 r=r1+i ;
	 f=Color [ r ] = stek[--j_stek] ;
	 c=Symbol[ r ] = stek[--j_stek] ;
      }
   }
   else
   {  for( i=s2 ; s1<=i ; i-- )
	 for( j=p2 ; p1<=j ; j-- )
	 {   r=max_x*i+j ;
	     c=Symbol[ r ] = stek[--j_stek] ; /* символ  */
	     f=Color [ r ] = stek[--j_stek] ; /* атрибут */
	 }
   }
}
/* ----------------------------------------------------------------------- */
void s_redraw( void )
{  short i,i1,j,r ;
   char  f,f1,Text[256] ;

   t_GC GC( Win, 15, 0 );
   XSetFont( Dis, GC.GC1, FontInfo->fid );

   f=Color[0] ;
   GC.SetForeground( f&0x0f );
   GC.SetBackground( (f>>4)&0x0f );

   for( i=0 ; i<n_Line ; i++ )
   {  for( i1=0,j=0 ; i1<n_Col ; i1++ )
      {  r=max_x*i+i1 ;
         f1=Color[r] ;            
	 if( f1!=f )
	 {   Text[j]=0 ;
	     GC.DrawImageString( (i1-j)*Symbol_W, (i+1)*Symbol_H, Text );
	     f=f1 ; j=0 ;
	     GC.SetForeground( f&0x0f );
	     GC.SetBackground( (f>>4)&0x0f );
	 }
	 Text[j++] = Symbol[r] ;
      }
      Text[j]=0 ;
      GC.DrawImageString( (i1-j)*Symbol_W, (i+1)*Symbol_H, Text );
   }
   GC.SetForeground( 0 );
   GC.SetBackground( 9 );
   Text[0] = Symbol[max_x*Cur_Y+Cur_X] ;
   Text[1] = 0 ;
   GC.DrawImageString( Cur_X*Symbol_W ,(Cur_Y+1)*Symbol_H, Text );
}
/* ----------------------------------------------------------------------- */
void   s_goto_xy( short y, short x )
{
   Cur_X=x ; Cur_Y=y ;
}
/***************************************************************************/
/*             принять событие и сделать из него Сканкод╗                  */
/***************************************************************************/
void s_getch( short *taste1, short *taste2 )
{
   int     Symbol,Symbol1 ;
   char    Symb[2] ;
   KeySym  RetSym ;
   XEvent  Event1 ;

M_Begin:
   s_redraw( );
   XNextEvent( Dis, &Event1 );
   Symbol=0 ; Symbol1=0 ;

   /* ------------------------------------ */
   if( Event1.type == KeyPress )
   {
      XLookupString(&(Event1.xkey), Symb, 1, &RetSym, NULL);

      switch( RetSym )
      {
	 case  XK_Caps_Lock : Shiftstatus=Shiftstatus ; break ;
	 case  XK_Shift_L   : Shiftstatus |= (S_Shift_L); break ;
	 case  XK_Control_L : Shiftstatus |= (S_Ctrl_L); break ;
	 case  XK_Alt_L     : Shiftstatus |= (S_Alt_L); break ;
	 case  XK_Alt_R     : Shiftstatus |= (S_Alt_R); break ;
	 case  XK_Control_R : Shiftstatus |= (S_Ctrl_R); break ;
	 case  XK_Shift_R   : Shiftstatus |= (S_Shift_R); break ;
	 default : goto M1 ;
      }
      goto M_Begin ;

      M1:
      switch( RetSym )
      {
	   case  XK_F1:            Symbol1 = S_key_F1;break;
	   case  XK_F2:            Symbol1 = S_key_F2;break;
	   case  XK_F3:            Symbol1 = S_key_F3;break;
	   case  XK_F4:            Symbol1 = S_key_F4;break;
	   case  XK_F5:            Symbol1 = S_key_F5;break;
	   case  XK_F6:            Symbol1 = S_key_F6;break;
	   case  XK_F7:            Symbol1 = S_key_F7;break;
	   case  XK_F8:            Symbol1 = S_key_F8;break;
	   case  XK_F9:            Symbol1 = S_key_F9;break;
	   case  XK_F10:           Symbol1 = S_key_F10;break;
	   
	   case  XK_L1:            Symbol1 = S_key_F1;break;
	   case  XK_L2:            Symbol1 = S_key_F2;break;
	   case  XK_L3:            Symbol1 = S_key_F3;break;
	   case  XK_L4:            Symbol1 = S_key_F4;break;
	   case  XK_L5:            Symbol1 = S_key_F5;break;
	   case  XK_L6:            Symbol1 = S_key_F6;break;
	   case  XK_L7:            Symbol1 = S_key_F7;break;
	   case  XK_L8:            Symbol1 = S_key_F8;break;
	   case  XK_L9:            Symbol1 = S_key_F9;break;
	   case  XK_L10:           Symbol1 = S_key_F10;break;

	   case  XK_Return:        Symbol  = '\r';  break;
//	   case  XK_Tab:           Symbol1 = S_key_TabL; break;
	   case  XK_Escape:        Symbol  = S_key_Esc;  break;
	   case  XK_BackSpace:     Symbol  = S_key_Back; break;
	   case  XK_Left:          Symbol1 = S_key_Left; break;
	   case  XK_Right:         Symbol1 = S_key_Right;break;
	   case  XK_Down:          Symbol1 = S_key_Down; break;
	   case  XK_Up:            Symbol1 = S_key_Up;   break;
	   case  XK_Insert:        Symbol1 = S_key_Ins;  break;
	   case  XK_Delete:        Symbol1 = S_key_Del;  break;
	   case  XK_Home:          Symbol1 = S_key_Home; break;
	   case  XK_End:           Symbol1 = S_key_End;  break;
	   case  XK_Prior:         Symbol1 = S_key_PgUp; break;
	   case  XK_Next:          Symbol1 = S_key_PgDn; break;
//	   case  XK_KP_Add:        Symbol1 = S_key_plus; break;
//	   case  XK_KP_Subtract:   Symbol1 = S_key_minus;break;
	   default:                Symbol  = (int)Symb[0];
      }
   }
   /* -------------------------------------- */
   if( Event1.type == KeyRelease )
   {
      XLookupString(&(Event1.xkey), Symb, 1, &RetSym, NULL);

      switch( RetSym )
      {
	 case  XK_Caps_Lock : Shiftstatus=Shiftstatus ; break ;
	 case  XK_Shift_L   : Shiftstatus &= (~S_Shift_L); break ;
	 case  XK_Control_L : Shiftstatus &= (~S_Ctrl_L); break ;
	 case  XK_Alt_L     : Shiftstatus &= (~S_Alt_L); break ;
	 case  XK_Alt_R     : Shiftstatus &= (~S_Alt_R); break ;
	 case  XK_Control_R : Shiftstatus &= (~S_Ctrl_R); break ;
	 case  XK_Shift_R   : Shiftstatus &= (~S_Shift_R); break ;

      }
      goto M_Begin ;
   }

   *taste1 = Symbol  ;
   *taste2 = Symbol1 ;
   if( (Event1.type != KeyPress) && (Event1.type != KeyRelease) )
      goto M_Begin ;
   return;
}
/* ----------------------------------------------------------------------- */
int    s_shiftstatus( void )
{
   return Shiftstatus ;

}
/***************************************************************************/
t_GC :: t_GC( Window Win1, ulong i1, ulong i2 )
{
   if( 16<=i1 ) i1=7 ;
   if( 16<=i2 ) i2=7 ;
   GC1=XCreateGC( Dis,Win,0,NULL );
   XSetFunction(  Dis, GC1, GXcopy );
   XSetForeground( Dis,GC1, xColor[i1].pixel );
   XSetBackground( Dis,GC1, xColor[i2].pixel );

}
/* ----------------------------------------------------------------------- */
t_GC :: ~t_GC( void )
{  XFreeGC( Dis,GC1 ); }
/* ----------------------------------------------------------------------- */

void t_GC :: SetForeground( ulong i )
{  XSetForeground( Dis,GC1, xColor[i].pixel );  }
/* ----------------------------------------------------------------------- */

void t_GC :: SetBackground( ulong i )
{  XSetBackground( Dis,GC1, xColor[i].pixel );  }
/* ----------------------------------------------------------------------- */

void t_GC :: DrawImageString( short x, short y, char *Text )
{  XDrawImageString( Dis,Win,GC1,x,y,Text,strlen(Text) );  }

/***************************************************************************/
void   s_set_size( short sx, short sy )
{
   n_Col=sx ; n_Line=sy ;
   XResizeWindow( Dis, Win, sx*Symbol_W, sy*Symbol_H );
}
/***************************************************************************/
void   s_get_size( short &sx, short &sy ){  sx=n_Col ; sy=n_Line ;  }
short  s_get_sx( void ) {  return n_Col ; }
short  s_get_sy( void ) {  return n_Line ; }

void   x_set_fonts( void ){;}
void   s_set_font( char *F ){ Strcpy( TextFont,F,100 ); }
char  *s_get_font( void ){ return TextFont ; }
short  s_clear_cursor( void ){ return 0; }
void   s_refresh( void ){  s_redraw(); XFlush( Dis );  }