_C PROGRAMMING COLUMN_ by Al Stevens [LISTING ONE] /* ------------- dflat.h ----------- */ #ifndef WINDOW_H #define WINDOW_H #define TRUE 1 #define FALSE 0 #include "system.h" #include "config.h" #include "rect.h" #include "menu.h" #include "keys.h" #include "commands.h" #include "config.h" #include "dialbox.h" /* ------ integer type for message parameters ----- */ typedef long PARAM; typedef enum window_class { NORMAL, APPLICATION, TEXTBOX, LISTBOX, EDITBOX, MENUBAR, POPDOWNMENU, BUTTON, DIALOG, ERRORBOX, MESSAGEBOX, HELPBOX, TEXT, RADIOBUTTON, DUMMY } CLASS; typedef struct window { CLASS class; /* window class */ char *title; /* window title */ struct window *parent; /* parent window */ int (*wndproc) (struct window *, enum messages, PARAM, PARAM); /* ---------------- window dimensions ----------------- */ RECT rc; /* window coordinates (0/0 to 79/24) */ int ht, wd; /* window height and width */ RECT RestoredRC; /* restored condition rect */ /* -------------- linked list pointers ---------------- */ struct window *next; /* next window on screen */ struct window *prev; /* previous window on screen*/ struct window *nextbuilt; /* next window built */ struct window *prevbuilt; /* previous window built */ int attrib; /* Window attributes */ char *videosave; /* video save buffer */ int condition; /* Restored, Maximized, Minimized */ void *extension; /* -> menus, dialog box, etc*/ struct window *PrevMouse; struct window *PrevKeyboard; /* ----------------- text box fields ------------------ */ int wlines; /* number of lines of text */ int wtop; /* text line that is on the top display */ char *text; /* window text */ int textlen; /* text length */ int wleft; /* left position in window viewport */ int textwidth; /* width of longest line in textbox */ int BlkBegLine; /* beginning line of marked block */ int BlkBegCol; /* beginning column of marked block */ int BlkEndLine; /* ending line of marked block */ int BlkEndCol; /* ending column of marked block */ int HScrollBox; /* position of horizontal scroll box */ int VScrollBox; /* position of vertical scroll box */ /* ------------------ list box field ------------------ */ int selection; /* current selection */ /* ----------------- edit box fields ------------------ */ int CurrCol; /* Current column */ char *CurrLine; /* Current line */ int WndRow; /* Current window row */ int TextChanged; /* TRUE if text has changed */ char *DeletedText; /* for undo */ int DeletedLength; /* " " */ /* ---------------- dialog box fields ----------------- */ struct window *dFocus; /* control that has the focus */ int ReturnCode; /* return code from a dialog box */ } * WINDOW; #include "message.h" #include "classdef.h" #include "video.h" enum Condition { ISRESTORED, ISMINIMIZED, ISMAXIMIZED }; /* ------- window methods ----------- */ #define WindowHeight(w) ((w)->ht) #define WindowWidth(w) ((w)->wd) #define BorderAdj(w,n) (TestAttribute(w,HASBORDER)?n:0) #define ClientWidth(w) (WindowWidth(w)-BorderAdj(w,2)) #define ClientHeight(w) (WindowHeight(w)-BorderAdj(w,2)) #define WindowRect(w) ((w)->rc) #define GetTop(w) (RectTop(WindowRect(w))) #define GetBottom(w) (RectBottom(WindowRect(w))) #define GetLeft(w) (RectLeft(WindowRect(w))) #define GetRight(w) (RectRight(WindowRect(w))) #define GetClientTop(w) (GetTop(w)+BorderAdj(w,1)) #define GetClientBottom(w) (GetBottom(w)-BorderAdj(w,1)) #define GetClientLeft(w) (GetLeft(w)+BorderAdj(w,1)) #define GetClientRight(w) (GetRight(w)-BorderAdj(w,1)) #define GetParent(w) ((w)->parent) #define GetTitle(w) ((w)->title) #define NextWindow(w) ((w)->next) #define PrevWindow(w) ((w)->prev) #define NextWindowBuilt(w) ((w)->nextbuilt) #define PrevWindowBuilt(w) ((w)->prevbuilt) #define GetClass(w) ((w)->class) #define GetAttribute(w) ((w)->attrib) #define AddAttribute(w,a) (GetAttribute(w) |= a) #define ClearAttribute(w,a) (GetAttribute(w) &= ~(a)) #define TestAttribute(w,a) (GetAttribute(w) & (a)) #define isVisible(w) (GetAttribute(w) & VISIBLE) #define SetVisible(w) (GetAttribute(w) |= VISIBLE) #define ClearVisible(w) (GetAttribute(w) &= ~VISIBLE) #define gotoxy(w,x,y) cursor(w->rc.lf+(x)+1,w->rc.tp+(y)+1) WINDOW CreateWindow(CLASS,char *,int,int,int,int,void*,WINDOW, int (*)(struct window *,enum messages,PARAM,PARAM),int); void AddTitle(WINDOW, char *); void RepaintBorder(WINDOW, RECT *); void ClearWindow(WINDOW, RECT *, int); void clipline(WINDOW, int, char *); void writeline(WINDOW, char *, int, int, int); void writefull(WINDOW, char *, int); void SetNextFocus(WINDOW,int); void PutWindowChar(WINDOW, int, int, int); void GetVideoBuffer(WINDOW); void RestoreVideoBuffer(WINDOW); int LineLength(char *); #define DisplayBorder(wnd) RepaintBorder(wnd, NULL) #define DefaultWndProc(wnd,msg,p1,p2) \ classdefs[FindClass(wnd->class)].wndproc(wnd,msg,p1,p2) #define BaseWndProc(class,wnd,msg,p1,p2) \ classdefs[DerivedClass(class)].wndproc(wnd,msg,p1,p2) #define NULLWND ((WINDOW) 0) struct LinkedList { WINDOW FirstWindow; WINDOW LastWindow; }; extern struct LinkedList Focus; extern struct LinkedList Built; extern WINDOW inFocus; extern WINDOW CaptureMouse; extern WINDOW CaptureKeyboard; extern int foreground, background; extern int WindowMoving; extern int WindowSizing; extern int TextMarking; extern char *Clipboard; extern WINDOW SystemMenuWnd; /* --------------- border characters ------------- */ #define FOCUS_NW '\xc9' #define FOCUS_NE '\xbb' #define FOCUS_SE '\xbc' #define FOCUS_SW '\xc8' #define FOCUS_SIDE '\xba' #define FOCUS_LINE '\xcd' #define NW '\xda' #define NE '\xbf' #define SE '\xd9' #define SW '\xc0' #define SIDE '\xb3' #define LINE '\xc4' #define LEDGE '\xc3' #define REDGE '\xb4' #define SHADOWFG DARKGRAY /* ------------- scroll bar characters ------------ */ #define UPSCROLLBOX '\x1e' #define DOWNSCROLLBOX '\x1f' #define LEFTSCROLLBOX '\x11' #define RIGHTSCROLLBOX '\x10' #define SCROLLBARCHAR 176 #define SCROLLBOXCHAR 178 #define CHECKMARK 251 /* menu item toggle */ /* ----------------- title bar characters ----------------- */ #define CONTROLBOXCHAR '\xf0' #define MAXPOINTER 24 /* maximize token */ #define MINPOINTER 25 /* minimize token */ #define RESTOREPOINTER 18 /* restore token */ /* --------------- text control characters ---------------- */ #define APPLCHAR 176 /* fills application window */ #define SHORTCUTCHAR '~' /* prefix: shortcut key display */ #define CHANGECOLOR 174 /* prefix to change colors */ #define RESETCOLOR 175 /* reset colors to default */ /* ---- standard window message processing prototypes ----- */ int ApplicationProc(WINDOW, MESSAGE, PARAM, PARAM); int NormalProc(WINDOW, MESSAGE, PARAM, PARAM); int TextBoxProc(WINDOW, MESSAGE, PARAM, PARAM); int ListBoxProc(WINDOW, MESSAGE, PARAM, PARAM); int EditBoxProc(WINDOW, MESSAGE, PARAM, PARAM); int MenuBarProc(WINDOW, MESSAGE, PARAM, PARAM); int PopDownProc(WINDOW, MESSAGE, PARAM, PARAM); int ButtonProc(WINDOW, MESSAGE, PARAM, PARAM); int DialogProc(WINDOW, MESSAGE, PARAM, PARAM); int SystemMenuProc(WINDOW, MESSAGE, PARAM, PARAM); int HelpBoxProc(WINDOW, MESSAGE, PARAM, PARAM); int MessageBoxProc(WINDOW, MESSAGE, PARAM, PARAM); /* ------------- normal box prototypes ------------- */ int isWindow(WINDOW); WINDOW inWindow(int, int); int WndForeground(WINDOW); int WndBackground(WINDOW); int FrameForeground(WINDOW); int FrameBackground(WINDOW); int SelectForeground(WINDOW); int SelectBackground(WINDOW); void SetStandardColor(WINDOW); void SetReverseColor(WINDOW); void SetClassColors(CLASS); WINDOW GetFirstChild(WINDOW); WINDOW GetNextChild(WINDOW); WINDOW GetLastChild(WINDOW); WINDOW GetPrevChild(WINDOW); #define HitControlBox(wnd, p1, p2) \ (TestAttribute(wnd, TITLEBAR) && \ TestAttribute(wnd, CONTROLBOX) && \ p1 == 2 && p2 == 0) /* -------- text box prototypes ---------- */ char *TextLine(WINDOW, int); void WriteTextLine(WINDOW, RECT *, int, int); void SetTextBlock(WINDOW, int, int, int, int); #define BlockMarked(wnd) ( wnd->BlkBegLine || \ wnd->BlkEndLine || \ wnd->BlkBegCol || \ wnd->BlkEndCol) #define ClearBlock(wnd) wnd->BlkBegLine = wnd->BlkEndLine = \ wnd->BlkBegCol = wnd->BlkEndCol = 0; #define GetText(w) ((w)->text) /* --------- menu prototypes ---------- */ int CopyCommand(char *, char *, int, int); void PrepOptionsMenu(void *, struct Menu *); void PrepEditMenu(void *, struct Menu *); void PrepWindowMenu(void *, struct Menu *); void BuildSystemMenu(WINDOW); /* ------------- edit box prototypes ----------- */ #define isMultiLine(wnd) TestAttribute(wnd, MULTILINE) /* --------- message box prototypes -------- */ void MessageBox(char *, char *); void ErrorMessage(char *); int TestErrorMessage(char *); int YesNoBox(char *); int MsgHeight(char *); int MsgWidth(char *); /* ------------- dialog box prototypes -------------- */ int DialogBox(DBOX *, int (*)(struct window *, enum messages, PARAM, PARAM)); int DlgOpenFile(char *, char *); int DlgSaveAs(char *); void GetDlgListText(WINDOW, char *, enum commands); int DlgDirList(WINDOW, char *, enum commands, enum commands, unsigned); int RadioButtonSetting(DBOX *, enum commands); void PushRadioButton(DBOX *, enum commands); void PutItemText(WINDOW, enum commands, char *); void GetItemText(WINDOW, enum commands, char *, int); /* ------------- help box prototypes ------------- */ void HelpFunction(void); void LoadHelpFile(void); #define swap(a,b){int x=a;a=b;b=x;} #endif [LISTING TWO] /* ----------- keys.h ------------ */ #ifndef KEYS_H #define KEYS_H #define RUBOUT 8 #define BELL 7 #define ESC 27 #define ALT_BS 197 #define SHIFT_DEL 198 #define CTRL_INS 186 #define SHIFT_INS 185 #define F1 187 #define F2 188 #define F3 189 #define F4 190 #define F5 191 #define F6 192 #define F7 193 #define F8 194 #define F9 195 #define F10 196 #define CTRL_F1 222 #define CTRL_F2 223 #define CTRL_F3 224 #define CTRL_F4 225 #define CTRL_F5 226 #define CTRL_F6 227 #define CTRL_F7 228 #define CTRL_F8 229 #define CTRL_F9 230 #define CTRL_F10 231 #define ALT_F1 232 #define ALT_F2 233 #define ALT_F3 234 #define ALT_F4 235 #define ALT_F5 236 #define ALT_F6 237 #define ALT_F7 238 #define ALT_F8 239 #define ALT_F9 240 #define ALT_F10 241 #define HOME 199 #define UP 200 #define PGUP 201 #define BS 203 #define FWD 205 #define END 207 #define DN 208 #define PGDN 209 #define INS 210 #define DEL 211 #define CTRL_HOME 247 #define CTRL_PGUP 132 #define CTRL_BS 243 #define CTRL_FIVE 143 #define CTRL_FWD 244 #define CTRL_END 245 #define CTRL_PGDN 246 #define SHIFT_HT 143 #define ALT_A 158 #define ALT_B 176 #define ALT_C 174 #define ALT_D 160 #define ALT_E 146 #define ALT_F 161 #define ALT_G 162 #define ALT_H 163 #define ALT_I 151 #define ALT_J 164 #define ALT_K 165 #define ALT_L 166 #define ALT_M 178 #define ALT_N 177 #define ALT_O 152 #define ALT_P 153 #define ALT_Q 144 #define ALT_R 147 #define ALT_S 159 #define ALT_T 148 #define ALT_U 150 #define ALT_V 175 #define ALT_W 145 #define ALT_X 173 #define ALT_Y 149 #define ALT_Z 172 #define ALT_1 0xf8 #define ALT_2 0xf9 #define ALT_3 0xfa #define ALT_4 0xfb #define ALT_5 0xfc #define ALT_6 0xfd #define ALT_7 0xfe #define ALT_8 0xff #define ALT_9 0x80 #define ALT_0 0x81 #define ALT_HYPHEN 130 #define RIGHTSHIFT 0x01 #define LEFTSHIFT 0x02 #define CTRLKEY 0x04 #define ALTKEY 0x08 #define SCROLLLOCK 0x10 #define NUMLOCK 0x20 #define CAPSLOCK 0x40 #define INSERTKEY 0x80 struct keys { int keycode; char *keylabel; }; int getkey(void); int getshift(void); int keyhit(void); void beep(void); extern struct keys keys[]; extern char altconvert[]; #endif [LISTING THREE] /* --------------- system.h -------------- */ #ifndef SYSTEM_H #define SYSTEM_H /* ----- interrupt vectors ----- */ #define TIMER 8 #define VIDEO 0x10 #define KEYBRD 0x16 #define DOS 0x21 #define CRIT 0x24 #define MOUSE 0x33 /* ------- platform-dependent values ------ */ #define FREQUENCY 100 #define COUNT (1193280L / FREQUENCY) #define ZEROFLAG 0x40 #define MAXSAVES 50 #define SCREENWIDTH 80 #define SCREENHEIGHT 25 /* ----- keyboard BIOS (0x16) functions -------- */ #define READKB 0 #define KBSTAT 1 /* ------- video BIOS (0x10) functions --------- */ #define SETCURSORTYPE 1 #define SETCURSOR 2 #define READCURSOR 3 #define READATTRCHAR 8 #define WRITEATTRCHAR 9 #define HIDECURSOR 0x20 /* ------- the interrupt function registers -------- */ typedef struct { int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,fl; } IREGS; /* ---------- cursor prototypes -------- */ void curr_cursor(int *x, int *y); void cursor(int x, int y); void hidecursor(void); void unhidecursor(void); void savecursor(void); void restorecursor(void); void normalcursor(void); void set_cursor_type(unsigned t); void videomode(void); /* ---------- mouse prototypes ---------- */ int mouse_installed(void); int mousebuttons(void); void get_mouseposition(int *x, int *y); void set_mouseposition(int x, int y); void show_mousecursor(void); void hide_mousecursor(void); int button_releases(void); void resetmouse(void); #define leftbutton() (mousebuttons()&1) #define rightbutton() (mousebuttons()&2) #define waitformouse() while(mousebuttons()); /* ------------ timer macros -------------- */ #define timed_out(timer) (timer==0) #define set_timer(timer, secs) timer=(secs)*182/10+1 #define disable_timer(timer) timer = -1 #define timer_running(timer) (timer > 0) #define countdown(timer) --timer #define timer_disabled(timer) (timer == -1) #ifdef MSC /* ============= MSC Compatibility Macros ============ */ #define BLACK 0 #define BLUE 1 #define GREEN 2 #define CYAN 3 #define RED 4 #define MAGENTA 5 #define BROWN 6 #define LIGHTGRAY 7 #define DARKGRAY 8 #define LIGHTBLUE 9 #define LIGHTGREEN 10 #define LIGHTCYAN 11 #define LIGHTRED 12 #define LIGHTMAGENTA 13 #define YELLOW 14 #define WHITE 15 #define getvect(v) _dos_getvect(v) #define setvect(v,f) _dos_setvect(v,f) #define MK_FP(s,o) ((void far *) \ (((unsigned long)(s) << 16) | (unsigned)(o))) #undef FP_OFF #undef FP_SEG #define FP_OFF(p) ((unsigned)(p)) #define FP_SEG(p) ((unsigned)((unsigned long)(p) >> 16)) #define poke(a,b,c) (*((int far*)MK_FP((a),(b))) = (int)(c)) #define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c)) #define peek(a,b) (*((int far*)MK_FP((a),(b)))) #define peekb(a,b) (*((char far*)MK_FP((a),(b)))) #define findfirst(p,f,a) _dos_findfirst(p,a,f) #define findnext(f) _dos_findnext(f) #define ffblk find_t #define ff_name name #define ff_fsize size #define ff_attrib attrib #define fnsplit _splitpath #define fnmerge _makepath #define EXTENSION 2 #define FILENAME 4 #define DIRECTORY 8 #define DRIVE 16 #define MAXPATH 80 #define MAXDRIVE 3 #define MAXDIR 66 #define MAXFILE 9 #define MAXEXT 5 #define setdisk(d) _dos_setdrive((d)+1, NULL) #define bioskey _bios_keybrd #define keyhit kbhit #endif #endif [LISTING FOUR] /* ----------- rect.h ------------ */ #ifndef RECT_H #define RECT_H typedef struct { int lf,tp,rt,bt; } RECT; #define within(p,v1,v2) ((p)>=(v1)&&(p)<=(v2)) #define RectTop(r) (r.tp) #define RectBottom(r) (r.bt) #define RectLeft(r) (r.lf) #define RectRight(r) (r.rt) #define InsideRect(x,y,r) (within(x,RectLeft(r),RectRight(r)) \ && \ within(y,RectTop(r),RectBottom(r))) #define ValidRect(r) (RectRight(r) || RectLeft(r)) #define RectWidth(r) (RectRight(r)-RectLeft(r)+1) #define RectHeight(r) (RectBottom(r)-RectTop(r)+1) RECT subRectangle(RECT, RECT); RECT RelativeRectangle(RECT, RECT); RECT ClientRect(void *); RECT SetRect(int,int,int,int); #endif [LISTING FIVE] /* ---------------- video.h ----------------- */ #ifndef VIDEO_H #define VIDEO_H #include "rect.h" void getvideo(RECT, void far *); void storevideo(RECT, void far *); extern unsigned video_mode; extern unsigned video_page; void wputch(WINDOW, int, int, int); int GetVideoChar(int, int); void PutVideoChar(int, int, int); void get_videomode(void); void wputs(WINDOW, void *, int, int); #define clr(fg,bg) ((fg)|((bg)<<4)) #define vad(x,y) ((y)*160+(x)*2) #define ismono() (video_mode == 7) #define istext() (video_mode < 4) #define videochar(x,y) (GetVideoChar(x,y) & 255) #endif [LISTING SIX] /* --------------------- video.c -------------------- */ #include #include #include #include #include "dflat.h" static unsigned video_address; /* -- read a rectangle of video memory into a save buffer -- */ void getvideo(RECT rc, void far *bf) { int ht = RectBottom(rc)-RectTop(rc)+1; int bytes_row = (RectRight(rc)-RectLeft(rc)+1) * 2; unsigned vadr = vad(RectLeft(rc), RectTop(rc)); hide_mousecursor(); while (ht--) { movedata(video_address, vadr, FP_SEG(bf), FP_OFF(bf), bytes_row); vadr += 160; (char far *)bf += bytes_row; } show_mousecursor(); } /* -- write a rectangle of video memory from a save buffer -- */ void storevideo(RECT rc, void far *bf) { int ht = RectBottom(rc)-RectTop(rc)+1; int bytes_row = (RectRight(rc)-RectLeft(rc)+1) * 2; unsigned vadr = vad(RectLeft(rc), RectTop(rc)); hide_mousecursor(); while (ht--) { movedata(FP_SEG(bf), FP_OFF(bf), video_address, vadr, bytes_row); vadr += 160; (char far *)bf += bytes_row; } show_mousecursor(); } /* -------- read a character of video memory ------- */ int GetVideoChar(int x, int y) { int c; hide_mousecursor(); c = peek(video_address, vad(x,y)); show_mousecursor(); return c; } /* -------- write a character of video memory ------- */ void PutVideoChar(int x, int y, int c) { if (x < SCREENWIDTH && y < SCREENHEIGHT) { hide_mousecursor(); poke(video_address, vad(x,y), c); show_mousecursor(); } } /* -------- write a character to a window ------- */ void wputch(WINDOW wnd, int c, int x, int y) { int x1 = GetClientLeft(wnd)+x; int y1 = GetClientTop(wnd)+y; if (x1 < SCREENWIDTH && y1 < SCREENHEIGHT) { hide_mousecursor(); poke(video_address, vad(x1,y1),(c & 255) | (clr(foreground, background) << 8)); show_mousecursor(); } } /* ------- write a string to a window ---------- */ void wputs(WINDOW wnd, void *s, int x, int y) { int x1 = GetLeft(wnd)+x; int y1 = GetTop(wnd)+y; if (x1 < SCREENWIDTH && y1 < SCREENHEIGHT) { int fg = foreground; int bg = background; unsigned char *str = s; char ss[200]; int ln[SCREENWIDTH]; int *cp1 = ln; int len; strncpy(ss, s, 199); ss[199] = '\0'; clipline(wnd, x, ss); str = (unsigned char *) ss; hide_mousecursor(); while (*str) { if (*str == CHANGECOLOR) { str++; foreground = (*str++) & 0x7f; background = (*str++) & 0x7f; continue; } if (*str == RESETCOLOR) { foreground = fg; background = bg; str++; continue; } *cp1++ = (*str & 255) | (clr(foreground, background) << 8); str++; } foreground = fg; background = bg; len = (int)(cp1-ln); if (x1+len > SCREENWIDTH) len = SCREENWIDTH-x1; movedata(FP_SEG(ln), FP_OFF(ln), video_address, vad(x1,y1), len*2); show_mousecursor(); } } /* --------- get the current video mode -------- */ void get_videomode(void) { videomode(); /* ---- Monochrome Display Adaptor or text mode ---- */ if (ismono()) video_address = 0xb000; else /* ------ Text mode -------- */ video_address = 0xb800 + video_page; } [LISTING SEVEN] /* ----------- console.c ---------- */ #include #include #include #include "system.h" #include "keys.h" /* ----- table of alt keys for finding shortcut keys ----- */ char altconvert[] = { ALT_A,ALT_B,ALT_C,ALT_D,ALT_E,ALT_F,ALT_G,ALT_H, ALT_I,ALT_J,ALT_K,ALT_L,ALT_M,ALT_N,ALT_O,ALT_P, ALT_Q,ALT_R,ALT_S,ALT_T,ALT_U,ALT_V,ALT_W,ALT_X, ALT_Y,ALT_Z,ALT_0,ALT_1,ALT_2,ALT_3,ALT_4,ALT_5, ALT_6,ALT_7,ALT_8,ALT_9,0 }; unsigned video_mode; unsigned video_page; static int near cursorpos[MAXSAVES]; static int near cursorshape[MAXSAVES]; static int cs = 0; static union REGS regs; #ifndef MSC #define ZEROFLAG 0x40 /* ---- Test for keystroke ---- */ int keyhit(void) { _AH = 1; geninterrupt(KEYBRD); return (_FLAGS & ZEROFLAG) == 0; } #endif /* ---- Read a keystroke ---- */ int getkey(void) { int c; while (keyhit() == 0) ; if (((c = bioskey(0)) & 0xff) == 0) c = (c >> 8) | 0x80; return c & 0xff; } /* ---------- read the keyboard shift status --------- */ int getshift(void) { regs.h.ah = 2; int86(KEYBRD, ®s, ®s); return regs.h.al; } /* ------- macro to wait one clock tick -------- */ #define wait() \ { \ int now = peek(0x40,0x6c); \ while (now == peek(0x40,0x6c)) \ ; \ } /* -------- sound a buzz tone ---------- */ void beep(void) { wait(); outp(0x43, 0xb6); /* program the frequency */ outp(0x42, (int) (COUNT % 256)); outp(0x42, (int) (COUNT / 256)); outp(0x61, inp(0x61) | 3); /* start the sound */ wait(); outp(0x61, inp(0x61) & ~3); /* stop the sound */ } /* -------- get the video mode and page from BIOS -------- */ void videomode(void) { regs.h.ah = 15; int86(VIDEO, ®s, ®s); video_mode = regs.h.al; video_page = regs.x.bx; video_page &= 0xff00; video_mode &= 0x7f; } /* ------ position the cursor ------ */ void cursor(int x, int y) { videomode(); regs.x.dx = ((y << 8) & 0xff00) + x; regs.x.ax = 0x0200; regs.x.bx = video_page; int86(VIDEO, ®s, ®s); } /* ------ get cursor shape and position ------ */ static void near getcursor(void) { videomode(); regs.h.ah = READCURSOR; regs.x.bx = video_page; int86(VIDEO, ®s, ®s); } /* ------- get the current cursor position ------- */ void curr_cursor(int *x, int *y) { getcursor(); *x = regs.h.dl; *y = regs.h.dh; } /* ------ save the current cursor configuration ------ */ void savecursor(void) { if (cs < MAXSAVES) { getcursor(); cursorshape[cs] = regs.x.cx; cursorpos[cs] = regs.x.dx; cs++; } } /* ---- restore the saved cursor configuration ---- */ void restorecursor(void) { if (cs) { --cs; videomode(); regs.x.dx = cursorpos[cs]; regs.h.ah = SETCURSOR; regs.x.bx = video_page; int86(VIDEO, ®s, ®s); set_cursor_type(cursorshape[cs]); } } /* ------ make a normal cursor ------ */ void normalcursor(void) { set_cursor_type(0x0607); } /* ------ hide the cursor ------ */ void hidecursor(void) { getcursor(); regs.h.ch |= HIDECURSOR; regs.h.ah = SETCURSORTYPE; int86(VIDEO, ®s, ®s); } /* ------ unhide the cursor ------ */ void unhidecursor(void) { getcursor(); regs.h.ch &= ~HIDECURSOR; regs.h.ah = SETCURSORTYPE; int86(VIDEO, ®s, ®s); } /* ---- use BIOS to set the cursor type ---- */ void set_cursor_type(unsigned t) { videomode(); regs.h.ah = SETCURSORTYPE; regs.x.bx = video_page; regs.x.cx = t; int86(VIDEO, ®s, ®s); } [LISTING EIGHT] /* ------------- mouse.c ------------- */ #include #include #include #include #include "system.h" static union REGS regs; static void near mouse(int m1,int m2,int m3,int m4) { regs.x.dx = m4; regs.x.cx = m3; regs.x.bx = m2; regs.x.ax = m1; int86(MOUSE, ®s, ®s); } /* ---------- reset the mouse ---------- */ void resetmouse(void) { mouse(0,0,0,0); } /* ----- test to see if the mouse driver is installed ----- */ int mouse_installed(void) { unsigned char far *ms; ms = MK_FP(peek(0, MOUSE*4+2), peek(0, MOUSE*4)); return (ms != NULL && *ms != 0xcf); } /* ------ return true if mouse buttons are pressed ------- */ int mousebuttons(void) { if (mouse_installed()) mouse(3,0,0,0); return regs.x.bx & 3; } /* ---------- return mouse coordinates ---------- */ void get_mouseposition(int *x, int *y) { if (mouse_installed()) { mouse(3,0,0,0); *x = regs.x.cx/8; *y = regs.x.dx/8; } } /* -------- position the mouse cursor -------- */ void set_mouseposition(int x, int y) { if(mouse_installed()) mouse(4,0,x*8,y*8); } /* --------- display the mouse cursor -------- */ void show_mousecursor(void) { if(mouse_installed()) mouse(1,0,0,0); } /* --------- hide the mouse cursor ------- */ void hide_mousecursor(void) { if(mouse_installed()) mouse(2,0,0,0); } /* --- return true if a mouse button has been released --- */ int button_releases(void) { if(mouse_installed()) mouse(6,0,0,0); return regs.x.bx; }