1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20     x_wrdwindow.c - MIMPI WRD for X Window written by Takanori Watanabe.
21                   - Modified by Masanao Izumo.
22 */
23 
24 /*
25  * PC98 Screen Emulator
26  * By Takanori Watanabe.
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif /* HAVE_CONFIG_H */
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <X11/Xlib.h>
36 #include <X11/Xutil.h>
37 #include "timidity.h"
38 #include "common.h"
39 #include "x_mag.h"
40 #include "x_wrdwindow.h"
41 #include "VTparse.h"
42 #include "wrd.h"
43 #include "controls.h"
44 #include "aq.h"
45 
46 #ifndef XSHM_SUPPORT
47 #if defined(HAVE_XSHMCREATEPIXMAP) && \
48     defined(HAVE_X11_EXTENSIONS_XSHM_H) && \
49     defined(HAVE_SYS_IPC_H) && \
50     defined(HAVE_SYS_SHM_H)
51 #define XSHM_SUPPORT 1
52 #else
53 #define XSHM_SUPPORT 0
54 #endif
55 #endif /* XSHM_SUPPORT */
56 
57 #if XSHM_SUPPORT
58 #include <X11/extensions/XShm.h>
59 #include <sys/ipc.h>
60 #include <sys/shm.h>
61 #endif
62 
63 #define SIZEX WRD_GSCR_WIDTH
64 #define SIZEY WRD_GSCR_HEIGHT
65 #define MBCS 1
66 #define DEFAULT -1
67 #define JISX0201 "-*-fixed-*-r-normal--16-*-*-*-*-*-jisx0201.1976-*"
68 #define JISX0208 "-*-fixed-*-r-normal--16-*-*-*-*-*-jisx0208.1983-*"
69 #define TXTCOLORS 8
70 #define LINES WRD_TSCR_HEIGHT
71 #define COLS WRD_TSCR_WIDTH
72 #define TAB_SET 8
73 #define CSIZEX ((SIZEX)/(COLS))
74 #define CSIZEY ((SIZEY)/(LINES))
75 #define min(a,b) ((a) <= (b) ? (a) : (b))
76 #define max(a,b) ((a) >= (b) ? (a) : (b))
77 typedef struct{
78   long attr;/*if attr<0 this attr is invalid*/
79 #define CATTR_LPART (1)
80 #define CATTR_16FONT (1<<1)
81 #define CATTR_COLORED (1<<2)
82 #define CATTR_BGCOLORED (1<<3)
83 #define CATTR_TXTCOL_MASK_SHIFT 4
84 #define CATTR_TXTCOL_MASK (7<<CATTR_TXTCOL_MASK_SHIFT)
85 #define CATTR_INVAL (1<<31)
86   char c;
87 }Linbuf;
88 /*VTParse Table externals*/
89 extern int groundtable[];
90 extern int csitable[];
91 extern int dectable[];
92 extern int eigtable[];
93 extern int esctable[];
94 extern int iestable[];
95 extern int igntable[];
96 extern int scrtable[];
97 extern int scstable[];
98 extern int mbcstable[];
99 extern int smbcstable[];
100 
101 typedef struct _ImagePixmap
102 {
103   Pixmap pm;
104   XImage *im; /* Shared pixmap image (NULL for non-support) */
105 #if XSHM_SUPPORT
106   XShmSegmentInfo	shminfo;
107 #endif /* XSHM_SUPPORT */
108 } ImagePixmap;
109 
110 static struct MyWin{
111   Display *d;
112   Window w;
113   XFontStruct *f8;/*8bit Font*/
114   XFontStruct *f16;/*16bit Font*/
115 
116   GC gc,	/* For any screens (nomask) */
117      gcgr,	/* For Graphic screens (masked by @gmode) */
118      gcbmp;	/* For bitmap (depth=1) */
119 
120 #define NUMVSCREEN 2
121   Pixmap screens[NUMVSCREEN];	/* Graphics screen buffers (PseudoColor) */
122   Pixmap active_screen, disp_screen; /* screens[0] or screens[1] */
123   Pixmap offscr;		/* Double buffer */
124   Pixmap workbmp;		/* Tempolary usage (bitmap) */
125 /* active_screen: Graphics current draw screen.
126  * disp_screen:   Graphics visiable screen.
127  * The color class of MIMPI graphics screen is 4 bit pseudo color.
128  * The plane bits is masked by (basepix | pmask[0..3])
129  *
130  * offscr: Background pixmap of the main window.
131  * This screen is also used for double buffer.
132  * Redraw(): (disp_screen + text) ----> offscr ----> Window
133  * In TrueColor, it is needed to convert PseudoColor to TrueColor, here.
134  */
135 
136   /* For PC98 screen emulation.
137    * Many text escape sequences are supported.
138    */
139   Linbuf **scrnbuf;
140   int curline;
141   int curcol;
142   long curattr;
143 
144 #define NUMPLANE 4
145 #define NUMPXL 16
146 #define MAXPAL 20
147   XColor txtcolor[TXTCOLORS],curcoltab[NUMPXL],
148   gcolor[MAXPAL][NUMPXL],gcolorbase[NUMPXL];
149   unsigned long basepix, pmask[NUMPLANE], gscreen_plane_mask;
150   int ton;
151   int gon;
152   int gmode;
153 #define TON_NOSHOW 0
154   Colormap cmap;
155 #define COLOR_BG 0
156 #define COLOR_DEFAULT 7
157   int redrawflag;
158 }mywin;
159 
160 static struct VGVRAM{
161   Pixmap *vpix;
162   int num;
163 }vgvram;
164 
165 const static char *TXTCOLORNAME[8]={
166     WRD_TEXT_COLOR0,
167     WRD_TEXT_COLOR1,
168     WRD_TEXT_COLOR2,
169     WRD_TEXT_COLOR3,
170     WRD_TEXT_COLOR4,
171     WRD_TEXT_COLOR5,
172     WRD_TEXT_COLOR6,
173     WRD_TEXT_COLOR7
174 };
175 const static int colval12[16]={
176   0x000,0xf00,0x0f0,0xff0,0x00f,0xf0f,0x0ff,0xfff,
177   0x444,0xc44,0x4c4,0xcc4,0x44c,0xc4c,0x4cc,0xccc
178 };
179 
180 static char *image_buffer; /* Used for @MAG or @PLOAD */
181 Visual *theVisual;
182 int theScreen, theDepth;
183 int bytes_per_image_pixel;
184 
185 static int Parse(int);
186 static void Redraw(int,int,int,int);
187 static int RedrawText(Drawable,int,int,int,int); /* Redraw only text */
188 static void RedrawInject(int x,int y,int width,int height,int flag);
189 
190 /**** ImagePixmap interfaces ****/
191 static ImagePixmap *create_shm_image_pixmap(int width, int height);
192 static void free_image_pixmap(ImagePixmap *ip);
193 
194 /* for truecolor */
195 static Bool truecolor;
196 static ImagePixmap *shm_screen;	/* for TrueColor conversion */
197 static unsigned long truecolor_palette[NUMPXL];
198 static int shm_format;
199 
200 /*12bit color value to color member of XColor structure */
col12toXColor(int val,XColor * set)201 static void col12toXColor(int val,XColor *set)
202 {
203   set->red=((val>>8)&0xf)*0x1111;
204   set->green=((val>>4)&0xf)*0x1111;
205   set->blue=(0xf&val)*0x1111;
206 }
207 
highbit(unsigned long ul)208 static int highbit(unsigned long ul)
209 {
210     int i;  unsigned long hb;
211     hb = 0x80000000UL;
212     for(i = 31; ((ul & hb) == 0) && i >= 0;  i--, ul<<=1)
213 	;
214     return i;
215 }
216 
trueColorPixel(unsigned long r,unsigned long g,unsigned long b)217 static unsigned long trueColorPixel(unsigned long r, /* 0..255 */
218 				    unsigned long g, /* 0..255 */
219 				    unsigned long b) /* 0..255 */
220 {
221     static int rs, gs, bs;
222 
223     if(r == 0xffffffff) /* for initialize */
224     {
225 	rs = 15 - highbit(theVisual->red_mask);
226 	gs = 15 - highbit(theVisual->green_mask);
227 	bs = 15 - highbit(theVisual->blue_mask);
228 	return 0;
229     }
230 
231     r *= 257; /* 0..65535 */
232     g *= 257; /* 0..65535 */
233     b *= 257; /* 0..65535 */
234     if(rs < 0)	r <<= -rs;
235     else	r >>=  rs;
236     if(gs < 0)	g <<= -gs;
237     else	g >>=  gs;
238     if(bs < 0)	b <<= -bs;
239     else	b >>=  bs;
240     r &= theVisual->red_mask;
241     g &= theVisual->green_mask;
242     b &= theVisual->blue_mask;
243 
244     return r | g | b;
245 }
246 
store_palette(void)247 static void store_palette(void)
248 {
249   if(truecolor) {
250     int i;
251     for(i = 0; i < NUMPXL; i++)
252       truecolor_palette[i] = trueColorPixel(mywin.curcoltab[i].red / 257,
253 					    mywin.curcoltab[i].green / 257,
254 					    mywin.curcoltab[i].blue / 257);
255     Redraw(0, 0, SIZEX, SIZEY);
256   }
257   else
258     XStoreColors(mywin.d, mywin.cmap, mywin.curcoltab, NUMPXL);
259 }
260 
InitColor(Colormap cmap,Bool allocate)261 static int InitColor(Colormap cmap, Bool allocate)
262 {
263   int i,j;
264   XColor dummy;
265   if(allocate) {
266     for(i=0;i<TXTCOLORS;i++)
267       XAllocNamedColor(mywin.d,cmap,TXTCOLORNAME[i],&mywin.txtcolor[i],&dummy);
268     if (!truecolor) {
269       if(!XAllocColorCells(mywin.d,cmap,True,mywin.pmask,NUMPLANE,&mywin.basepix,1))
270 	return 1;
271     } else {
272       trueColorPixel(0xffffffff, 0, 0);
273       mywin.basepix = 0;
274       for(i = 0; i < NUMPLANE; i++)
275 	mywin.pmask[i] = (1u<<i); /* 1,2,4,8 */
276     }
277     mywin.gscreen_plane_mask = 0;
278     for(i = 0; i < NUMPLANE; i++)
279       mywin.gscreen_plane_mask |= mywin.pmask[i];
280     mywin.gscreen_plane_mask |= mywin.basepix;
281   }
282 
283   for(i=0;i<NUMPXL;i++){
284     int k;
285     unsigned long pvalue=mywin.basepix;
286     k=i;
287     for(j=0;j<NUMPLANE;j++){
288       pvalue|=(((k&1)==1)?mywin.pmask[j]:0);
289       k=k>>1;
290     }
291     col12toXColor(colval12[i],&mywin.curcoltab[i]);
292     mywin.curcoltab[i].pixel=pvalue;
293     mywin.curcoltab[i].flags=DoRed|DoGreen|DoBlue;
294   }
295   if(!truecolor)
296     XStoreColors(mywin.d, mywin.cmap, mywin.curcoltab, NUMPXL);
297   else {
298     int i;
299     for(i = 0; i < NUMPXL; i++)
300       truecolor_palette[i] = trueColorPixel(mywin.curcoltab[i].red / 257,
301 					    mywin.curcoltab[i].green / 257,
302 					    mywin.curcoltab[i].blue / 257);
303   }
304 
305   for(i=0;i<MAXPAL;i++)
306     memcpy(mywin.gcolor[i],mywin.curcoltab,sizeof(mywin.curcoltab));
307   memcpy(mywin.gcolorbase,mywin.curcoltab,sizeof(mywin.curcoltab));
308   return 0;
309 }
310 
311 /*Initialize Window subsystem*/
312 /* return:
313  * -1: error
314  *  0: success
315  *  1: already initialized
316  */
InitWin(char * opt)317 static int InitWin(char *opt)
318 {
319   XSizeHints *sh;
320   XGCValues gcv;
321   int i;
322   static int init_flag = 0;
323 
324   if(init_flag)
325       return init_flag;
326 
327   ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "Initialize WRD window");
328 
329   /*Initialize Charactor buffer and attr */
330   mywin.curline=0;
331   mywin.curcol=0;
332   mywin.ton=1;
333   mywin.gon=1;
334   mywin.gmode=-1;
335   mywin.curattr=0;/*Attribute Ground state*/
336   mywin.scrnbuf=(Linbuf **)calloc(LINES,sizeof(Linbuf *));
337   mywin.redrawflag=1;
338   if((mywin.d=XOpenDisplay(NULL))==NULL){
339     ctl->cmsg(CMSG_ERROR,VERB_NORMAL,"WRD: Can't Open Display");
340     init_flag = -1;
341     return -1;
342   }
343 
344   if(strchr(opt, 'd')) {
345       /* For debug */
346       fprintf(stderr,"Entering -Wx Debug mode\n");
347       XSynchronize(mywin.d, True);
348   }
349 
350   theScreen = DefaultScreen(mywin.d);
351   theDepth = DefaultDepth(mywin.d, theScreen);
352   theVisual = DefaultVisual(mywin.d, theScreen);
353 
354   /* check truecolor */
355   if(theVisual->class == TrueColor || theVisual->class == StaticColor)
356     truecolor=True;
357   else
358     truecolor=False;
359 
360   if((mywin.f8=XLoadQueryFont(mywin.d,JISX0201))==NULL){
361     ctl->cmsg(CMSG_ERROR,VERB_NORMAL,"%s: Can't load font",JISX0201);
362     /* Can't load font JISX0201 */
363     XCloseDisplay(mywin.d);
364     mywin.d=NULL;
365     init_flag = -1;
366     return -1;
367   }
368   if((mywin.f16=XLoadQueryFont(mywin.d,JISX0208))==NULL){
369     ctl->cmsg(CMSG_ERROR,VERB_NORMAL,"%s: Can't load font",JISX0208);
370     XCloseDisplay(mywin.d);
371     mywin.d=NULL;
372     init_flag = -1;
373     return -1;
374   }
375 
376   mywin.w=XCreateSimpleWindow(mywin.d,DefaultRootWindow(mywin.d)
377 			      ,0,0,SIZEX,SIZEY
378 			      ,10,
379 			      BlackPixel(mywin.d, theScreen),
380 			      WhitePixel(mywin.d, theScreen));
381   mywin.cmap=DefaultColormap(mywin.d, theScreen);
382 
383   if(truecolor) {
384 #if XSHM_SUPPORT
385     shm_format = XShmPixmapFormat(mywin.d);
386     if(shm_format == ZPixmap)
387       shm_screen = create_shm_image_pixmap(SIZEX, SIZEY);
388     else
389       shm_screen = NULL; /* No-support other format */
390     if(!shm_screen)
391       ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "X SHM Extention is off");
392 #else
393     shm_screen = NULL;
394 #endif
395   }
396 
397   /*This block initialize Colormap*/
398   if(InitColor(mywin.cmap, True)!=0){
399     mywin.cmap=XCopyColormapAndFree(mywin.d,mywin.cmap);
400     if(InitColor(mywin.cmap, True)!=0){
401       ctl->cmsg(CMSG_ERROR,VERB_NORMAL,"WRD: Can't initialize colormap");
402       XCloseDisplay(mywin.d);
403       mywin.d=NULL;
404       init_flag = -1;
405       return -1;
406     }
407     XSetWindowColormap(mywin.d,mywin.w,mywin.cmap);
408   }
409   /*Tell Window manager not to allow resizing
410    * And set Application name
411    */
412   sh=XAllocSizeHints();
413   sh->flags=PMinSize|PMaxSize;
414   sh->min_width=SIZEX;
415   sh->min_height=SIZEY;
416   sh->max_width=SIZEX;
417   sh->max_height=SIZEY;
418   XSetWMNormalHints(mywin.d,mywin.w,sh);
419   XStoreName(mywin.d,mywin.w,"timidity");
420   XSetIconName(mywin.d,mywin.w,"TiMidity");
421   XFree(sh);
422 
423   /* Alloc background pixmap(Graphic plane)*/
424   for(i=0;i<NUMVSCREEN;i++)
425     mywin.screens[i]=XCreatePixmap(mywin.d,mywin.w,SIZEX,SIZEY,theDepth);
426   mywin.offscr=XCreatePixmap(mywin.d,mywin.w,SIZEX,SIZEY,theDepth);
427   mywin.workbmp=XCreatePixmap(mywin.d,mywin.w,SIZEX,CSIZEY,1);
428   mywin.active_screen=mywin.screens[0];
429   mywin.disp_screen=mywin.screens[0];
430   XSetWindowBackgroundPixmap(mywin.d, mywin.w, mywin.offscr);
431 
432   gcv.graphics_exposures = False;
433   mywin.gc=XCreateGC(mywin.d,mywin.w,GCGraphicsExposures, &gcv);
434   mywin.gcgr=XCreateGC(mywin.d,mywin.w,GCGraphicsExposures, &gcv);
435   mywin.gcbmp=XCreateGC(mywin.d,mywin.workbmp,0,0);
436 
437   XSetForeground(mywin.d,mywin.gcbmp,0);
438   XSetBackground(mywin.d,mywin.gcbmp,1);
439 
440   /*This Initialize background pixmap(Graphic plane)*/
441   XSetForeground(mywin.d,mywin.gcgr,mywin.curcoltab[0].pixel);
442   XFillRectangle(mywin.d,mywin.active_screen,mywin.gcgr,0,0,SIZEX,SIZEY);
443   for(i=0;i<NUMVSCREEN;i++)
444       XFillRectangle(mywin.d, mywin.screens[i], mywin.gcgr,
445 		     0, 0, SIZEX, SIZEY);
446   XFillRectangle(mywin.d, mywin.offscr, mywin.gcgr, 0, 0, SIZEX, SIZEY);
447 
448   XSetForeground(mywin.d,mywin.gc,mywin.txtcolor[COLOR_DEFAULT].pixel);
449   XSelectInput(mywin.d,mywin.w,ButtonPressMask);
450 
451   { /* calc bytes_per_image_pixel */
452     XImage *im;
453     im = XCreateImage(mywin.d, theVisual, theDepth, ZPixmap,
454 		      0, NULL, 1, 1, 8, 0);
455     bytes_per_image_pixel = im->bits_per_pixel/8;
456     XDestroyImage(im);
457   }
458   image_buffer=(char *)safe_malloc(SIZEX*SIZEY*bytes_per_image_pixel);
459   init_flag = 1;
460   return 0;
461 }
462 
463 /***************************************************
464  Redraw Routine
465   This redraw Text screen.
466   Graphic Screen is treated as background bitmap
467  ***************************************************/
DrawReverseString16(Display * disp,Drawable d,GC gc,int x,int y,XChar2b * string,int length)468 static int DrawReverseString16(Display *disp,Drawable d,GC gc,int x,int y,
469 		  XChar2b *string,int length)
470 {
471   int lbearing,ascent;
472   lbearing=mywin.f16->min_bounds.lbearing;
473   ascent=mywin.f16->max_bounds.ascent;
474   XSetFont(disp,mywin.gcbmp,mywin.f16->fid);
475   XDrawImageString16(disp,mywin.workbmp,mywin.gcbmp,-lbearing,ascent,
476 		     string,length);
477   XSetClipMask(disp,gc,mywin.workbmp);
478   XSetClipOrigin(disp,gc,x+lbearing,y-ascent);
479   XFillRectangle(disp,d,gc,x+lbearing,y-ascent,CSIZEX*length*2,CSIZEY);
480   XSetClipMask(disp,gc,None);
481   return 0;
482 }
483 
DrawReverseString(Display * disp,Drawable d,GC gc,int x,int y,char * string,int length)484 static int DrawReverseString(Display *disp,Drawable d,GC gc,int x,int y,
485 		  char *string,int length)
486 {
487   int lbearing,ascent;
488   lbearing=mywin.f16->min_bounds.lbearing;
489   ascent=mywin.f16->max_bounds.ascent;
490   XSetFont(disp,mywin.gcbmp,mywin.f8->fid);
491   XDrawImageString(disp,mywin.workbmp,mywin.gcbmp,-lbearing,ascent,
492 		   string,length);
493   XSetClipMask(disp,gc,mywin.workbmp);
494   XSetClipOrigin(disp,gc,x+lbearing,y-ascent);
495   XFillRectangle(disp,d,gc,x+lbearing,y-ascent,CSIZEX*length,CSIZEY);
496   XSetClipMask(disp,gc,None);
497   return 0;
498 }
499 
RedrawText(Drawable drawable,int x,int y,int width,int height)500 static int RedrawText(Drawable drawable, int x,int y,int width,int height)
501 {
502   int i,yfrom,yto,xfrom,xto;
503   int drawflag;
504 
505   xfrom=x/CSIZEX;
506   xfrom=max(xfrom,0);
507   xto=(x+width-1)/CSIZEX;
508   xto=(xto<COLS-1)?xto:COLS-1;
509   yfrom=y/CSIZEY;
510   yfrom=max(yfrom,0);
511   yto=(y+height-1)/CSIZEY;
512   yto=(yto<LINES-1)?yto:LINES-1;
513 
514   drawflag=0;
515   for(i=yfrom;i<=yto;i++){
516     if(mywin.scrnbuf[i]!=NULL){
517       long prevattr,curattr;
518       char line[COLS+1];
519       int pos,s_x,e_x;
520       int j,jfrom,jto;
521 
522       jfrom=xfrom;
523       jto=xto;
524 
525       /* Check multibyte boudary */
526       if(jfrom > 0 && (mywin.scrnbuf[i][jfrom-1].attr&CATTR_LPART))
527 	  jfrom--;
528       if(jto < COLS-1 && (mywin.scrnbuf[i][jto].attr&CATTR_LPART))
529 	  jto++;
530 
531       pos=0;
532       prevattr=CATTR_INVAL;
533       s_x=e_x=jfrom*CSIZEX;
534       for(j=jfrom;j<=jto+1;j++){
535 	if(j==jto+1 || mywin.scrnbuf[i][j].c==0) {
536 	  curattr=CATTR_INVAL;
537 	}
538 	else
539 	  curattr=mywin.scrnbuf[i][j].attr;
540 	if((prevattr&~CATTR_LPART)!=(curattr&~CATTR_LPART)){
541 	  XFontStruct *f=NULL;
542 	  int lbearing,ascent;
543 	  int (*DrawStringFunc)();
544 	  DrawStringFunc=XDrawString;
545 	  line[pos]=0;
546 	  if(prevattr<0){
547 	    DrawStringFunc=NULL;
548 	  }else if(prevattr&CATTR_16FONT){
549 	    f=mywin.f16;
550 	    DrawStringFunc=XDrawString16;
551 	    pos/=2;
552 	  }else
553 	    f=mywin.f8;
554 	  if(DrawStringFunc!=NULL){
555 	    XSetFont(mywin.d,mywin.gc,f->fid);
556 	    lbearing=f->min_bounds.lbearing;
557 	    ascent=f->max_bounds.ascent;
558 	    if(prevattr&CATTR_COLORED){
559 	      int tcol;
560 	      tcol=(prevattr&CATTR_TXTCOL_MASK)>>CATTR_TXTCOL_MASK_SHIFT;
561 	      XSetForeground(mywin.d,mywin.gc,
562 			     mywin.txtcolor[tcol].pixel);
563   	    }else if(prevattr&CATTR_BGCOLORED){
564   	      int tcol;
565   	      tcol=(prevattr&CATTR_TXTCOL_MASK)>>CATTR_TXTCOL_MASK_SHIFT;
566 	      DrawStringFunc=(DrawStringFunc==XDrawString)?(int(*)())DrawReverseString:(int(*)())DrawReverseString16;
567 	      XSetForeground(mywin.d,mywin.gc,
568 			     mywin.txtcolor[tcol].pixel);
569 	    }
570 	    (*DrawStringFunc)(mywin.d,drawable,mywin.gc,
571 			      s_x-lbearing,i*CSIZEY+ascent,line,pos);
572 	    drawflag=1;
573 	    if((prevattr&CATTR_COLORED)||(prevattr&CATTR_BGCOLORED))
574 	      XSetForeground(mywin.d,mywin.gc,mywin.txtcolor[COLOR_DEFAULT].pixel);
575 	  }
576 	  prevattr=curattr;
577 	  s_x=e_x;
578 	  pos=0;
579 	}
580 	line[pos++]=mywin.scrnbuf[i][j].c;
581 	e_x+=CSIZEX;
582       }
583     }
584   }
585   return drawflag;
586 }
587 
588 /* Copy disp_screen to offscr */
TransferArea(int sx,int sy,int width,int height)589 static void TransferArea(int sx, int sy, int width, int height)
590 {
591     if(!truecolor)
592 	XCopyArea(mywin.d, mywin.disp_screen, mywin.offscr, mywin.gc,
593 		  sx, sy, width, height, sx, sy);
594     else
595     {
596 	XImage *im;
597 	int x, y, i, c;
598 	int units_per_line;
599 	int x0, y0;
600 
601 	if(sx + width > SIZEX)
602 	    width = SIZEX - sx;
603 	if(sy + height > SIZEY)
604 	    height = SIZEY - sy;
605 
606 #if XSHM_SUPPORT
607 	if(shm_screen)
608 	{
609 	    im = shm_screen->im;
610 	    XCopyArea(mywin.d, mywin.disp_screen, shm_screen->pm, mywin.gc,
611 		      sx, sy, width, height, 0, 0);
612 	    XSync(mywin.d, 0); /* Wait until ready */
613 	    x0 = 0;
614 	    y0 = 0;
615 	}
616 	else
617 #endif /* XSHM_SUPPORT */
618 	{
619 	    im = XGetImage(mywin.d, mywin.disp_screen,
620 			   sx, sy, width, height, AllPlanes, ZPixmap);
621 	    x0 = 0;
622 	    y0 = 0;
623 	}
624 
625 	units_per_line = im->bytes_per_line / (im->bits_per_pixel / 8);
626 
627 	/* Optimize 8, 16, 32 bit depth image */
628 	switch(im->bits_per_pixel)
629 	{
630 	  case 8:
631 	    for(y = 0; y < height; y++)
632 		for(x = 0; x < width; x++)
633 		{
634 		    i = (y0 + y) * units_per_line + x0 + x;
635 		    c = im->data[i];
636 		    im->data[i] = truecolor_palette[c];
637 		}
638 	    break;
639 	  case 16:
640 	    for(y = 0; y < height; y++)
641 		for(x = 0; x < width; x++)
642 		{
643 		    i = (y0 + y) * units_per_line + x0 + x;
644 		    c = ((uint16 *)im->data)[i];
645 		    ((uint16 *)im->data)[i] = truecolor_palette[c];
646 		}
647 	    break;
648 	  case 32:
649 	    for(y = 0; y < height; y++)
650 		for(x = 0; x < width; x++)
651 		{
652 		    i = (y0 + y) * units_per_line + x0 + x;
653 		    c = ((uint32 *)im->data)[i];
654 		    ((uint32 *)im->data)[i] = truecolor_palette[c];
655 		}
656 	    break;
657 	  default:
658 	    for(y = 0; y < height; y++)
659 		for(x = 0; x < width; x++)
660 		{
661 		    c = XGetPixel(im, x0 + x, y0 + y);
662 		    XPutPixel(im, x0 + x, y0 + y, truecolor_palette[c]);
663 		}
664 	    break;
665 	}
666 
667 #if XSHM_SUPPORT
668 	if(shm_screen)
669 	    XCopyArea(mywin.d, shm_screen->pm, mywin.offscr, mywin.gc,
670 		      x0, y0, width, height, sx, sy);
671 	else
672 #endif
673 	{
674 	    XPutImage(mywin.d, mywin.offscr, mywin.gc, im,
675 		      x0, y0, sx, sy, width, height);
676 	    XDestroyImage(im);
677 	}
678     }
679 }
680 
Redraw(int x,int y,int width,int height)681 static void Redraw(int x, int y, int width, int height)
682 {
683   if(!mywin.redrawflag)
684     return;
685 
686   if(mywin.gon)
687     TransferArea(x, y, width, height);
688   else {
689     XSetForeground(mywin.d, mywin.gc,
690 		   BlackPixel(mywin.d,DefaultScreen(mywin.d)));
691     XFillRectangle(mywin.d, mywin.offscr, mywin.gc, x, y, width, height);
692   }
693 
694   if(mywin.ton)
695     RedrawText(mywin.offscr, x, y, width, height);
696   XClearArea(mywin.d, mywin.w, x, y, width, height, False);
697 }
698 
699 
700 /*******************************************************
701  *  Utilities for VT Parser
702  ********************************************************/
703 
DelChar(int line,int col)704 static void DelChar(int line,int col)
705 {
706   int rx1,ry1,rx2,ry2;
707   rx1=(col)*CSIZEX;
708   rx2=(col+1)*CSIZEX;
709   ry1=(line)*CSIZEY;
710   ry2=(line+1)*CSIZEY;
711   if(mywin.scrnbuf[line][col].attr&CATTR_16FONT){
712     if(mywin.scrnbuf[line][col].attr&CATTR_LPART){
713       mywin.scrnbuf[line][col+1].c=0;
714       mywin.scrnbuf[line][col+1].attr=0;
715       rx2+=CSIZEX;
716     }
717     else{
718       mywin.scrnbuf[line][col-1].c=0;
719       mywin.scrnbuf[line][col-1].attr=0;
720       rx1-=CSIZEX;
721     }
722   }
723   RedrawInject(rx1,ry1,rx2-rx1,ry2-ry1,False);
724   mywin.scrnbuf[line][col].c=0;
725   mywin.scrnbuf[line][col].attr=0;
726 }
727 
ClearLine(int j)728 static void ClearLine(int j)
729 {
730   free(mywin.scrnbuf[j]);
731   mywin.scrnbuf[j]=NULL;
732   RedrawInject(0,j*CSIZEY,SIZEX,CSIZEY,False);
733 }
ClearLeft(void)734 static void ClearLeft(void)
735 {
736   memset(mywin.scrnbuf[mywin.curline],0,sizeof(Linbuf)*mywin.curcol);
737   if(!(mywin.scrnbuf[mywin.curline][mywin.curcol+1].attr
738        &(CATTR_LPART))){
739     mywin.scrnbuf[mywin.curline][mywin.curcol+1].attr=0;
740     mywin.scrnbuf[mywin.curline][mywin.curcol+1].c=0;
741   }
742   RedrawInject(0,(mywin.curline)*CSIZEY,SIZEX,CSIZEY,False);
743 }
ClearRight(void)744 static void ClearRight(void)
745 {
746   /*Erase Right*/
747   memset(mywin.scrnbuf[mywin.curline]+mywin.curcol,0,
748 	 sizeof(Linbuf)*(COLS-mywin.curcol));
749   if((mywin.scrnbuf[mywin.curline][mywin.curcol-1].attr
750        &(CATTR_LPART))){
751     mywin.scrnbuf[mywin.curline][mywin.curcol-1].attr=0;
752     mywin.scrnbuf[mywin.curline][mywin.curcol-1].c=0;
753   }
754   RedrawInject(0,(mywin.curline)*CSIZEY,SIZEX,CSIZEY,False);
755 }
RedrawInject(int x,int y,int width,int height,int flag)756 static void RedrawInject(int x,int y,int width,int height,int flag){
757   static int xfrom,yfrom,xto,yto;
758   int x2,y2;
759   x2=x+width;
760   y2=y+height;
761   if(x==-1){
762     xfrom=yfrom=xto=yto=-1;
763     return;
764   }
765   if(flag==False){
766     if(xfrom==-1){
767       xfrom=x;
768       yfrom=y;
769       xto=x2;
770       yto=y2;
771     }
772     else{
773       xfrom=(xfrom<x)?xfrom:x;
774       yfrom=(yfrom<y)?yfrom:y;
775       xto=(xto>x2)?xto:x2;
776       yto=(yto>y2)?yto:y2;
777     }
778   }
779   else if(xfrom!=-1)
780     Redraw(xfrom,yfrom,xto-xfrom,yto-yfrom);
781 }
782 /************************************************************
783  *   Graphic Command Functions
784  *
785  *
786  *
787  **************************************************************/
x_GMode(int mode)788 void x_GMode(int mode)
789 {
790   int i;
791   unsigned long  mask;
792 
793   if(mode == -1)
794   {
795       /* Initialize plane mask */
796       mywin.gmode = -1;
797       XSetPlaneMask(mywin.d,mywin.gcgr,AllPlanes);
798       return;
799   }
800 
801   mode&=15;
802   mywin.gmode = mode;
803   mode = (mode&8)|wrd_plane_remap[mode&7];
804   mask = mywin.basepix;
805   for(i=0;i<NUMPLANE;i++){
806     mask|=(((mode&1)==1)?mywin.pmask[i]:0);
807     mode=mode>>1;
808   }
809   XSetPlaneMask(mywin.d,mywin.gcgr,mask);
810 }
x_GMove(int xorig,int yorig,int xend,int yend,int xdist,int ydist,int srcp,int endp,int swflag)811 void x_GMove(int xorig,int yorig,int xend,int yend,int xdist,int ydist,
812 	     int srcp,int endp,int swflag)
813 {
814   int w, h;
815 
816   w=xend-xorig+1;
817   h=yend-yorig+1;
818   if((srcp<2)&&(endp<2)){
819     if(swflag==1){
820       XSetFunction(mywin.d,mywin.gcgr,GXxor);
821       XCopyArea(mywin.d,mywin.screens[endp],mywin.screens[srcp],mywin.gcgr
822 		,xdist,ydist,w,h,xorig,yorig);
823       XCopyArea(mywin.d,mywin.screens[srcp],mywin.screens[endp],mywin.gcgr
824 		,xorig,yorig,w,h,xdist,ydist);
825       XCopyArea(mywin.d,mywin.screens[endp],mywin.screens[srcp],mywin.gcgr
826 		,xdist,ydist,w,h,xorig,yorig);
827       XSetFunction(mywin.d,mywin.gcgr,GXcopy);
828       if(mywin.screens[srcp]==mywin.disp_screen)
829 	Redraw(xorig,yorig,w,h);
830     }
831     else
832       XCopyArea(mywin.d,mywin.screens[srcp],mywin.screens[endp],mywin.gcgr
833 		,xorig,yorig,w,h,xdist,ydist);
834     if(mywin.screens[endp]==mywin.disp_screen) {
835       Redraw(xdist,ydist,w,h);
836     }
837   }
838 }
x_VSget(int * params,int nparam)839 void x_VSget(int *params,int nparam)
840 {
841   int numalloc,depth;
842   depth=DefaultDepth(mywin.d,DefaultScreen(mywin.d));
843   if(vgvram.vpix!=NULL)
844     x_VRel();
845   vgvram.vpix=safe_malloc(sizeof(Pixmap)*params[0]);
846   for(numalloc=0;numalloc<params[0];numalloc++){
847     vgvram.vpix[numalloc]=XCreatePixmap(mywin.d,mywin.w,SIZEX,SIZEY,depth);
848   }
849   vgvram.num=numalloc;
850 }
x_VRel()851 void x_VRel()
852 {
853   int i;
854   if(mywin.d == NULL)
855       return;
856   if(vgvram.vpix==NULL)
857     return;
858   for(i=0;i<vgvram.num;i++)
859     XFreePixmap(mywin.d,vgvram.vpix[i]);
860   free(vgvram.vpix);
861   vgvram.vpix=NULL;
862   vgvram.num=0;
863 }
864 
x_VCopy(int sx1,int sy1,int sx2,int sy2,int tx,int ty,int ss,int ts,int mode)865 void x_VCopy(int sx1,int sy1,int sx2,int sy2,int tx,int ty
866 	     ,int ss,int ts,int mode)
867 {
868   int vpg,rpg,w,h;
869   Pixmap srcpage,distpage,tmp;
870 
871   w=sx2-sx1+1;
872   h=sy2-sy1+1;
873   if(mode!=0){
874     vpg=ss;
875     rpg=ts;
876   }else{
877     vpg=ts;
878     rpg=ss;
879   }
880   if(vpg<vgvram.num)
881     srcpage=vgvram.vpix[vpg];
882   else
883     return;
884   if(rpg<2)
885     distpage=mywin.screens[rpg];
886   else
887     return;
888   if(mode==0){
889     tmp=srcpage;
890     srcpage=distpage;
891     distpage=tmp;
892   }
893   XCopyArea(mywin.d,srcpage,distpage,mywin.gc
894 	    ,sx1,sy1,w,h,tx,ty);
895   if(distpage==mywin.disp_screen)
896     Redraw(tx,ty,w,h);
897 }
898 
x_XCopy(int sx1,int sy1,int sx2,int sy2,int tx,int ty,int ss,int ts,int method,int * opts,int nopts)899 void x_XCopy(int sx1,
900 	     int sy1,
901 	     int sx2,
902 	     int sy2,
903 	     int tx,
904 	     int ty,
905 	     int ss,
906 	     int ts,
907 	     int method,
908 	     int *opts,
909 	     int nopts)
910 {
911     XImage *simg, *timg;
912     int i, x, y, w, h;
913     int gmode_save;
914 
915     w = sx2 - sx1 + 1;
916     h = sy2 - sy1 + 1;
917     gmode_save = mywin.gmode;
918 
919     if(w <= 0 || w > SIZEX ||
920        h <= 0 || h > SIZEY ||
921        ss < 0 || ss >= NUMVSCREEN ||
922        ts < 0 || ts >= NUMVSCREEN)
923 	return;
924 
925     simg = timg = NULL;
926     x_GMode(-1);
927     switch(method)
928     {
929       default:
930       case 0: /* copy */
931 	x_GMove(sx1, sy1, sx2, sy2, tx, ty, ss, ts, 0);
932 	break;
933 
934       case 1: /* copy except pallet No.0 */
935 	simg = XGetImage(mywin.d, mywin.screens[ss],
936 			 sx1, sy1, w, h, mywin.gscreen_plane_mask, ZPixmap);
937 	if(!simg) break;
938 	timg = XGetImage(mywin.d, mywin.screens[ts],
939 			 tx, ty, w, h, mywin.gscreen_plane_mask, ZPixmap);
940 	if(!timg) break;
941 	for(y = 0; y < h; y++)
942 	    for(x = 0; x < w; x++)
943 	    {
944 		int pixel = XGetPixel(simg, x, y);
945 		if(pixel != mywin.curcoltab[0].pixel)
946 		    XPutPixel(timg, x, y, pixel);
947 	    }
948 	XPutImage(mywin.d, mywin.screens[ts], mywin.gcgr, timg,
949 		  0, 0, tx, ty, w, h);
950 	if(mywin.screens[ts] == mywin.disp_screen)
951 	    Redraw(tx, ty, w, h);
952 	break;
953 
954       case 2: /* xor */
955 	XSetFunction(mywin.d,mywin.gcgr,GXxor);
956 	x_GMove(sx1, sy1, sx2, sy2, tx, ty, ss, ts, 0);
957 	XSetFunction(mywin.d,mywin.gcgr,GXcopy);
958 	break;
959 
960       case 3: /* and */
961 	XSetFunction(mywin.d,mywin.gcgr,GXand);
962 	x_GMove(sx1, sy1, sx2, sy2, tx, ty, ss, ts, 0);
963 	XSetFunction(mywin.d,mywin.gcgr,GXcopy);
964 	break;
965 
966       case 4: /* or */
967 	XSetFunction(mywin.d,mywin.gcgr,GXor);
968 	x_GMove(sx1, sy1, sx2, sy2, tx, ty, ss, ts, 0);
969 	XSetFunction(mywin.d,mywin.gcgr,GXcopy);
970 	break;
971 
972       case 5: /* reverse x */
973 	simg = XGetImage(mywin.d, mywin.screens[ss],
974 			 sx1, sy1, w, h, mywin.gscreen_plane_mask, ZPixmap);
975 	if(!simg)
976 	    break;
977 	for(y = 0; y < h; y++)
978 	{
979 	    for(x = 0; x < w/2; x++)
980 	    {
981 		int p1, p2;
982 		p1 = XGetPixel(simg, x, y);
983 		p2 = XGetPixel(simg, w-x-1, y);
984 		XPutPixel(simg, x, y, p2);
985 		XPutPixel(simg, w-x-1, y, p1);
986 	    }
987 	}
988 	XPutImage(mywin.d, mywin.screens[ts], mywin.gcgr, simg,
989 		  0, 0, tx, ty, w, h);
990 	if(mywin.screens[ts] == mywin.disp_screen)
991 	    Redraw(tx, ty, w, h);
992 	break;
993 
994       case 6: /* reverse y */
995 	simg = XGetImage(mywin.d, mywin.screens[ss],
996 			 sx1, sy1, w, h, mywin.gscreen_plane_mask, ZPixmap);
997 	if(!simg)
998 	    break;
999 	for(y = 0; y < h/2; y++)
1000 	{
1001 	    for(x = 0; x < w; x++)
1002 	    {
1003 		int p1, p2;
1004 		p1 = XGetPixel(simg, x, y);
1005 		p2 = XGetPixel(simg, x, h-y-1);
1006 		XPutPixel(simg, x, y, p2);
1007 		XPutPixel(simg, x, h-y-1, p1);
1008 	    }
1009 	}
1010 	XPutImage(mywin.d, mywin.screens[ts], mywin.gcgr, simg,
1011 		  0, 0, tx, ty, w, h);
1012 	if(mywin.screens[ts] == mywin.disp_screen)
1013 	    Redraw(tx, ty, w, h);
1014 	break;
1015 
1016       case 7: /* reverse x-y */
1017 	simg = XGetImage(mywin.d, mywin.screens[ss],
1018 			 sx1, sy1, w, h, mywin.gscreen_plane_mask, ZPixmap);
1019 	if(!simg)
1020 	    break;
1021 	for(i = 0; i < w*h/2; i++)
1022 	{
1023 	    int p1, p2;
1024 	    p1 = simg->data[i];
1025 	    p2 = simg->data[w*h-i-1];
1026 	    simg->data[i] = p2;
1027 	    simg->data[w*h-i-1] = p1;
1028 	}
1029 	XPutImage(mywin.d, mywin.screens[ts], mywin.gcgr, simg,
1030 		  0, 0, tx, ty, w, h);
1031 	if(mywin.screens[ts] == mywin.disp_screen)
1032 	    Redraw(tx, ty, w, h);
1033 	break;
1034 
1035       case 8: /* copy except pallet No.0 (type2) */
1036 	if(nopts < 2)
1037 	    break;
1038 	simg = XGetImage(mywin.d, mywin.screens[ss],
1039 			 sx1, sy1, w, h, mywin.gscreen_plane_mask, ZPixmap);
1040 	if(!simg) break;
1041 	timg = XGetImage(mywin.d, mywin.screens[ts],
1042 			 opts[0], opts[1], w, h, mywin.gscreen_plane_mask, ZPixmap);
1043 	if(!timg) break;
1044 	for(y = 0; y < h; y++)
1045 	    for(x = 0; x < w; x++)
1046 	    {
1047 		int pixel = XGetPixel(simg, x, y);
1048 		if(pixel != mywin.curcoltab[0].pixel)
1049 		    XPutPixel(timg, x, y, pixel);
1050 	    }
1051 	XPutImage(mywin.d, mywin.screens[ts], mywin.gcgr, timg,
1052 		  0, 0, tx, ty, w, h);
1053 	if(mywin.screens[ts] == mywin.disp_screen)
1054 	    Redraw(tx, ty, w, h);
1055 	break;
1056 
1057       case 9: { /* Mask copy */
1058 	  int m, opt5, c;
1059 	  if(nopts < 5)
1060 	    break;
1061 	  opt5 = opts[4];
1062 	  simg = XGetImage(mywin.d, mywin.screens[ss],
1063 			   sx1, sy1, w, h, mywin.gscreen_plane_mask, ZPixmap);
1064 	  if(!simg) break;
1065 	  timg = XGetImage(mywin.d, mywin.screens[ts],
1066 			   tx, ty, w, h, mywin.gscreen_plane_mask, ZPixmap);
1067 	  if(!timg) break;
1068 	  for(y = 0; y < h; y++)
1069 	  {
1070 	      m = opts[y & 3] & 0xff;
1071 	      for(x = 0; x < w; x++)
1072 	      {
1073 		  if((1 << (x&7)) & m)
1074 		  {
1075 		      if(opt5 == 16)
1076 			  continue;
1077 		      c = mywin.curcoltab[opt5 & 0xf].pixel;
1078 		  }
1079 		  else
1080 		      c = XGetPixel(simg, x, y);
1081 		  XPutPixel(timg, x, y, c);
1082 	      }
1083 	  }
1084 	  XPutImage(mywin.d, mywin.screens[ts], mywin.gcgr, timg,
1085 		    0, 0, tx, ty, w, h);
1086 	  if(mywin.screens[ts] == mywin.disp_screen)
1087 	      Redraw(tx, ty, w, h);
1088 	}
1089 	break;
1090 
1091       case 10: { /* line copy */
1092 	  int cp, sk, i;
1093 	  if(nopts < 2)
1094 	      break;
1095 	  if((cp = opts[0]) < 0)
1096 	      break;
1097 	  if((sk = opts[1]) < 0)
1098 	      break;
1099 	  if(cp + sk == 0)
1100 	      break;
1101 	  simg = XGetImage(mywin.d, mywin.screens[ss],
1102 			   sx1, sy1, w, h, mywin.gscreen_plane_mask, ZPixmap);
1103 	  if(!simg) break;
1104 	  timg = XGetImage(mywin.d, mywin.screens[ts],
1105 			   tx, ty, w, h, mywin.gscreen_plane_mask, ZPixmap);
1106 	  if(!timg) break;
1107 	  y = 0;
1108 	  while(y < h)
1109 	  {
1110 	      for(i = 0; i < cp && y < h; i++, y++)
1111 	      {
1112 		  for(x = 0; x < w; x++)
1113 		      XPutPixel(timg, x, y, XGetPixel(simg, x, y));
1114 	      }
1115 	      y += sk;
1116 	  }
1117 	}
1118 	if(mywin.screens[ts] == mywin.disp_screen)
1119 	    Redraw(tx, ty, w, h);
1120 	break;
1121 
1122       case 11: {
1123 	  int etx, ety;
1124 	  while(tx < 0) tx += SIZEX;
1125 	  tx %= SIZEX;
1126 	  while(ty < 0) ty += SIZEY;
1127 	  ty %= SIZEY;
1128 	  etx = tx + w;
1129 	  ety = ty + h;
1130 
1131 	  XCopyArea(mywin.d,mywin.screens[ss],mywin.screens[ts],mywin.gcgr,
1132 		    sx1, sx2, w, h, tx, ty);
1133 	  if(etx > SIZEX)
1134 	      XCopyArea(mywin.d,mywin.screens[ss],mywin.screens[ts],mywin.gcgr,
1135 			sx1 + (etx - SIZEX),
1136 			sy1,
1137 			w - (etx - SIZEX),
1138 			h,
1139 			0, ty);
1140 	  if(ety > SIZEY)
1141 	      XCopyArea(mywin.d,mywin.screens[ss],mywin.screens[ts],mywin.gcgr,
1142 			sx1,
1143 			sy1 + (ety - SIZEY),
1144 			w,
1145 			h - (ety - SIZEY),
1146 			tx, 0);
1147 	  if(etx > SIZEX && ety > SIZEY)
1148 	  {
1149 	      XCopyArea(mywin.d,mywin.screens[ss],mywin.screens[ts],mywin.gcgr,
1150 			sx1 + (etx - SIZEX),
1151 			sy1 + (ety - SIZEY),
1152 			w - (etx - SIZEX),
1153 			h - (ety - SIZEY),
1154 			0, 0);
1155 	  }
1156 	  if(mywin.screens[ts] == mywin.disp_screen)
1157 	  {
1158 	      if(etx < SIZEX && ety < SIZEY)
1159 		  Redraw(tx, ty, w, h);
1160 	      else
1161 		  Redraw(0, 0, SIZEX, SIZEY);
1162 	  }
1163 	}
1164 	break;
1165 
1166       case 12: {
1167 	  unsigned long psm, ptm;
1168 	  int plane_map[4] = {2, 0, 1, 3};
1169 	  psm = mywin.pmask[plane_map[opts[0] & 3]] | mywin.basepix;
1170 	  ptm = mywin.pmask[plane_map[opts[1] & 3]] | mywin.basepix;
1171 
1172 	  simg = XGetImage(mywin.d, mywin.screens[ss],
1173 			   sx1, sy1, w, h, mywin.gscreen_plane_mask, ZPixmap);
1174 	  if(!simg) break;
1175 	  timg = XGetImage(mywin.d, mywin.screens[ts],
1176 			   tx, ty, w, h, mywin.gscreen_plane_mask, ZPixmap);
1177 	  if(!timg) break;
1178 	  for(y = 0; y < h; y++)
1179 	      for(x = 0; x < w; x++)
1180 	      {
1181 		  int p1, p2;
1182 		  p1 = XGetPixel(simg, x, y);
1183 		  p2 = XGetPixel(timg, x, y);
1184 		  if(p1 & psm)
1185 		      p2 |= ptm;
1186 		  else
1187 		      p2 &= ~ptm;
1188 		  XPutPixel(timg, x, y, p2);
1189 	      }
1190 	  if(mywin.screens[ts] == mywin.disp_screen)
1191 	      Redraw(tx, ty, w, h);
1192 	}
1193 	break;
1194     }
1195     if(simg != NULL)
1196 	XDestroyImage(simg);
1197     if(timg != NULL)
1198 	XDestroyImage(timg);
1199     x_GMode(gmode_save);
1200 }
1201 
MyDestroyImage(XImage * img)1202 static void MyDestroyImage(XImage *img)
1203 {
1204     img->data = NULL; /* Don't free in XDestroyImage() */
1205     XDestroyImage(img);
1206 }
1207 
x_PLoad(char * filename)1208 void x_PLoad(char *filename){
1209   static XImage *image = NULL;
1210   if(image == NULL) {
1211     image=XCreateImage(mywin.d,
1212 		       DefaultVisual(mywin.d,DefaultScreen(mywin.d)),
1213 		       DefaultDepth(mywin.d,DefaultScreen(mywin.d)),
1214 		       ZPixmap,0,None,SIZEX,SIZEY,8,0);
1215     image->data = image_buffer;
1216   }
1217   memset(image->data, 0, SIZEX * SIZEY);
1218   if(!pho_load_pixel(image,mywin.curcoltab,filename))
1219     return;
1220   XPutImage(mywin.d,mywin.active_screen,mywin.gc
1221 	    ,image,0,0,0,0,SIZEX,SIZEY);
1222   if(mywin.active_screen==mywin.disp_screen)
1223     Redraw(0,0,SIZEX,SIZEY);
1224 }
1225 
x_Mag(magdata * mag,int32 x,int32 y,int32 s,int32 p)1226 void x_Mag(magdata *mag,int32 x,int32 y,int32 s,int32 p)
1227 {
1228   XImage *image;
1229   int pixsizex,pixsizey;
1230   if(mag==NULL){
1231     ctl->cmsg(CMSG_INFO,VERB_VERBOSE,"mag ERROR!\n");
1232     return;
1233   }
1234   x=(x==WRD_NOARG)?mag->xorig:x;
1235   y=(y==WRD_NOARG)?mag->yorig:y;
1236   p=(p==WRD_NOARG)?0:p;
1237   x=x+mag->xorig/8*8-mag->xorig;
1238   pixsizex=mag->xend-mag->xorig/8*8+1;
1239   pixsizey=mag->yend-mag->yorig+1;
1240 
1241   mag->pal[0]=17;
1242   x_Pal(mag->pal,16);
1243   if(mywin.active_screen==mywin.screens[0]){ /* Foreground screen */
1244     mag->pal[0]=18;
1245     x_Pal(mag->pal,16);
1246   } else {			/* Background screen */
1247     mag->pal[0]=19;
1248     x_Pal(mag->pal,16);
1249   }
1250   if((p&1)==0){
1251     mag->pal[0]=0;
1252     x_Pal(mag->pal,16);
1253   }
1254   if(p==2)
1255     return;
1256   image=XCreateImage(mywin.d,
1257 		     DefaultVisual(mywin.d,DefaultScreen(mywin.d)),
1258 		     DefaultDepth(mywin.d,DefaultScreen(mywin.d)),
1259 		     ZPixmap,0,None,pixsizex,pixsizey,8,0);
1260   image->data=image_buffer;
1261   memset(image->data, 0, pixsizex*pixsizey);
1262   mag_load_pixel(image,mywin.curcoltab,mag);
1263   XPutImage(mywin.d,mywin.active_screen,mywin.gc
1264 	    ,image,0,0,x,y,pixsizex,pixsizey);
1265   if(mywin.active_screen==mywin.disp_screen)
1266     Redraw(x,y,pixsizex,pixsizey);
1267   MyDestroyImage(image);
1268 }
x_Gcls(int mode)1269 void x_Gcls(int mode)
1270 {
1271   int gmode_save;
1272   gmode_save = mywin.gmode;
1273 
1274   if(mode==0)
1275     mode=15;
1276   x_GMode(mode);
1277   XSetFunction(mywin.d,mywin.gcgr,GXclear);
1278   XFillRectangle(mywin.d,mywin.active_screen,mywin.gcgr,0,0,SIZEX,SIZEY);
1279   XSetFunction(mywin.d,mywin.gcgr,GXcopy);
1280   x_GMode(gmode_save);
1281   Redraw(0,0,SIZEX,SIZEY);
1282 }
1283 
x_Ton(int param)1284 void x_Ton(int param)
1285 {
1286   mywin.ton=param;
1287   Redraw(0,0,SIZEX,SIZEY);
1288 }
1289 
x_Gon(int param)1290 void x_Gon(int param)
1291 {
1292   mywin.gon=param;
1293   Redraw(0,0,SIZEX,SIZEY);
1294 }
1295 
x_RedrawControl(int flag)1296 void x_RedrawControl(int flag)
1297 {
1298   mywin.redrawflag = flag;
1299   if(flag)
1300   {
1301     Redraw(0,0,SIZEX,SIZEY);
1302     store_palette();
1303   }
1304   XFlush(mywin.d);
1305 }
x_Gline(int * params,int nparam)1306 void x_Gline(int *params,int nparam)
1307 {
1308     int x, y, w, h; /* Update rectangle region */
1309     unsigned long color;
1310     Pixmap screen;
1311 
1312     x = min(params[0], params[2]);
1313     y = min(params[1], params[3]);
1314     w = max(params[0], params[2]) - x + 1;
1315     h = max(params[1], params[3]) - y + 1;
1316 
1317     screen = mywin.active_screen;
1318 
1319     switch(params[5])
1320     {
1321       default:
1322       case 0:
1323 	if (truecolor)
1324 	  color = (unsigned long) params[4];
1325 	else
1326 	  color = mywin.curcoltab[params[4]].pixel;
1327 	XSetForeground(mywin.d,mywin.gcgr,color);
1328 	XDrawLine(mywin.d,screen,mywin.gcgr,
1329 		  params[0],params[1],params[2],params[3]);
1330 	break;
1331       case 1:
1332 	if (truecolor)
1333 	  color = (unsigned long) params[4];
1334 	else
1335 	  color = mywin.curcoltab[params[4]].pixel;
1336 	XSetForeground(mywin.d,mywin.gcgr,color);
1337 	XDrawRectangle(mywin.d,screen,mywin.gcgr,x,y,w-1,h-1);
1338 
1339 	break;
1340       case 2:
1341 	if (truecolor)
1342 	  color = (unsigned long) params[6];
1343 	else
1344 	  color = mywin.curcoltab[params[6]].pixel;
1345 	XSetForeground(mywin.d,mywin.gcgr,color);
1346 	XFillRectangle(mywin.d,screen,mywin.gcgr,x,y,w,h);
1347 
1348 	break;
1349   }
1350   if(mywin.active_screen==mywin.disp_screen)
1351     Redraw(x,y,w,h);
1352 }
x_GCircle(int * params,int nparam)1353 void x_GCircle(int *params,int nparam)
1354 {
1355   int pad=0;
1356   int (*Linefunc)();
1357   Linefunc=XDrawArc;
1358   if(nparam>=5){
1359     switch(params[4]){
1360     default:
1361     case 0:
1362     case 1:
1363       Linefunc=XDrawArc;
1364       if (truecolor)
1365 	XSetForeground(mywin.d,mywin.gcgr,(unsigned long) params[3]);
1366       else
1367 	XSetForeground(mywin.d,mywin.gcgr,mywin.curcoltab[params[3]].pixel);
1368 
1369       pad=-1;
1370       break;
1371     case 2:
1372       Linefunc=XFillArc;
1373       if (truecolor)
1374 	XSetForeground(mywin.d,mywin.gcgr,(unsigned long) params[5]);
1375       else
1376 	XSetForeground(mywin.d,mywin.gcgr,mywin.curcoltab[params[5]].pixel);
1377       break;
1378     }
1379   }
1380   if(nparam>=3){
1381     int xcorner,ycorner,width,height,angle;
1382     xcorner=params[0]-params[2];/*x_center-radius*/
1383     ycorner=params[1]-params[2];/*y_center-radius*/
1384     width=height=params[2]*2;/*radius*2*/
1385     angle=360*64;
1386     (*Linefunc)(mywin.d,mywin.active_screen,mywin.gcgr,xcorner,ycorner,
1387 		width+pad,height+pad,
1388 		0,angle);
1389     if(mywin.active_screen==mywin.disp_screen)
1390       Redraw(xcorner,ycorner,width,height);
1391   }
1392 }
1393 
1394 
1395 #define FOREGROUND_PALLET 0
x_Pal(int * param,int nparam)1396 void x_Pal(int *param,int nparam){
1397   int pallet;
1398 
1399   if(nparam==NUMPXL){
1400     pallet=param[0];
1401     nparam--;
1402     param++;
1403   }
1404   else
1405     pallet=FOREGROUND_PALLET;
1406 
1407   if(nparam==NUMPXL-1){
1408     int i;
1409     for(i=0;i<NUMPXL;i++){
1410       col12toXColor(param[i],&mywin.gcolor[pallet][i]);
1411     }
1412     if(pallet==FOREGROUND_PALLET){
1413       memcpy(mywin.curcoltab,mywin.gcolor[FOREGROUND_PALLET],sizeof(mywin.curcoltab));
1414       if(mywin.redrawflag)
1415 	  store_palette();
1416     }
1417   }
1418 }
x_Palrev(int pallet)1419 void x_Palrev(int pallet)
1420 {
1421   int i;
1422   if(pallet < 0 || pallet > MAXPAL)
1423     return;
1424   for(i = 0; i < NUMPXL; i++){
1425     mywin.gcolor[pallet][i].red ^= 0xffff;
1426     mywin.gcolor[pallet][i].green ^= 0xffff;
1427     mywin.gcolor[pallet][i].blue ^= 0xffff;
1428   }
1429 
1430   if(pallet == FOREGROUND_PALLET){
1431     memcpy(mywin.curcoltab,
1432 	   mywin.gcolor[FOREGROUND_PALLET],
1433 	   sizeof(mywin.curcoltab));
1434     if(mywin.redrawflag)
1435 	  store_palette();
1436   }
1437 }
x_Gscreen(int active,int appear)1438 void x_Gscreen(int active,int appear)
1439 {
1440   if(active<NUMVSCREEN)
1441      mywin.active_screen=mywin.screens[active];
1442   if((appear<NUMVSCREEN)&&(mywin.disp_screen!=mywin.screens[appear])){
1443     mywin.disp_screen=mywin.screens[appear];
1444     Redraw(0,0,SIZEX,SIZEY);
1445   }
1446 }
1447 
1448 #define FADE_REDUCE_TIME 0.1
x_Fade(int * params,int nparam,int step,int maxstep)1449 void x_Fade(int *params,int nparam,int step,int maxstep)
1450 {
1451   static XColor *frompal=NULL,*topal=NULL;
1452   if(params==NULL){
1453     int i;
1454     if(frompal==NULL||topal==NULL)
1455       return;
1456 
1457     if(step==maxstep){
1458       memcpy(mywin.curcoltab,topal,sizeof(mywin.curcoltab));
1459       memcpy(mywin.gcolor[0],mywin.curcoltab,sizeof(mywin.curcoltab));
1460     }
1461     else{
1462       int tmp;
1463       if(!mywin.redrawflag)
1464 	return;
1465       if(truecolor) {
1466       /* @FADE for TrueColor takes many CPU powers.
1467        * So reduce @FADE controls.
1468        */
1469 	if((step & 1) == 0 || aq_filled() < AUDIO_BUFFER_SIZE)
1470 	  return; /* Skip fade */
1471       }
1472       for(i=0;i<NUMPXL;i++){
1473 	tmp=(topal[i].red-frompal[i].red)/maxstep;
1474 	mywin.curcoltab[i].red=tmp*step+frompal[i].red;
1475 	tmp=(topal[i].green-frompal[i].green)/maxstep;
1476 	mywin.curcoltab[i].green=tmp*step+frompal[i].green;
1477 	tmp=(topal[i].blue-frompal[i].blue)/maxstep;
1478 	mywin.curcoltab[i].blue=tmp*step+frompal[i].blue;
1479       }
1480     }
1481     if(mywin.redrawflag)
1482 	store_palette();
1483   }
1484   else{
1485     if(params[2] == 0 && params[1] < MAXPAL) {
1486       memcpy(mywin.curcoltab,mywin.gcolor[params[1]],sizeof(mywin.curcoltab));
1487       memcpy(mywin.gcolor[0],mywin.curcoltab,sizeof(mywin.curcoltab));
1488       if(mywin.redrawflag) {
1489 	  store_palette();
1490       }
1491     }
1492     else if(params[0] < MAXPAL && params[1] < MAXPAL)
1493     {
1494       frompal=mywin.gcolor[params[0]];
1495       topal=mywin.gcolor[params[1]];
1496     }
1497     else
1498       frompal=topal=NULL;
1499 
1500     return;
1501   }
1502 }
1503 
x_Startup(int version)1504 void x_Startup(int version)
1505 {
1506     int i;
1507     Parse(-1);
1508     memset(mywin.scrnbuf, 0, LINES*sizeof(Linbuf *));
1509     mywin.curline = 0;
1510     mywin.curcol = 0;
1511     mywin.ton = 1;
1512     mywin.gon = 1;
1513     mywin.curattr = 0;
1514     x_VRel();
1515     x_GMode(-1);
1516     InitColor(mywin.cmap, False);
1517     mywin.active_screen = mywin.disp_screen = mywin.screens[0];
1518 
1519     XSetForeground(mywin.d, mywin.gcgr, mywin.curcoltab[0].pixel);
1520     XSetForeground(mywin.d, mywin.gc, mywin.txtcolor[COLOR_DEFAULT].pixel);
1521     for(i = 0; i < NUMVSCREEN; i++)
1522 	XFillRectangle(mywin.d, mywin.screens[i], mywin.gcgr,
1523 		       0, 0, SIZEX, SIZEY);
1524     XFillRectangle(mywin.d, mywin.offscr, mywin.gcgr, 0, 0, SIZEX, SIZEY);
1525     XSetWindowBackgroundPixmap(mywin.d, mywin.w, mywin.offscr);
1526     XFillRectangle(mywin.d, mywin.w, mywin.gcgr, 0, 0, SIZEX, SIZEY);
1527     if(truecolor && shm_screen)
1528 	XFillRectangle(mywin.d, shm_screen->pm, mywin.gcgr,
1529 		       0, 0, SIZEX, SIZEY);
1530 }
1531 
1532 /*Graphic Definition*/
1533 #define GRPH_LINE_MODE 1
1534 #define GRPH_CIRCLE_MODE 2
1535 #define GRPH_PAL_CHANGE 3
1536 #define GRPH_FADE 4
1537 #define GRPH_FADE_STEP 5
GrphCMD(int * params,int nparam)1538 static void GrphCMD(int *params,int nparam)
1539 {
1540   switch(params[0]){
1541   case GRPH_LINE_MODE:
1542     x_Gline(params+1,nparam-1);
1543     break;
1544   case GRPH_CIRCLE_MODE:
1545     x_GCircle(params+1,nparam-1);
1546     break;
1547   case GRPH_PAL_CHANGE:
1548     x_Pal(params+1,nparam-1);
1549     break;
1550   case GRPH_FADE:
1551     x_Fade(params+1,nparam-1,-1,-1);
1552     break;
1553   case GRPH_FADE_STEP:
1554     x_Fade(NULL,0,params[1],params[2]);
1555     break;
1556   }
1557 }
1558 /*****************************************************
1559  * VT parser
1560  *
1561  *
1562  ******************************************************/
1563 #define MAXPARAM 20
Parse(int c)1564 static int Parse(int c)
1565 {
1566   static int *prstbl=groundtable;
1567   static char mbcs;
1568   static int params[MAXPARAM],nparam=0;
1569   static int hankaku=0;
1570   static int savcol,savline;
1571   static long savattr;
1572   if(c==-1) {
1573     prstbl=groundtable;
1574     mbcs=0;
1575     nparam=0;
1576     hankaku=0;
1577     savcol=savline=0;
1578     return 0;
1579   }
1580 
1581   if(mbcs&&
1582      prstbl !=mbcstable&&
1583      prstbl !=scstable&&
1584      prstbl !=scstable){
1585     mbcs=0;
1586   }
1587   switch(prstbl[c]){
1588   case CASE_IGNORE_STATE:
1589     prstbl=igntable;
1590     break;
1591   case CASE_IGNORE_ESC:
1592     prstbl=iestable;
1593     break;
1594   case CASE_ESC:
1595     prstbl=esctable;
1596     break;
1597   case CASE_ESC_IGNORE:
1598     prstbl=eigtable;
1599     break;
1600   case CASE_ESC_DIGIT:
1601     if(nparam<MAXPARAM){
1602       if(params[nparam]==DEFAULT){
1603 	params[nparam]=0;
1604       }
1605       params[nparam]*=10;
1606       params[nparam]+=c-'0';
1607     }
1608     break;
1609   case CASE_ESC_SEMI:
1610     nparam++;
1611     params[nparam]=DEFAULT;
1612     break;
1613   case CASE_TAB:
1614     mywin.curcol+=TAB_SET;
1615     mywin.curcol&=~(TAB_SET-1);
1616     break;
1617   case CASE_BS:
1618     if(mywin.curcol > 0)
1619       mywin.curcol--;
1620 #if 0 /* ^H maybe work backward character in MIMPI's screen */
1621     DelChar(mywin.curline,mywin.curcol);
1622     mywin.scrnbuf[mywin.curline][mywin.curcol].c=0;
1623     mywin.scrnbuf[mywin.curline][mywin.curcol].attr=0;
1624 #endif
1625     break;
1626   case CASE_CSI_STATE:
1627     nparam=0;
1628     params[0]=DEFAULT;
1629     prstbl=csitable;
1630     break;
1631   case CASE_SCR_STATE:
1632     prstbl=scrtable;
1633     mbcs=0;
1634     break;
1635   case CASE_MBCS:
1636     hankaku=0;
1637     prstbl=mbcstable;
1638     mbcs=MBCS;
1639     break;
1640   case CASE_SCS_STATE:
1641     if(mbcs)
1642       prstbl=smbcstable;
1643     else
1644       prstbl=scstable;
1645     break;
1646   case CASE_GSETS:
1647     mywin.curattr=(mbcs)?(mywin.curattr|CATTR_16FONT):
1648       (mywin.curattr&~(CATTR_16FONT));
1649     if(!mbcs){
1650       hankaku=(c=='I')?1:0;
1651     }
1652     prstbl=groundtable;
1653     break;
1654   case CASE_DEC_STATE:
1655     prstbl =dectable;
1656     break;
1657   case CASE_SS2:
1658   case CASE_SS3:
1659     /*These are ignored because this will not accept SS2 SS3 charset*/
1660   case CASE_GROUND_STATE:
1661     prstbl=groundtable;
1662     break;
1663   case CASE_CR:
1664     mywin.curcol=0;
1665     prstbl=groundtable;
1666     break;
1667   case CASE_IND:
1668   case CASE_VMOT:
1669     mywin.curline++;
1670     mywin.curcol=0;
1671     prstbl=groundtable;
1672     break;
1673   case CASE_CUP:
1674     mywin.curline=(params[0]<1)?0:params[0]-1;
1675     if(nparam>=1)
1676       mywin.curcol=(params[1]<1)?0:params[1]-1;
1677     else
1678       mywin.curcol=0;
1679     prstbl=groundtable;
1680     break;
1681   case CASE_PRINT:
1682     if(mywin.curcol==COLS){
1683       mywin.curcol++;
1684       return 1;
1685     }
1686     if(mywin.curattr&CATTR_16FONT){
1687       if(!(mywin.curattr&CATTR_LPART)&&(mywin.curcol==COLS-1)){
1688 	mywin.curcol+=2;
1689 	return 1;
1690       }
1691       mywin.curattr^=CATTR_LPART;
1692     }
1693     else
1694       mywin.curattr&=~CATTR_LPART;
1695     DelChar(mywin.curline,mywin.curcol);
1696     if(hankaku==1)
1697       c|=0x80;
1698     mywin.scrnbuf[mywin.curline][mywin.curcol].attr=mywin.curattr;
1699     mywin.scrnbuf[mywin.curline][mywin.curcol].c=c;
1700     mywin.curcol++;
1701     break;
1702   case CASE_CUU:
1703     mywin.curline-=((params[0]<1)?1:params[0]);
1704     prstbl=groundtable;
1705     break;
1706   case CASE_CUD:
1707     mywin.curline+=((params[0]<1)?1:params[0]);
1708     prstbl=groundtable;
1709     break;
1710   case CASE_CUF:
1711     mywin.curcol+=((params[0]<1)?1:params[0]);
1712     prstbl=groundtable;
1713     break;
1714   case CASE_CUB:
1715     mywin.curcol-=((params[0]<1)?1:params[0]);
1716     prstbl=groundtable;
1717     break;
1718   case CASE_ED:
1719     switch(params[0]){
1720     case DEFAULT:
1721     case 1:
1722       {
1723 	int j;
1724 	if(mywin.scrnbuf[mywin.curline]!=NULL)
1725 	  ClearLeft();
1726 	for(j=0;j<mywin.curline;j++)
1727 	  ClearLine(j);
1728       }
1729       break;
1730     case 0:
1731       {
1732 	int j;
1733 	if(mywin.scrnbuf[mywin.curline]!=NULL){
1734 	  ClearRight();
1735 	}
1736 	for(j=mywin.curline;j<LINES;j++)
1737 	  ClearLine(j);
1738       }
1739       break;
1740     case 2:
1741       {
1742 	int j;
1743 	for(j=0;j<LINES;j++){
1744 	  free(mywin.scrnbuf[j]);
1745 	  mywin.scrnbuf[j]=NULL;
1746 	}
1747 	mywin.curline=0;
1748 	mywin.curcol=0;
1749 	break;
1750       }
1751     }
1752     RedrawInject(0,0,SIZEX,SIZEY,False);
1753     prstbl=groundtable;
1754     break;
1755   case CASE_DECSC:
1756     savcol=mywin.curcol;
1757     savline=mywin.curline;
1758     savattr=mywin.curattr;
1759     prstbl=groundtable;
1760   case CASE_DECRC:
1761     mywin.curcol=savcol;
1762     mywin.curline=savline;
1763     mywin.curattr=savattr;
1764     prstbl=groundtable;
1765     break;
1766   case CASE_SGR:
1767     {
1768       int i;
1769       for(i=0;i<nparam+1;i++)
1770 	switch(params[i]){
1771 	default:
1772 	  mywin.curattr&=~(CATTR_COLORED|CATTR_BGCOLORED|CATTR_TXTCOL_MASK);
1773 	  break;
1774 	case 16:
1775 	case 17:
1776 	case 18:
1777 	case 19:
1778 	case 20:
1779 	case 21:
1780 	case 22:
1781 	case 23:
1782 	  /* Remap 16-23 into 30-37 */
1783 	  params[i] = wrd_color_remap[params[i] - 16] + 30;
1784 	  /*FALLTHROUGH*/
1785 	case 30:
1786 	case 31:
1787 	case 32:
1788 	case 33:
1789 	case 34:
1790 	case 35:
1791 	case 36:
1792 	case 37:
1793 	  mywin.curattr&=~CATTR_TXTCOL_MASK;
1794 	  mywin.curattr|=(params[i]-30)<<CATTR_TXTCOL_MASK_SHIFT;
1795 	  mywin.curattr|=CATTR_COLORED;
1796 	  break;
1797 	case 40:
1798 	case 41:
1799 	case 42:
1800 	case 43:
1801 	case 44:
1802 	case 45:
1803 	case 46:
1804 	case 47:
1805 	  mywin.curattr&=~CATTR_TXTCOL_MASK;
1806 	  mywin.curattr&=~CATTR_COLORED;
1807 	  mywin.curattr|=(params[i]-40)<<CATTR_TXTCOL_MASK_SHIFT;
1808 	  mywin.curattr|=CATTR_BGCOLORED;
1809 	  break;
1810 	}
1811     }
1812     prstbl=groundtable;
1813     break;
1814   case CASE_EL:
1815     switch(params[0]){
1816     case DEFAULT:
1817     case 0:
1818       ClearRight();
1819       break;
1820     case 1:
1821       ClearLeft();
1822       break;
1823     case 2:
1824       ClearLine(mywin.curline);
1825       break;
1826     }
1827     prstbl=groundtable;
1828     break;
1829   case CASE_NEL:
1830     mywin.curline++;
1831     mywin.curcol=0;
1832     mywin.curline=(mywin.curline<LINES)?mywin.curline:LINES;
1833     break;
1834 /*Graphic Commands*/
1835   case CASE_MY_GRAPHIC_CMD:
1836     GrphCMD(params,nparam);
1837     prstbl=groundtable;
1838     break;
1839 /*Unimpremented Command*/
1840   case CASE_ICH:
1841   case CASE_IL:
1842   case CASE_DL:
1843   case CASE_DCH:
1844   case CASE_DECID:
1845   case CASE_DECKPAM:
1846   case CASE_DECKPNM:
1847   case CASE_HP_BUGGY_LL:
1848   case CASE_HTS:
1849   case CASE_RI:
1850   case CASE_DA1:
1851   case CASE_CPR:
1852   case CASE_DECSET:
1853   case CASE_RST:
1854   case CASE_DECSTBM:
1855   case CASE_DECREQTPARM:
1856   case CASE_OSC:
1857   case CASE_RIS:
1858   case CASE_HP_MEM_LOCK:
1859   case CASE_HP_MEM_UNLOCK:
1860   case CASE_LS2:
1861   case CASE_LS3:
1862   case CASE_LS3R:
1863   case CASE_LS2R:
1864   case CASE_LS1R:
1865     ctl->cmsg(CMSG_INFO,VERB_VERBOSE,"NOT IMPREMENTED:%d\n",prstbl[c]);
1866     prstbl=groundtable;
1867     break;
1868   case CASE_BELL:
1869   case CASE_IGNORE:
1870   default:
1871     break;
1872   }
1873   return 0;
1874 }
AddLine(const unsigned char * str,int len)1875 void AddLine(const unsigned char *str,int len)
1876 {
1877   Linbuf *ptr;
1878   int i,j;
1879   /*Initialize Redraw rectangle Manager*/
1880   RedrawInject(-1,-1,-1,-1,False);
1881 
1882   /*Allocate LineBuffer*/
1883   if(len==0)
1884     len=strlen(str);
1885   for(i=0;i<len;i++){
1886     if(mywin.scrnbuf[mywin.curline]==NULL){
1887       ptr=(Linbuf *)calloc(COLS,sizeof(Linbuf)+1);
1888       if(ptr==NULL)
1889 	exit(-1);
1890       else
1891 	mywin.scrnbuf[mywin.curline]=ptr;
1892     }
1893     /*
1894      * Proc Each Charactor
1895      * If >0 Returned unput current value
1896      */
1897     if(Parse(str[i])!=0){
1898       i--;
1899     }
1900     /*Wrapping Proc*/
1901     while(mywin.curcol>=COLS+1){
1902       mywin.curcol-=COLS;
1903       mywin.curline++;
1904     }
1905     while(mywin.curcol<0){
1906       mywin.curcol+=COLS;
1907       mywin.curline--;
1908     }
1909     /*Scroll Proc*/
1910     mywin.curline=(mywin.curline<0)?0:mywin.curline;
1911     while(mywin.curline>=LINES){
1912       mywin.curline--;
1913       free(mywin.scrnbuf[0]);
1914       mywin.scrnbuf[0]=NULL;
1915       for(j=1;j<LINES;j++){
1916 	mywin.scrnbuf[j-1]=mywin.scrnbuf[j];
1917       }
1918       mywin.scrnbuf[LINES-1]=NULL;
1919       RedrawInject(0,0,SIZEX,SIZEY,False);
1920     }
1921   }
1922   RedrawInject(0,0,0,0,True);
1923 }
WinFlush(void)1924 void WinFlush(void){
1925   if(mywin.redrawflag)
1926     XFlush(mywin.d);
1927 }
1928 /*
1929  *This Function Dumps Charactor Screen buffer status
1930  *Purely Debugging Purpose this code should be desabled
1931  *if you need not.
1932  */
1933 
1934 #ifdef SCREENDEBUG
DebugDump(void)1935 DebugDump(void)
1936 {
1937   FILE *f;
1938   int i,j;
1939   f=fopen("screen","w+");
1940   for(i=0;i<LINES;i++){
1941     fprintf(f,"LINE %d \n",i);
1942     for(j=0;j<COLS;j++){
1943       if(mywin.scrnbuf[i]!=NULL){
1944 	Linbuf *a=&mywin.scrnbuf[i][j];
1945 	fprintf(f,"{%x %c}",a->attr,a->c);
1946       }
1947     }
1948    fprintf(f,"\n");
1949   }
1950   fclose(f);
1951 }
1952 #endif
WinEvent(void)1953 void WinEvent(void)
1954 {
1955   XEvent e;
1956   int rdx1, rdy1, rdx2, rdy2;
1957   rdx1 = rdy1 = rdx2 = rdy2 = -1;
1958   XSync(mywin.d, False);
1959   while(QLength(mywin.d)>0){
1960     XNextEvent(mywin.d,&e);
1961     switch(e.type){
1962     case ButtonPress:
1963       Redraw(0,0,SIZEX,SIZEY);
1964       rdx1=0;
1965       rdy1=0;
1966       rdx2=SIZEX;
1967       rdy2=SIZEY;
1968       if(e.xbutton.button==3){
1969 #ifdef SCREENDEBUG
1970 	DebugDump();
1971 #endif
1972       }
1973     }
1974   }
1975 
1976   if(rdx1 != -1){
1977     Redraw(rdx1, rdy1, rdx2 - rdx1, rdy2 - rdy1);
1978     XFlush(mywin.d);
1979   }
1980 }
EndWin(void)1981 void EndWin(void)
1982 {
1983   if(mywin.d!=NULL)
1984   {
1985     if(truecolor && shm_screen)
1986       free_image_pixmap(shm_screen);
1987 
1988     XCloseDisplay(mywin.d);
1989     free(image_buffer);
1990   }
1991   mywin.d=NULL;
1992 }
1993 
OpenWRDWindow(char * opt)1994 int OpenWRDWindow(char *opt)
1995 {
1996     if(InitWin(opt) == -1)
1997     {
1998 	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1999 		  "WRD: Can't open WRD window becase of error");
2000 	return -1;
2001     }
2002     XMapWindow(mywin.d, mywin.w);
2003     XSync(mywin.d, False);
2004     return 0;
2005 }
2006 
CloseWRDWindow(void)2007 void CloseWRDWindow(void)
2008 {
2009     if(mywin.d != NULL)
2010     {
2011 	XUnmapWindow(mywin.d, mywin.w);
2012 	XSync(mywin.d, False);
2013     }
2014 }
2015 
free_image_pixmap(ImagePixmap * ip)2016 static void free_image_pixmap(ImagePixmap *ip)
2017 {
2018     XFreePixmap(mywin.d, ip->pm);
2019 
2020 #if XSHM_SUPPORT
2021     if(ip->shminfo.shmid != -1)
2022     {
2023 	/* To destroy a shard memory XImage, you should call XShmDetach()
2024 	 * first.
2025 	 */
2026 	XShmDetach(mywin.d, &ip->shminfo);
2027 
2028 	/* Unmap shared memory segment */
2029 	shmdt(ip->shminfo.shmaddr);
2030 
2031 	/* Remove a shared memory ID from the system */
2032 	shmctl(ip->shminfo.shmid, IPC_RMID, NULL);
2033     }
2034 #endif /* XSHM_SUPPORT */
2035     if(ip->im != NULL)
2036       XDestroyImage(ip->im);
2037     free(ip);
2038 }
2039 
2040 
2041 #if XSHM_SUPPORT
2042 static int shm_error;
my_err_handler(Display * dpy,XErrorEvent * e)2043 static int my_err_handler(Display* dpy, XErrorEvent* e)
2044 {
2045     shm_error = e->error_code;
2046     ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
2047 	      "Warning: X WRD Warning: Can't create SHM Pixmap. error-code=%d",
2048 	      shm_error);
2049     return shm_error;
2050 }
2051 
create_shm_image_pixmap(int width,int height)2052 static ImagePixmap *create_shm_image_pixmap(int width, int height)
2053 {
2054     XErrorHandler origh;
2055     ImagePixmap *ip;
2056     int shm_depth;
2057 
2058     shm_depth = theDepth;
2059     ip = (ImagePixmap *)safe_malloc(sizeof(ImagePixmap));
2060 
2061     shm_error = 0;
2062     origh = XSetErrorHandler(my_err_handler);
2063 
2064     /* There is no need to initialize XShmSegmentInfo structure
2065      * before the call to XShmCreateImage.
2066      */
2067     ip->im = XShmCreateImage(mywin.d, theVisual, theDepth,
2068 			     ZPixmap, NULL,
2069 			     &ip->shminfo, width, height);
2070     if(ip->im == NULL)
2071     {
2072 	if(shm_error == 0)
2073 	    shm_error = -1;
2074 	goto done;
2075     }
2076 
2077     /* allocate n-depth Z image data structure */
2078     ip->im->data = (char *)safe_malloc(ip->im->bytes_per_line *
2079 				       ip->im->height);
2080 
2081     /* The next step is to create the shared memory segment.
2082      * The return value of shmat() should be stored both
2083      * the XImage structure and the shminfo structure.
2084      */
2085     ip->shminfo.shmid = shmget(IPC_PRIVATE,
2086 			       ip->im->bytes_per_line * ip->im->height,
2087 			       IPC_CREAT | 0777);
2088 
2089     if(ip->shminfo.shmid == -1)
2090     {
2091 	ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
2092 		  "X Sherry Warning: Can't create SHM Pixmap.\n"
2093 		  "shmget: %s", strerror(errno));
2094 	XDestroyImage(ip->im);
2095 	ip->im = NULL;
2096 	shm_error = -1;
2097 	goto done;
2098     }
2099     ip->shminfo.shmaddr = ip->im->data =
2100 	(char *)shmat(ip->shminfo.shmid, NULL, 0);
2101     if(ip->shminfo.shmaddr == (void *)-1)
2102     {
2103 	ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
2104 		  "X Sherry Warning: Can't create SHM Pixmap.\n"
2105 		  "shmget: %s", strerror(errno));
2106 	shmctl(ip->shminfo.shmid, IPC_RMID, NULL);
2107 	XDestroyImage(ip->im);
2108 	ip->im = NULL;
2109 	shm_error = -1;
2110 	goto done;
2111     }
2112 
2113     /* If readOnly is True, XShmGetImage calls will fail. */
2114     ip->shminfo.readOnly = False;
2115 
2116 
2117     /* Tell the server to attach to your shared memory segment. */
2118     if(XShmAttach(mywin.d, &ip->shminfo) == 0)
2119     {
2120 	if(shm_error == 0)
2121 	{
2122 	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
2123 		      "X Sherry Warning: Can't create SHM Pixmap.\n"
2124 		      "Can't attach to the shared memory segment.");
2125 	    shm_error = -1;
2126 	}
2127 	shmdt(ip->shminfo.shmaddr);
2128 	shmctl(ip->shminfo.shmid, IPC_RMID, NULL);
2129 	XDestroyImage(ip->im);
2130 	ip->im = NULL;
2131 	goto done;
2132     }
2133 
2134     XSync(mywin.d, False);		/* Wait until ready. */
2135 
2136     ip->pm = XShmCreatePixmap(mywin.d, mywin.w, ip->im->data,
2137 			      &ip->shminfo, width, height, shm_depth);
2138     if(ip->pm == None)
2139     {
2140 	if(shm_error == 0)
2141 	{
2142 	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
2143 		      "X Sherry Warning: Can't create SHM Pixmap.\n"
2144 		      "XShmCreatePixmap() is failed");
2145 	    shm_error = -1;
2146 	}
2147 	shmdt(ip->shminfo.shmaddr);
2148 	shmctl(ip->shminfo.shmid, IPC_RMID, NULL);
2149 	XDestroyImage(ip->im);
2150 	ip->im = NULL;
2151 	goto done;
2152     }
2153 
2154   done:
2155     XSetErrorHandler(origh);
2156 
2157     if(ip->im == NULL)
2158     {
2159 	free(ip);
2160 	return NULL;
2161     }
2162     return ip;
2163 }
2164 #endif
2165