/*
|
/*
|
* Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
|
* Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
|
* Copyright (c) 1991 David I. Bell
|
* Copyright (c) 1991 David I. Bell
|
* Permission is granted to use, distribute, or modify this source,
|
* Permission is granted to use, distribute, or modify this source,
|
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
*
|
*
|
* Graphics server event routines for windows.
|
* Graphics server event routines for windows.
|
*/
|
*/
|
#include "windows.h"
|
#include "windows.h"
|
#include "wintern.h"
|
#include "wintern.h"
|
#include "device.h"
|
#include "device.h"
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
#if !(DOS_TURBOC | DOS_QUICKC | _MINIX | VXWORKS)
|
#if !(DOS_TURBOC | DOS_QUICKC | _MINIX | VXWORKS)
|
static int
|
static int
|
abs(int n)
|
abs(int n)
|
{
|
{
|
return n >= 0? n: -n;
|
return n >= 0? n: -n;
|
}
|
}
|
#endif
|
#endif
|
|
|
/*
|
/*
|
* Update mouse status and issue events on it if necessary.
|
* Update mouse status and issue events on it if necessary.
|
* This function doesn't block, but is normally only called when
|
* This function doesn't block, but is normally only called when
|
* there is known to be some data waiting to be read from the mouse.
|
* there is known to be some data waiting to be read from the mouse.
|
*/
|
*/
|
BOOL
|
BOOL
|
MwCheckMouseEvent(void)
|
MwCheckMouseEvent(void)
|
{
|
{
|
MWCOORD rootx; /* latest mouse x position */
|
MWCOORD rootx; /* latest mouse x position */
|
MWCOORD rooty; /* latest mouse y position */
|
MWCOORD rooty; /* latest mouse y position */
|
int newbuttons; /* latest buttons */
|
int newbuttons; /* latest buttons */
|
int mousestatus; /* latest mouse status */
|
int mousestatus; /* latest mouse status */
|
|
|
/* Read the latest mouse status: */
|
/* Read the latest mouse status: */
|
mousestatus = GdReadMouse(&rootx, &rooty, &newbuttons);
|
mousestatus = GdReadMouse(&rootx, &rooty, &newbuttons);
|
if(mousestatus < 0) {
|
if(mousestatus < 0) {
|
/*MwError(GR_ERROR_MOUSE_ERROR, 0);*/
|
/*MwError(GR_ERROR_MOUSE_ERROR, 0);*/
|
return FALSE;
|
return FALSE;
|
} else if(mousestatus) { /* Deliver events as appropriate: */
|
} else if(mousestatus) { /* Deliver events as appropriate: */
|
MwHandleMouseStatus(rootx, rooty, newbuttons);
|
MwHandleMouseStatus(rootx, rooty, newbuttons);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
/*
|
/*
|
* Update keyboard status and issue events on it if necessary.
|
* Update keyboard status and issue events on it if necessary.
|
* This function doesn't block, but is normally only called when
|
* This function doesn't block, but is normally only called when
|
* there is known to be some data waiting to be read from the keyboard.
|
* there is known to be some data waiting to be read from the keyboard.
|
*/
|
*/
|
BOOL
|
BOOL
|
MwCheckKeyboardEvent(void)
|
MwCheckKeyboardEvent(void)
|
{
|
{
|
MWKEY mwkey; /* latest character */
|
MWKEY mwkey; /* latest character */
|
MWKEYMOD modifiers; /* latest modifiers */
|
MWKEYMOD modifiers; /* latest modifiers */
|
MWSCANCODE scancode;
|
MWSCANCODE scancode;
|
int keystatus; /* latest keyboard status */
|
int keystatus; /* latest keyboard status */
|
|
|
/* Read the latest keyboard status: */
|
/* Read the latest keyboard status: */
|
keystatus = GdReadKeyboard(&mwkey, &modifiers, &scancode);
|
keystatus = GdReadKeyboard(&mwkey, &modifiers, &scancode);
|
if(keystatus < 0) {
|
if(keystatus < 0) {
|
if(keystatus == -2) /* special case for ESC pressed*/
|
if(keystatus == -2) /* special case for ESC pressed*/
|
MwTerminate();
|
MwTerminate();
|
/*MwError(GR_ERROR_KEYBOARD_ERROR, 0);*/
|
/*MwError(GR_ERROR_KEYBOARD_ERROR, 0);*/
|
return FALSE;
|
return FALSE;
|
} else if(keystatus) { /* Deliver events as appropriate: */
|
} else if(keystatus) { /* Deliver events as appropriate: */
|
switch (mwkey) {
|
switch (mwkey) {
|
case MWKEY_QUIT:
|
case MWKEY_QUIT:
|
MwTerminate();
|
MwTerminate();
|
/* no return*/
|
/* no return*/
|
case MWKEY_REDRAW:
|
case MWKEY_REDRAW:
|
MwRedrawScreen();
|
MwRedrawScreen();
|
break;
|
break;
|
case MWKEY_PRINT:
|
case MWKEY_PRINT:
|
if (keystatus == 1)
|
if (keystatus == 1)
|
GdCaptureScreen("screen.bmp");
|
GdCaptureScreen("screen.bmp");
|
break;
|
break;
|
}
|
}
|
MwDeliverKeyboardEvent(mwkey, modifiers, scancode,
|
MwDeliverKeyboardEvent(mwkey, modifiers, scancode,
|
keystatus==1? TRUE: FALSE);
|
keystatus==1? TRUE: FALSE);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
/*
|
/*
|
* Handle all mouse events. These are mouse enter, mouse exit, mouse
|
* Handle all mouse events. These are mouse enter, mouse exit, mouse
|
* motion, mouse position, button down, and button up. This also moves
|
* motion, mouse position, button down, and button up. This also moves
|
* the cursor to the new mouse position and changes it shape if needed.
|
* the cursor to the new mouse position and changes it shape if needed.
|
*/
|
*/
|
void
|
void
|
MwHandleMouseStatus(MWCOORD newx, MWCOORD newy, int newbuttons)
|
MwHandleMouseStatus(MWCOORD newx, MWCOORD newy, int newbuttons)
|
{
|
{
|
int changebuttons; /* buttons that have changed */
|
int changebuttons; /* buttons that have changed */
|
MWKEYMOD modifiers; /* latest modifiers */
|
MWKEYMOD modifiers; /* latest modifiers */
|
static int curbuttons;
|
static int curbuttons;
|
|
|
GdGetModifierInfo(NULL, &modifiers); /* Read kbd modifiers */
|
GdGetModifierInfo(NULL, &modifiers); /* Read kbd modifiers */
|
|
|
/*
|
/*
|
* First, if the mouse has moved, then position the cursor to the
|
* First, if the mouse has moved, then position the cursor to the
|
* new location, which will send mouse enter, mouse exit, focus in,
|
* new location, which will send mouse enter, mouse exit, focus in,
|
* and focus out events if needed. Check here for mouse motion and
|
* and focus out events if needed. Check here for mouse motion and
|
* mouse position events.
|
* mouse position events.
|
*/
|
*/
|
if (newx != cursorx || newy != cursory) {
|
if (newx != cursorx || newy != cursory) {
|
MwMoveCursor(newx, newy);
|
MwMoveCursor(newx, newy);
|
MwDeliverMouseEvent(newbuttons, 0, modifiers);
|
MwDeliverMouseEvent(newbuttons, 0, modifiers);
|
}
|
}
|
|
|
/*
|
/*
|
* Next, generate a button up event if any buttons have been released.
|
* Next, generate a button up event if any buttons have been released.
|
*/
|
*/
|
changebuttons = (curbuttons & ~newbuttons);
|
changebuttons = (curbuttons & ~newbuttons);
|
if (changebuttons)
|
if (changebuttons)
|
MwDeliverMouseEvent(newbuttons, changebuttons, modifiers);
|
MwDeliverMouseEvent(newbuttons, changebuttons, modifiers);
|
|
|
/*
|
/*
|
* Finally, generate a button down event if any buttons have been
|
* Finally, generate a button down event if any buttons have been
|
* pressed.
|
* pressed.
|
*/
|
*/
|
changebuttons = (~curbuttons & newbuttons);
|
changebuttons = (~curbuttons & newbuttons);
|
if (changebuttons)
|
if (changebuttons)
|
MwDeliverMouseEvent(newbuttons, changebuttons, modifiers);
|
MwDeliverMouseEvent(newbuttons, changebuttons, modifiers);
|
|
|
curbuttons = newbuttons;
|
curbuttons = newbuttons;
|
}
|
}
|
|
|
/*
|
/*
|
* Translate and deliver hardware mouse message to proper window.
|
* Translate and deliver hardware mouse message to proper window.
|
*/
|
*/
|
void
|
void
|
MwTranslateMouseMessage(HWND hwnd,UINT msg,int hittest)
|
MwTranslateMouseMessage(HWND hwnd,UINT msg,int hittest)
|
{
|
{
|
POINT pt;
|
POINT pt;
|
DWORD tick;
|
DWORD tick;
|
static UINT lastmsg = 0;
|
static UINT lastmsg = 0;
|
static HWND lasthwnd;
|
static HWND lasthwnd;
|
static DWORD lasttick;
|
static DWORD lasttick;
|
static int lastx, lasty;
|
static int lastx, lasty;
|
|
|
/* determine double click eligibility*/
|
/* determine double click eligibility*/
|
if(msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN) {
|
if(msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN) {
|
tick = GetTickCount();
|
tick = GetTickCount();
|
if((hwnd->pClass->style & CS_DBLCLKS) &&
|
if((hwnd->pClass->style & CS_DBLCLKS) &&
|
msg == lastmsg && hwnd == lasthwnd &&
|
msg == lastmsg && hwnd == lasthwnd &&
|
tick - lasttick < DBLCLICKSPEED &&
|
tick - lasttick < DBLCLICKSPEED &&
|
abs(cursorx-lastx) < mwSYSMETRICS_CXDOUBLECLK &&
|
abs(cursorx-lastx) < mwSYSMETRICS_CXDOUBLECLK &&
|
abs(cursory-lasty) < mwSYSMETRICS_CYDOUBLECLK)
|
abs(cursory-lasty) < mwSYSMETRICS_CYDOUBLECLK)
|
msg += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
|
msg += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
|
lastmsg = msg;
|
lastmsg = msg;
|
lasthwnd = hwnd;
|
lasthwnd = hwnd;
|
lasttick = tick;
|
lasttick = tick;
|
lastx = cursorx;
|
lastx = cursorx;
|
lasty = cursory;
|
lasty = cursory;
|
}
|
}
|
|
|
/*
|
/*
|
* We always send nc mouse message
|
* We always send nc mouse message
|
* unlike Windows, for HTCLIENT default processing
|
* unlike Windows, for HTCLIENT default processing
|
*/
|
*/
|
PostMessage(hwnd, msg + (WM_NCMOUSEMOVE-WM_MOUSEMOVE), hittest,
|
PostMessage(hwnd, msg + (WM_NCMOUSEMOVE-WM_MOUSEMOVE), hittest,
|
MAKELONG(cursorx, cursory));
|
MAKELONG(cursorx, cursory));
|
|
|
/* then possibly send user mouse message*/
|
/* then possibly send user mouse message*/
|
if(hittest == HTCLIENT) {
|
if(hittest == HTCLIENT) {
|
pt.x = cursorx;
|
pt.x = cursorx;
|
pt.y = cursory;
|
pt.y = cursory;
|
ScreenToClient(hwnd, &pt);
|
ScreenToClient(hwnd, &pt);
|
PostMessage(hwnd, msg, 0, MAKELONG(pt.x, pt.y));
|
PostMessage(hwnd, msg, 0, MAKELONG(pt.x, pt.y));
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* Deliver a mouse button or motion event.
|
* Deliver a mouse button or motion event.
|
*/
|
*/
|
int mwCurrentButtons;
|
int mwCurrentButtons;
|
|
|
void
|
void
|
MwDeliverMouseEvent(int buttons, int changebuttons, MWKEYMOD modifiers)
|
MwDeliverMouseEvent(int buttons, int changebuttons, MWKEYMOD modifiers)
|
{
|
{
|
HWND hwnd;
|
HWND hwnd;
|
int hittest;
|
int hittest;
|
UINT msg;
|
UINT msg;
|
|
|
mwCurrentButtons = buttons;
|
mwCurrentButtons = buttons;
|
|
|
hwnd = GetCapture();
|
hwnd = GetCapture();
|
if(!hwnd)
|
if(!hwnd)
|
hwnd = mousewp;
|
hwnd = mousewp;
|
hittest = SendMessage(hwnd, WM_NCHITTEST, 0, MAKELONG(cursorx,cursory));
|
hittest = SendMessage(hwnd, WM_NCHITTEST, 0, MAKELONG(cursorx,cursory));
|
|
|
if(!changebuttons)
|
if(!changebuttons)
|
MwTranslateMouseMessage(hwnd, WM_MOUSEMOVE, hittest);
|
MwTranslateMouseMessage(hwnd, WM_MOUSEMOVE, hittest);
|
|
|
if(changebuttons & MWBUTTON_L) {
|
if(changebuttons & MWBUTTON_L) {
|
msg = (buttons&MWBUTTON_L)? WM_LBUTTONDOWN: WM_LBUTTONUP;
|
msg = (buttons&MWBUTTON_L)? WM_LBUTTONDOWN: WM_LBUTTONUP;
|
MwTranslateMouseMessage(hwnd, msg, hittest);
|
MwTranslateMouseMessage(hwnd, msg, hittest);
|
}
|
}
|
|
|
if(changebuttons & MWBUTTON_M) {
|
if(changebuttons & MWBUTTON_M) {
|
msg = (buttons&MWBUTTON_M)? WM_MBUTTONDOWN: WM_MBUTTONUP;
|
msg = (buttons&MWBUTTON_M)? WM_MBUTTONDOWN: WM_MBUTTONUP;
|
MwTranslateMouseMessage(hwnd, msg, hittest);
|
MwTranslateMouseMessage(hwnd, msg, hittest);
|
}
|
}
|
|
|
if(changebuttons & MWBUTTON_R) {
|
if(changebuttons & MWBUTTON_R) {
|
msg = (buttons&MWBUTTON_R)? WM_RBUTTONDOWN: WM_RBUTTONUP;
|
msg = (buttons&MWBUTTON_R)? WM_RBUTTONDOWN: WM_RBUTTONUP;
|
MwTranslateMouseMessage(hwnd, msg, hittest);
|
MwTranslateMouseMessage(hwnd, msg, hittest);
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* Deliver a keyboard event.
|
* Deliver a keyboard event.
|
*/
|
*/
|
void
|
void
|
MwDeliverKeyboardEvent(MWKEY keyvalue, MWKEYMOD modifiers, MWSCANCODE scancode,
|
MwDeliverKeyboardEvent(MWKEY keyvalue, MWKEYMOD modifiers, MWSCANCODE scancode,
|
BOOL pressed)
|
BOOL pressed)
|
{
|
{
|
WPARAM VK_Code = keyvalue; /* default no translation*/
|
WPARAM VK_Code = keyvalue; /* default no translation*/
|
|
|
/* Keysyms from 1-255 are mapped to ASCII*/
|
/* Keysyms from 1-255 are mapped to ASCII*/
|
if (keyvalue < 1 || keyvalue > 255)
|
if (keyvalue < 1 || keyvalue > 255)
|
switch(keyvalue) {
|
switch(keyvalue) {
|
|
|
/* arrows + home/end pad*/
|
/* arrows + home/end pad*/
|
case MWKEY_LEFT:
|
case MWKEY_LEFT:
|
VK_Code = VK_LEFT;
|
VK_Code = VK_LEFT;
|
break;
|
break;
|
case MWKEY_RIGHT:
|
case MWKEY_RIGHT:
|
VK_Code = VK_RIGHT;
|
VK_Code = VK_RIGHT;
|
break;
|
break;
|
case MWKEY_UP:
|
case MWKEY_UP:
|
VK_Code = VK_UP;
|
VK_Code = VK_UP;
|
break;
|
break;
|
case MWKEY_DOWN:
|
case MWKEY_DOWN:
|
VK_Code = VK_DOWN;
|
VK_Code = VK_DOWN;
|
break;
|
break;
|
case MWKEY_INSERT:
|
case MWKEY_INSERT:
|
VK_Code = VK_INSERT;
|
VK_Code = VK_INSERT;
|
break;
|
break;
|
case MWKEY_DELETE:
|
case MWKEY_DELETE:
|
VK_Code = VK_DELETE;
|
VK_Code = VK_DELETE;
|
break;
|
break;
|
case MWKEY_HOME:
|
case MWKEY_HOME:
|
VK_Code = VK_HOME;
|
VK_Code = VK_HOME;
|
break;
|
break;
|
case MWKEY_END:
|
case MWKEY_END:
|
VK_Code = VK_END;
|
VK_Code = VK_END;
|
break;
|
break;
|
case MWKEY_PAGEUP:
|
case MWKEY_PAGEUP:
|
VK_Code = VK_PRIOR;
|
VK_Code = VK_PRIOR;
|
break;
|
break;
|
case MWKEY_PAGEDOWN:
|
case MWKEY_PAGEDOWN:
|
VK_Code = VK_NEXT;
|
VK_Code = VK_NEXT;
|
break;
|
break;
|
|
|
/* Numeric keypad*/
|
/* Numeric keypad*/
|
case MWKEY_KP0:
|
case MWKEY_KP0:
|
VK_Code = VK_NUMPAD0;
|
VK_Code = VK_NUMPAD0;
|
break;
|
break;
|
case MWKEY_KP1:
|
case MWKEY_KP1:
|
VK_Code = VK_NUMPAD1;
|
VK_Code = VK_NUMPAD1;
|
break;
|
break;
|
case MWKEY_KP2:
|
case MWKEY_KP2:
|
VK_Code = VK_NUMPAD2;
|
VK_Code = VK_NUMPAD2;
|
break;
|
break;
|
case MWKEY_KP3:
|
case MWKEY_KP3:
|
VK_Code = VK_NUMPAD3;
|
VK_Code = VK_NUMPAD3;
|
break;
|
break;
|
case MWKEY_KP4:
|
case MWKEY_KP4:
|
VK_Code = VK_NUMPAD4;
|
VK_Code = VK_NUMPAD4;
|
break;
|
break;
|
case MWKEY_KP5:
|
case MWKEY_KP5:
|
VK_Code = VK_NUMPAD5;
|
VK_Code = VK_NUMPAD5;
|
break;
|
break;
|
case MWKEY_KP6:
|
case MWKEY_KP6:
|
VK_Code = VK_NUMPAD6;
|
VK_Code = VK_NUMPAD6;
|
break;
|
break;
|
case MWKEY_KP7:
|
case MWKEY_KP7:
|
VK_Code = VK_NUMPAD7;
|
VK_Code = VK_NUMPAD7;
|
break;
|
break;
|
case MWKEY_KP8:
|
case MWKEY_KP8:
|
VK_Code = VK_NUMPAD8;
|
VK_Code = VK_NUMPAD8;
|
break;
|
break;
|
case MWKEY_KP9:
|
case MWKEY_KP9:
|
VK_Code = VK_NUMPAD9;
|
VK_Code = VK_NUMPAD9;
|
break;
|
break;
|
case MWKEY_KP_PERIOD:
|
case MWKEY_KP_PERIOD:
|
VK_Code = VK_DECIMAL;
|
VK_Code = VK_DECIMAL;
|
break;
|
break;
|
case MWKEY_KP_DIVIDE:
|
case MWKEY_KP_DIVIDE:
|
VK_Code = VK_DIVIDE;
|
VK_Code = VK_DIVIDE;
|
break;
|
break;
|
case MWKEY_KP_MULTIPLY:
|
case MWKEY_KP_MULTIPLY:
|
VK_Code = VK_MULTIPLY;
|
VK_Code = VK_MULTIPLY;
|
break;
|
break;
|
case MWKEY_KP_MINUS:
|
case MWKEY_KP_MINUS:
|
VK_Code = VK_SUBTRACT;
|
VK_Code = VK_SUBTRACT;
|
break;
|
break;
|
case MWKEY_KP_PLUS:
|
case MWKEY_KP_PLUS:
|
VK_Code = VK_ADD;
|
VK_Code = VK_ADD;
|
break;
|
break;
|
case MWKEY_KP_ENTER:
|
case MWKEY_KP_ENTER:
|
VK_Code = VK_RETURN;
|
VK_Code = VK_RETURN;
|
break;
|
break;
|
|
|
/* Function keys */
|
/* Function keys */
|
case MWKEY_F1:
|
case MWKEY_F1:
|
VK_Code = VK_F1;
|
VK_Code = VK_F1;
|
break;
|
break;
|
case MWKEY_F2:
|
case MWKEY_F2:
|
VK_Code = VK_F2;
|
VK_Code = VK_F2;
|
break;
|
break;
|
case MWKEY_F3:
|
case MWKEY_F3:
|
VK_Code = VK_F3;
|
VK_Code = VK_F3;
|
break;
|
break;
|
case MWKEY_F4:
|
case MWKEY_F4:
|
VK_Code = VK_F4;
|
VK_Code = VK_F4;
|
break;
|
break;
|
case MWKEY_F5:
|
case MWKEY_F5:
|
VK_Code = VK_F5;
|
VK_Code = VK_F5;
|
break;
|
break;
|
case MWKEY_F6:
|
case MWKEY_F6:
|
VK_Code = VK_F6;
|
VK_Code = VK_F6;
|
break;
|
break;
|
case MWKEY_F7:
|
case MWKEY_F7:
|
VK_Code = VK_F7;
|
VK_Code = VK_F7;
|
break;
|
break;
|
case MWKEY_F8:
|
case MWKEY_F8:
|
VK_Code = VK_F8;
|
VK_Code = VK_F8;
|
break;
|
break;
|
case MWKEY_F9:
|
case MWKEY_F9:
|
VK_Code = VK_F9;
|
VK_Code = VK_F9;
|
break;
|
break;
|
case MWKEY_F10:
|
case MWKEY_F10:
|
VK_Code = VK_F10;
|
VK_Code = VK_F10;
|
break;
|
break;
|
case MWKEY_F11:
|
case MWKEY_F11:
|
VK_Code = VK_F11;
|
VK_Code = VK_F11;
|
break;
|
break;
|
case MWKEY_F12:
|
case MWKEY_F12:
|
VK_Code = VK_F12;
|
VK_Code = VK_F12;
|
break;
|
break;
|
|
|
/* Key state modifier keys*/
|
/* Key state modifier keys*/
|
case MWKEY_NUMLOCK:
|
case MWKEY_NUMLOCK:
|
VK_Code = VK_NUMLOCK;
|
VK_Code = VK_NUMLOCK;
|
break;
|
break;
|
case MWKEY_CAPSLOCK:
|
case MWKEY_CAPSLOCK:
|
VK_Code = VK_CAPITAL;
|
VK_Code = VK_CAPITAL;
|
break;
|
break;
|
case MWKEY_SCROLLOCK:
|
case MWKEY_SCROLLOCK:
|
VK_Code = VK_CAPITAL;
|
VK_Code = VK_CAPITAL;
|
break;
|
break;
|
case MWKEY_LSHIFT:
|
case MWKEY_LSHIFT:
|
VK_Code = VK_LSHIFT;
|
VK_Code = VK_LSHIFT;
|
break;
|
break;
|
case MWKEY_RSHIFT:
|
case MWKEY_RSHIFT:
|
VK_Code = VK_RSHIFT;
|
VK_Code = VK_RSHIFT;
|
break;
|
break;
|
case MWKEY_LCTRL:
|
case MWKEY_LCTRL:
|
VK_Code = VK_LCONTROL;
|
VK_Code = VK_LCONTROL;
|
break;
|
break;
|
case MWKEY_RCTRL:
|
case MWKEY_RCTRL:
|
VK_Code = VK_RCONTROL;
|
VK_Code = VK_RCONTROL;
|
break;
|
break;
|
case MWKEY_LALT:
|
case MWKEY_LALT:
|
VK_Code = VK_MENU;
|
VK_Code = VK_MENU;
|
break;
|
break;
|
case MWKEY_RALT:
|
case MWKEY_RALT:
|
VK_Code = VK_MENU;
|
VK_Code = VK_MENU;
|
break;
|
break;
|
|
|
/* Misc function keys*/
|
/* Misc function keys*/
|
case MWKEY_PRINT:
|
case MWKEY_PRINT:
|
VK_Code = VK_PRINT;
|
VK_Code = VK_PRINT;
|
break;
|
break;
|
case MWKEY_PAUSE:
|
case MWKEY_PAUSE:
|
VK_Code = VK_PAUSE;
|
VK_Code = VK_PAUSE;
|
break;
|
break;
|
case MWKEY_MENU:
|
case MWKEY_MENU:
|
VK_Code = VK_LMENU; /* virtual key*/
|
VK_Code = VK_LMENU; /* virtual key*/
|
break;
|
break;
|
|
|
/* questionable mappings or no mappings...*/
|
/* questionable mappings or no mappings...*/
|
case MWKEY_KP_EQUALS:
|
case MWKEY_KP_EQUALS:
|
VK_Code = '='; /* FIXME*/
|
VK_Code = '='; /* FIXME*/
|
break;
|
break;
|
|
|
/* map all non-handled MWKEY values to VK_NONAME*/
|
/* map all non-handled MWKEY values to VK_NONAME*/
|
#if 0
|
#if 0
|
case MWKEY_UNKNOWN:
|
case MWKEY_UNKNOWN:
|
case MWKEY_SYSREQ:
|
case MWKEY_SYSREQ:
|
case MWKEY_BREAK
|
case MWKEY_BREAK
|
case MWKEY_QUIT:
|
case MWKEY_QUIT:
|
case MWKEY_REDRAW:
|
case MWKEY_REDRAW:
|
case MWKEY_LMETA:
|
case MWKEY_LMETA:
|
case MWKEY_RMETA:
|
case MWKEY_RMETA:
|
case MWKEY_ALTGR:
|
case MWKEY_ALTGR:
|
/* Handheld function keys*/
|
/* Handheld function keys*/
|
case MWKEY_RECORD:
|
case MWKEY_RECORD:
|
case MWKEY_PLAY:
|
case MWKEY_PLAY:
|
case MWKEY_CONTRAST:
|
case MWKEY_CONTRAST:
|
case MWKEY_BRIGHTNESS:
|
case MWKEY_BRIGHTNESS:
|
case MWKEY_SELECTUP:
|
case MWKEY_SELECTUP:
|
case MWKEY_SELECTDOWN:
|
case MWKEY_SELECTDOWN:
|
case MWKEY_ACCEPT:
|
case MWKEY_ACCEPT:
|
case MWKEY_CANCEL:
|
case MWKEY_CANCEL:
|
case MWKEY_APP1:
|
case MWKEY_APP1:
|
case MWKEY_APP2:
|
case MWKEY_APP2:
|
case MWKEY_LAST:
|
case MWKEY_LAST:
|
#endif
|
#endif
|
default:
|
default:
|
VK_Code = VK_NONAME;
|
VK_Code = VK_NONAME;
|
break;
|
break;
|
}
|
}
|
|
|
if (pressed)
|
if (pressed)
|
SendMessage(focuswp, WM_CHAR, VK_Code, 0L);
|
SendMessage(focuswp, WM_CHAR, VK_Code, 0L);
|
}
|
}
|
|
|
/*
|
/*
|
* Deliver a window expose event.
|
* Deliver a window expose event.
|
* Most of the work is in calculating the update region
|
* Most of the work is in calculating the update region
|
* for better redraw look and feel, and then queuing a
|
* for better redraw look and feel, and then queuing a
|
* WM_PAINT message to the window.
|
* WM_PAINT message to the window.
|
*/
|
*/
|
void
|
void
|
MwDeliverExposureEvent(HWND wp, MWCOORD x, MWCOORD y, MWCOORD width,
|
MwDeliverExposureEvent(HWND wp, MWCOORD x, MWCOORD y, MWCOORD width,
|
MWCOORD height)
|
MWCOORD height)
|
{
|
{
|
if (wp->unmapcount)
|
if (wp->unmapcount)
|
return;
|
return;
|
|
|
MwUnionUpdateRegion(wp, x, y, width, height, TRUE);
|
MwUnionUpdateRegion(wp, x, y, width, height, TRUE);
|
PostMessage(wp, WM_PAINT, 0, 0L);
|
PostMessage(wp, WM_PAINT, 0, 0L);
|
}
|
}
|
|
|
/*
|
/*
|
* Combine the passed rectangle with the update region for the given window.
|
* Combine the passed rectangle with the update region for the given window.
|
* Coordinates are passed relative to window.
|
* Coordinates are passed relative to window.
|
* If bUnion is TRUE, union the rectangle, otherwise subtract it.
|
* If bUnion is TRUE, union the rectangle, otherwise subtract it.
|
*/
|
*/
|
void
|
void
|
MwUnionUpdateRegion(HWND wp, MWCOORD x, MWCOORD y, MWCOORD width,
|
MwUnionUpdateRegion(HWND wp, MWCOORD x, MWCOORD y, MWCOORD width,
|
MWCOORD height, BOOL bUnion)
|
MWCOORD height, BOOL bUnion)
|
{
|
{
|
#if UPDATEREGIONS
|
#if UPDATEREGIONS
|
MWRECT rc;
|
MWRECT rc;
|
|
|
if (wp->unmapcount)
|
if (wp->unmapcount)
|
return;
|
return;
|
|
|
/* convert window relative coords to screen coords*/
|
/* convert window relative coords to screen coords*/
|
rc.left = x + wp->winrect.left;
|
rc.left = x + wp->winrect.left;
|
rc.top = y + wp->winrect.top;
|
rc.top = y + wp->winrect.top;
|
rc.right = rc.left + width;
|
rc.right = rc.left + width;
|
rc.bottom = rc.top + height;
|
rc.bottom = rc.top + height;
|
|
|
if(bUnion)
|
if(bUnion)
|
GdUnionRectWithRegion(&rc, wp->update);
|
GdUnionRectWithRegion(&rc, wp->update);
|
else
|
else
|
GdSubtractRectFromRegion(&rc, wp->update);
|
GdSubtractRectFromRegion(&rc, wp->update);
|
#endif
|
#endif
|
}
|
}
|
|
|
/*
|
/*
|
* Move the cursor to the specified absolute screen coordinates.
|
* Move the cursor to the specified absolute screen coordinates.
|
* The coordinates are that of the defined hot spot of the cursor.
|
* The coordinates are that of the defined hot spot of the cursor.
|
* The cursor's appearance is changed to that defined for the window
|
* The cursor's appearance is changed to that defined for the window
|
* in which the cursor is moved to. In addition, the window the
|
* in which the cursor is moved to. In addition, the window the
|
* cursor is in is recalculated.
|
* cursor is in is recalculated.
|
*/
|
*/
|
void MwMoveCursor(MWCOORD x, MWCOORD y)
|
void MwMoveCursor(MWCOORD x, MWCOORD y)
|
{
|
{
|
/*
|
/*
|
* Move the cursor only if necessary, offsetting it to
|
* Move the cursor only if necessary, offsetting it to
|
* place the hot spot at the specified coordinates.
|
* place the hot spot at the specified coordinates.
|
*/
|
*/
|
if (x != cursorx || y != cursory) {
|
if (x != cursorx || y != cursory) {
|
if(curcursor)
|
if(curcursor)
|
GdMoveCursor(x - curcursor->cursor.hotx,
|
GdMoveCursor(x - curcursor->cursor.hotx,
|
y - curcursor->cursor.hoty);
|
y - curcursor->cursor.hoty);
|
cursorx = x;
|
cursorx = x;
|
cursory = y;
|
cursory = y;
|
}
|
}
|
|
|
/*
|
/*
|
* Now check to see which window the mouse is in and whether or
|
* Now check to see which window the mouse is in and whether or
|
* not the cursor shape should be changed.
|
* not the cursor shape should be changed.
|
*/
|
*/
|
MwCheckMouseWindow();
|
MwCheckMouseWindow();
|
MwCheckCursor();
|
MwCheckCursor();
|
}
|
}
|
|
|
/*
|
/*
|
* Check to see if the cursor shape is the correct shape for its current
|
* Check to see if the cursor shape is the correct shape for its current
|
* location. If not, its shape is changed.
|
* location. If not, its shape is changed.
|
*/
|
*/
|
void MwCheckCursor(void)
|
void MwCheckCursor(void)
|
{
|
{
|
HWND wp; /* window cursor is in */
|
HWND wp; /* window cursor is in */
|
HCURSOR cp; /* cursor definition */
|
HCURSOR cp; /* cursor definition */
|
|
|
/*
|
/*
|
* Get the cursor at its current position, and if it is not the
|
* Get the cursor at its current position, and if it is not the
|
* currently defined one, then set the new cursor. However,
|
* currently defined one, then set the new cursor. However,
|
* if the window is currently captured, then leave it alone.
|
* if the window is currently captured, then leave it alone.
|
*/
|
*/
|
wp = capturewp;
|
wp = capturewp;
|
if (wp == NULL)
|
if (wp == NULL)
|
wp = mousewp;
|
wp = mousewp;
|
|
|
cp = wp->cursor;
|
cp = wp->cursor;
|
if (cp == curcursor)
|
if (cp == curcursor)
|
return;
|
return;
|
|
|
/*
|
/*
|
* It needs redefining, so do it.
|
* It needs redefining, so do it.
|
*/
|
*/
|
curcursor = cp;
|
curcursor = cp;
|
GdMoveCursor(cursorx - cp->cursor.hotx, cursory - cp->cursor.hoty);
|
GdMoveCursor(cursorx - cp->cursor.hotx, cursory - cp->cursor.hoty);
|
GdSetCursor(&cp->cursor);
|
GdSetCursor(&cp->cursor);
|
}
|
}
|
|
|
/*
|
/*
|
* Find the window which is currently visible for the specified coordinates.
|
* Find the window which is currently visible for the specified coordinates.
|
* This just walks down the window tree looking for the deepest mapped
|
* This just walks down the window tree looking for the deepest mapped
|
* window which contains the specified point. If the coordinates are
|
* window which contains the specified point. If the coordinates are
|
* off the screen, the root window is returned.
|
* off the screen, the root window is returned.
|
*/
|
*/
|
HWND
|
HWND
|
MwFindVisibleWindow(MWCOORD x, MWCOORD y)
|
MwFindVisibleWindow(MWCOORD x, MWCOORD y)
|
{
|
{
|
HWND wp; /* current window */
|
HWND wp; /* current window */
|
HWND retwp; /* returned window */
|
HWND retwp; /* returned window */
|
|
|
wp = rootwp;
|
wp = rootwp;
|
retwp = wp;
|
retwp = wp;
|
while (wp) {
|
while (wp) {
|
if (!wp->unmapcount &&
|
if (!wp->unmapcount &&
|
wp->winrect.left <= x && wp->winrect.top <= y &&
|
wp->winrect.left <= x && wp->winrect.top <= y &&
|
wp->winrect.right > x && wp->winrect.bottom > y) {
|
wp->winrect.right > x && wp->winrect.bottom > y) {
|
retwp = wp;
|
retwp = wp;
|
wp = wp->children;
|
wp = wp->children;
|
continue;
|
continue;
|
}
|
}
|
wp = wp->siblings;
|
wp = wp->siblings;
|
}
|
}
|
return retwp;
|
return retwp;
|
}
|
}
|
|
|
/*
|
/*
|
* Check to see if the window the mouse is currently in has changed.
|
* Check to see if the window the mouse is currently in has changed.
|
*/
|
*/
|
void MwCheckMouseWindow(void)
|
void MwCheckMouseWindow(void)
|
{
|
{
|
HWND wp;
|
HWND wp;
|
|
|
/* Don't change if window drag or capture in progress*/
|
/* Don't change if window drag or capture in progress*/
|
wp = dragwp;
|
wp = dragwp;
|
if(!wp)
|
if(!wp)
|
wp = capturewp;
|
wp = capturewp;
|
if(!wp)
|
if(!wp)
|
wp = MwFindVisibleWindow(cursorx, cursory);
|
wp = MwFindVisibleWindow(cursorx, cursory);
|
mousewp = wp;
|
mousewp = wp;
|
}
|
}
|
|
|
/*
|
/*
|
* Copy dstsiz bytes, including nul, from src to dst.
|
* Copy dstsiz bytes, including nul, from src to dst.
|
* Return # bytes, excluding nul, copied.
|
* Return # bytes, excluding nul, copied.
|
*/
|
*/
|
int
|
int
|
strzcpy(char *dst,const char *src,int dstsiz)
|
strzcpy(char *dst,const char *src,int dstsiz)
|
{
|
{
|
int cc = dstsiz;
|
int cc = dstsiz;
|
|
|
/* return 0 on NULL src*/
|
/* return 0 on NULL src*/
|
if(!src)
|
if(!src)
|
cc = dstsiz = 1;
|
cc = dstsiz = 1;
|
|
|
while(--dstsiz > 0) {
|
while(--dstsiz > 0) {
|
if((*dst++ = *src++) == '\0')
|
if((*dst++ = *src++) == '\0')
|
return cc - dstsiz - 1;
|
return cc - dstsiz - 1;
|
}
|
}
|
*dst = 0;
|
*dst = 0;
|
return cc - dstsiz - 1;
|
return cc - dstsiz - 1;
|
}
|
}
|
|
|