Category : C++ Source Code
Archive   : EVENT1.ZIP
Filename : INEVENT.CPP
Output of file : INEVENT.CPP contained in archive : EVENT1.ZIP
#include
#include
#include
#include
#include "mouse.h"
// Used to run the TEST program, else is a library.
#define TEST
#include "inevent.h"
/* ********************************************** */
// Since only members of this class will be talking
// to the mouse, we have placed this inline function
// in this file. However, it is not unusal for
// inline functions to be placed in the class header
// file, to share with other programs that will be
// using the class.
/* ********************************************** */
inline int Event::_mouse(int service, int *bx_reg,
int *cx_reg, int *dx_reg)
{
inregs.x.ax = service;
inregs.x.bx = *bx_reg;
inregs.x.cx = *cx_reg;
inregs.x.dx = *dx_reg;
int86(0x33, &inregs, &outregs);
*bx_reg = outregs.x.bx;
*cx_reg = outregs.x.cx;
*dx_reg = outregs.x.dx;
return(outregs.x.ax);
} /* _mouse() */
/* ********************************************** */
/* ********************************************** */
Event::Event(){
CTRLKEY = NULL;
bBellOn = TRUE;
// Ret T if mouse installed
bMouseOn = MouseReset();
if(bMouseOn == TRUE) {
bx = cx = dx = 0;
// Turn the mouse on
_mouse(MOUSE_ON, &bx, &cx, &dx);
// Set C2X, C2Y, and BUTTON
MouseStatus();
}
// init keyboard stuff
WhereXY();
_setcursortype(_NOCURSOR);
} //Event()
/* ********************************************** */
/* ********************************************** */
Event::~Event(){
if(bMouseOn == TRUE) {
// Turn the mouse off
bx = cx = dx = 0;
_mouse(MOUSE_OFF, &bx, &cx, &dx);
} else {
// destruct keyboard stuff
// (not needed on DOS)
}
_setcursortype(_NORMALCURSOR);
} //~Event()
/* ********************************************** */
// MouseReset(): Used to reset mouse or to check if
// mouse is installed. Returns 0 TRUE or FALSE.
/* ********************************************** */
BOOL Event::MouseReset() {
bx = cx = dx = 0;
if(_mouse(MOUSE_RESET, &bx, &cx, &dx))
return TRUE;
return FALSE;
} // MouseReset()
/* ********************************************** */
/* ********************************************** */
int Event::MouseStatus() {
int x, y, button;
if(bMouseOn == TRUE) {
_mouse(MOUSE_STATUS, &button, &x, &y);
C2Y = y /8;
C2X = x /8;
switch(button) {
case LEFTBUTTON:
BUTTON = MSG_MOUSE_LEFT_CLICK;
break;
case RIGHTBUTTON:
BUTTON = MSG_MOUSE_RIGHT_CLICK;
break;
default:
BUTTON = NULL;
break;
}
}
return button;
} // MouseStatus()
/* ********************************************** */
// Returns X position of cursor #1
/* ********************************************** */
int Event::WhereX() {
if(bMouseOn == TRUE) {
MouseStatus();
}
C1X = wherex();
return C1X;
} // WhereX()
/* ********************************************** */
// Returns Y position of cursor #1
/* ********************************************** */
int Event::WhereY() {
if(bMouseOn == TRUE) {
MouseStatus();
}
C1Y = wherey();
return C1Y;
} // WhereY()
/* ********************************************** */
// Sets the global X and Y positons && returns their
// values. Cursor #1, only.
/* ********************************************** */
POINT Event::WhereXY() {
POINT result;
C1X = result.x = wherex();
C1Y = result.y = wherey();
return result; // The two ints become a long
} // WhereXY()
/* ********************************************** */
// Returns TRUE is the user has a mouse, else FALSE.
/* ********************************************** */
BOOL Event::HasMouse(){
return bMouseOn;
} // HasMouse()
/* ********************************************** */
// Sets the global X and Y positons && returns their
// values. If !mouse, then you get cursor #1.
/* ********************************************** */
POINT Event::WhereMouseXY() {
POINT result;
if(bMouseOn == TRUE) {
result.x = C2X;
result.y = C2Y;
} else {
C1X = result.x = wherex();
C1Y = result.y = wherey();
}
return result; // The two ints become a long
} // WhereMouseXY()
/* ********************************************** */
// Positions the mouse-cursor. (Cursor #2).
/* ********************************************** */
BOOL Event::SetMouseXY(int x, int y) {
int xx, yy;
if(bMouseOn == TRUE) {
xx = x*8;
yy = y*8;
_mouse(MOUSE_SET, 0, &xx, &yy);
} else {
gotoxy(x, y);
}
C2X = x;
C2Y = y;
return TRUE;
} // GotoXY()
/* ********************************************** */
// Positions the screen-cursor. (Cursor #1).
/* ********************************************** */
BOOL Event::GotoXY(int x, int y) {
int xx, yy;
gotoxy(x, y);
C1X = x;
C1Y = y;
return TRUE;
} // GotoXY()
/* ********************************************** */
// Toggles the BELL on and off for string-overflow
// errors.
/* ********************************************** */
void Event::BellAlert(BOOL setit) {
bBellOn = setit;
} // BellAlert()
/* ********************************************** */
// This is the interface into the system area. It
// is the "clearing house" from which we get all
// our events.
// For BOTH mouse && keyboard. Returns MSG_* upon
// MOUSE or CONTROL activity, else a single key.
/* ********************************************** */
int Event::GetEvent() {
int ch;
// Discard result of last MouseStatus().
BUTTON = NULL;
// Loop until info
while( (!kbhit()) && (BUTTON == NULL) )
{
// This would be a great place to hook-up
// a multi-taking routine. The routine could
// merely execute a "hook" function, or do some
// sophisticated round-robin processing. The
// idea here is that, since we're "polling", we
// could be doing something more "fun". For
// example, in Windows, this point is analogous
// to the "GetMessage" loop which allows Windows
// to run other processes.
if (bMouseOn) MouseStatus();
}
// Flag MOUSE activity (set by lower driver).
if(BUTTON) return MSG_MOUSE;
ch=getch();
if(ch==NULL) {
// Save the scan code.
// Flag CTRL activity.
CTRLKEY=getch();
WhereXY(); // Exact position of function keyin
return MSG_KEY_CONTROL;
}
// If we're here, then it's a simple keystroke;
// Read the keyboard cursor;
WhereXY();
return(ch);
} // GetEvent()
/* ********************************************** */
// This is the preferred interface into events.
// No strings are ever returned.
// Keyboard strings are echoed upon demand (note
// that the default is to echo, if none supplied).
/* ********************************************** */
DOSMSG *Event::GetMessage(BOOL bEcho = TRUE) {
DOSMSG *pDm;
pDm = &DosMsg;
pDm->Type = GetEvent();
switch(pDm->Type)
{
case MSG_MOUSE:
pDm->pt.x = C2X;
pDm->pt.y = C2Y;
pDm->Msg = BUTTON;
break;
case MSG_KEY_CONTROL:
pDm->pt.x = C1X;
pDm->pt.y = C1Y;
pDm->Msg = CTRLKEY;
break;
default:
// signal <= KEYBOARD message (character).
pDm->pt.x = C1X;
pDm->pt.y = C1Y;
pDm->Msg = pDm->Type;
pDm->Type = MSG_KEY;
if(bEcho == TRUE) printf("%c",pDm->Msg);
break;
}
return pDm;
} // GetMessage()
/* ********************************************** */
// Builds Zstring or mouse message. Returns a
// populated "buf" string <= bufsz, as well as the
// last DOSMSG received.
/* ********************************************** */
DOSMSG *Event::GetMessage(char *buf, int bufsz) {
int nelem = 0;
DOSMSG *pDm;
// Here we want to be sure to save the position of
// the string as we enter the module. If we get
// interrupted with control-code activity, then
// we will use the apropriate message position.
// If not, then we want to return the XY pair of
// the BEGINNING of the string, not at the last
// character keyed-in.
pDm = &DosMsg;
pDm->pt.x = WhereX();
pDm->pt.y = WhereY();
while((pDm->Type != 0x0d))
{
*buf = pDm->Type = GetEvent();
// BUTTON Mouse activity. Mk message.
if(pDm->Type == MSG_MOUSE)
{
pDm->Msg = BUTTON;
pDm->pt.x = C2X;
pDm->pt.y = C2Y;
*buf = NULL;
return pDm; // signal MOUSE message.
}
// FUNCTION key activity. Mk message.
if(pDm->Type == MSG_KEY_CONTROL)
{
pDm->Msg = CTRLKEY;
pDm->pt.x = C1X;
pDm->pt.y = C1Y;
*buf = NULL;
return pDm; // signal CTRLKEY message.
}
// NORMAL string building activity. Note that
// on normal-size strings (ie: no overflow),
// we will get a \r (0x0a) just before the
// NULL. This is the universal "newline"
// character on all C platforms, and is
// easily removed here if you don't want it.
buf++;
nelem++;
printf("%c",pDm->Type);
if(nelem >= (bufsz -1))
{
if(bBellOn == TRUE)
printf("%c",0x07); // Sound a bell
break;
}
}
if(nelem) // good insurance.
{
pDm->Type = MSG_KEY;
*buf = NULL;
}
// signal <= KEYBOARD message (string).
return pDm;
} // GetMessage()
/* ********************************************** */
// This is used to support graphics screens, only.
// It is included for illustrative puropses only.
// Since we are running in TEXT mode, it is not
// used.
/* ********************************************** */
void Event::install_cursor_image(void)
{
static int immage[16][2] = {
{0xe1ff, 0xe1ff}, /* Screen Mask */
{0xe1ff, 0xe1ff},
{0xe1ff, 0xe000},
{0xe000, 0xe000},
{0x0000, 0x0000},
{0x0000, 0x0000},
{0x0000, 0x0000},
{0x0000, 0x0000},
{0x1e00, 0x1200}, /* Image Mask */
{0x1200, 0x1200},
{0x1200, 0x13ff},
{0x1249, 0x1249},
{0x1249, 0x9001},
{0x9001, 0x9001},
{0x8001, 0x8001},
{0x8001, 0xffff}
};
segread(&segregs);
segregs.es = segregs.ds;
inregs.x.ax = MOUSE_GIMAGE;
inregs.x.bx = 5;
inregs.x.cx = 0;
inregs.x.dx = (int) immage;
int86x(0x33, &inregs, &outregs, &segregs);
} /* install_cursor_image() */
#ifdef TEST
#define STRING_SZ 30
class Event DosEvent;
void TestPointer(void *pClass)
{
class Event *pEClass;
pEClass = (class Event *)pClass;
clrscr();
pEClass->GotoXY(1,0);
puts("Keyin \"BYE\" to Exit");
printf("Mouse is %s",
pEClass->HasMouse() ? "ON" : "OFF"
);
} // TestPointer()
void main() {
int i = 0, result = TRUE;
char buf[STRING_SZ +1];
char blanker[] = " \
";
DOSMSG *pDm;
memset(buf, 0, STRING_SZ +1);
TestPointer((void *) &DosEvent);
while(result == TRUE) {
DosEvent.GotoXY(1,3);
printf("%02d, %02d", DosEvent.WhereX(),
DosEvent.WhereY() );
DosEvent.GotoXY(1,15);
printf("%02d.) Message key-in: ", i++);
// This is the main interface. Notice that the
// overloaded entry-point to the class allows us
// to use either
// pDm = DosEvent.GetMessage(TRUE);
// to get a SINGLE event with character-echoing
// or
pDm = DosEvent.GetMessage(buf, STRING_SZ);
// to build a string.
// Of the two, the latter is used here to
// illustrate how strings are gathered && how
// function keys will interrupt the gathering of
// strings.
// Clean-up after the last-message;
DosEvent.GotoXY(0, 20);
puts(blanker);
DosEvent.GotoXY(0, 21);
puts(blanker);
DosEvent.GotoXY(0, 22);
puts(blanker);
switch(pDm->Type)
{
case MSG_MOUSE:
DosEvent.GotoXY(10, 20);
printf("Mouse Message = %02d, %02d ",
pDm->pt.x, pDm->pt.y);
DosEvent.GotoXY(40, 10);
switch(pDm->Msg)
{
case MSG_MOUSE_LEFT_CLICK:
puts("MSG_MOUSE_LEFT_CLICK: ");
break;
case MSG_MOUSE_RIGHT_CLICK:
puts("MSG_MOUSE_RIGHT_CLICK:");
break;
default:
puts("???????????????: ");
break;
}
break;
case MSG_KEY:
DosEvent.GotoXY(10, 20);
printf("Last Key Message = %02d, %02d",
pDm->pt.x, pDm->pt.y);
DosEvent.GotoXY(10, 21);
printf("Message Keys= \"%s\" ", &buf[0]);
// Exit requested...
if(!strcmp(&buf[0], "BYE\r"))
result = FALSE;
break;
case MSG_KEY_CONTROL:
DosEvent.GotoXY(10, 20);
printf("Control Message = %02d, %02d ",
pDm->pt.x, pDm->pt.y);
DosEvent.GotoXY(10, 22);
printf("Function Key = %c ", pDm->Msg);
// Just to remind us that we may STILL have
// something interesting in the 'ol key-buffer;
DosEvent.GotoXY(10, 21);
printf("Message Keys= \"%s\" ", &buf[0]);
break;
default:
DosEvent.GotoXY(10, 20);
printf("Error Message = %02d, %02d ",
pDm->pt.x, pDm->pt.y);
DosEvent.GotoXY(10, 23);
printf("Error!! \7");
break;
}
}
} // main()
#endif
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/