/* * X.c : X11 Window System driver for ME * This code is junk! But it might be helpful. * C Durland Public Domain */ #include #include #include #include #define PRINT char *strcpy(), *getenv(); /***********************************************************************/ #include "me2.h" #include "term.h" #include /* !!! temp */ #define NROW 30 /* Number of rows on screen */ #define NCOL 80 /* Number of columns on screen */ int mcolor, tcolor; typedef unsigned long int COLOR; int t_nrow = NROW -1, t_ncol = NCOL; void t_putchar(), ttopen(), t_flush(), cursor_on(), cursor_off(); static COLOR tfgcolor, tbgcolor, mfgcolor, mbgcolor, fg,bg; static Display *display; static XFontStruct *font; static short int crow, ccol; static GC gc, cgc; static Window window; /* ******************************************************************* */ /* ****************** FONTS ****************************************** */ /* ******************************************************************* */ #define FONTNAME "9x15" int cwidth, cheight, cascent, row_max, col_max; int roffset = 0, coffset = 0; #define RtoY(row) ((row)*cheight +roffset) /* row to top left of char */ #define RtoYc(row) (RtoY(row) +cascent) /* row to baseline */ #define CtoX(col) ((col)*cwidth +coffset) #define CHAR_XY(row,col) CtoX(col),RtoYc(row) #define MCWIDTH(font) /* width of biggest character in font */ \ ((font)->max_bounds.rbearing -(font)->min_bounds.lbearing) #define MCHEIGHT(font) /* height of biggest character in font */ \ ((font)->max_bounds.ascent +(font)->max_bounds.descent) load_font(fontname) char *fontname; { XFontStruct *f, *XLoadQueryFont(); if ((f = XLoadQueryFont(display,fontname)) ==NULL) return FALSE; font = f; cwidth = MCWIDTH(font); cheight = MCHEIGHT(font); cascent = font->max_bounds.ascent; return TRUE; } /* ******************************************************************** */ /* ******************************************************************** */ /* ******************************************************************** */ setcolor() {} mapcolor(tcolor,mcolor) COLOR tcolor, mcolor; { } void t_move(row,col) { cursor_off(); crow = row; ccol = col; cursor_on(); } clear_nchars(row,col,n) /* clear n characters from (row,col) */ { XSetState(display,gc,fg,bg,GXclear,AllPlanes); XFillRectangle(display,window,gc, CtoX(col),RtoY(row), cwidth*(n),cheight); XSetFunction(display,gc,GXcopy); } void t_eeol() /* erase to end of line */ { cursor_off(); clear_nchars(crow,ccol, t_ncol -ccol); cursor_on(); } void t_eeop() /* erase to end of page or screen */ { cursor_off(); XClearWindow(display,window); } /* Write a character to the display */ void t_putchar(c) unsigned char c; { if (c=='\r' || c=='\n') return; /* ignore carriage return */ cursor_off(); if (c=='\b') /* backspace */ { clear_nchars(crow,--ccol,1); cursor_on(); return; } XDrawImageString(display,window,gc, CHAR_XY(crow,ccol), &c, 1); ccol++; cursor_on(); } void t_putchars(ptr,n) unsigned char *ptr; { cursor_off(); XDrawImageString(display,window,gc, CHAR_XY(crow,ccol), ptr, n); ccol += n; } void t_beep() { XBell(display,100); XFlush(display); } /* use beeper for volume */ /* * This function is called once to set up the terminal device streams. */ void t_open() { char *dname; unsigned long int bd, bw, pad; /* pixel values */ XGCValues gcv; /* struct for creating GC */ XSizeHints xsh; /* Size hints for window manager */ XSetWindowAttributes xwa; static int doodaa = FALSE; if (doodaa) return; doodaa = TRUE; /* open display */ dname = getenv("DISPLAY"); if (dname==NULL || (display = XOpenDisplay(display))==NULL) { puts("Can't open display."); exit(1); } /* load a font */ if (!load_font(FONTNAME)) { puts("Could not load font"); exit(1); } /* Select colors */ #if 0 bd = WhitePixel(display, DefaultScreen(display)); bg = BlackPixel(display, DefaultScreen(display)); fg = WhitePixel(display, DefaultScreen(display)); printf ("WhitePixel is %ld",bd); printf ("BlackPixel is %ld\n",bg); printf ("Display in %d x %d pixels\n ", DisplayWidth(display,DefaultScreen(display)), DisplayHeight(display,DefaultScreen(display))); #endif bd = 7; /* white */ fg = 7; /* white */ bg = 0; /* black */ /* Set the border width of the window, and the gap between the text and the egde of the window, "pad". */ pad = 3; bw = 5; /* Provide the window with an initial position & size. * See section 9.1.6 & 10.3. */ xsh.flags = (PPosition | PSize); /* width and height of the window */ xsh.height = (t_nrow+1)*MCHEIGHT(font); xsh.width = t_ncol*MCWIDTH(font); xsh.x = (DisplayWidth(display, DefaultScreen(display)) -xsh.width) /4; xsh.y = (DisplayHeight(display, DefaultScreen(display)) -xsh.height) /4; /* Create Window. See section 3.3 */ window = XCreateSimpleWindow(display, DefaultRootWindow(display), xsh.x,xsh.y, xsh.width,xsh.height, bw, bd, bg); #if 0 /* Set standard properties for window managers. See section 9.1 */ XSetStandardProperties(display,window,STRING,STRING, None, argv,argc,&xsh); XSetWMHints(display, window, &xwmh); /* Ensure that the window's colormap field points to the default colormap, so that the window manager knows the correct colormap to use for the window. See Section 3.2.9 also, set the window's Bit Gravity to reduce expose events */ xwa.colormap = DefaultColormap(display, DefaultScreen(display)); xwa.bit_gravity = CenterGravity; XChangeWindowAttributes(display,window, CWColormap, &xwa); #endif /* Create the GC for writing the text. See Section 5.3 */ gcv.font = font->fid; gcv.foreground = fg; gcv.background = bg; gc = XCreateGC(display,window, GCFont | GCForeground | GCBackground,&gcv); cgc = XCreateGC(display,window, GCFont | GCForeground | GCBackground,&gcv); XSetState(display,cgc,fg,bg,GXxor,AllPlanes); /* Specify event types of interest. See sections 8.5 & 8.4.5.1 */ XSelectInput(display,window, ExposureMask|KeyPressMask); /* Map the window to make it visible. see section 3.5. */ XMapWindow(display,window); XFlush(display); } /* * This function gets called just before we go back home to the command * interpreter. */ void t_close() { } /* * Flush terminal buffer. */ void t_flush() { /* XFlush(display); */ } /* !!!needed? */ /* * Read a character from the terminal, performing no editing and doing no echo * at all. Map terminal softkeys, etc to ME keys. * For X, this also processes events. */ KeyCode t_getchar() { KeyCode key; KeySym c; unsigned int state; XEvent event; XKeyEvent *xkey; XWindowAttributes xwa; while (TRUE) /* stay here until a key is pressed */ { XNextEvent(display,&event); if (event.type==KeyPress) { state = event.xkey.state; c = XLookupKeysym(&event.xkey, state & ShiftMask); PRINT(">> %x %x => %x\n",state,(int)event.xkey.keycode,(int)c); if (!map_key(state,c,&key)) continue; PRINT("keypress event: %x %x => %x\n",state,(int)c,(int)key); return key; } /* On the last of each group of Expose events, repaint the entire * window. See Section 8.4.5.1. */ if (event.type==Expose && event.xexpose.count==0) { int x,y; PRINT("expose event\n"); /* Remove any other pending Expose events from the queue to avoid * multiple repaints. See Section 8.7. */ while (XCheckTypedEvent(display,Expose,&event)) ; /* check to see if window resized */ /* if (XGetWindowAttributes(display,window,&xwa) ==0) continue; /* !!!??? */ screen_is_garbage = TRUE; wmunge(WFHARD|WFMODE); update(); continue; } } } /* Check to see is an event is waiting */ int keywaiting() { return XPending(display); } #if 0 /* Fast video support for DISPLAY.C for X */ void putline(row, buf, attr) /* note: row is 0 relative */ int row,attr; char *buf; { cursor_off(); XDrawImageString(display,window,gc, CHAR_XY(row,0), buf,t_ncol); } #endif /* ******************************************************************** */ /* *********** Cursor ************************************************* */ /* ******************************************************************** */ #define OFF 0 #define ON 1 static int cursor_state = OFF; static void blinkcursor() /* toggle the cursor */ { cursor_state = !cursor_state; /* put cursor between characters ie the real dot position */ XFillRectangle(display,window,cgc, CtoX(ccol)+1,RtoY(crow), cwidth-1,cheight); } static void cursor_off() { if (cursor_state==OFF) return; blinkcursor(); } static void cursor_on() { if (cursor_state==ON) return; blinkcursor(); }