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