Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!uwm.edu!spool.mu.edu!munnari.oz.au!manuel!anucsd!pdact!dbell From: dbell@pdact.pd.necisa.oz.au (David I. Bell) Newsgroups: comp.os.minix Subject: MINI-X graphics package (part 2/9) Message-ID: <993@pdact.pd.necisa.oz.au> Date: 22 Apr 91 00:49:50 GMT Organization: NEC Information Systems Australia, Canberra Lines: 1963 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'mini-x/clients/demo.c' <<'END_OF_FILE' X/* X * Demonstration program for mini-X graphics. X */ X#include X#include X X/* X * Definitions to make it easy to define cursors X */ X#define _ ((unsigned) 0) /* off bits */ X#define X ((unsigned) 1) /* on bits */ X#define MASK(a,b,c,d,e,f,g) \ X (((((((((((((a * 2) + b) * 2) + c) * 2) + d) * 2) \ X + e) * 2) + f) * 2) + g) << 9) X X#define W2_WIDTH 70 X#define W2_HEIGHT 40 X X Xstatic GR_WINDOW_ID w1; /* id for large window */ Xstatic GR_WINDOW_ID w2; /* id for small window */ Xstatic GR_WINDOW_ID w3; /* id for third window */ Xstatic GR_WINDOW_ID w4; /* id for grabbable window */ Xstatic GR_WINDOW_ID w5; /* id for testing enter/exit window */ Xstatic GR_GC_ID gc1; /* graphics context for text */ Xstatic GR_GC_ID gc2; /* graphics context for rectangle */ Xstatic GR_GC_ID gc3; /* graphics context for circles */ Xstatic GR_GC_ID gc4; /* graphics context for lines */ Xstatic GR_COORD begxpos; /* beginning x position */ Xstatic GR_COORD xpos; /* x position for text drawing */ Xstatic GR_COORD ypos; /* y position for text drawing */ Xstatic GR_COORD linexpos; /* x position for line drawing */ Xstatic GR_COORD lineypos; /* y position for line drawing */ Xstatic GR_COORD xorxpos; /* x position for xor line */ Xstatic GR_COORD xorypos; /* y position for xor line */ Xstatic GR_BOOL lineok; /* ok to draw line */ Xstatic GR_SCREEN_INFO si; /* information about screen */ X Xvoid errorcatcher(); /* routine to handle errors */ X X Xmain(argc, argv) X char **argv; X{ X GR_EVENT event; /* current event */ X GR_BITMAP bitmap1fg[7]; /* bitmaps for first cursor */ X GR_BITMAP bitmap1bg[7]; X GR_BITMAP bitmap2fg[7]; /* bitmaps for second cursor */ X GR_BITMAP bitmap2bg[7]; X X if (GrOpen() < 0) { X fprintf(stderr, "cannot open graphics\n"); X exit(1); X } X GrGetScreenInfo(&si); X X GrSetErrorHandler(errorcatcher); X X w1 = GrNewWindow(GR_ROOT_WINDOW_ID, 100, 50, si.cols - 120, X si.rows - 60, 1, 6, 15); X w2 = GrNewWindow(GR_ROOT_WINDOW_ID, 6, 6, W2_WIDTH, W2_HEIGHT, 2, 2, 15); X w3 = GrNewWindow(GR_ROOT_WINDOW_ID, 250, 30, 80, 100, 1, 7, 2); X w4 = GrNewWindow(GR_ROOT_WINDOW_ID, 350, 20, 200, 150, 5, 0, 15); X w5 = GrNewWindow(GR_ROOT_WINDOW_ID, 11, 143, 209, 100, 1, 1, 2); X X GrSelectEvents(w1, GR_EVENT_MASK_BUTTON_DOWN | X GR_EVENT_MASK_KEY_DOWN | GR_EVENT_MASK_EXPOSURE | X GR_EVENT_MASK_FOCUS_IN | GR_EVENT_MASK_FOCUS_OUT); X GrSelectEvents(w2, GR_EVENT_MASK_BUTTON_UP); X GrSelectEvents(w3, GR_EVENT_MASK_BUTTON_DOWN | X GR_EVENT_MASK_MOUSE_MOTION); X GrSelectEvents(w4, GR_EVENT_MASK_BUTTON_DOWN | X GR_EVENT_MASK_BUTTON_UP | GR_EVENT_MASK_MOUSE_POSITION | X GR_EVENT_MASK_KEY_DOWN); X GrSelectEvents(w5, GR_EVENT_MASK_MOUSE_ENTER | X GR_EVENT_MASK_MOUSE_EXIT); X GrSelectEvents(GR_ROOT_WINDOW_ID, GR_EVENT_MASK_BUTTON_DOWN); X X GrMapWindow(w1); X GrMapWindow(w2); X GrMapWindow(w3); X GrMapWindow(w4); X GrMapWindow(w5); X X gc1 = GrNewGC(); X gc2 = GrNewGC(); X gc3 = GrNewGC(); X gc4 = GrNewGC(); X X GrSetGCForeground(gc1, 4); X GrSetGCBackground(gc1, 6); X GrSetGCForeground(gc2, 5); X GrSetGCMode(gc4, GR_MODE_XOR); X X bitmap1fg[0] = MASK(_,_,_,X,_,_,_); X bitmap1fg[1] = MASK(_,_,_,X,_,_,_); X bitmap1fg[2] = MASK(_,_,_,X,_,_,_); X bitmap1fg[3] = MASK(X,X,X,X,X,X,X); X bitmap1fg[4] = MASK(_,_,_,X,_,_,_); X bitmap1fg[5] = MASK(_,_,_,X,_,_,_); X bitmap1fg[6] = MASK(_,_,_,X,_,_,_); X X bitmap1bg[0] = MASK(_,_,X,X,X,_,_); X bitmap1bg[1] = MASK(_,_,X,X,X,_,_); X bitmap1bg[2] = MASK(X,X,X,X,X,X,X); X bitmap1bg[3] = MASK(X,X,X,X,X,X,X); X bitmap1bg[4] = MASK(X,X,X,X,X,X,X); X bitmap1bg[5] = MASK(_,_,X,X,X,_,_); X bitmap1bg[6] = MASK(_,_,X,X,X,_,_); X X bitmap2fg[0] = MASK(_,_,X,X,X,_,_); X bitmap2fg[1] = MASK(_,X,_,_,_,X,_); X bitmap2fg[2] = MASK(X,_,_,_,_,_,X); X bitmap2fg[3] = MASK(X,_,_,_,_,_,X); X bitmap2fg[4] = MASK(_,X,_,_,_,X,_); X bitmap2fg[5] = MASK(_,_,X,X,X,_,_); X X bitmap2bg[0] = MASK(_,_,X,X,X,_,_); X bitmap2bg[1] = MASK(_,X,X,X,X,X,_); X bitmap2bg[2] = MASK(X,X,X,X,X,X,X); X bitmap2bg[3] = MASK(X,X,X,X,X,X,X); X bitmap2bg[4] = MASK(_,X,X,X,X,X,_); X bitmap2bg[5] = MASK(_,_,X,X,X,_,_); X X GrSetCursor(w1, 7, 7, 3, 3, si.white, si.black, bitmap1fg, bitmap1bg); X GrSetCursor(w2, 7, 7, 3, 3, si.white, si.black, bitmap2fg, bitmap2bg); X X GrRect(GR_ROOT_WINDOW_ID, gc1, 0, 0, si.cols, si.rows); X X while (1) { X GrCheckNextEvent(&event); X X switch (event.type) { X case GR_EVENT_TYPE_BUTTON_DOWN: X do_buttondown(&event.button); X break; X X case GR_EVENT_TYPE_BUTTON_UP: X do_buttonup(&event.button); X break; X X case GR_EVENT_TYPE_MOUSE_POSITION: X case GR_EVENT_TYPE_MOUSE_MOTION: X do_motion(&event.mouse); X break; X X case GR_EVENT_TYPE_KEY_DOWN: X do_keystroke(&event.keystroke); X break; X X case GR_EVENT_TYPE_EXPOSURE: X do_exposure(&event.exposure); X break; X X case GR_EVENT_TYPE_FOCUS_IN: X do_focusin(&event.general); X break; X X case GR_EVENT_TYPE_FOCUS_OUT: X do_focusout(&event.general); X break; X X case GR_EVENT_TYPE_MOUSE_ENTER: X do_enter(&event.general); X break; X X case GR_EVENT_TYPE_MOUSE_EXIT: X do_exit(&event.general); X break; X X case GR_EVENT_TYPE_NONE: X do_idle(); X break; X } X } X} X X X/* X * Here when a button is pressed. X */ Xdo_buttondown(bp) X GR_EVENT_BUTTON *bp; X{ X GR_COLOR8 intable[W2_WIDTH * W2_HEIGHT]; X GR_COLOR8 outtable[W2_WIDTH * W2_HEIGHT * 4]; X GR_COLOR8 *inp; X GR_COLOR8 *outp; X GR_COLOR8 *oldinp; X GR_COORD row; X GR_COORD col; X X if (bp->wid == w3) { X GrRaiseWindow(w3); X GrReadArea8(w2, 0, 0, W2_WIDTH, W2_HEIGHT, intable); X inp = intable; X outp = outtable; X for (row = 0; row < W2_HEIGHT; row++) { X oldinp = inp; X for (col = 0; col < W2_WIDTH; col++) { X *outp++ = *inp; X *outp++ = *inp++; X } X inp = oldinp; X for (col = 0; col < W2_WIDTH; col++) { X *outp++ = *inp; X *outp++ = *inp++; X } X } X GrArea8(w1, gc1, 0, 0, W2_WIDTH * 2, W2_HEIGHT * 2, outtable); X return; X } X X if (bp->wid == w4) { X GrRaiseWindow(w4); X linexpos = bp->x; X lineypos = bp->y; X xorxpos = bp->x; X xorypos = bp->y; X GrLine(w4, gc4, xorxpos, xorypos, linexpos, lineypos); X lineok = GR_TRUE; X return; X } X X if (bp->wid != w1) { X /* X * Cause a fatal error for testing if more than one X * button is pressed. X */ X if ((bp->buttons & -((int) bp->buttons)) != bp->buttons) X GrClearWindow(-1, 0); X return; X } X X GrRaiseWindow(w1); X X if (bp->buttons & GR_BUTTON_1) { X GrClearWindow(w1, GR_TRUE); X return; X } X X begxpos = bp->x; X xpos = bp->x; X ypos = bp->y; X} X X X/* X * Here when a button is released. X */ Xdo_buttonup(bp) X GR_EVENT_BUTTON *bp; X{ X if (bp->wid == w4) { X if (lineok) { X GrLine(w4, gc4, xorxpos, xorypos, linexpos, lineypos); X GrLine(w4, gc3, bp->x, bp->y, linexpos, lineypos); X } X lineok = GR_FALSE; X return; X } X X if (bp->wid == w2) { X GrClose(); X exit(0); X } X} X X X/* X * Here when the mouse has a motion event. X */ Xdo_motion(mp) X GR_EVENT_MOUSE *mp; X{ X if (mp->wid == w4) { X if (lineok) { X GrLine(w4, gc4, xorxpos, xorypos, linexpos, lineypos); X xorxpos = mp->x; X xorypos = mp->y; X GrLine(w4, gc4, xorxpos, xorypos, linexpos, lineypos); X } X return; X } X X if (mp->wid == w3) { X GrPoint(w3, gc3, mp->x, mp->y); X return; X } X} X X X/* X * Here when a keyboard press occurs. X */ Xdo_keystroke(kp) X GR_EVENT_KEYSTROKE *kp; X{ X GR_SIZE width; /* width of character */ X GR_SIZE height; /* height of character */ X GR_SIZE base; /* height of baseline */ X X if (kp->wid == w4) { X if (lineok) { X GrLine(w4, gc4, xorxpos, xorypos, linexpos, lineypos); X lineok = GR_FALSE; X } X return; X } X X GrGetGCTextSize(gc1, &kp->ch, 1, &width, &height, &base); X if ((kp->ch == '\r') || (kp->ch == '\n')) { X xpos = begxpos; X ypos += height; X return; X } X if (kp->ch == '\b') { /* assumes fixed width font!! */ X if (xpos <= begxpos) X return; X xpos -= width; X GrSetGCForeground(gc3, 6); X GrFillRect(w1, gc3, xpos, ypos - height + base + 1, X width, height); X return; X } X GrText(w1, gc1, xpos, ypos + base, &kp->ch, 1); X xpos += width; X} X X X/* X * Here when an exposure event occurs. X */ Xdo_exposure(ep) X GR_EVENT_EXPOSURE *ep; X{ X GR_POINT points[3]; X X if (ep->wid != w1) X return; X points[0].x = 311; X points[0].y = 119; X points[1].x = 350; X points[1].y = 270; X points[2].x = 247; X points[2].y = 147; X X GrFillRect(w1, gc2, 50, 50, 150, 200); X GrFillPoly(w1, gc2, 3, points); X} X X X/* X * Here when a focus in event occurs. X */ Xdo_focusin(gp) X GR_EVENT_GENERAL *gp; X{ X if (gp->wid != w1) X return; X GrSetBorderColor(w1, 15); X} X X X/* X * Here when a focus out event occurs. X */ Xdo_focusout(gp) X GR_EVENT_GENERAL *gp; X{ X if (gp->wid != w1) X return; X GrSetBorderColor(w1, 7); X} X X X/* X * Here when a enter window event occurs. X */ Xdo_enter(gp) X GR_EVENT_GENERAL *gp; X{ X if (gp->wid != w5) X return; X GrSetBorderColor(w5, 15); X GrRaiseWindow(w5); X} X X X/* X * Here when a exit window event occurs. X */ Xdo_exit(gp) X GR_EVENT_GENERAL *gp; X{ X if (gp->wid != w5) X return; X GrSetBorderColor(w5, 2); X GrLowerWindow(w5); X} X X X/* X * Here to do an idle task when nothing else is happening. X * Just draw a randomly colored filled circle in the small window. X */ Xdo_idle() X{ X GR_COORD x; X GR_COORD y; X GR_SIZE rx; X GR_SIZE ry; X GR_COLOR color; X X x = rand() % 70; X y = rand() % 40; X rx = (rand() % 10) + 5; X ry = (rx * si.ydpcm) / si.xdpcm; /* make it appear circular */ X color = rand() % (si.maxcolor + 1); X X GrSetGCForeground(gc3, color); X GrFillEllipse(w2, gc3, x, y, rx, ry); X} X X X/* X * Here on an unrecoverable error. X */ Xvoid Xerrorcatcher(code, name, id) X GR_ERROR code; /* error code */ X GR_FUNC_NAME name; /* function name which failed */ X GR_ID id; /* resource id */ X{ X GrClose(); X fprintf(stderr, "DEMO ERROR: code %d, function %s, resource id %d\n", X code, name, id); X exit(1); X} END_OF_FILE if test 9582 -ne `wc -c <'mini-x/clients/demo.c'`; then echo shar: \"'mini-x/clients/demo.c'\" unpacked with wrong size! fi # end of 'mini-x/clients/demo.c' fi if test -f 'mini-x/include/graph_msg.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mini-x/include/graph_msg.h'\" else echo shar: Extracting \"'mini-x/include/graph_msg.h'\" \(5685 characters\) sed "s/^X//" >'mini-x/include/graph_msg.h' <<'END_OF_FILE' X/* Copyright (c) 1991 David I. Bell X * Permission is granted to use, distribute, or modify this source, X * provided that this copyright notice remains intact. X * X * mini-X graphics - message interface between server and device driver X */ X X#ifndef GRAPH_MSG_H X#define GRAPH_MSG_H X X#include X X X/* Flag definitions. */ Xtypedef unsigned short GR_FLAGS; /* flag values */ X X#define GR_FLAG_FILLAREA ((GR_FLAGS) 0x01) /* fill areas */ X X X/* Messages for drawing primitives. */ Xtypedef struct { X GR_FUNC func; /* function code */ X GR_COUNT count; /* count of items */ X GR_FLAGS flags; /* flags to modify function */ X short pad; /* padding */ X} GR_MSG_HEADER; X X Xtypedef struct { X GR_MSG_HEADER head; X long magic; /* magic number (and version) */ X GR_SIZE rows; /* number of rows (or 0) */ X GR_SIZE cols; /* number of columns (or 0) */ X long colors; /* number of colors (or 0) */ X} GR_MSG_INIT; X X Xtypedef struct { X GR_MSG_HEADER head; X} GR_MSG_TERM; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_POINT points[1]; X} GR_MSG_POINTS; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_LINE lines[1]; X} GR_MSG_LINES; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_RECT rects[1]; X} GR_MSG_RECTS; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_ELLIPSE ellips[1]; X} GR_MSG_ELLIPS; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_POINT points[1]; X} GR_MSG_POLY; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_COLOR foreground; X} GR_MSG_SETFOREGROUND; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_COLOR background; X} GR_MSG_SETBACKGROUND; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_BOOL flag; X} GR_MSG_SETUSEBACKGROUND; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_RECT cliprects[1]; X} GR_MSG_SETCLIPRECTS; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_MODE mode; X} GR_MSG_SETMODE; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_COORD x; X GR_COORD y; X GR_SIZE width; X GR_SIZE height; X GR_COLOR8 colors[1]; X} GR_MSG_AREA8; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_COORD x; X GR_COORD y; X GR_SIZE width; X GR_SIZE height; X GR_BITMAP bitmaps[1]; X} GR_MSG_BITMAP; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_COORD x; X GR_COORD y; X GR_CHAR chars[1]; X} GR_MSG_TEXT; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_COORD sx; X GR_COORD sy; X GR_COORD dx; X GR_COORD dy; X GR_SIZE width; X GR_SIZE height; X} GR_MSG_COPYAREA; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_SIZE width; X GR_SIZE height; X GR_COLOR foreground; X GR_COLOR background; X GR_BITMAP bitmaps[1]; X} GR_MSG_SETCURSOR; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_COORD x; X GR_COORD y; X} GR_MSG_MOVECURSOR; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_COORD x; X GR_COORD y; X GR_SIZE width; X GR_SIZE height; X} GR_MSG_READAREA8; X X Xtypedef struct { X GR_MSG_HEADER head; X} GR_MSG_GETSCREENINFO; X X Xtypedef struct { X GR_MSG_HEADER head; X GR_FONT font; X} GR_MSG_GETFONTINFO; X X X/* Rounding function to make sure that each message in a buffer begins X * on a word boundary. Some machines will trap if this is not done. X */ X#define GR_ROUND(len) (((len) + 3) & ~3) X X X/* Sizes of some messages, according to the number of items in the message. */ X#define GR_SIZEOF_MSG_POINTS(count) GR_ROUND(sizeof(GR_MSG_POINTS) + \ X (((long) (count)) - 1) * sizeof(GR_POINT)) X X#define GR_SIZEOF_MSG_LINES(count) GR_ROUND(sizeof(GR_MSG_LINES) + \ X (((long) (count)) - 1) * sizeof(GR_LINE)) X X#define GR_SIZEOF_MSG_RECTS(count) GR_ROUND(sizeof(GR_MSG_RECTS) + \ X (((long) (count)) - 1) * sizeof(GR_RECT)) X X#define GR_SIZEOF_MSG_ELLIPS(count) GR_ROUND(sizeof(GR_MSG_ELLIPS) + \ X (((long) (count)) - 1) * sizeof(GR_ELLIPSE)) X X#define GR_SIZEOF_MSG_POLY(count) GR_ROUND(sizeof(GR_MSG_POLY) + \ X (((long) (count)) - 1) * sizeof(GR_POINT)) X X#define GR_SIZEOF_MSG_AREA8(count) GR_ROUND(sizeof(GR_MSG_AREA8) + \ X (((long) (count)) - 1) * sizeof(GR_COLOR8)) X X#define GR_SIZEOF_MSG_BITMAP(count) GR_ROUND(sizeof(GR_MSG_BITMAP) + \ X (((long) (count)) - 1) * sizeof(GR_BITMAP)) X X#define GR_SIZEOF_MSG_TEXT(count) GR_ROUND(sizeof(GR_MSG_TEXT) + \ X (((long) (count)) - 1) * sizeof(GR_CHAR)) X X#define GR_SIZEOF_MSG_SETCLIPRECTS(count) GR_ROUND(sizeof(GR_MSG_SETCLIPRECTS) + \ X (((long) (count)) - 1) * sizeof(GR_RECT)) X X#define GR_SIZEOF_MSG_SETCURSOR(count) GR_ROUND(sizeof(GR_MSG_SETCURSOR) + \ X (((long) (count)) - 1) * sizeof(GR_BITMAP)) X X X/* Macro to convert from a number of adjacent bits to the number of X * bitmap words needed to hold that many bits. X */ X#define BITMAP_WORDS(bits) (((bits) + (sizeof(GR_BITMAP) * 8) - 1) \ X / (sizeof(GR_BITMAP) * 8)) X X X/* Maximum values */ X#define GR_MAX_SIZEOF_MSG 2000 X#define GR_MAX_COUNT 1000 X X X/* Magic value to prevent accidental use of the graphics device, and also to X * verify that the device driver and graphics library structures are in sync. X * Incrementing this value allows for new versions of the structures to be used. X * It also allows the word and byte order of messages to be determined if X * that ever becomes necessary (networks). X */ X#define GR_INIT_MAGIC 0x99880001L X X X/* Function codes */ X#define GR_FUNC_NOP 0 X#define GR_FUNC_INIT 1 X#define GR_FUNC_SETFOREGROUND 2 X#define GR_FUNC_SETCLIPRECTS 3 X#define GR_FUNC_DRAWPOINTS 4 X#define GR_FUNC_DRAWLINES 5 X#define GR_FUNC_DRAWRECTS 6 X#define GR_FUNC_DRAWPOLY 7 X#define GR_FUNC_DRAWELLIPS 8 X#define GR_FUNC_DRAWTEXT 9 X#define GR_FUNC_DRAWAREA8 10 X#define GR_FUNC_DRAWBITMAP 11 X#define GR_FUNC_COPYAREA 12 X#define GR_FUNC_SETCURSOR 13 X#define GR_FUNC_MOVECURSOR 14 X#define GR_FUNC_SETBACKGROUND 15 X#define GR_FUNC_SETMODE 16 X#define GR_FUNC_TERM 17 X#define GR_FUNC_READAREA8 18 X#define GR_FUNC_GETSCREENINFO 19 X#define GR_FUNC_SETUSEBACKGROUND 20 X#define GR_FUNC_GETFONTINFO 21 X X#endif X X/* END CODE */ END_OF_FILE if test 5685 -ne `wc -c <'mini-x/include/graph_msg.h'`; then echo shar: \"'mini-x/include/graph_msg.h'\" unpacked with wrong size! fi # end of 'mini-x/include/graph_msg.h' fi if test -f 'mini-x/kernel/cursor_gen.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mini-x/kernel/cursor_gen.c'\" else echo shar: Extracting \"'mini-x/kernel/cursor_gen.c'\" \(8077 characters\) sed "s/^X//" >'mini-x/kernel/cursor_gen.c' <<'END_OF_FILE' X/* Copyright (c) 1991 David I. Bell X * Permission is granted to use, distribute, or modify this source, X * provided that this copyright notice remains intact. X * X * Generic routines to keep track of the cursor. X * This implements totally software driven graphics cursors. X * If your system has hardware cursors, then none of this is X * needed, and a set of functions for your hardware will suffice. X */ X X#include "kernel.h" X#include "graph_dev.h" X#include X X X/* The following definition is used to save old colors for the cursor. X * For space reasons, this is defined to be 8 bit colors. If your colors X * are more than 8 bits, then redefine this. X */ X#ifndef GR_COLORN X#define GR_COLORN GR_COLOR8 X#endif X X X/* Cursor size, position, colors, and bitmap. */ XPRIVATE GR_BOOL curenabled; /* TRUE if cursor is visible */ XPRIVATE GR_BOOL curneedfix; /* TRUE if cursor needs fixing */ XPRIVATE GR_COORD curminx; /* minimum x value of cursor */ XPRIVATE GR_COORD curminy; /* minimum y value of cursor */ XPRIVATE GR_COORD curmaxx; /* maximum x value of cursor */ XPRIVATE GR_COORD curmaxy; /* maximum y value of cursor */ XPRIVATE GR_COLOR curfg; /* foreground color of cursor */ XPRIVATE GR_COLOR curbg; /* background color of cursor */ XPRIVATE GR_BITMAP curfgbitmap[GR_MAX_CURSOR_SIZE]; /* foreground bitmap */ XPRIVATE GR_BITMAP curbgbitmap[GR_MAX_CURSOR_SIZE]; /* background bitmap */ X X X/* Saved pixels from graphics screen so they can be restored later. X * The only pixels that are actually saved are the ones where the foreground X * or background bitmaps are nonzero. X */ XPRIVATE GR_COLORN savedpoints[GR_MAX_CURSOR_SIZE * GR_MAX_CURSOR_SIZE]; X X XFORWARD removecursor(); XFORWARD showcursor(); X X X/*===========================================================================* X * gen_initcursor * X *===========================================================================*/ XPUBLIC void gen_initcursor() X{ X/* Initialize the cursor when graphics is initialized. This just indicates X * that the cursor is not being show. X */ X curenabled = GR_FALSE; X curneedfix = GR_FALSE; X} X X X/*===========================================================================* X * gen_setcursor * X *===========================================================================*/ XPUBLIC void gen_setcursor(width, height, foreground, background, fgbitmap, bgbitmap) XGR_SIZE width; /* width of cursor */ XGR_SIZE height; /* height of cursor */ XGR_COLOR foreground; /* foreground color */ XGR_COLOR background; /* background color */ XGR_BITMAP *fgbitmap; /* foreground bitmap table */ XGR_BITMAP *bgbitmap; /* background bitmap table */ X{ X/* Set the size, shape, and colors of the cursor. X * This first removes the old cursor if there was one visible. X * The new cursor is only drawn if the old one was too. X */ X GR_BOOL saveenabled; /* saved enabled flag */ X int bytes; /* number of bytes to copy */ X X if ((width <= 0) || (width > GR_MAX_CURSOR_SIZE) X || (height <= 0) || (height > GR_MAX_CURSOR_SIZE)) X return; X X saveenabled = removecursor(); X curfg = foreground; X curbg = background; X curmaxx = curminx + width - 1; X curmaxy = curminy + height - 1; X bytes = BITMAP_WORDS(width) * height * sizeof(GR_BITMAP); X memcpy(curfgbitmap, fgbitmap, bytes); X memcpy(curbgbitmap, bgbitmap, bytes); X if (saveenabled) showcursor(); X} X X X/*===========================================================================* X * gen_movecursor * X *===========================================================================*/ XPUBLIC void gen_movecursor(x, y) XGR_COORD x; /* new x position of cursor */ XGR_COORD y; /* new y position of cursor */ X{ X/* Change the position of the cursor to the specified coordinates. X * This makes the cursor visible if it was not previously visible. X * The cursor can be made invisible by moving it off of the screen. X */ X GR_COORD shiftx; X GR_COORD shifty; X X shiftx = x - curminx; X shifty = y - curminy; X if ((shiftx == 0) && (shifty == 0)) return; X removecursor(); X curminx += shiftx; X curmaxx += shiftx; X curminy += shifty; X curmaxy += shifty; X if ((curmaxx >= 0) && (curminx < gr_dev.cols) && (curmaxy >= 0) X && (curminy < gr_dev.rows)) X showcursor(); X} X X X/*===========================================================================* X * removecursor * X *===========================================================================*/ XPRIVATE int removecursor() X{ X/* Remove the cursor from the screen. X * This just restores the pixels that were saved before the cursor was put X * on the screen. Returns the previous state of the cursor enabled flag. X */ X GR_COLORN *saveptr; X GR_BITMAP *fgbitptr; X GR_BITMAP *bgbitptr; X GR_COORD x; X GR_COORD y; X GR_BITMAP allbits; X GR_BITMAP curbit; X X if (!curenabled) return GR_FALSE; X X if (gr_mode != GR_MODE_SET) (*gr_dev.setmode) (GR_MODE_SET); X X saveptr = savedpoints; X fgbitptr = curfgbitmap; X bgbitptr = curbgbitmap; X X for (y = curminy; y <= curmaxy; y++) { X curbit = 0; X for (x = curminx; x <= curmaxx; x++) { X if (curbit == 0) { X allbits = *fgbitptr++ | *bgbitptr++; X curbit = GR_FIRSTBIT; X } X if (curbit & allbits) (*gr_dev.drawpoint) (x, y, *saveptr++); X curbit = GR_NEXTBIT(curbit); X } X } X if (gr_mode != GR_MODE_SET) (*gr_dev.setmode) (gr_mode); X X curenabled = GR_FALSE; X X return GR_TRUE; X} X X X/*===========================================================================* X * showcursor * X *===========================================================================*/ XPRIVATE int showcursor() X{ X/* Show the cursor on the screen. X * This must first save the pixel values on the screen that will be X * overwritten by the cursor, so that they can be restored later. X * Returns the previous state of the cursor enabled flag. X */ X GR_COLORN *saveptr; X GR_BITMAP *fgbitptr; X GR_BITMAP *bgbitptr; X GR_COORD x; X GR_COORD y; X GR_BITMAP fgbits; X GR_BITMAP bgbits; X GR_BITMAP curbit; X GR_COLOR oldcolor; X GR_COLOR newcolor; X GR_BOOL dosave; X X if (curenabled) return GR_TRUE; X X if (gr_mode != GR_MODE_SET) (*gr_dev.setmode) (GR_MODE_SET); X X saveptr = savedpoints; X fgbitptr = curfgbitmap; X bgbitptr = curbgbitmap; X X for (y = curminy; y <= curmaxy; y++) { X curbit = 0; X for (x = curminx; x <= curmaxx; x++) { X if (curbit == 0) { X fgbits = *fgbitptr++; X bgbits = *bgbitptr++; X curbit = GR_FIRSTBIT; X } X dosave = GR_FALSE; X if (curbit & fgbits) { X newcolor = curfg; X dosave = GR_TRUE; X } else if (curbit & bgbits) { X newcolor = curbg; X dosave = GR_TRUE; X } X if (dosave) { X oldcolor = (*gr_dev.readpoint) (x, y); X if (oldcolor != newcolor) X (*gr_dev.drawpoint) (x, y, newcolor); X *saveptr++ = oldcolor; X } X curbit = GR_NEXTBIT(curbit); X } X } X X if (gr_mode != GR_MODE_SET) (*gr_dev.setmode) (gr_mode); X X curenabled = GR_TRUE; X curneedfix = GR_FALSE; X X return GR_FALSE; X} X X X/*===========================================================================* X * gen_checkcursor * X *===========================================================================*/ XPUBLIC void gen_checkcursor(x1, y1, x2, y2) XGR_COORD x1; XGR_COORD y1; XGR_COORD x2; XGR_COORD y2; X{ X/* Check to see if the cursor is about to be overwritten. X * If so, then remove the cursor so that the graphics operation X * works correctly. If the cursor is removed, then this fact will X * be remembered and a later call to fixcursor will restore it. X */ X GR_COORD temp; X X if (!curenabled) return; X X if (x1 > x2) { X temp = x1; X x1 = x2; X x2 = temp; X } X if (y1 > y2) { X temp = y1; X y1 = y2; X y2 = temp; X } X if ((x1 > curmaxx) || (x2 < curminx) || X (y1 > curmaxy) || (y2 < curminy)) X return; X X removecursor(); X curneedfix = GR_TRUE; X return; X} X X X/*===========================================================================* X * gen_fixcursor * X *===========================================================================*/ XPUBLIC void gen_fixcursor() X{ X/* Fix back up the cursor if it was removed because of a graphics operation. */ X if (curneedfix) showcursor(); X} X X/* END CODE */ END_OF_FILE if test 8077 -ne `wc -c <'mini-x/kernel/cursor_gen.c'`; then echo shar: \"'mini-x/kernel/cursor_gen.c'\" unpacked with wrong size! fi # end of 'mini-x/kernel/cursor_gen.c' fi if test -f 'mini-x/kernel/graph_clip.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mini-x/kernel/graph_clip.c'\" else echo shar: Extracting \"'mini-x/kernel/graph_clip.c'\" \(8352 characters\) sed "s/^X//" >'mini-x/kernel/graph_clip.c' <<'END_OF_FILE' X/* Copyright (c) 1991 David I. Bell X * Permission is granted to use, distribute, or modify this source, X * provided that this copyright notice remains intact. X * X * Routines to determine clipping regions. X */ X X#include "kernel.h" X#include "graph_dev.h" X X X/* Clip cache rectangle information. X * After calling clippoint, this rectangle is guaranteed to contain the X * specified point (among others), and all points in the rectangle are X * plottable or not according to the value of clipresult. X */ XGR_COORD clipminx; /* minimum x value of cache rectangle */ XGR_COORD clipminy; /* minimum y value of cache rectangle */ XGR_COORD clipmaxx; /* maximum x value of cache rectangle */ XGR_COORD clipmaxy; /* maximum y value of cache rectangle */ XGR_BOOL clipresult; /* whether clip rectangle is plottable */ X X XPRIVATE GR_COUNT clipcount; /* number of clip rectangles */ XPRIVATE GR_RECT cliprects[GR_MAX_CLIPRECTS]; /* clip rectangles */ X X X/*===========================================================================* X * clipinit * X *===========================================================================*/ XPUBLIC void clipinit(count, table) XGR_COUNT count; /* number of clip rectangles */ XGR_RECT *table; /* rectangle table */ X{ X/* Specify a new set of clip rectangles. X * This should only be called after the device has been initialized. X * If zero clip rectangles are specified, then clipping is done to the X * full device area. All clip rectangles are modified if necessary to X * lie within the device area. X */ X register GR_RECT *rp; /* current rectangle */ X X /* If there are no clip rectangles, then default to the full device area. */ X if (count <= 0) { X clipminx = 0; X clipminy = 0; X clipmaxx = gr_dev.cols - 1; X clipmaxy = gr_dev.rows - 1; X clipcount = 0; X clipresult = GR_TRUE; X return; X } X X /* Copy the clip table to our own static array, modifying each X * rectangle as necesary to fit within the device area. If the clip X * rectangle lies entirely outside of the device area, then skip it. X */ X rp = cliprects; X clipcount = 0; X if (count > GR_MAX_CLIPRECTS) count = GR_MAX_CLIPRECTS; X while (count-- > 0) { X *rp = *table++; X if (rp->x < 0) { X rp->width += rp->x; X rp->x = 0; X } X if (rp->y < 0) { X rp->height += rp->y; X rp->y = 0; X } X if ((rp->x >= gr_dev.cols) || (rp->width <= 0) || X (rp->y >= gr_dev.rows) || (rp->height <= 0)) X continue; X if (rp->x + rp->width > gr_dev.cols) rp->width = gr_dev.cols - rp->x; X if (rp->y + rp->height > gr_dev.rows) X rp->height = gr_dev.rows - rp->y; X rp++; X clipcount++; X } X X /* If there were no surviving clip rectangles, then set the clip X * cache to prevent all drawing. X */ X if (clipcount == 0) { X clipminx = GR_COORD_MIN; X clipminy = GR_COORD_MIN; X clipmaxx = GR_COORD_MAX; X clipmaxy = GR_COORD_MAX; X clipresult = GR_FALSE; X return; X } X X /* There was at least one valid clip rectangle. Default the clip X * cache to be the first clip rectangle. X */ X clipminx = cliprects[0].x; X clipminy = cliprects[0].y; X clipmaxx = clipminx + cliprects[0].width - 1; X clipmaxy = clipminy + cliprects[0].height - 1; X clipresult = GR_TRUE; X} X X X/*===========================================================================* X * clippoint * X *===========================================================================*/ XPUBLIC GR_BOOL X clippoint(x, y) XGR_COORD x; XGR_COORD y; X{ X/* Check a point against the list of clip rectangles. X * Returns TRUE if the point is within one or more rectangles and thus X * can be plotted, or FALSE if the point is not within any rectangle and X * thus cannot be plotted. Also remembers the coordinates of a clip cache X * rectangle containing the specified point such that every point in the X * rectangle would give the same result. By examining this clip cache X * rectangle after a call to this routine, the caller can efficiently X * check many nearby points without needing any further calls. If the X * point lies within the cursor, then the cursor is removed. X */ X GR_COUNT count; X GR_RECT *rp; X GR_COORD temp; X X /* First see whether the point lies within the current clip cache X * rectangle. If so, then we already know the result. X */ X if ((x >= clipminx) && (x <= clipmaxx) && X (y >= clipminy) && (y <= clipmaxy)) { X if (clipresult) (*gr_dev.checkcursor) (x, y, x, y); X return clipresult; X } X X /* If the point is outside of the screen area, then it is not X * plottable, and the clip cache rectangle is the whole half-plane X * outside of the screen area. X */ X if (x < 0) { X clipminx = GR_COORD_MIN; X clipmaxx = -1; X clipminy = GR_COORD_MIN; X clipmaxy = GR_COORD_MAX; X clipresult = GR_FALSE; X return GR_FALSE; X } X if (y < 0) { X clipminx = GR_COORD_MIN; X clipmaxx = GR_COORD_MAX; X clipminy = GR_COORD_MIN; X clipmaxy = -1; X clipresult = GR_FALSE; X return GR_FALSE; X } X if (x >= gr_dev.cols) { X clipminx = gr_dev.cols; X clipmaxx = GR_COORD_MAX; X clipminy = GR_COORD_MIN; X clipmaxy = GR_COORD_MAX; X clipresult = GR_FALSE; X return GR_FALSE; X } X if (y >= gr_dev.rows) { X clipminx = GR_COORD_MIN; X clipmaxx = GR_COORD_MAX; X clipminy = gr_dev.rows; X clipmaxy = GR_COORD_MAX; X clipresult = GR_FALSE; X return GR_FALSE; X } X X /* The point is within the screen area. If there are no clip X * rectangles, then the point is plottable and the rectangle is the X * whole screen. X */ X count = clipcount; X if (count <= 0) { X clipminx = 0; X clipmaxx = gr_dev.cols - 1; X clipminy = 0; X clipmaxy = gr_dev.rows - 1; X clipresult = GR_TRUE; X (*gr_dev.checkcursor) (x, y, x, y); X return GR_TRUE; X } X X /* We need to scan the list of clip rectangles to calculate a new X * clip cache rectangle containing this point, and the result. First X * see if the point lies within any of the clip rectangles. If so, X * then it is plottable and use that clip rectangle as the cache X * rectangle. This is not necessarily the best result, but works ok X * and is fast. X */ X for (rp = cliprects; count-- > 0; rp++) { X if ((x >= rp->x) && (y >= rp->y) && (x < rp->x + rp->width) X && (y < rp->y + rp->height)) { X clipminx = rp->x; X clipminy = rp->y; X clipmaxx = rp->x + rp->width - 1; X clipmaxy = rp->y + rp->height - 1; X clipresult = GR_TRUE; X (*gr_dev.checkcursor) (x, y, x, y); X return GR_TRUE; X } X } X X /* The point is not plottable. Scan the clip rectangles again to X * determine a rectangle containing more non-plottable points. X * Simply pick the largest rectangle whose area doesn't contain any X * of the same coordinates as appropriate sides of the clip X * rectangles. This is not necessarily the best result, but works ok X * and is fast. X */ X clipminx = GR_COORD_MIN; X clipminy = GR_COORD_MIN; X clipmaxx = GR_COORD_MAX; X clipmaxy = GR_COORD_MAX; X count = clipcount; X for (rp = cliprects; count-- > 0; rp++) { X if ((x < rp->x) && (rp->x <= clipmaxx)) clipmaxx = rp->x - 1; X temp = rp->x + rp->width - 1; X if ((x > temp) && (temp >= clipminx)) clipminx = temp + 1; X if ((y < rp->y) && (rp->y <= clipmaxy)) clipmaxy = rp->y - 1; X temp = rp->y + rp->height - 1; X if ((y > temp) && (temp >= clipminy)) clipminy = temp + 1; X } X clipresult = GR_FALSE; X return GR_FALSE; X} X X X/*===========================================================================* X * cliparea * X *===========================================================================*/ XPUBLIC int cliparea(x1, y1, x2, y2) XGR_COORD x1; XGR_COORD y1; XGR_COORD x2; XGR_COORD y2; X{ X/* Check the area determined by the specified pair of points against the X * list of clip rectangles. The area will either be totally visible, X * totally visible, or possibly partially visible. This routine updates X * the clip cache rectangle, and returns one of the following values: X * GR_CLIP_VISIBLE The whole rectangle is visible X * GR_CLIP_INVISIBLE The whole rectangle is invisible X * GR_CLIP_PARTIAL The rectangle may be partially visible X * In the case that the area is totally visible, the cursor is removed X * if it overlaps the clip area. X */ X if ((x1 < clipminx) || (x1 > clipmaxx) || X (y1 < clipminy) || (y1 > clipmaxy)) X clippoint(x1, y1); X X if ((x2 >= clipminx) && (x2 <= clipmaxx) && X (y2 >= clipminy) && (y2 <= clipmaxy)) { X if (!clipresult) return GR_CLIP_INVISIBLE; X (*gr_dev.checkcursor) (x1, y1, x2, y2); X return GR_CLIP_VISIBLE; X } X return GR_CLIP_PARTIAL; X} X X/* END CODE */ END_OF_FILE if test 8352 -ne `wc -c <'mini-x/kernel/graph_clip.c'`; then echo shar: \"'mini-x/kernel/graph_clip.c'\" unpacked with wrong size! fi # end of 'mini-x/kernel/graph_clip.c' fi if test -f 'mini-x/server/graph_serv.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mini-x/server/graph_serv.h'\" else echo shar: Extracting \"'mini-x/server/graph_serv.h'\" \(9325 characters\) sed "s/^X//" >'mini-x/server/graph_serv.h' <<'END_OF_FILE' X/* X * Copyright (c) 1991 David I. Bell X * Permission is granted to use, distribute, or modify this source, X * provided that this copyright notice remains intact. X * X * Private definitions for the graphics server. X * These definitions are not to be used by the clients. X * Clients must call the GrXXXX routines instead of these GsXXXX routines. X */ X X#ifndef GRAPH_SERV_H X#define GRAPH_SERV_H X X#include X X X/* X * Drawing types. X */ Xtypedef int GR_DRAW_TYPE; X X#define GR_DRAW_TYPE_NONE ((GR_DRAW_TYPE) 0) /* none or error */ X#define GR_DRAW_TYPE_WINDOW ((GR_DRAW_TYPE) 1) /* windows */ X#define GR_DRAW_TYPE_PIXMAP ((GR_DRAW_TYPE) 2) /* pixmaps */ X X X/* X * Maximum number of clients that can be simultaneously run by the server. X * This is limited to 255 because of resource ids, but the number of X * file descriptor can also limit it. X */ X#define GR_MAX_CLIENTS 1 /* maximum number of clients */ X X X/* X * The following is used to determine whether a client has already been X * given an event. For each event, a global value is incremented, and X * this value is saved in the client structure when it is delivered X * to the client. X */ Xtypedef unsigned long GR_EVENT_NUMBER; X X X/* X * List of elements for events. X */ Xtypedef struct gr_event_list GR_EVENT_LIST; Xstruct gr_event_list { X GR_EVENT_LIST *next; /* next element in list */ X GR_EVENT event; /* event */ X}; X X X/* X * Data structure to keep track of state of clients. X */ Xtypedef struct { X int infd; /* handle for input from client */ X int outfd; /* handle for output to client */ X int num; /* client number */ X GR_ID allocid; /* next resource id to allocate */ X GR_EVENT_NUMBER eventnumber; /* event number delivered to client */ X GR_EVENT_LIST *eventhead; /* head of event chain (or NULL) */ X GR_EVENT_LIST *eventtail; /* tail of event chain (or NULL) */ X GR_EVENT_ERROR errorevent; /* waiting error event to deliver */ X} GR_CLIENT; X X X/* X * Structure to remember clients associated with events. X */ Xtypedef struct gr_event_client GR_EVENT_CLIENT; Xstruct gr_event_client { X GR_EVENT_CLIENT *next; /* next interested client or NULL */ X GR_EVENT_MASK eventmask; /* events client wants to see */ X GR_CLIENT *client; /* client who is interested */ X}; X X X/* X * Structure to remember graphics contexts. X */ Xtypedef struct gr_gc GR_GC; Xstruct gr_gc { X GR_GC_ID id; /* graphics context id */ X GR_MODE mode; /* drawing mode */ X GR_FONT font; /* current font number */ X GR_COLOR foreground; /* foreground color */ X GR_COLOR background; /* background color */ X GR_BOOL usebackground; /* actually display the background */ X GR_BOOL changed; /* graphics context has been changed */ X GR_GC *next; /* next graphics context */ X int usecount; /* usecount */ X}; X X X/* X * Structure to remember cursor definitions. X */ Xtypedef struct { X int usecount; /* use counter */ X GR_SIZE width; /* width of cursor */ X GR_SIZE height; /* height of cursor */ X GR_COORD hotx; /* relative x position of hot spot */ X GR_COORD hoty; /* relative y position of hot spot */ X GR_COLOR foreground; /* foreground color */ X GR_COLOR background; /* background color */ X GR_BITMAP fgbitmap[GR_MAX_BITMAP_SIZE]; /* foreground bitmap */ X GR_BITMAP bgbitmap[GR_MAX_BITMAP_SIZE]; /* background bitmap */ X} GR_CURSOR; X X X/* X * Window structure X */ Xtypedef struct gr_window GR_WINDOW; Xstruct gr_window { X GR_WINDOW_ID id; /* window id */ X GR_WINDOW *parent; /* parent window */ X GR_WINDOW *children; /* first child window */ X GR_WINDOW *siblings; /* next sibling window */ X GR_WINDOW *next; /* next window in complete list */ X GR_COORD x; /* absolute x position */ X GR_COORD y; /* absolute y position */ X GR_SIZE width; /* width */ X GR_SIZE height; /* height */ X GR_SIZE bordersize; /* size of border */ X GR_COLOR bordercolor; /* color of border */ X GR_COLOR background; /* background color */ X GR_EVENT_MASK nopropmask; /* events not to be propagated */ X GR_EVENT_CLIENT *eventclients; /* clients interested in events */ X GR_CURSOR *cursor; /* cursor for this window */ X GR_BOOL mapped; /* TRUE if explicitly mapped */ X GR_COUNT unmapcount; /* count of reasons not really mapped */ X GR_BOOL output; /* TRUE if window can do output */ X}; X X X/* X * Pixmap structure (not yet implemented). X * Pixmaps of 2 colors use bitmaps, otherwise they use color values. X */ Xtypedef struct gr_pixmap GR_PIXMAP; Xstruct gr_pixmap { X GR_PIXMAP_ID id; /* pixmap id */ X GR_PIXMAP *next; /* next pixmap in list */ X GR_SIZE width; /* width of pixmap */ X GR_SIZE height; /* height of pixmap */ X GR_COLOR maxcolor; /* maximum color used in pixmap */ X GR_COLOR *colors; /* table of color values */ X GR_COLOR8 *color8; /* OR: table of 8 bit color values */ X GR_BITMAP *bitmap; /* OR: table of bitmap values */ X}; X X X/* X * Macros to obtain the client number from a resource id, and to X * produce the first resource id to be used for a client number. X * Client numbers must not be zero. This allows for 255 clients. X */ X#define GR_ID_CLIENT(n) (((unsigned long) (n)) >> 24) X#define GR_ID_BASE(n) (((unsigned long) (n)) << 24) X X X/* X * Graphics server routines. X */ Xextern int GdOpenScreen(); Xextern void GdCloseScreen(); Xextern void GdGetScreenInfo(); Xextern void GdGetFontInfo(); Xextern void GdTextMode(); Xextern void GdFlush(); Xextern GR_BOOL GdCheckError(); X Xextern int GsInitialize(); Xextern void GsTerminate(); Xextern GR_ID GsOpen(); Xextern void GsClose(); Xextern void GsFlush(); Xextern void GsError(); Xextern GR_WINDOW_ID GsNewWindow(); Xextern GR_WINDOW_ID GsNewInputWindow(); Xextern void GsDestroyWindow(); Xextern void GsGetWindowInfo(); Xextern GR_GC_ID GsNewGC(); Xextern GR_GC_ID GsCopyGC(); Xextern void GsDestroyGC(); Xextern void GsSetGCForeground(); Xextern void GsSetGCBackground(); Xextern void GsSetGCUseBackground(); Xextern void GsSetGCMode(); Xextern void GsSetGCFont(); Xextern void GsGetGCTextSize(); Xextern void GsGetScreenInfo(); Xextern void GsClearWindow(); Xextern void GsSelectEvents(); Xextern void GsPoint(); Xextern void GsPoly(); Xextern void GsFillPoly(); Xextern void GsLine(); Xextern void GsEllipse(); Xextern void GsFillEllipse(); Xextern void GsRect(); Xextern void GsFillRect(); Xextern void GsBitmap(); Xextern void GsArea8(); Xextern void GsReadArea8(); Xextern void GsText(); Xextern void GsSetCursor(); Xextern void GsMoveCursor(); Xextern void GsDrawBorder(); Xextern void GsMapWindow(); Xextern void GsUnmapWindow(); Xextern void GsRaiseWindow(); Xextern void GsLowerWindow(); Xextern void GsMoveWindow(); Xextern void GsResizeWindow(); Xextern void GsSetFocus(); Xextern void GsSetBorderColor(); Xextern void GsGetNextEvent(); Xextern void GsPeekEvent(); Xextern void GsCheckEvent(); X Xextern int GsReadMouse(); Xextern int GsReadKeyboard(); Xextern void GsMoveMouse(); Xextern int GsOpenMouse(); Xextern int GsOpenKeyboard(); Xextern void GsCloseMouse(); Xextern void GsCloseKeyboard(); Xextern void GsSetAccelMouse(); Xextern void GsRestrictMouse(); X Xextern void GsExposeArea(); Xextern void GsCheckCursor(); Xextern void GsWpSetFocus(); Xextern void GsWpClearWindow(); Xextern void GsWpUnmapWindow(); Xextern void GsWpDestroyWindow(); Xextern void GsSetClipWindow(); Xextern GR_COUNT GsSplitClipRect(); Xextern void GsHandleMouseStatus(); Xextern void GsFreePositionEvent(); Xextern void GsDeliverButtonEvent(); Xextern void GsDeliverMotionEvent(); Xextern void GsDeliverKeyboardEvent(); Xextern void GsDeliverExposureEvent(); Xextern void GsDeliverGeneralEvent(); Xextern void GsCheckMouseWindow(); Xextern void GsCheckFocusWindow(); Xextern GR_DRAW_TYPE GsPrepareDrawing(); Xextern GR_BOOL GsCheckOverlap(); Xextern GR_EVENT *GsAllocEvent(); Xextern GR_WINDOW *GsFindWindow(); Xextern GR_GC *GsFindGC(); Xextern GR_WINDOW *GsPrepareWindow(); Xextern GR_WINDOW *GsFindVisibleWindow(); Xextern void GsDrawBorder(); Xextern void GsMoveMouse(); X X X/* X * External data definitions. X */ Xextern char * curfunc; /* current function name */ Xextern GR_WINDOW_ID cachewindowid; /* cached window id */ Xextern GR_GC_ID cachegcid; /* cached graphics context id */ Xextern GR_GC *cachegcp; /* cached graphics context */ Xextern GR_GC *listgcp; /* list of all gc */ Xextern GR_GC *curgcp; /* current graphics context */ Xextern GR_WINDOW *cachewp; /* cached window pointer */ Xextern GR_WINDOW *listwp; /* list of all windows */ Xextern GR_WINDOW *rootwp; /* root window pointer */ Xextern GR_WINDOW *clipwp; /* window clipping is set for */ Xextern GR_WINDOW *focuswp; /* focus window for keyboard */ Xextern GR_WINDOW *mousewp; /* window mouse is currently in */ Xextern GR_WINDOW *grabbuttonwp; /* window grabbed by button */ Xextern GR_CURSOR *curcursor; /* currently enabled cursor */ Xextern GR_COORD cursorx; /* x position of cursor */ Xextern GR_COORD cursory; /* y position of cursor */ Xextern GR_BUTTON curbuttons; /* current state of buttons */ Xextern GR_CLIENT *curclient; /* current client */ Xextern GR_EVENT_LIST *eventfree; /* list of free events */ Xextern GR_EVENT_NUMBER eventnumber; /* current event number */ Xextern GR_BOOL inited; /* TRUE if been initialized */ Xextern GR_BOOL focusfixed; /* TRUE if focus is fixed */ Xextern GR_SCREEN_INFO sinfo; /* screen information */ Xextern GR_FONT_INFO curfont; /* current font information */ Xextern GR_CLIENT clients[GR_MAX_CLIENTS]; /* table of clients */ X X#endif X X/* END CODE */ END_OF_FILE if test 9325 -ne `wc -c <'mini-x/server/graph_serv.h'`; then echo shar: \"'mini-x/server/graph_serv.h'\" unpacked with wrong size! fi # end of 'mini-x/server/graph_serv.h' fi if test -f 'mini-x/server/mousedev.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mini-x/server/mousedev.c'\" else echo shar: Extracting \"'mini-x/server/mousedev.c'\" \(6673 characters\) sed "s/^X//" >'mini-x/server/mousedev.c' <<'END_OF_FILE' X/* X * Copyright (c) 1991 David I. Bell X * Permission is granted to use, distribute, or modify this source, X * provided that this copyright notice remains intact. X * X * Serial mouse user-level device driver. X */ X#include X#include X#include X#include X#include X X X/* X * Configuration for mouse. X */ X#ifndef MOUSE_TYPE X#define MOUSE_TYPE "ms" /* default mouse type ("ms" or "pc") */ X#endif X X#ifndef MOUSE_PORT X#define MOUSE_PORT "/dev/tty64" /* default mouse tty port */ X#endif X X#define MAX_BYTES 128 /* number of bytes for buffer */ X X X/* X * States for the mouse. X */ X#define IDLE 0 /* start of byte sequence */ X#define XSET 1 /* setting x delta */ X#define YSET 2 /* setting y delta */ X#define XADD 3 /* adjusting x delta */ X#define YADD 4 /* adjusting y delta */ X X X/* X * Values in the bytes returned by the mouse for the buttons. X */ X#define PC_LEFT_BUTTON 4 X#define PC_RIGHT_BUTTON 1 X#define PC_MIDDLE_BUTTON 2 X X#define MS_LEFT_BUTTON 2 X#define MS_RIGHT_BUTTON 1 X X X/* X * Bit fields in the bytes sent by the mouse. X */ X#define TOP_FIVE_BITS 0xf8 X#define BOTTOM_THREE_BITS 0x07 X#define TOP_BIT 0x80 X#define SIXTH_BIT 0x40 X#define BOTTOM_TWO_BITS 0x03 X#define THIRD_FOURTH_BITS 0x0c X#define BOTTOM_SIX_BITS 0x3f X X Xstatic int (*parse)(); /* parse routine */ Xstatic int fd; /* file descriptor for mouse */ Xstatic int state; /* IDLE, XSET, ... */ Xstatic GR_BUTTON buttons; /* bits 1, 2 and 3 are buttons l, r and m */ Xstatic GR_BUTTON availbuttons; /* which buttons are available */ Xstatic GR_COORD xd; /* change in x */ Xstatic GR_COORD yd; /* change in y */ X Xstatic int left; /* because the button values change */ Xstatic int middle; /* between mice, the buttons are */ Xstatic int right; /* redefined */ X Xstatic char *bp; /* buffer pointer */ Xstatic int nbytes; /* number of bytes left */ Xstatic unsigned char buffer[MAX_BYTES]; /* data bytes read */ X X X/* X * Parse routines. X */ Xstatic int ParsePC(); /* routine to interpret PC mouse */ Xstatic int ParseMS(); /* routine to interpret MS mouse */ X X Xextern char *getenv(); X X X/* X * Open up the mouse device. X * The mouse can either be a Microsoft serial mouse or a PC serial mouse. X * Arguments are the type of mouse, and the tty device name the mouse is on. X * Type is either "pc" or "ms". If arguments are NULL, then the environment X * variables are used for the values. If there are none, then defaults are X * used. Returns zero if successful, or negative if unsuccessful. X */ Xint XGdOpenMouse(type, port) X char *type; /* type of mouse */ X char *port; /* tty port name */ X{ X struct sgttyb sgttyb; /* terminal modes */ X X if ((type == NULL) || (*type == '\0')) { X type = getenv("MOUSE_TYPE"); X if (type == NULL) X type = MOUSE_TYPE; X } X X if ((port == NULL) || (*port == '\0')) { X port = getenv("MOUSE_PORT"); X if (port == NULL) X port = MOUSE_PORT; X } X X if (strcmp(type, "pc") == 0) { /* PC */ X left = PC_LEFT_BUTTON; X middle = PC_MIDDLE_BUTTON; X right = PC_RIGHT_BUTTON; X parse = ParsePC; X } else if (strcmp(type, "ms") == 0) { /* Microsoft */ X left = MS_LEFT_BUTTON; X right = MS_RIGHT_BUTTON; X middle = 0; X parse = ParseMS; X } else X return -1; X X fd = open(port, O_NONBLOCK); X if (fd < 0) X return -1; X X if (ioctl(fd, TIOCGETP, &sgttyb) == -1) X return -1; X X sgttyb.sg_flags |= RAW; X sgttyb.sg_flags &= ~(EVENP | ODDP | ECHO | XTABS | CRMOD); X X if (ioctl(fd, TIOCSETP, &sgttyb) == -1) X return -1; X X if (ioctl(fd, TIOCFLUSH, 0) < 0) X return -1; X X availbuttons = left | middle | right; X state = IDLE; X nbytes = 0; X buttons = 0; X xd = 0; X yd = 0; X X return 0; X} X X X/* X * Return which buttons are available. X */ Xvoid XGdGetButtonInfo(buttons) X GR_BUTTON *buttons; /* implemented buttons */ X{ X *buttons = availbuttons; X} X X X/* X * Close the mouse device. X */ Xvoid XGdCloseMouse() X{ X if (fd > 0) X close(fd); X fd = 0; X} X X X/* X * Attempt to read bytes from the mouse and interpret them. X * Returns -1 on error, 0 if either no bytes were read or not enough X * was read for a complete state, or 1 if the new state was read. X * When a new state is read, the current buttons and x and y deltas X * are returned. This routine does not block. X */ Xint XGdReadMouse(xdptr, ydptr, bptr) X GR_COORD *xdptr; /* returned X delta */ X GR_COORD *ydptr; /* returned Y delta */ X GR_BUTTON *bptr; /* returned buttons */ X{ X *xdptr = 0; X *ydptr = 0; X *xdptr = buttons; X X /* X * If there are no more bytes left, then read some more, X * waiting for them to arrive. On a signal or a non-blocking X * error, return saying there is no new state available yet. X */ X if (nbytes <= 0) { X bp = buffer; X nbytes = read(fd, bp, MAX_BYTES); X if (nbytes < 0) { X if ((errno == EINTR) || (errno == EAGAIN)) X return 0; X return -1; X } X } X X /* X * Loop over all the bytes read in the buffer, parsing them. X * When a complete state has been read, return the results, X * leaving further bytes in the buffer for later calls. X */ X while (nbytes-- > 0) { X if ((*parse)((int) *bp++)) { X *xdptr = xd; X *ydptr = yd; X *bptr = buttons; X return 1; X } X } X X return 0; X} X X X/* X * Input routine for PC mouse. X * Returns nonzero when a new mouse state has been completed. X */ Xstatic int XParsePC(byte) X int byte; /* current byte read */ X{ X int sign; /* sign of movement */ X X switch (state) { X case IDLE: X if ((byte & TOP_FIVE_BITS) == TOP_BIT) { X buttons = ~byte & BOTTOM_THREE_BITS; X state = XSET; X } X break; X X case XSET: X sign = 1; X if (byte > 127) { X byte = 256 - byte; X sign = -1; X } X xd = byte * sign; X state = YSET; X break; X X case YSET: X sign = 1; X if (byte > 127) { X byte = 256 - byte; X sign = -1; X } X yd = -byte * sign; X state = XADD; X break; X X case XADD: X sign = 1; X if (byte > 127) { X byte = 256 - byte; X sign = -1; X } X xd += byte; X state = YADD; X break; X X case YADD: X sign = 1; X if (byte > 127) { X byte = 256 - byte; X sign = -1; X } X yd -= byte; X state = IDLE; X return 1; X } X return 0; X} X X X/* X * Input routine for Microsoft mouse. X * Returns nonzero when a new mouse state has been completed. X */ Xstatic int XParseMS(byte) X int byte; /* current byte from buffer */ X{ X switch (state) { X case IDLE: X if (byte & SIXTH_BIT) { X buttons = (byte >> 4) & BOTTOM_TWO_BITS; X yd = ((byte & THIRD_FOURTH_BITS) << 4); X xd = ((byte & BOTTOM_TWO_BITS) << 6); X state = XADD; X } X break; X X case XADD: X xd |= (byte & BOTTOM_SIX_BITS); X state = YADD; X break; X X case YADD: X yd |= (byte & BOTTOM_SIX_BITS); X state = IDLE; X if (xd > 127) X xd -= 256; X if (yd > 127) X yd -= 256; X return 1; X } X return 0; X} X X/* END CODE */ END_OF_FILE if test 6673 -ne `wc -c <'mini-x/server/mousedev.c'`; then echo shar: \"'mini-x/server/mousedev.c'\" unpacked with wrong size! fi # end of 'mini-x/server/mousedev.c' fi echo shar: End of archive 2 \(of 9\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 9 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0