📄 x_wrdwindow.c
字号:
/* TiMidity++ -- MIDI to WAVE converter and player Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp> Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA x_wrdwindow.c - MIMPI WRD for X Window written by Takanori Watanabe. - Modified by Masanao Izumo.*//* * PC98 Screen Emulator * By Takanori Watanabe. */#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include "timidity.h"#include "common.h"#include "x_mag.h"#include "x_wrdwindow.h"#include "VTparse.h"#include "wrd.h"#include "controls.h"#include "aq.h"#ifndef XSHM_SUPPORT#if defined(HAVE_XSHMCREATEPIXMAP) && \ defined(HAVE_X11_EXTENSIONS_XSHM_H) && \ defined(HAVE_SYS_IPC_H) && \ defined(HAVE_SYS_SHM_H)#define XSHM_SUPPORT 1#else#define XSHM_SUPPORT 0#endif#endif /* XSHM_SUPPORT */#if XSHM_SUPPORT#include <X11/extensions/XShm.h>#include <sys/ipc.h>#include <sys/shm.h>#endif#define SIZEX WRD_GSCR_WIDTH#define SIZEY WRD_GSCR_HEIGHT#define MBCS 1#define DEFAULT -1#define JISX0201 "-*-fixed-*-r-normal--16-*-*-*-*-*-jisx0201.1976-*"#define JISX0208 "-*-fixed-*-r-normal--16-*-*-*-*-*-jisx0208.1983-*"#define TXTCOLORS 8#define LINES WRD_TSCR_HEIGHT#define COLS WRD_TSCR_WIDTH#define TAB_SET 8#define CSIZEX ((SIZEX)/(COLS))#define CSIZEY ((SIZEY)/(LINES))#define min(a,b) ((a) <= (b) ? (a) : (b))#define max(a,b) ((a) >= (b) ? (a) : (b))typedef struct{ long attr;/*if attr<0 this attr is invalid*/#define CATTR_LPART (1)#define CATTR_16FONT (1<<1)#define CATTR_COLORED (1<<2)#define CATTR_BGCOLORED (1<<3) #define CATTR_TXTCOL_MASK_SHIFT 4#define CATTR_TXTCOL_MASK (7<<CATTR_TXTCOL_MASK_SHIFT)#define CATTR_INVAL (1<<31) char c;}Linbuf;/*VTParse Table externals*/extern int groundtable[];extern int csitable[];extern int dectable[];extern int eigtable[];extern int esctable[];extern int iestable[];extern int igntable[];extern int scrtable[];extern int scstable[];extern int mbcstable[];extern int smbcstable[];typedef struct _ImagePixmap{ Pixmap pm; XImage *im; /* Shared pixmap image (NULL for non-support) */#if XSHM_SUPPORT XShmSegmentInfo shminfo;#endif /* XSHM_SUPPORT */} ImagePixmap;static struct MyWin{ Display *d; Window w; XFontStruct *f8;/*8bit Font*/ XFontStruct *f16;/*16bit Font*/ GC gc, /* For any screens (nomask) */ gcgr, /* For Graphic screens (masked by @gmode) */ gcbmp; /* For bitmap (depth=1) */#define NUMVSCREEN 2 Pixmap screens[NUMVSCREEN]; /* Graphics screen buffers (PseudoColor) */ Pixmap active_screen, disp_screen; /* screens[0] or screens[1] */ Pixmap offscr; /* Double buffer */ Pixmap workbmp; /* Tempolary usage (bitmap) *//* active_screen: Graphics current draw screen. * disp_screen: Graphics visiable screen. * The color class of MIMPI graphics screen is 4 bit pseudo color. * The plane bits is masked by (basepix | pmask[0..3]) * * offscr: Background pixmap of the main window. * This screen is also used for double buffer. * Redraw(): (disp_screen + text) ----> offscr ----> Window * In TrueColor, it is needed to convert PseudoColor to TrueColor, here. */ /* For PC98 screen emulation. * Many text escape sequences are supported. */ Linbuf **scrnbuf; int curline; int curcol; long curattr;#define NUMPLANE 4#define NUMPXL 16#define MAXPAL 20 XColor txtcolor[TXTCOLORS],curcoltab[NUMPXL], gcolor[MAXPAL][NUMPXL],gcolorbase[NUMPXL]; unsigned long basepix, pmask[NUMPLANE], gscreen_plane_mask; int ton; int gon; int gmode;#define TON_NOSHOW 0 Colormap cmap;#define COLOR_BG 0#define COLOR_DEFAULT 7 int redrawflag;}mywin;static struct VGVRAM{ Pixmap *vpix; int num;}vgvram;const static char *TXTCOLORNAME[8]={ WRD_TEXT_COLOR0, WRD_TEXT_COLOR1, WRD_TEXT_COLOR2, WRD_TEXT_COLOR3, WRD_TEXT_COLOR4, WRD_TEXT_COLOR5, WRD_TEXT_COLOR6, WRD_TEXT_COLOR7};const static int colval12[16]={ 0x000,0xf00,0x0f0,0xff0,0x00f,0xf0f,0x0ff,0xfff, 0x444,0xc44,0x4c4,0xcc4,0x44c,0xc4c,0x4cc,0xccc};static char *image_buffer; /* Used for @MAG or @PLOAD */Visual *theVisual;int theScreen, theDepth;int bytes_per_image_pixel;static int Parse(int);static void Redraw(int,int,int,int);static int RedrawText(Drawable,int,int,int,int); /* Redraw only text */static void RedrawInject(int x,int y,int width,int height,int flag);/**** ImagePixmap interfaces ****/static ImagePixmap *create_shm_image_pixmap(int width, int height);static void free_image_pixmap(ImagePixmap *ip);/* for truecolor */static Bool truecolor;static ImagePixmap *shm_screen; /* for TrueColor conversion */static unsigned long truecolor_palette[NUMPXL];static int shm_format;/*12bit color value to color member of XColor structure */static void col12toXColor(int val,XColor *set){ set->red=((val>>8)&0xf)*0x1111; set->green=((val>>4)&0xf)*0x1111; set->blue=(0xf&val)*0x1111;}static int highbit(unsigned long ul){ int i; unsigned long hb; hb = 0x80000000UL; for(i = 31; ((ul & hb) == 0) && i >= 0; i--, ul<<=1) ; return i;}static unsigned long trueColorPixel(unsigned long r, /* 0..255 */ unsigned long g, /* 0..255 */ unsigned long b) /* 0..255 */{ static int rs, gs, bs; if(r == 0xffffffff) /* for initialize */ { rs = 15 - highbit(theVisual->red_mask); gs = 15 - highbit(theVisual->green_mask); bs = 15 - highbit(theVisual->blue_mask); return 0; } r *= 257; /* 0..65535 */ g *= 257; /* 0..65535 */ b *= 257; /* 0..65535 */ if(rs < 0) r <<= -rs; else r >>= rs; if(gs < 0) g <<= -gs; else g >>= gs; if(bs < 0) b <<= -bs; else b >>= bs; r &= theVisual->red_mask; g &= theVisual->green_mask; b &= theVisual->blue_mask; return r | g | b;}static void store_palette(void){ if(truecolor) { int i; for(i = 0; i < NUMPXL; i++) truecolor_palette[i] = trueColorPixel(mywin.curcoltab[i].red / 257, mywin.curcoltab[i].green / 257, mywin.curcoltab[i].blue / 257); Redraw(0, 0, SIZEX, SIZEY); } else XStoreColors(mywin.d, mywin.cmap, mywin.curcoltab, NUMPXL);}static int InitColor(Colormap cmap, Bool allocate){ int i,j; XColor dummy; if(allocate) { for(i=0;i<TXTCOLORS;i++) XAllocNamedColor(mywin.d,cmap,TXTCOLORNAME[i],&mywin.txtcolor[i],&dummy); if (!truecolor) { if(!XAllocColorCells(mywin.d,cmap,True,mywin.pmask,NUMPLANE,&mywin.basepix,1)) return 1; } else { trueColorPixel(0xffffffff, 0, 0); mywin.basepix = 0; for(i = 0; i < NUMPLANE; i++) mywin.pmask[i] = (1u<<i); /* 1,2,4,8 */ } mywin.gscreen_plane_mask = 0; for(i = 0; i < NUMPLANE; i++) mywin.gscreen_plane_mask |= mywin.pmask[i]; mywin.gscreen_plane_mask |= mywin.basepix; } for(i=0;i<NUMPXL;i++){ int k; unsigned long pvalue=mywin.basepix; k=i; for(j=0;j<NUMPLANE;j++){ pvalue|=(((k&1)==1)?mywin.pmask[j]:0); k=k>>1; } col12toXColor(colval12[i],&mywin.curcoltab[i]); mywin.curcoltab[i].pixel=pvalue; mywin.curcoltab[i].flags=DoRed|DoGreen|DoBlue; } if(!truecolor) XStoreColors(mywin.d, mywin.cmap, mywin.curcoltab, NUMPXL); else { int i; for(i = 0; i < NUMPXL; i++) truecolor_palette[i] = trueColorPixel(mywin.curcoltab[i].red / 257, mywin.curcoltab[i].green / 257, mywin.curcoltab[i].blue / 257); } for(i=0;i<MAXPAL;i++) memcpy(mywin.gcolor[i],mywin.curcoltab,sizeof(mywin.curcoltab)); memcpy(mywin.gcolorbase,mywin.curcoltab,sizeof(mywin.curcoltab)); return 0;}/*Initialize Window subsystem*//* return: * -1: error * 0: success * 1: already initialized */static int InitWin(char *opt){ XSizeHints *sh; XGCValues gcv; int i; static int init_flag = 0; if(init_flag) return init_flag; ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "Initialize WRD window"); /*Initialize Charactor buffer and attr */ mywin.curline=0; mywin.curcol=0; mywin.ton=1; mywin.gon=1; mywin.gmode=-1; mywin.curattr=0;/*Attribute Ground state*/ mywin.scrnbuf=(Linbuf **)calloc(LINES,sizeof(Linbuf *)); mywin.redrawflag=1; if((mywin.d=XOpenDisplay(NULL))==NULL){ ctl->cmsg(CMSG_ERROR,VERB_NORMAL,"WRD: Can't Open Display"); init_flag = -1; return -1; } if(strchr(opt, 'd')) { /* For debug */ fprintf(stderr,"Entering -Wx Debug mode\n"); XSynchronize(mywin.d, True); } theScreen = DefaultScreen(mywin.d); theDepth = DefaultDepth(mywin.d, theScreen); theVisual = DefaultVisual(mywin.d, theScreen); /* check truecolor */ if(theVisual->class == TrueColor || theVisual->class == StaticColor) truecolor=True; else truecolor=False; if((mywin.f8=XLoadQueryFont(mywin.d,JISX0201))==NULL){ ctl->cmsg(CMSG_ERROR,VERB_NORMAL,"%s: Can't load font",JISX0201); /* Can't load font JISX0201 */ XCloseDisplay(mywin.d); mywin.d=NULL; init_flag = -1; return -1; } if((mywin.f16=XLoadQueryFont(mywin.d,JISX0208))==NULL){ ctl->cmsg(CMSG_ERROR,VERB_NORMAL,"%s: Can't load font",JISX0208); XCloseDisplay(mywin.d); mywin.d=NULL; init_flag = -1; return -1; } mywin.w=XCreateSimpleWindow(mywin.d,DefaultRootWindow(mywin.d) ,0,0,SIZEX,SIZEY ,10, BlackPixel(mywin.d, theScreen), WhitePixel(mywin.d, theScreen)); mywin.cmap=DefaultColormap(mywin.d, theScreen); if(truecolor) {#if XSHM_SUPPORT shm_format = XShmPixmapFormat(mywin.d); if(shm_format == ZPixmap) shm_screen = create_shm_image_pixmap(SIZEX, SIZEY); else shm_screen = NULL; /* No-support other format */ if(!shm_screen) ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "X SHM Extention is off");#else shm_screen = NULL;#endif } /*This block initialize Colormap*/ if(InitColor(mywin.cmap, True)!=0){ mywin.cmap=XCopyColormapAndFree(mywin.d,mywin.cmap); if(InitColor(mywin.cmap, True)!=0){ ctl->cmsg(CMSG_ERROR,VERB_NORMAL,"WRD: Can't initialize colormap"); XCloseDisplay(mywin.d); mywin.d=NULL; init_flag = -1; return -1; } XSetWindowColormap(mywin.d,mywin.w,mywin.cmap); } /*Tell Window manager not to allow resizing * And set Application name */ sh=XAllocSizeHints(); sh->flags=PMinSize|PMaxSize; sh->min_width=SIZEX; sh->min_height=SIZEY; sh->max_width=SIZEX; sh->max_height=SIZEY; XSetWMNormalHints(mywin.d,mywin.w,sh); XStoreName(mywin.d,mywin.w,"timidity"); XSetIconName(mywin.d,mywin.w,"TiMidity"); XFree(sh); /* Alloc background pixmap(Graphic plane)*/ for(i=0;i<NUMVSCREEN;i++) mywin.screens[i]=XCreatePixmap(mywin.d,mywin.w,SIZEX,SIZEY,theDepth); mywin.offscr=XCreatePixmap(mywin.d,mywin.w,SIZEX,SIZEY,theDepth); mywin.workbmp=XCreatePixmap(mywin.d,mywin.w,SIZEX,CSIZEY,1); mywin.active_screen=mywin.screens[0]; mywin.disp_screen=mywin.screens[0]; XSetWindowBackgroundPixmap(mywin.d, mywin.w, mywin.offscr); gcv.graphics_exposures = False; mywin.gc=XCreateGC(mywin.d,mywin.w,GCGraphicsExposures, &gcv); mywin.gcgr=XCreateGC(mywin.d,mywin.w,GCGraphicsExposures, &gcv); mywin.gcbmp=XCreateGC(mywin.d,mywin.workbmp,0,0); XSetForeground(mywin.d,mywin.gcbmp,0); XSetBackground(mywin.d,mywin.gcbmp,1); /*This Initialize background pixmap(Graphic plane)*/ XSetForeground(mywin.d,mywin.gcgr,mywin.curcoltab[0].pixel); XFillRectangle(mywin.d,mywin.active_screen,mywin.gcgr,0,0,SIZEX,SIZEY); for(i=0;i<NUMVSCREEN;i++) XFillRectangle(mywin.d, mywin.screens[i], mywin.gcgr, 0, 0, SIZEX, SIZEY); XFillRectangle(mywin.d, mywin.offscr, mywin.gcgr, 0, 0, SIZEX, SIZEY); XSetForeground(mywin.d,mywin.gc,mywin.txtcolor[COLOR_DEFAULT].pixel); XSelectInput(mywin.d,mywin.w,ButtonPressMask); { /* calc bytes_per_image_pixel */ XImage *im; im = XCreateImage(mywin.d, theVisual, theDepth, ZPixmap, 0, NULL, 1, 1, 8, 0); bytes_per_image_pixel = im->bits_per_pixel/8; XDestroyImage(im); } image_buffer=(char *)safe_malloc(SIZEX*SIZEY*bytes_per_image_pixel); init_flag = 1; return 0;}/*************************************************** Redraw Routine This redraw Text screen. Graphic Screen is treated as background bitmap ***************************************************/static int DrawReverseString16(Display *disp,Drawable d,GC gc,int x,int y, XChar2b *string,int length){ int lbearing,ascent; lbearing=mywin.f16->min_bounds.lbearing; ascent=mywin.f16->max_bounds.ascent; XSetFont(disp,mywin.gcbmp,mywin.f16->fid); XDrawImageString16(disp,mywin.workbmp,mywin.gcbmp,-lbearing,ascent, string,length); XSetClipMask(disp,gc,mywin.workbmp); XSetClipOrigin(disp,gc,x+lbearing,y-ascent); XFillRectangle(disp,d,gc,x+lbearing,y-ascent,CSIZEX*length*2,CSIZEY); XSetClipMask(disp,gc,None); return 0;}static int DrawReverseString(Display *disp,Drawable d,GC gc,int x,int y, char *string,int length){ int lbearing,ascent; lbearing=mywin.f16->min_bounds.lbearing; ascent=mywin.f16->max_bounds.ascent; XSetFont(disp,mywin.gcbmp,mywin.f8->fid); XDrawImageString(disp,mywin.workbmp,mywin.gcbmp,-lbearing,ascent, string,length); XSetClipMask(disp,gc,mywin.workbmp); XSetClipOrigin(disp,gc,x+lbearing,y-ascent); XFillRectangle(disp,d,gc,x+lbearing,y-ascent,CSIZEX*length,CSIZEY); XSetClipMask(disp,gc,None); return 0;}static int RedrawText(Drawable drawable, int x,int y,int width,int height){ int i,yfrom,yto,xfrom,xto; int drawflag; xfrom=x/CSIZEX; xfrom=max(xfrom,0); xto=(x+width-1)/CSIZEX; xto=(xto<COLS-1)?xto:COLS-1; yfrom=y/CSIZEY; yfrom=max(yfrom,0); yto=(y+height-1)/CSIZEY; yto=(yto<LINES-1)?yto:LINES-1; drawflag=0; for(i=yfrom;i<=yto;i++){ if(mywin.scrnbuf[i]!=NULL){ long prevattr,curattr; char line[COLS+1]; int pos,s_x,e_x; int j,jfrom,jto; jfrom=xfrom; jto=xto; /* Check multibyte boudary */ if(jfrom > 0 && (mywin.scrnbuf[i][jfrom-1].attr&CATTR_LPART)) jfrom--; if(jto < COLS-1 && (mywin.scrnbuf[i][jto].attr&CATTR_LPART)) jto++; pos=0; prevattr=CATTR_INVAL; s_x=e_x=jfrom*CSIZEX; for(j=jfrom;j<=jto+1;j++){ if(j==jto+1 || mywin.scrnbuf[i][j].c==0) { curattr=CATTR_INVAL; } else curattr=mywin.scrnbuf[i][j].attr; if((prevattr&~CATTR_LPART)!=(curattr&~CATTR_LPART)){ XFontStruct *f=NULL; int lbearing,ascent;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -