/* $Id: keyevent.c,v 1.3 2001/12/24 01:09:03 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved */ static char *id = "$Id: keyevent.c,v 1.3 2001/12/24 01:09:03 sybalsky Exp $ Copyright (C) Venue"; /************************************************************************/ /* */ /* (C) Copyright 1989-95 Venue. All Rights Reserved. */ /* Manufactured in the United States of America. */ /* */ /* The contents of this file are proprietary information */ /* belonging to Venue, and are provided to you under license. */ /* They may not be further distributed or disclosed to third */ /* parties without the specific permission of Venue. */ /* */ /************************************************************************/ #include "version.h" /* * This file contains the routines that interface Lisp to the * Sun keyboard and mouse. * */ #include #include #include #ifndef DOS #include #include #include #else #include #endif /* DOS */ #ifdef DOS #include /* Defines "#pragma interrupt" */ #include /* Defines REGS & other structs */ #include /* _XSTACK struct definition */ #pragma interrupt(Mouse_hndlr) void Mouse_hndlr(void); /* Fields mouse events from driver */ /* (during servicing of mouse interrupt) */ #elif XWINDOW #else #include #include #include #include #include #endif /* DOS */ #ifdef ISC #include #include #define SIGIO SIGPOLL #endif /* ISC */ #include "lispemul.h" #include "lspglob.h" #include "adr68k.h" #include "address.h" #include "stack.h" #include "keyboard.h" #include "display.h" #include "lsptypes.h" #include "iopage.h" #include "ifpage.h" #include "bb.h" #include "bitblt.h" #include "pilotbbt.h" #include "dbprint.h" #if (defined(DOS) || defined(XWINDOW)) #include "devif.h" extern DspInterface currentdsp, colordsp; extern IOPAGE *IOPage68K; #endif /* DOS */ #ifdef ISC /*****************************************************/ /* ISC Unix uses POLL, rather than SELECT, because */ /* SELECT causes intermittent wild jumps. This is */ /* the pollfd structure to drive it. */ /*****************************************************/ #include struct pollfd pollfds[33] = { {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}, {0, POLLIN | POLLOUT, 0}}; #endif /* ISC */ /* for contextsw */ #define AS_OPCODE 1 #define AS_CPROG 0 /* EmMouseX68K are already swapped, no need for GETWORD */ #define MouseMove(x, y) \ { \ *((DLword *)EmMouseX68K) = x; \ *((DLword *)EmMouseY68K) = y; \ } #ifdef NEVER #ifndef BYTESWAP #define PUTBASEBIT68K(base68k, offset, bitvalue) \ { \ if (bitvalue) \ *((DLword *)(base68k) + (((u_short)(offset)) >> 4)) |= \ 1 << (15 - ((u_short)(offset)) % BITSPER_DLWORD); \ else \ *((DLword *)(base68k) + (((u_short)(offset)) >> 4)) &= \ ~(1 << (15 - ((u_short)(offset)) % BITSPER_DLWORD)); \ } #else /* convert to real 68 k address, then do arithmetic, and convert back to i386 address pointer */ #define PUTBASEBIT68K(base68k, offset, bitvalue) \ { \ int real68kbase; \ real68kbase = 2 ^ ((int)(base68k)); \ if (bitvalue) \ GETWORD((DLword *)(real68kbase) + (((u_short)(offset)) >> 4)) |= \ 1 << (15 - ((u_short)(offset)) % BITSPER_DLWORD); \ else \ GETWORD((DLword *)(real68kbase) + (((u_short)(offset)) >> 4)) &= \ ~(1 << (15 - ((u_short)(offset)) % BITSPER_DLWORD)); \ } #endif #endif /* NEVER */ extern DLword *EmMouseX68K, *EmMouseY68K, *EmKbdAd068K, *EmRealUtilin68K, *EmUtilin68K; extern DLword *EmKbdAd168K, *EmKbdAd268K, *EmKbdAd368K, *EmKbdAd468K, *EmKbdAd568K; extern u_char *SUNLispKeyMap; extern u_int LispReadFds, LispWindowFd; extern int RS232CReadFds, RS232C_remain_data, XLocked; int XNeedSignal = 0; /* T if an X interrupt happened while XLOCK asserted */ #ifdef NOETHER extern u_int LogFileFd; #else extern int ether_fd; extern u_int LogFileFd, EtherReadFds; #endif /* NOETHER */ extern DLword *DisplayRegion68k; u_int LispIOFds = 0; #ifndef DOS static struct timeval SelectTimeout = {0, 0}; #endif /* DOS */ #ifdef XWINDOW static int Xcount = 1; extern int Event_Req; #endif /* XWINDOW */ extern MISCSTATS *MiscStats; LispPTR *LASTUSERACTION68k; LispPTR *CLastUserActionCell68k; LispPTR *CURSORDESTHEIGHT68k; LispPTR *CURSORDESTWIDTH68k; LispPTR *CURSORHOTSPOTX68k; LispPTR *CURSORHOTSPOTY68k; LispPTR *SOFTCURSORUPP68k; LispPTR *SOFTCURSORWIDTH68k; LispPTR *SOFTCURSORHEIGHT68k; LispPTR *CURRENTCURSOR68k; extern DLword *EmCursorX68K; extern DLword *EmCursorY68K; #ifndef BYTESWAP typedef struct { unsigned nil : 8; unsigned type : 8; unsigned num : 16; } SNum; #else typedef struct { unsigned num : 16; unsigned type : 8; unsigned nil : 8; } SNum; #endif /* BYTESWAP */ #define IDiff(x68k, y68k) (((SNum *)(x68k))->num - ((SNum *)(y68k))->num) /* EmXXXX68K are already swapped, no need for GETWORD */ #ifdef OLD_CURSOR #define TrackCursor(cx, cy) \ { \ *CLastUserActionCell68k = MiscStats->secondstmp; \ *EmCursorX68K = cx; \ *EmCursorY68K = cy; \ } #else #define TrackCursor(cx, cy) \ { \ *CLastUserActionCell68k = MiscStats->secondstmp; \ taking_mouse_down(); \ taking_mouse_up(cx, cy); \ *EmCursorX68K = cx; \ *EmCursorY68K = cy; \ } #endif /* OLD_CURSOR */ /* function that checks to see if more input is waiting on a file; if some is, it bumps FileIOFlag so it'll get seen next time around */ /* commented out is some code that would also clobber Irq_Stk_Check & Irq_Stk_End to force a new interrupt as rapidly as possible; it causes odd behavior... needs some study and thought */ /* this is currently called EVERY time the timer expires. It checks for keyboard input */ LispPTR *MOUSECHORDTICKS68k; /**NEW GLOBAL***-> will be moved***/ LispPTR *KEYBOARDEVENTQUEUE68k; LispPTR *KEYBUFFERING68k; int KBDEventFlg = NIL; DLword *CTopKeyevent; LispPTR DOBUFFEREDTRANSITION_index; LispPTR INTERRUPTFRAME_index; LispPTR *TIMER_INTERRUPT_PENDING68k; LispPTR *PENDINGINTERRUPT68k; LispPTR ATOM_STARTED; LispPTR *PERIODIC_INTERRUPT68k; LispPTR *PERIODIC_INTERRUPT_FREQUENCY68k; LispPTR PERIODIC_INTERRUPTFRAME_index; LispPTR DORECLAIM_index; LispPTR *IOINTERRUPTFLAGS_word; int URaid_req = NIL; int ScreenLocked = NIL; DLword MonoCursor_savebitmap[CURSORHEIGHT]; /* for mono cursor save-image */ #define COLOR_DEPTH 8 #define COLORPIXELS_IN_LONGWORD 4 #define COLORPIXELS_IN_DLWORD 2 DLword ColorCursor_savebitmap[CURSORWIDTH / COLORPIXELS_IN_DLWORD * CURSORHEIGHT]; /************************************************************************/ /* */ /* G E T S I G N A L D A T A */ /* */ /* Handler for the SIGIO interrupt, which happens */ /* 1. When a key transition happens */ /* 2. On mouse moves */ /* 3. When TCP input becomes available. */ /* 4. When a NIT ethernet packet becomes available. */ /* 5. When a console/log/stderr msg needs to be printed. */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* Statics: LispReadFds A 32-bit vector with a 1 for each */ /* FD that can get SIGIO interrupts. */ /* */ /* LispWindowFd The keyboard/window FD, for keyboard */ /* and mouse events. */ /* */ /* LispIOFds A bit vector of TCP FDs, or other */ /* FDs Lisp is doing async I/O on. */ /* Activity on any of these will signal */ /* the Lisp IOInterrupt interrupt. */ /* */ /* ether_fd The raw ethernet FD, for 10MB I/O */ /* */ /* EtherReadFds A bit vector with the raw enet's */ /* bit turned on. To speed up processing. */ /* */ /* LogFileFd A bit vector with the log-file's */ /* bit on, for capturing console msgs. */ /* */ /* */ /* */ /************************************************************************/ void getsignaldata(int sig, int code, struct sigcontext *scp) { #ifndef DOS #ifndef XWINDOW struct inputevent event; #endif /* XWINDOW */ static int rfds, wfds, efds, res; #ifdef ISC int fdcount = 0; int bit; #endif #ifdef XWINDOW #if (defined(APOLLO) || defined(sun)) if (Event_Req) { if (!XLocked++) getXsignaldata(currentdsp); else XNeedSignal = 1; Event_Req = FALSE; XLocked--; } #endif #endif /* XWINDOW */ /* #ifndef KBINT */ rfds = LispReadFds; efds = LispReadFds; /* label and ifs not needed if only keyboard on SIGIO */ getmore: #ifdef ISC for (res = 0, bit = 1; res < 32; res++, bit <<= 1) if (LispReadFds & bit) { pollfds[fdcount++].fd = res; } if ((res = poll(pollfds, fdcount, 0)) > 0) #else if (select(32, (fd_set *)&rfds, NULL, (fd_set *)&efds, &SelectTimeout) >= 0) #endif { DBPRINT(("SIGIO: fd mask(r/e) = 0x%x/0x%x.\n", rfds, efds)); #ifdef SUNDISPLAY if (rfds & (1 << LispWindowFd)) { /* #endif */ while (input_readevent(LispWindowFd, &event) >= 0) { /*if(!kb_event( &event )) {goto getmore;};*/ if ((KBDEventFlg += kb_event(&event)) > 0) { /* immidiately request for IRQ check */ Irq_Stk_End = Irq_Stk_Check = 0; } } /* #ifndef KBINT */ } #endif /* SUNDISPLAY */ #ifdef XWINDOW if (rfds & (1 << ConnectionNumber(currentdsp->display_id))) { if (!XLocked) getXsignaldata(currentdsp); else XNeedSignal = 1; } #endif /* XWINDOW */ #ifdef NOETHER #else if (rfds & EtherReadFds) { /* Raw ethernet (NIT) I/O happened, so handle it. */ DBPRINT(("Handling enet interrupt.\n\n")); check_ether(); } #endif /* NOETHER */ #ifdef RS232 if (((rfds & RS232CReadFds) == RS232CReadFds) || (RS232C_remain_data && rs232c_lisp_is_ready())) rs232c_read(); #endif /* RS232 */ #ifdef LOGINT if (rfds & LogFileFd) { /* There's info in the log file. Tell Lisp to print it. */ flush_pty(); /* move the msg(s) to the log file */ ((INTSTAT *)Addr68k_from_LADDR(*INTERRUPTSTATE_word))->LogFileIO = 1; *PENDINGINTERRUPT68k = ATOM_T; Irq_Stk_End = Irq_Stk_Check = 0; } #endif if (rfds & LispIOFds) { /* There's activity on a Lisp-opened FD. Tell Lisp. */ u_int *flags; flags = (u_int *)Addr68k_from_LADDR(*IOINTERRUPTFLAGS_word); *flags = rfds & LispIOFds; ((INTSTAT *)Addr68k_from_LADDR(*INTERRUPTSTATE_word))->IOInterrupt = 1; *PENDINGINTERRUPT68k = ATOM_T; Irq_Stk_End = Irq_Stk_Check = 0; } } /* #endif */ #endif /* DOS */ } /* end getsignaldata */ void kb_trans(u_short keycode, u_short upflg); /************************************************************************/ /* */ /* k b _ e v e n t */ /* */ /* Given an event from the kbd code, return 1 if a key transition */ /* occurred, 0 if one didn't occur. */ /* */ /************************************************************************/ #if (!defined(XWINDOW) && !defined(DOS)) extern int for_makeinit; int kb_event(struct inputevent *event); { register u_int upflg; int kn; DLword w, r; KBEVENT *kbevent; #ifdef INIT /* generate some code to check if we are running as an INIT. Don't needlessly generate this code, and don't return if we aren't running with the -INIT flag turned on. --was 2/7/89 */ if (for_makeinit) { return (0); }; #endif upflg = event_is_up(event); #ifdef SHOWKEYSTROKES printf("Key # %d, upflg %d.\n", (unsigned short)event->ie_code, upflg); #endif switch (((unsigned short)event->ie_code)) { case LOC_MOVE: #ifndef OLD_CURSOR if (!ScreenLocked) #endif { ScreenLocked = T; MouseMove(event->ie_locx, event->ie_locy); TrackCursor(event->ie_locx, event->ie_locy); ScreenLocked = NIL; } return (0); case MS_LEFT: /*mouse_button( MOUSE_LEFT, upflg );*/ PUTBASEBIT68K(EmRealUtilin68K, MOUSE_LEFT, upflg); break; case MS_MIDDLE: /*mouse_button( MOUSE_MIDDLE, upflg );*/ PUTBASEBIT68K(EmRealUtilin68K, MOUSE_MIDDLE, upflg); break; case MS_RIGHT: /*mouse_button( MOUSE_RIGHT, upflg );*/ PUTBASEBIT68K(EmRealUtilin68K, MOUSE_RIGHT, upflg); break; default: /* keystroke */ if ((kn = SUNLispKeyMap[((unsigned short)event->ie_code)]) > -1) kb_trans(kn, upflg); else printf("kb_event: unknown key number=%d\n", event->ie_code); break; }; { do_ring: /* Emxxx do not use GETWORD */ if (((*EmKbdAd268K) & 2113) == 0) { /*Ctrl-shift-NEXT*/ error("****** EMERGENCY Interrupt ******"); (*EmKbdAd268K) = KB_ALLUP; /*reset*/ ((RING *)CTopKeyevent)->read = 0; /* reset queue */ ((RING *)CTopKeyevent)->write = MINKEYEVENT; /*return(0);*/ } else if (((*EmKbdAd268K) & 2114) == 0) { /* Ctrl-Shift-DEL */ (*EmKbdAd268K) = KB_ALLUP; /*reset*/ URaid_req = T; ((RING *)CTopKeyevent)->read = 0; /* reset queue */ ((RING *)CTopKeyevent)->write = MINKEYEVENT; /*return(0);*/ } #ifdef OS4_TYPE4BUG else if (((*EmKbdAd268K) & 2120) == 0) { /* Ctrl-Shift-Return */ error("****** EMERGENCY Interrupt ******"); (*EmKbdAd268K) = KB_ALLUP; /*reset*/ ((RING *)CTopKeyevent)->read = 0; /* reset queue */ ((RING *)CTopKeyevent)->write = MINKEYEVENT; /*return(0);*/ } #endif r = RING_READ(CTopKeyevent); w = RING_WRITE(CTopKeyevent); if (r == w) goto KBnext; /* event queue FULL */ kbevent = (KBEVENT *)(CTopKeyevent + w); /* RCLK(kbevent->time); */ kbevent->W0 = (*EmKbdAd068K); /* Emxxxx do not use GETWORD */ kbevent->W1 = (*EmKbdAd168K); kbevent->W2 = (*EmKbdAd268K); kbevent->W3 = (*EmKbdAd368K); kbevent->W4 = (*EmKbdAd468K); kbevent->W5 = (*EmKbdAd568K); kbevent->WU = (*EmRealUtilin68K); if (r == 0) /* Queue was empty */ ((RING *)CTopKeyevent)->read = w; if (w >= MAXKEYEVENT) ((RING *)CTopKeyevent)->write = MINKEYEVENT; else ((RING *)CTopKeyevent)->write = w + KEYEVENTSIZE; KBnext: if (*KEYBUFFERING68k == NIL) *KEYBUFFERING68k = ATOM_T; } /* if *EmRealUtilin68K end */ return (1); } #endif /* neither XWINDOW nor DOS*/ /************************************************************************/ /* */ /* k b _ t r a n s */ /* */ /* Return the transition code?? */ /* */ /************************************************************************/ void kb_trans(u_short keycode, u_short upflg) { extern IFPAGE *InterfacePage; if (keycode < 64) /* DLKBDAD0 ~ 3 */ { PUTBASEBIT68K(EmKbdAd068K, keycode, upflg); } else if (keycode >= 80) /* DLKBDAD4, 5 */ { PUTBASEBIT68K(EmKbdAd068K, keycode - 16, upflg); } else if (keycode >= 64 && keycode < 80) /* DLUTILIN */ { PUTBASEBIT68K(EmRealUtilin68K, (keycode & 15), upflg); PUTBASEBIT68K(EmUtilin68K, (keycode & 15), upflg); } } /**********************************************************/ /* MOUSE tracking */ /**********************************************************/ typedef struct { LispPTR CUIMAGE; LispPTR CUMASK; LispPTR CUHOTSPOTX; LispPTR CUHOTSPOTY; LispPTR CUDATA; } CURSOR; #define CursorClippingX(posx, width) \ { \ if (displaywidth < (posx + HARD_CURSORWIDTH)) { \ LastCursorClippingX = width = displaywidth - posx; \ } else { \ LastCursorClippingX = width = HARD_CURSORWIDTH; \ } \ } #define CursorClippingY(posy, height) \ { \ if (displayheight < (posy + HARD_CURSORHEIGHT)) { \ LastCursorClippingY = height = displayheight - posy; \ } else { \ LastCursorClippingY = height = HARD_CURSORHEIGHT; \ } \ } extern int displaywidth, displayheight; extern int DisplayInitialized; extern int MonoOrColor; /* MONO_SCREEN or COLOR_SCREEN */ int LastCursorClippingX = HARD_CURSORWIDTH; int LastCursorClippingY = HARD_CURSORHEIGHT; int LastCursorX = 0; int LastCursorY = 0; void cursor_hidden_bitmap(int, int); #ifndef COLOR /* FOR MONO ONLY */ void taking_mouse_down() { register DLword *srcbase, *dstbase; static int sx, dx, w, h, srcbpl, dstbpl, backwardflg = 0; static int src_comp = 0, op = 0, gray = 0, num_gray = 0, curr_gray_line = 0; #ifdef DOS (currentdsp->mouse_invisible)(currentdsp, IOPage68K); #else if (!DisplayInitialized) return; /* restore saved image */ srcbase = MonoCursor_savebitmap; dstbase = DisplayRegion68k + ((LastCursorY)*DLWORD_PERLINE); /* old y */ sx = 0; dx = LastCursorX; /* old x */ w = LastCursorClippingX; /* Old clipping */ h = LastCursorClippingY; srcbpl = HARD_CURSORWIDTH; dstbpl = displaywidth; op = 0; new_bitblt_code; #ifdef DISPLAYBUFFER flush_display_region(dx, (LastCursorY), w, h); #endif /* DISPLAYBUFFER */ #endif /* DOS */ } #else /* For COLOR & MONO */ extern DLword *ColorDisplayRegion68k; /* It assumes that MONO screen size and COLOR screen size are identical */ void taking_mouse_down() { register DLword *srcbase, *dstbase; static int sx, dx, w, h, srcbpl, dstbpl, backwardflg = 0; static int src_comp = 0, op = 0, gray = 0, num_gray = 0, curr_gray_line = 0; if (!DisplayInitialized) return; /* restore saved image */ sx = 0; if (MonoOrColor == MONO_SCREEN) { dx = LastCursorX; /* old x */ srcbase = MonoCursor_savebitmap; dstbase = DisplayRegion68k + ((LastCursorY)*DLWORD_PERLINE); /* old y */ w = LastCursorClippingX; /* Old clipping */ h = LastCursorClippingY; srcbpl = HARD_CURSORWIDTH; dstbpl = displaywidth; } else { dx = LastCursorX * COLOR_BITSPER_PIXEL; /* old x */ srcbase = ColorCursor_savebitmap; dstbase = ColorDisplayRegion68k + ((LastCursorY)*DLWORD_PERLINE * COLOR_BITSPER_PIXEL); /* old y */ w = LastCursorClippingX * COLOR_BITSPER_PIXEL; /* Old clipping */ h = LastCursorClippingY; srcbpl = HARD_CURSORWIDTH * COLOR_BITSPER_PIXEL; dstbpl = displaywidth * COLOR_BITSPER_PIXEL; } op = 0; new_bitblt_code; #ifdef DISPLAYBUFFER if (MonoOrColor == MONO_SCREEN) flush_display_region(dx, LastCursorY, w, h); #endif } #endif /* COLOR */ /* LastCursorClippingX must be set brfore calling To avoid duplicate caluculation */ #ifndef COLOR /* FOR MONO ONLY */ void copy_cursor(int newx, int newy) { register DLword *srcbase, *dstbase; register int offsetx, offsety; static int sx, dx, w, h, srcbpl, dstbpl, backwardflg = 0; static int src_comp = 0, op = 0, gray = 0, num_gray = 0, curr_gray_line = 0; extern DLword *EmCursorBitMap68K; /* copy cursor image */ srcbase = EmCursorBitMap68K; dstbase = DisplayRegion68k + (newy * DLWORD_PERLINE); sx = 0; dx = newx; w = LastCursorClippingX; h = LastCursorClippingY; ; srcbpl = HARD_CURSORWIDTH; dstbpl = displaywidth; op = 2; /* OR-in */ new_bitblt_code; #ifdef DISPLAYBUFFER flush_display_region(dx, newy, w, h); #endif } /* store bitmap image inside rect. which specified by x,y */ void cursor_hidden_bitmap(int x, int y) { register DLword *srcbase, *dstbase; static int sx, dx, w, h, srcbpl, dstbpl, backwardflg = 0; static int src_comp = 0, op = 0, gray = 0, num_gray = 0, curr_gray_line = 0; /* save image */ srcbase = DisplayRegion68k + (y * DLWORD_PERLINE); dstbase = MonoCursor_savebitmap; sx = x; dx = 0; CursorClippingX(x, w); /* w and LastCursorClippingX rest */ CursorClippingY(y, h); /* h and LastCursorClippingY reset */ srcbpl = displaywidth; dstbpl = HARD_CURSORWIDTH; op = 0; /* replace */ new_bitblt_code; } #else /* For COLOR & MONO */ #define IMIN(x, y) (((x) > (y)) ? (y) : (x)) void copy_cursor(int newx, int newy) { register DLword *srcbase, *dstbase; register int offsetx, offsety; static int sx, dx, w, h, srcbpl, dstbpl, backwardflg = 0; static int src_comp = 0, op = 0, gray = 0, num_gray = 0, curr_gray_line = 0; CURSOR *cursor68k; BITMAP *bitmap68k; extern DLword *EmCursorBitMap68K; /* copy cursor image */ if (MonoOrColor == MONO_SCREEN) { srcbase = EmCursorBitMap68K; dstbase = DisplayRegion68k + (newy * DLWORD_PERLINE); sx = 0; dx = newx; w = LastCursorClippingX; h = LastCursorClippingY; ; srcbpl = HARD_CURSORWIDTH; dstbpl = displaywidth; } else { cursor68k = (CURSOR *)Addr68k_from_LADDR(*CURRENTCURSOR68k); bitmap68k = (BITMAP *)Addr68k_from_LADDR(cursor68k->CUIMAGE); srcbase = (DLword *)Addr68k_from_LADDR(bitmap68k->bmbase); dstbase = ColorDisplayRegion68k + (newy * DLWORD_PERLINE * COLOR_BITSPER_PIXEL); sx = 0; dx = newx * COLOR_BITSPER_PIXEL; w = IMIN(LastCursorClippingX, LOLOC(bitmap68k->bmwidth)) * COLOR_BITSPER_PIXEL; h = IMIN(LastCursorClippingY, LOLOC(bitmap68k->bmheight)); /* srcbpl=HARD_CURSORWIDTH * COLOR_BITSPER_PIXEL;*/ srcbpl = bitmap68k->bmwidth * COLOR_BITSPER_PIXEL; dstbpl = displaywidth * COLOR_BITSPER_PIXEL; } op = 2; /* OR-in */ new_bitblt_code; #ifdef DISPLAYBUFFER if (MonoOrColor == MONO_SCREEN) flush_display_region(dx, newy, w, h); #endif } /* I'll make it MACRO */ void taking_mouse_up(int newx, int newy) { #ifdef DOS (currentdsp->mouse_visible)(newx, newy); #else if (!DisplayInitialized) return; /* save hidden bitmap */ cursor_hidden_bitmap(newx, newy); /* Copy Cursor Image */ #ifndef INIT copy_cursor(newx, newy); #endif LastCursorX = newx; LastCursorY = newy; #endif } /* store bitmap image inside rect. which specified by x,y */ void cursor_hidden_bitmap(int x, int y) { register DLword *srcbase, *dstbase; static int sx, dx, w, h, srcbpl, dstbpl, backwardflg = 0; static int src_comp = 0, op = 0, gray = 0, num_gray = 0, curr_gray_line = 0; /* save image */ if (MonoOrColor == MONO_SCREEN) { srcbase = DisplayRegion68k + (y * DLWORD_PERLINE); dstbase = MonoCursor_savebitmap; sx = x; dx = 0; CursorClippingX(x, w); /* w and LastCursorClippingX rest */ CursorClippingY(y, h); /* h and LastCursorClippingY reset */ srcbpl = displaywidth; dstbpl = HARD_CURSORWIDTH; } else { srcbase = ColorDisplayRegion68k + (y * DLWORD_PERLINE * COLOR_BITSPER_PIXEL); dstbase = ColorCursor_savebitmap; sx = x * COLOR_BITSPER_PIXEL; dx = 0; CursorClippingX(x, w); /* w and LastCursorClippingX rest */ CursorClippingY(y, h); /* h and LastCursorClippingY reset */ w = w * COLOR_BITSPER_PIXEL; srcbpl = displaywidth * COLOR_BITSPER_PIXEL; dstbpl = HARD_CURSORWIDTH * COLOR_BITSPER_PIXEL; } op = 0; /* replace */ new_bitblt_code; } #endif /* COLOR */