/*******************************************************************/
// "Меркурий"-"Правда" - 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 ); }