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