Date: Wed, 28 Sep 94 23:11:59 EDT From: dliu AT faraday-gw DOT njit DOT edu (Dong Liu) To: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: [Q] _go32_dpmi_allocate_real_mode_callback_retf Mailer: VM 5.32 (beta) for GNU Emacs 18.59.5 Hi, I have a question about the function _go32_dpmi_allocate_real_mode_callback_retf (such a long name), what is the restriction of the callback function, how large is the stack of that function? I try to allocate a real mode callback then install the real mode address as a mouse handler. If the callback function just modified a static variable, it is ok. But if this function tried to do something more compilcate (in my case, convert the value of CX to hex number then directly write to ScreenPrimay), I got a seg violation at EIP=1 if I moved my mouse for a while. The program is taken from the turbvision mouse handling part. I have it appeded here. Please tell me what I did wrong here? Thanks, --dong PS. are disable() and enable() necessary for the callback function? ---- tstmouse.cc ------- // mouse functions #include #include #include #include typedef unsigned short ushort; typedef unsigned char uchar; enum Boolean { False, True }; struct TPoint { ushort x,y; }; struct MouseEventType { uchar buttons; Boolean doubleClick; TPoint where; }; class THWMouse { protected: THWMouse(); THWMouse( const THWMouse& ) {}; ~THWMouse(); static void show(); static void hide(); static void setRange( ushort, ushort ); static void getEvent( MouseEventType& ); static void registerHandler( unsigned, void (*)(_go32_dpmi_registers *) ); static Boolean present(); static void suspend(); static void resume(); static void inhibit(); protected: static uchar buttonCount; private: static Boolean handlerInstalled; static Boolean noMouse; }; inline Boolean THWMouse::present() { return Boolean( buttonCount != 0 ); } inline void THWMouse::inhibit() { noMouse = True; } uchar THWMouse::buttonCount = 0; Boolean THWMouse::handlerInstalled = False; Boolean THWMouse:: noMouse= False; // !!! not used at all!? static _go32_dpmi_registers mouse_handler_regs; static _go32_dpmi_seginfo mouse_handler_seginfo; THWMouse::THWMouse() { resume(); } void THWMouse::resume() { _go32_dpmi_seginfo info; _go32_dpmi_get_real_mode_interrupt_vector(0x33, &info); if (info.rm_offset == 0 && info.rm_segment == 0) return; _go32_dpmi_registers regs; memset(®s, 0, sizeof(regs)); regs.x.ax=0; // reset mouse _go32_dpmi_simulate_int(0x33, ®s); buttonCount = regs.x.bx; if (buttonCount==0x7FFF) return; if (buttonCount==0xffff) buttonCount=2; memset(®s, 0, sizeof(regs)); regs.x.ax=4; // set mouse position regs.x.cx=0; regs.x.dx=0; _go32_dpmi_simulate_int(0x33, ®s); } THWMouse::~THWMouse() { suspend(); } void THWMouse::suspend() { if( present() == False ) return; hide(); if( handlerInstalled == True ) { registerHandler( 0, 0 ); handlerInstalled = False; } buttonCount = 0; } void THWMouse::show() { _go32_dpmi_registers regs; memset(®s, 0, sizeof regs); regs.x.ax=1; // Show cursor _go32_dpmi_simulate_int( 0x33, ®s ); } void THWMouse::hide() { _go32_dpmi_registers regs; memset(®s, 0, sizeof regs); regs.x.ax=2; // Hide cursor _go32_dpmi_simulate_int( 0x33, ®s ); } void THWMouse::setRange( ushort rx, ushort ry ) { if( buttonCount != 0 ) { _go32_dpmi_registers regs; memset(®s, 0, sizeof regs); regs.x.ax=7; regs.x.cx=0; regs.x.dx=(rx<<3); _go32_dpmi_simulate_int( 0x33, ®s ); memset(®s, 0, sizeof regs); regs.x.ax=8; regs.x.cx=0; regs.x.dx=(ry<<3); _go32_dpmi_simulate_int( 0x33, ®s ); } } void THWMouse::getEvent( MouseEventType& me ) { _go32_dpmi_registers r; memset(&r, 0, sizeof r); r.x.ax=3; // get state _go32_dpmi_simulate_int( 0x33, &r ); me.buttons = r.h.bl; me.where.x = r.x.cx >> 3; me.where.y = r.x.dx >> 3; me.doubleClick = False; } void THWMouse::registerHandler ( unsigned mask, void (*func)(_go32_dpmi_registers *r) ) { if( !present() ) return; if (func && (handlerInstalled != False)) // already register an // handler return; _go32_dpmi_registers regs; if ( func == 0) { regs.x.ax = 12; // install handler regs.x.cx = mask; regs.x.dx = 0; regs.x.es = 0; regs.x.ss = regs.x.sp = 0; _go32_dpmi_simulate_int(0x33, ®s ); if (handlerInstalled == True) { handlerInstalled = False; _go32_dpmi_free_real_mode_callback(&mouse_handler_seginfo); } return; } mouse_handler_seginfo.pm_offset = (unsigned long)func; _go32_dpmi_allocate_real_mode_callback_retf( &mouse_handler_seginfo, &mouse_handler_regs); memset(®s, 0, sizeof regs); regs.x.ax = 12; // install handler regs.x.cx = mask; regs.x.dx = mouse_handler_seginfo.rm_offset; regs.x.es = mouse_handler_seginfo.rm_segment; _go32_dpmi_simulate_int(0x33, ®s); handlerInstalled = True; } class TMouse : public THWMouse { public: TMouse(){}; ~TMouse(){}; static void show(); static void hide(); static void setRange( ushort, ushort ); static void getEvent( MouseEventType& ); static void registerHandler( unsigned, void (*)(_go32_dpmi_registers *) ); static Boolean present(); static void suspend() { THWMouse::suspend(); } static void resume(); }; inline void TMouse::show() { THWMouse::show(); } inline void TMouse::resume() { THWMouse::resume(); show(); }; inline void TMouse::hide() { THWMouse::hide(); } inline void TMouse::setRange( ushort rx, ushort ry ) { THWMouse::setRange( rx, ry ); } inline void TMouse::getEvent( MouseEventType& me ) { THWMouse::getEvent( me ); } #ifdef __GO32__ inline void TMouse::registerHandler ( unsigned mask, void (*func)(_go32_dpmi_registers *) ) #else inline void TMouse::registerHandler( unsigned mask, void (*func)() ) #endif { THWMouse::registerHandler( mask, func ); } inline Boolean TMouse::present() { return THWMouse::present(); } // test static char tmp[100]; static char *myitoa(unsigned int value, char *string, int radix) { char *tp = tmp; int i; unsigned v; int sign; char *sp; sp = string; sign = (radix == 10 && value < 0); if (sign) v = -value; else v = (unsigned)value; while (v || tp == tmp) { i = v % radix; v = v / radix; if (i < 10) *tp++ = i+'0'; else *tp++ = i + 'a' - 10; } if (sign) *sp++ = '-'; while (tp > tmp) *sp++ = *--tp; *sp = 0; return string; } static void ScreenPuts(int line, char *p) { char *d = (char *)ScreenPrimary + 160*line; for(; *p; p++, d+= 2) *d = *p; } static char num[100]; void mouseProc(_go32_dpmi_registers *regs) { disable(); // ScreenPuts(0, "XXXX"); // return; myitoa(regs -> x.cx, num, 16); ScreenPuts(0,num); enable(); } main() { TMouse mouse; if(mouse.present()) { mouse.show(); mouse.registerHandler(0xffff, mouseProc); while (getkey() != 0x1b) ; mouse.hide(); } }