home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
evbl0627.zip
/
everblue_20010627.zip
/
x11
/
Xlib_pmctls.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-04-30
|
40KB
|
1,094 lines
#include "Xlib_private.h"
#include <time.h>
#include "Xatomtype.h"
#define UM_UNMAP (WM_USER+10)
#define UM_MAP (WM_USER+11)
#define UM_GRAVITY (WM_USER+12)
#define UM_RESIZE (WM_USER+13)
#define UM_SETFOCUS (WM_USER+14)
#define UM_GIMMIE (WM_USER+15)
#define UM_CHARSEQ (WM_USER+16)
#define UM_REPARENT (WM_USER+17)
#include "x11pmvk.h"
HAB pmctls_hab = 0;
HACCEL haccel;
int serial = 0;
HMODULE hk_module = NULLHANDLE;
Atom (*Xlib_XInternAtom)(char*, Bool);
char *(*Xlib_GetAtomName)(Atom);
int Xlib_PMWM_Handler0(HWND*, ULONG*, MPARAM*, MPARAM*);
int Xlib_PMWM_Handler1(HWND*, ULONG*, MPARAM*, MPARAM*);
MRESULT EXPENTRY pmhwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
MRESULT result = (MRESULT)0;
Xlib_PMWM_Handler0(&hWnd, &msg, &mp1, &mp2);
switch(msg) {
case UM_CreateWindow:
{
/*static ULONG flStyle = FCF_MINMAX | FCF_SYSMENU | FCF_TITLEBAR |
FCF_SIZEBORDER | FCF_TASKLIST;*/
Xlib_CreateWindow *args = PVOIDFROMMP(mp1);
HPOINTER tmpicon = 0;
HMODULE x11mod = 0;
HWND hwndClient, hwndFrame = args->hwndParent;
if (mp2)
hwndFrame = WinCreateStdWindow( args->hwndParent, args->flStyle,
&args->frameStyle, NULL, args->pszTitle, 0L, NULLHANDLE, 0, NULL);
hwndClient = WinCreateWindow( hwndFrame,
"XPMChild", args->pszTitle, args->flStyle,
args->x, args->y, args->cx, args->cy, NULLHANDLE,
HWND_TOP, FID_CLIENT, args->winattrib, NULL);
if (hwndClient) wndcount++;
if(mp2)
{
DosQueryModuleHandle("X11", &x11mod);
if(x11mod && (tmpicon = WinLoadPointer(HWND_DESKTOP,x11mod,PMXLIB_DEFAULT_ICON)))
WinSendMsg(hwndFrame, WM_SETICON,(MPARAM)tmpicon, 0);
}
if (mp2) WinSetWindowULong(hwndClient, QWP_FRAMEHWND, hwndFrame);
else WinSetWindowULong(hwndClient, QWP_FRAMEHWND, hwndClient);
args->winattrib->hdc = WinOpenWindowDC(hwndClient);
/*WinSetVisibleRegionNotify(hwndClient, TRUE);*/
result = MPFROMHWND(hwndClient);
break;
}
case UM_DestroyWindow:
{
BOOL rc;
rc = WinDestroyWindow((HWND)mp1);
if (rc) {
wndcount--;
result = (MRESULT)TRUE;
}
break;
}
case UM_SetWindowPos:
{
Xlib_SetWindowPos *args = PVOIDFROMMP(mp1);
result = (MRESULT)
WinSetWindowPos( args->hwnd, args->hwndInsertBehind,
args->x, args->y, args->cx, args->cy, args->fl);
if (args->fl & SWP_HIDE)
WinPostMsg(args->hwnd, UM_UNMAP, MPFROMHWND(args->hwnd), (MPARAM)1); else
if (args->fl & SWP_SHOW)
WinPostMsg(args->hwnd, UM_MAP, MPFROMHWND(args->hwnd), (MPARAM)1);
break;
}
case UM_ReparentWindow:
{
Xlib_ReparentWindow *args = PVOIDFROMMP(mp1);
if (WinSetParent((HWND)args->w, (HWND)args->p, FALSE)) {
SWP swp;
WinQueryWindowPos((HWND)args->p, &swp);
WinSetWindowPos((HWND)args->w, 0, args->x, swp.cy - args->y, 0, 0, SWP_MOVE);
result = (MRESULT)1;
}
break;
}
case UM_ChangeProperty:
{
Xlib_ChangeProperty *args = PVOIDFROMMP(mp1);
XWindowAttributes *winattrib = GetWinAttrib(args->w, NULL);
WinAttribData *attrib = (winattrib)?WinQueryWindowPtr(args->w, QWP_WINATTRIB):NULL;
char *st1, *st2;
int state=PropertyNewValue, i;
Atom tmpatm;
if (!mp1 || !args->property || !attrib) return (MRESULT)0;
if (args->property == XA_WM_NAME && args->type == XA_STRING) {
if (attrib) {
if (attrib->wm_name) free(attrib->wm_name);
attrib->wm_name = malloc(args->nelements+1);
strncpy(attrib->wm_name, args->data, args->nelements);
attrib->wm_name[args->nelements] = '\0';
}
} else
if (args->property == XA_WM_ICON_NAME && args->type == XA_STRING) {
if (attrib && args->nelements) {
if (attrib->wm_iconname) free(attrib->wm_iconname);
attrib->wm_iconname = malloc(args->nelements+1);
strncpy(attrib->wm_iconname, args->data, args->nelements);
attrib->wm_iconname[args->nelements] = '\0';
}
} else
if (args->property == XA_WM_COMMAND && args->type == XA_STRING) {
if (attrib) {
st1 = malloc(args->nelements+1);
strncpy(st1, args->data, args->nelements);
st1[args->nelements] = '\0';
WinSetWindowText(mainhwnd,st1);
free(st1);
}
} else
if (args->property == XA_WM_CLASS && args->type == XA_STRING) {
if (attrib && args->nelements) {
if (attrib->wm_class) free(attrib->wm_class);
attrib->wm_class = malloc(args->nelements+1);
strncpy(attrib->wm_class, args->data, args->nelements);
attrib->wm_class[args->nelements] = '\0';
}
} else
if (args->property == XA_WM_NORMAL_HINTS && args->type == XA_WM_SIZE_HINTS) {
if (attrib && args->nelements) {
if (attrib->sizehints) free(attrib->sizehints);
attrib->sizehints = calloc(1, sizeof(XSizeHints) );
memcpy(attrib->sizehints, args->data,
(args->format * args->nelements) / 8);
}
} else
if (args->property == XA_WM_HINTS && args->type == XA_WM_HINTS) {
if (attrib && args->nelements) {
if (attrib->hints) free(attrib->hints);
attrib->hints = calloc(1, sizeof(XWMHints) );
memcpy(attrib->hints, args->data,
(args->format * args->nelements) / 8);
}
} else
if (args->property == XA_WM_CLIENT_MACHINE
|| ((tmpatm = XInternAtom(maindisplay,"__SWM_VROOT", True)) && tmpatm == args->property)
|| ((tmpatm = XInternAtom(maindisplay,"WM_LOCALE_NAME", True)) && tmpatm == args->property)
){ /* not useful in Everblue */ } else
if ((tmpatm = XInternAtom(maindisplay,"WM_CLIENT_LEADER", True)) &&
args->property == tmpatm && args->type == XA_WINDOW) {
if (attrib && args->nelements) {
attrib->wm_client_leader = ((Window *)args->data)[0];
}
} else
if ((tmpatm = XInternAtom(maindisplay,"WM_TRANSIENT_FOR", True)) &&
args->property == tmpatm && args->type == XA_WINDOW) {
if (attrib && args->nelements) {
/* This appears to be broken - Brian */
/* XWindowAttributes *mattrib = GetWinAttrib(((Window *)args->data)[0], NULL);
HWND hwndframe = mattrib?
WinQueryWindowULong(((Window *)args->data)[0],
QWP_FRAMEHWND):((Window *)args->data)[0];
WinSetOwner(args->w, hwndframe);
if(mattrib)
free(mattrib);*/
}
} else
if ((tmpatm = XInternAtom(maindisplay,"WM_PROTOCOLS", True)) &&
args->property == tmpatm && args->type == XA_ATOM)
for (i=0; i<args->nelements; i++)
{
Atom atom = ((Atom*)(args->data))[i];
char *protocol = XGetAtomName(maindisplay, atom);
if (!protocol) continue;
if (!strcmp(protocol,"WM_DELETE_WINDOW") && attrib)
attrib->delete_window_notify = TRUE; else
printf("Unhandled WM_PROTOCOL method '%s'\n",protocol);
free(protocol);
} else {
fprintf(stderr,"UM_ChangeProperty not implemented!\n property='%s'(%ld), type='%s'(%ld), format=%d, mode=%d, ",
st1=XGetAtomName(maindisplay, args->property), args->property,
st2=XGetAtomName(maindisplay, args->type), args->type, args->format, args->mode);
free(st1); free(st2);
if (!args->nelements)
fprintf(stderr,"no args\n");
else {
fprintf(stderr,"{ ");
if (args->type == XA_ATOM)
for (i=0; i<args->nelements; i++) {
fprintf(stderr,"'%s' ",
st1=XGetAtomName(maindisplay, ((Atom *)(args->data))[i]));
free(st1);
} else
if (args->type == XA_STRING) {
st1 = malloc(args->nelements+1);
strncpy(st1, args->data, args->nelements);
st1[args->nelements] = '\0';
fprintf(stderr,"'%s' ",st1);
free(st1);
} else
fprintf(stderr,"%d elements ",args->nelements);
fprintf(stderr,"}\n");
}
}
WinPostMsg((HWND)args->w,UM_ChangeProperty,(MPARAM)args->property,(MPARAM)state);
break;
}
case UM_GetWinProperty:
{
Xlib_GetWinProperty *args = PVOIDFROMMP(mp1);
XWindowAttributes *winattrib = GetWinAttrib(args->w, NULL);
WinAttribData *attrib = (winattrib)?WinQueryWindowPtr(args->w, QWP_WINATTRIB):NULL;
Atom tmpatm;
*args->prop_return = NULL;
*args->actual_type_return = None;
if (((tmpatm = XInternAtom(maindisplay,"__SWM_VROOT", True)) && tmpatm == args->property)) {
/* not useful in Everblue */
} else if((tmpatm = XInternAtom(maindisplay,"WM_NORMAL_HINTS", True)) && tmpatm == args->property) {
if(attrib->hints /*&& args->req_type == (XA_WM_HINTS || AnyPropertyType)*/)
{
*args->actual_type_return = XA_WM_SIZE_HINTS;
*args->nitems_return = OldNumPropSizeElements;
*args->actual_format_return = 32;
*args->prop_return = (unsigned char *)malloc(sizeof(XSizeHints));
memcpy(*args->prop_return, attrib->sizehints, sizeof(XSizeHints));
}
} else if((tmpatm = XInternAtom(maindisplay,"WM_HINTS", True)) && tmpatm == args->property) {
if(attrib->hints /*&& args->req_type == (XA_WM_HINTS || AnyPropertyType)*/)
{
*args->actual_type_return = XA_WM_HINTS;
*args->nitems_return = NumPropWMHintsElements;
*args->actual_format_return = 32;
*args->prop_return = (unsigned char *)malloc(sizeof(XWMHints));
memcpy(*args->prop_return, attrib->hints, sizeof(XWMHints));
}
} else if((tmpatm = XInternAtom(maindisplay,"RESOURCE_MANAGER", True)) && tmpatm == args->property) {
if(maindisplay->xdefaults)
{
*args->actual_type_return = XA_RESOURCE_MANAGER;
*args->nitems_return = 1;
*args->actual_format_return = 32;
*args->prop_return = (unsigned char *)strdup(maindisplay->xdefaults);
}
} else {
char *st1, *st2;
fprintf(stderr,"UM_GetWinProperty not implemented!\n property='%s', type='%s', \n",
st1=XGetAtomName(maindisplay, args->property),
st2=XGetAtomName(maindisplay, args->req_type));
free(st1); free(st2);
*args->actual_type_return = None;
*args->nitems_return = 0;
*args->prop_return = NULL;
}
break;
}
case UM_CreateGC:
fprintf(stderr,"UM_CreateGC obseleted!\n");
break;
default:
result = WinDefWindowProc(hWnd, msg, mp1, mp2);
}
Xlib_PMWM_Handler1(&hWnd, &msg, &mp1, &mp2);
return result;
}
MRESULT EXPENTRY xpmwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
MRESULT result = (MRESULT)0;
WinAttribData *attrib = WinQueryWindowPtr(hWnd, QWP_WINATTRIB);
XWindowAttributes *winattrib = (attrib)?GetWinAttrib(hWnd,NULL):NULL;
XEvent *new = Xlib_NewEvent();
new->xany.serial = serial++;
new->xany.display = maindisplay;
new->xany.window = hWnd;
new->xany.send_event = False;
Xlib_PMWM_Handler0(&hWnd, &msg, &mp1, &mp2);
switch(msg) {
case WM_CREATE:
attrib = ((CREATESTRUCT *)(PVOIDFROMMP(mp2)))->pCtlData;
winattrib = &attrib->winattrib;
/*x11_console_notice("CreateNotify");*/
new->type = CreateNotify;
new->xcreatewindow.x = winattrib->x;
new->xcreatewindow.y = winattrib->y;
new->xcreatewindow.width = winattrib->width;
new->xcreatewindow.height = winattrib->height;
new->xcreatewindow.border_width = winattrib->border_width;
winattrib->root = hwndDesktop;
WinSetWindowPtr(hWnd, QWP_WINATTRIB, attrib);
WinPostMsg(hWnd,WM_SEM3,0,0);
break;
case WM_DESTROY:
if (!attrib) goto passover;
free(attrib);
x11_console_notice("DestroyNotify");
new->type = DestroyNotify;
new->xdestroywindow.event = hWnd;
break;
case WM_REALIZEPALETTE:
{
ULONG pc;
HPS hps;
hps = WinBeginPaint(hWnd, NULLHANDLE, NULL);
WinRealizePalette(hWnd, hps, &pc);
WinEndPaint(hps);
}
break;
case WM_CLOSE:
if (attrib && attrib->delete_window_notify) {
/*x11_console_notice("WM_DELETE_WINDOW");*/
new->type = ClientMessage;
new->xclient.message_type = XInternAtom(maindisplay,"WM_PROTOCOLS", False);
new->xclient.format = 32;
new->xclient.data.l[0] = XInternAtom(maindisplay,"WM_DELETE_WINDOW",False);
new->xclient.data.l[1] = 0;
new->xclient.send_event = True;
if (attrib->wm_client_leader)
new->xclient.window = attrib->wm_client_leader;
} else {
Xlib_RemoveEvent(new);
WinDestroyWindow(hWnd);
goto endproc;
}
break;
case UM_SETFOCUS:
{
char winclass[32];
HWND parent = WinQueryWindow(hWnd, QW_PARENT);
winclass[WinQueryClassName(parent, sizeof(winclass), winclass)] = 0;
if (!strcmp(winclass,"XPMChild"))
WinPostMsg(parent, UM_SETFOCUS, mp1, mp2);
if (!(winattrib->your_event_mask & FocusChangeMask))
goto nonevent;
if (SHORT1FROMMP(mp2)==TRUE) {
/*x11_console_notice("FocusIn");*/
new->type = FocusIn;
} else {
/*x11_console_notice("FocusOut");*/
new->type = FocusOut;
}
new->xfocus.mode = NotifyNormal;
new->xfocus.detail = NotifyNonlinear;
break;
}
case WM_SETFOCUS:
{
char winclass[32];
HWND parent = WinQueryWindow(hWnd, QW_PARENT);
winclass[WinQueryClassName(parent, sizeof(winclass), winclass)] = 0;
if (!strcmp(winclass,"XPMChild"))
WinPostMsg(parent, UM_SETFOCUS, mp1, mp2);
if (!(winattrib->your_event_mask & FocusChangeMask))
goto nonevent;
if (SHORT1FROMMP(mp2)==TRUE) {
/*x11_console_notice("FocusIn");*/
new->type = FocusIn;
} else {
/*x11_console_notice("FocusOut");*/
new->type = FocusOut;
}
new->xfocus.mode = NotifyNormal;
new->xfocus.detail = NotifyPointer;
break;
}
case WM_MOVE:
{
HWND hwndframe = WinQueryWindowULong(hWnd, QWP_FRAMEHWND);
SWP swp, parent;
if (!winattrib || !hwndframe)
goto passover;
WinQueryWindowPos(hwndframe,&swp);
if (!(swp.fl &(SWP_HIDE|SWP_MINIMIZE)) && attrib->wm_name)
WinSetWindowText(hwndframe, attrib->wm_name);
if ((swp.fl &(SWP_HIDE|SWP_MINIMIZE)) && attrib->wm_iconname)
WinSetWindowText(hwndframe, attrib->wm_iconname);
WinQueryWindowPos(WinQueryWindow(hwndframe,QW_PARENT),&parent);
new->type = ConfigureNotify;
new->xconfigure.event = hWnd;
if (hwndframe == hWnd) {
new->xconfigure.x = winattrib->x = swp.x;
new->xconfigure.y = winattrib->y = parent.cy - swp.y - swp.cy;
} else {
new->xconfigure.x = winattrib->x = swp.x + winattrib->border_width;
new->xconfigure.y = winattrib->y = parent.cy - swp.y - swp.cy +
winattrib->border_width + WinQuerySysValue(hwndDesktop,SV_CYTITLEBAR);
}
new->xconfigure.width = winattrib->width;
new->xconfigure.height = winattrib->height;
new->xconfigure.border_width = winattrib->border_width;
if (attrib->wm_client_leader)
new->xconfigure.window = attrib->wm_client_leader;
pthread_mutex_lock(&evmutex);
if (attrib->lastconfigure) {
XEvent *last = attrib->lastconfigure;
memcpy(last, new, sizeof(XEvent));
pthread_mutex_unlock(&evmutex);
goto nonevent;
}
attrib->lastconfigure = new;
pthread_mutex_unlock(&evmutex);
break;
}
case UM_UNMAP:
case UM_MAP:
if (msg == UM_UNMAP)
new->type = UnmapNotify;
else
new->type = MapNotify;
new->xunmap.event = HWNDFROMMP(mp1);
new->xunmap.from_configure = mp2?TRUE:FALSE;
if (!(GetWinAttrib(hWnd,NULL)->your_event_mask &
(StructureNotifyMask | SubstructureNotifyMask)))
goto nonevent;
break;
case WM_SIZE:
{
POINTL delta;
HENUM children;
HWND child;
if (!winattrib) goto passover;
delta.x = SHORT1FROMMP(mp2) - winattrib->width;
delta.y = SHORT2FROMMP(mp2) - winattrib->height;
children = WinBeginEnumWindows(hWnd);
while ((child = WinGetNextWindow(children))) {
XWindowAttributes *chattrib = GetWinAttrib(child,NULL);
int change = 0;
SWP swp;
if (!chattrib) continue;
WinQueryWindowPos(child, &swp);
switch (chattrib->win_gravity) {
case ForgetGravity:
WinSetWindowPos(child,NULLHANDLE,0,0,0,0,SWP_HIDE);
WinPostMsg(child,UM_UNMAP,MPFROMHWND(child),(MPARAM)1);
continue;
case NorthWestGravity:
case NorthGravity:
case NorthEastGravity:
case StaticGravity:
swp.y += delta.y / 2;
case WestGravity:
case CenterGravity:
case EastGravity:
swp.y += delta.y - (delta.y / 2);
change++;
}
switch (chattrib->win_gravity) {
case NorthEastGravity:
case EastGravity:
case SouthEastGravity:
swp.x += delta.x / 2;
case NorthGravity:
case CenterGravity:
case SouthGravity:
swp.x += delta.x - (delta.x / 2);
change++;
}
if (change)
WinSetWindowPos(child, NULLHANDLE, swp.x, swp.y,
0, 0, SWP_MOVE | SWP_NOREDRAW);
WinPostMsg(child, UM_GRAVITY,
MPFROM2SHORT(swp.x, winattrib->height-swp.y), (MPARAM)hWnd);
}
WinEndEnumWindows(children);
new->type = ConfigureNotify;
new->xconfigure.x = winattrib->x;
new->xconfigure.y = winattrib->y;
new->xconfigure.width = winattrib->width = SHORT1FROMMP(mp2);
new->xconfigure.height = winattrib->height = SHORT2FROMMP(mp2);
new->xconfigure.border_width = winattrib->border_width;
if (attrib->wm_client_leader)
new->xconfigure.window = attrib->wm_client_leader;
pthread_mutex_lock(&evmutex);
if (attrib->lastconfigure) {
XEvent *last = attrib->lastconfigure;
memcpy(last, new, sizeof(XEvent));
pthread_mutex_unlock(&evmutex);
goto nonevent;
}
attrib->lastconfigure = new;
pthread_mutex_unlock(&evmutex);
break;
}
case UM_GRAVITY:
new->type = GravityNotify;
new->xgravity.x = SHORT1FROMMP(mp1);
new->xgravity.y = SHORT2FROMMP(mp1);
new->xgravity.event = (Window) mp2;
break;
case UM_CHARSEQ:
new->type = SHORT1FROMMP(mp2);
new->xkey.root = hwndDesktop;
new->xkey.keycode = SHORT1FROMMP(mp1);
new->xkey.state = SHORT2FROMMP(mp1);
new->xkey.time = WinGetCurrentTime(pmctls_hab);
break;
case WM_CHAR:
if (!attrib || !winattrib) goto passover;
if (SHORT1FROMMP(mp1) & KC_KEYUP) {
new->type = KeyRelease;
if (!(winattrib->your_event_mask & KeyReleaseMask))
goto nonevent;
} else {
new->type = KeyPress;
if (SHORT1FROMMP(mp1) & KC_PREVDOWN) {
/* Key repeat! */
Xlib_RemoveEvent(new);
if (auto_repeat) {
SHORT us1 = SHORT1FROMMP((MPARAM)attrib->prevkeystate);
SHORT us2 = SHORT2FROMMP((MPARAM)attrib->prevkeystate);
MPARAM mp2 = (MPARAM)attrib->prevkeycode;
xpmwndproc(hWnd, msg, MPFROM2SHORT(us1 | KC_KEYUP, us2), mp2);
xpmwndproc(hWnd, msg, MPFROM2SHORT(us1, us2), mp2);
}
goto endproc;
}
attrib->prevkeycode = (unsigned int)mp2;
attrib->prevkeystate = (unsigned int)mp1;
if (!(winattrib->your_event_mask & KeyPressMask))
goto nonevent;
}
new->xkey.root = hwndDesktop;
/* There will probably need to be lots of keycode translations */
/* Keycode translations happen in XKeycodeToKeysym() funcs */
new->xkey.state = 0;
if (SHORT1FROMMP(mp1) & KC_SHIFT) new->xkey.state |= ShiftMask;
if (SHORT1FROMMP(mp1) & KC_CTRL) new->xkey.state |= ControlMask;
if (SHORT1FROMMP(mp1) & KC_ALT) new->xkey.state |= Mod2Mask;
if (WinGetKeyState(hwndDesktop, VK_CAPSLOCK)&0x0001)
new->xkey.state |= LockMask;
if (WinGetKeyState(hwndDesktop, VK_BUTTON1)&0x8000)
new->xkey.state |= Button1Mask;
if (WinGetKeyState(hwndDesktop, VK_BUTTON2)&0x8000)
new->xkey.state |= Button2Mask;
if (WinGetKeyState(hwndDesktop, VK_BUTTON3)&0x8000)
new->xkey.state |= Button3Mask;
if (SHORT1FROMMP(mp1) & KC_CHAR && !(SHORT1FROMMP(mp2) & 0xff80))
new->xkey.keycode = SHORT1FROMMP(mp2); else
if (SHORT1FROMMP(mp1) & KC_CHAR && !(SHORT1FROMMP(mp2) & 0xff00)) {
new->xkey.keycode = SHORT1FROMMP(mp2);
new->xkey.state |= Mod1Mask;
/*MPARAM rp1a = MPFROM2SHORT(17, new->xkey.state);
MPARAM rp1b = MPFROM2SHORT(SHORT1FROMMP(mp2), new->xkey.state | Mod1Mask);
MPARAM rp2 = MPFROM2SHORT(new->type, 0);
Xlib_RemoveEvent(new);
xpmwndproc(hWnd, UM_CHARSEQ, rp1a, rp2);
xpmwndproc(hWnd, UM_CHARSEQ, rp1b, rp2);
goto endproc;*/
} else
if (SHORT1FROMMP(mp1) & KC_SCANCODE && CHAR4FROMMP(mp1))
new->xkey.keycode = CHAR4FROMMP(mp1) | 0x80;
else goto nonevent;
if (new->xkey.keycode < maindisplay->min_keycode ||
new->xkey.keycode > maindisplay->max_keycode)
goto nonevent;
if (SHORT1FROMMP(mp1) & KC_SCANCODE)
switch (CHAR4FROMMP(mp1)) {
case 0x2a: /* Shift_L */
case 0x36: /* Shift_R */
case 0x1d: /* Control_L */
case 0x5b: /* Control_R */
case 0x38: /* Alt_L */
case 0x5e: /* Alt_R */
case 0x3a: /* Caps Lock */
case 0x39: /* Spacebar */
case 0x5c: /* KP_Divide */
case 0x37: /* KP_Multiply */
case 0x4a: /* KP_Subtract */
case 0x4e: /* KP_Add */
case 0x5a: /* KP_Enter */
new->xkey.keycode = CHAR4FROMMP(mp1) | 0x80;
new->xkey.state &= ~Mod1Mask;
break;
case 0x53: /* KP_Decimal */
case 0x52: /* KP_0 */
case 0x4f: /* KP_1 */
case 0x50: /* KP_2 */
case 0x51: /* KP_3 */
case 0x4b: /* KP_4 */
case 0x4c: /* KP_5 */
case 0x4d: /* KP_6 */
case 0x47: /* KP_7 */
case 0x48: /* KP_8 */
case 0x49: /* KP_9 */
new->xkey.keycode = CHAR4FROMMP(mp1) | 0x80;
if (((WinGetKeyState(hwndDesktop, VK_NUMLOCK)&0x0001)==1) ==
((new->xkey.state & ShiftMask) == ShiftMask)) {
new->xkey.keycode &= 0x7f;
new->xkey.state |= Mod1Mask;
/*MPARAM rp1a = MPFROM2SHORT(17, new->xkey.state);
MPARAM rp1b = MPFROM2SHORT(new->xkey.keycode & 0x7f, new->xkey.state | Mod1Mask);
MPARAM rp2 = MPFROM2SHORT(new->type, 0);
Xlib_RemoveEvent(new);
xpmwndproc(hWnd, UM_CHARSEQ, rp1a, rp2);
xpmwndproc(hWnd, UM_CHARSEQ, rp1b, rp2);
goto endproc;*/
}
break;
}
new->xkey.time = WinGetCurrentTime(pmctls_hab);
break;
/*case UM_MAPPINGNOTIFY:
new->type = MappingNotify;
new->xmapping.request = */
case WM_MOUSEMOVE:
case WM_BUTTON1MOTIONSTART:
case WM_BUTTON2MOTIONSTART:
case WM_BUTTON3MOTIONSTART:
case WM_BUTTON1MOTIONEND:
case WM_BUTTON2MOTIONEND:
case WM_BUTTON3MOTIONEND:
case WM_SEM4:
{
POINTL ptls = { SHORT1FROMMP(mp1), SHORT2FROMMP(mp1) };
LONG btns=0, btnmask = 0;
new->type = MotionNotify;
new->xmotion.state = 0;
new->xmotion.root = hwndDesktop;
new->xmotion.x = ptls.x;
new->xmotion.y = winattrib->height - ptls.y;
new->xmotion.is_hint = (msg == WM_SEM4);
new->xmotion.same_screen = 1;
if ((msg != WM_SEM4 && (winattrib->your_event_mask & PointerMotionHintMask))
|| !WinMapWindowPoints(hWnd, hwndDesktop, &ptls, 1)) {
WinPostMsg(hWnd, WM_SEM4, 0, 0);
if (msg == WM_MOUSEMOVE && attrib->cursor)
WinSetPointer(hwndDesktop, attrib->cursor);
else goto passover;
goto nonevent;
}
new->xmotion.x_root = ptls.x;
new->xmotion.y_root = WinQuerySysValue(hwndDesktop,SV_CYSCREEN) - ptls.y;
if (WinGetKeyState(hwndDesktop,VK_BUTTON1) & 0x8000) btns |= 1;
if (WinGetKeyState(hwndDesktop,VK_BUTTON2) & 0x8000) btns |= 2;
if (WinGetKeyState(hwndDesktop,VK_BUTTON3) & 0x8000) btns |= 4;
if (!(winattrib->your_event_mask & PointerMotionMask)) {
if (winattrib->your_event_mask & ButtonMotionMask) btnmask |= 7;
else {
if (winattrib->your_event_mask & Button1MotionMask) btnmask |= 1;
if (winattrib->your_event_mask & Button2MotionMask) btnmask |= 2;
if (winattrib->your_event_mask & Button3MotionMask) btnmask |= 4;
}
if (!(btns & btnmask)) {
if (msg == WM_MOUSEMOVE && attrib->cursor)
WinSetPointer(hwndDesktop, attrib->cursor);
else result = WinDefWindowProc(hWnd, msg, mp1, mp2);
goto nonevent;
}
}
if (btns & 1) new->xmotion.state |= Button1Mask;
if (btns & 2) new->xmotion.state |= Button2Mask;
if (btns & 4) new->xmotion.state |= Button3Mask;
if (WinGetKeyState(hwndDesktop,VK_CAPSLOCK) & 0x0001) new->xmotion.state |= LockMask;
if (WinGetKeyState(hwndDesktop,VK_SHIFT) & 0x8000) new->xmotion.state |= ShiftMask;
if (WinGetKeyState(hwndDesktop,VK_CTRL) & 0x8000) new->xmotion.state |= ControlMask;
if (WinGetKeyState(hwndDesktop,VK_ALT) & 0x8000) new->xmotion.state |= Mod2Mask;
new->xmotion.time = WinGetCurrentTime(pmctls_hab);
}
break;
case WM_ACTIVATE:
WinPostMsg(hWnd, WM_MOVE, NULL, NULL);
goto nonevent;
case UM_GIMMIE:
WinSetFocus(hwndDesktop, hWnd);
goto nonevent;
case WM_BUTTON1UP:
case WM_BUTTON2UP:
case WM_BUTTON3UP:
case WM_BUTTON1DOWN:
case WM_BUTTON2DOWN:
case WM_BUTTON3DOWN:
{
POINTL ptls = { SHORT1FROMMP(mp1), SHORT2FROMMP(mp1) };
if (!winattrib) goto passover;
/* Will need to map the window points for x and y since X expects
* them to be relative to the event window */
if (msg == WM_BUTTON1UP || msg == WM_BUTTON2UP || msg == WM_BUTTON3UP) {
if (!(winattrib->your_event_mask & ButtonReleaseMask))
goto nonevent;
/*x11_console_notice("ButtonRelease");*/
new->type = ButtonRelease;
} else {
if (!(WinQueryFocus(hwndDesktop) == hWnd)) {
WinPostMsg(hWnd, UM_GIMMIE, 0, 0);
}
if (!(winattrib->your_event_mask & ButtonPressMask))
goto nonevent;
/*x11_console_notice("ButtonPress");*/
new->type = ButtonPress;
}
new->xbutton.state = 0;
if (msg == WM_BUTTON1UP || msg == WM_BUTTON1DOWN)
new->xbutton.button = 1; else
if (msg == WM_BUTTON3UP || msg == WM_BUTTON3DOWN)
new->xbutton.button = 2; else
if (msg == WM_BUTTON2UP || msg == WM_BUTTON2DOWN)
new->xbutton.button = 3;
if (SHORT1FROMMP(mp1) & KC_SHIFT) new->xbutton.state |= ShiftMask;
if (SHORT1FROMMP(mp1) & KC_CTRL) new->xbutton.state |= ControlMask;
if (SHORT1FROMMP(mp1) & KC_ALT) new->xbutton.state |= Mod2Mask;
if (WinGetKeyState(hwndDesktop, VK_CAPSLOCK)&0x0001)
new->xbutton.state |= LockMask;
if (WinGetKeyState(hwndDesktop, VK_BUTTON1)&0x8000)
new->xbutton.state |= Button1Mask;
if (WinGetKeyState(hwndDesktop, VK_BUTTON2)&0x8000)
new->xbutton.state |= Button2Mask;
if (WinGetKeyState(hwndDesktop, VK_BUTTON3)&0x8000)
new->xbutton.state |= Button3Mask;
new->xbutton.root = hwndDesktop;
new->xbutton.x = ptls.x;
new->xbutton.y = winattrib->height - ptls.y;
if (!WinMapWindowPoints(hWnd, new->xbutton.root, &ptls, 1))
goto nonevent;
new->xbutton.x_root = ptls.x;
new->xbutton.y_root = WinQuerySysValue(hwndDesktop,SV_CYSCREEN) - ptls.y;
new->xbutton.time = WinGetCurrentTime(pmctls_hab);
break;
}
case WM_PAINT:
{
RECTL rectl;
SWP swp;
if (!attrib) goto passover;
/* x11_console_notice("Expose"); */
WinQueryWindowPos(hWnd, &swp);
new->type = Expose;
new->xexpose.count = 0;
if (!WinQueryUpdateRect(hWnd, &rectl)) {
new->xexpose.x = rectl.xLeft = 0;
new->xexpose.y = rectl.yBottom = 0;
new->xexpose.width = rectl.xRight = swp.cx;
new->xexpose.height = rectl.yTop = swp.cy;
} else {
new->xexpose.x = rectl.xLeft;
new->xexpose.y = swp.cy - rectl.yTop;
new->xexpose.width = rectl.xRight - rectl.xLeft;
new->xexpose.height = rectl.yTop - rectl.yBottom;
}
/*if (attrib->background_pixmap != ParentRelative)*/
{
HPS hps;
hps = WinBeginPaint(hWnd, NULLHANDLE, &rectl);
GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL );
WinFillRect(hps, &rectl, attrib->background_pixel);
WinEndPaint(hps);
}/* else
if (!attrib->inhiding) {
HWND hwndframe = WinQueryWindowULong(hWnd, QWP_FRAMEHWND);
HWND parent = WinQueryWindow(hwndframe, QW_PARENT);
RECTL rectl1 = { 0, 0, attrib->winattrib.width, attrib->winattrib.height};
RECTL rectl2 = { 0, 0, attrib->winattrib.width, attrib->winattrib.height};
WinMapWindowPoints(hWnd, parent, (PPOINTL)&rectl1, 2);
WinEnableWindowUpdate(hwndframe, FALSE);
WinInvalidateRect(parent, &rectl1, TRUE);
attrib->inhiding = 1;
WinUpdateWindow(parent);
}*/
if (!(attrib->winattrib.your_event_mask & ExposureMask))
goto passover;
#if 1
pthread_mutex_lock(&evmutex);
if (attrib->lastexpose) {
XEvent *last = attrib->lastexpose;
int i;
if (new->xexpose.x < last->xexpose.x) {
last->xexpose.width += last->xexpose.x - new->xexpose.x;
last->xexpose.x = new->xexpose.x;
}
if (last->xexpose.x > swp.cx) last->xexpose.x = swp.cx;
i = new->xexpose.x + new->xexpose.width - last->xexpose.x;
if (last->xexpose.width < i) last->xexpose.width = i;
if (last->xexpose.width > swp.cx - last->xexpose.x)
last->xexpose.width = swp.cx - last->xexpose.x;
if (new->xexpose.y < last->xexpose.y) {
last->xexpose.height += last->xexpose.y - new->xexpose.y;
last->xexpose.y = new->xexpose.y;
}
if (last->xexpose.y > swp.cy) last->xexpose.y = swp.cy;
i = new->xexpose.y + new->xexpose.height - last->xexpose.y;
if (last->xexpose.height < i) last->xexpose.height = i;
if (last->xexpose.height > swp.cy - last->xexpose.y)
last->xexpose.height = swp.cy - last->xexpose.y;
pthread_mutex_unlock(&evmutex);
goto passover;
}
attrib->lastexpose = new;
pthread_mutex_unlock(&evmutex);
#endif
break;
}
case 0x041e:
{
POINTL ptl;
new->type = EnterNotify;
if (!winattrib || !(winattrib->your_event_mask & EnterWindowMask))
goto nonevent;
WinQueryPointerPos(hwndDesktop, &ptl);
new->xcrossing.x_root = ptl.x;
new->xcrossing.y_root = WinQuerySysValue(hwndDesktop,SV_CYSCREEN) - ptl.y;
WinMapWindowPoints(hwndDesktop, hWnd, &ptl, 1);
new->xcrossing.x = ptl.x;
new->xcrossing.y = winattrib->height - ptl.y;
new->xcrossing.mode = NotifyNormal;
new->xcrossing.focus = WinIsChild(hWnd,WinQueryFocus(hwndDesktop));
new->xcrossing.subwindow = hWnd;
new->xcrossing.same_screen = 1;
new->xcrossing.time = WinGetCurrentTime(pmctls_hab);
break;
}
case 0x041f:
{
POINTL ptl;
new->type = LeaveNotify;
if (!winattrib || !(winattrib->your_event_mask & LeaveWindowMask))
goto nonevent;
WinQueryPointerPos(hwndDesktop, &ptl);
new->xcrossing.x_root = ptl.x;
new->xcrossing.y_root = WinQuerySysValue(hwndDesktop,SV_CYSCREEN) - ptl.y;
WinMapWindowPoints(hwndDesktop, hWnd, &ptl, 1);
if (ptl.x < 0) ptl.x = 0; else if (ptl.x > winattrib->width) ptl.x = winattrib->width;
if (ptl.y < 0) ptl.y = 0; else if (ptl.y > winattrib->height) ptl.y = winattrib->height;
new->xcrossing.x = ptl.x;
new->xcrossing.y = winattrib->height - ptl.y;
new->xcrossing.mode = NotifyNormal;
new->xcrossing.focus = WinIsChild(hWnd,WinQueryFocus(hwndDesktop))?1:0;
new->xcrossing.subwindow = None;
new->xcrossing.same_screen = 1;
new->xcrossing.time = WinGetCurrentTime(pmctls_hab);
break;
}
case UM_ChangeProperty:
{
HWND hwndframe = WinQueryWindowULong(hWnd, QWP_FRAMEHWND);
new->type = PropertyNotify;
new->xproperty.atom = (Atom)mp1;
new->xproperty.state = (int)mp2;
new->xproperty.time = (Time)time(NULL);
switch (new->xproperty.atom) {
case XA_WM_NAME:
{
SWP swp;
WinQueryWindowPos(hwndframe,&swp);
if (!(swp.fl &(SWP_HIDE|SWP_MINIMIZE)))
WinSetWindowText(hwndframe, attrib->wm_name);
break;
}
case XA_WM_ICON_NAME:
{
SWP swp;
WinQueryWindowPos(hwndframe,&swp);
if ((swp.fl &(SWP_HIDE|SWP_MINIMIZE)))
WinSetWindowText(hwndframe, attrib->wm_iconname);
}
default:
/* nothing happens here */
}
if (attrib->wm_client_leader)
new->xproperty.window = attrib->wm_client_leader;
break;
}
case UM_REPARENT:
{
SWP swp, pswp;
new->type = ReparentNotify;
new->xreparent.parent = WinQueryWindow(hWnd, QW_PARENT);
WinQueryWindowPos(hWnd, &swp);
WinQueryWindowPos(new->xreparent.parent, &pswp);
new->xreparent.x = swp.x;
new->xreparent.y = pswp.cy - swp.y;
new->xreparent.override_redirect = attrib->winattrib.override_redirect;
if (attrib->wm_client_leader)
new->xreparent.window = attrib->wm_client_leader;
break;
}
default:
goto passover;
}
maindisplay->qlen++;
write(pmout[1], (char *) &new, sizeof(void *));
if (msg == WM_MOUSEMOVE && attrib->cursor) {
WinSetPointer(hwndDesktop, attrib->cursor);
} else
if (msg == WM_PAINT || msg == WM_MOUSEMOVE || msg == WM_DESTROY)
result = WinDefWindowProc(hWnd, msg, mp1, mp2);
goto endproc;
passover:
result = WinDefWindowProc(hWnd, msg, mp1, mp2);
nonevent:
/* If you return from this procedure without adding to the
* queue you MUST remove the event from the queue, otherwise
* the linked list will become out of sync with the pipe.
* Brian Smith.
*/
Xlib_RemoveEvent(new);
endproc:
Xlib_PMWM_Handler1(&hWnd, &msg, &mp1, &mp2);
return result;
}
VOID APIENTRY Xlib_ExitHandler(VOID)
{
APIRET erc = NO_ERROR;
if(WinReleaseHook(pmctls_hab, NULLHANDLE, HK_INPUT, Xlib_InputQueueHook, hk_module)==FALSE)
x11_console_notice("Error removing the input hook!\n");
else
{
x11_console_notice("Xlib/PM successfully shutdown. (Xlib_ExitHandler)\n");
DosFreeModule(hk_module); /* Decrement the DLL usage count*/
}
#ifdef DEBUG
if (Xlib_DebugOffset) {
struct Xlib_DebugInfo_st *info =
(struct Xlib_DebugInfo_st *)&Xlib_DebugInfo[Xlib_DebugOffset];
int i = Xlib_DebugOffset;
fprintf(stderr,"Post-mortem: \n - body found in %s(), line %i, %s, %s\n",
info->procname, info->linenumb, info->filename, info->procinfo);
while (--i) {
info--;
fprintf(stderr," + called from %s(), line %i, %s, %s\n",
info->procname, info->linenumb, info->filename, info->procinfo);
}
} else {
struct Xlib_DebugInfo_st *info =
(struct Xlib_DebugInfo_st *)&Xlib_DebugInfo[1];
fprintf(stderr,"Last touched %s(), line %d, %s, %s\n",
info->procname, info->linenumb, info->filename, info->procinfo);
}
#endif
erc = DosExitList(EXLST_EXIT, (PFNEXITLIST)NULL);
x11_console_notice("Error in ExitList");
return;
}
void * pm_thread(void * arg)
{
HMQ hmq = 0;
QMSG qmsg;
ULONG fstyle = FCF_TASKLIST;
APIRET rc;
int z, ulAccelLen;
PACCELTABLE pacctAccelTable = NULL;
HACCEL holdaccel;
/* Our replacement accellerator table */
ACCEL acctable[] = {
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F4 , SC_CLOSE },
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_ENTER, SC_RESTORE },
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_NEWLINE, SC_RESTORE },
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F5, SC_RESTORE },
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F6, SC_NEXTFRAME },
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F7, SC_MOVE },
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F8, SC_SIZE },
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F9, SC_MINIMIZE },
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_F10, SC_MAXIMIZE },
{ AF_SYSCOMMAND | AF_VIRTUALKEY, VK_F10, SC_APPMENU },
{ AF_SYSCOMMAND | AF_LONEKEY | AF_VIRTUALKEY, VK_ALT, SC_APPMENU },
{ AF_SYSCOMMAND | AF_LONEKEY | AF_VIRTUALKEY, VK_ALTGRAF, SC_APPMENU },
{ AF_SYSCOMMAND | AF_ALT | AF_VIRTUALKEY, VK_SPACE, SC_SYSMENU },
{ AF_SYSCOMMAND | AF_SHIFT | AF_VIRTUALKEY, VK_ESC, SC_SYSMENU },
{ AF_SYSCOMMAND | AF_CONTROL | AF_VIRTUALKEY, VK_ESC, SC_TASKMANAGER }
};
pmctls_hab = WinInitialize(0);
hmq = WinCreateMsgQueue(pmctls_hab, 0);
EventQueue = NULL;
/*Grab = NULL;*/
/* NOTE: Brian, I don't think so... Antony.
signal(SIGSEGV, Xlib_crash);
*/
if ((!pmctls_hab) || (!hmq)) {
x11_console_notice("Error init PM instance\n");
pthread_kill(mainthread, SIGABRT);
pthread_exit(NULL);
}
rc = WinRegisterClass(pmctls_hab, "ObjClass", pmhwndproc, 0, 0);
rc = WinRegisterClass(pmctls_hab, "XPMChild", xpmwndproc, CS_SIZEREDRAW | CS_MOVENOTIFY, 8);
mainhwnd = WinCreateStdWindow(HWND_OBJECT, 0, &fstyle,
"ObjClass", "X Application", 0, NULLHANDLE, 0, NULL);
if (mainhwnd == NULLHANDLE) {
x11_console_notice("Error creating PM instance\n");
pthread_kill(mainthread, SIGABRT);
pthread_exit(NULL);
}
if (!hk_module) {
if (DosLoadModule(NULL,0,"X11pmhk.dll",&hk_module))
x11_console_notice("Could not acquire handle for X11pmhk.DLL\n");
else {
DosQueryProcAddr(hk_module, 0, "Xlib_NewGrab", (PFN *)&Xlib_NewGrab);
DosQueryProcAddr(hk_module, 0, "Xlib_FindGrab", (PFN *)&Xlib_FindGrab);
DosQueryProcAddr(hk_module, 0, "Xlib_RemoveGrab", (PFN *)&Xlib_RemoveGrab);
DosQueryProcAddr(hk_module, 0, "Xlib_RemoveGrabAny", (PFN *)&Xlib_RemoveGrabAny);
DosQueryProcAddr(hk_module, 0, "Xlib_InputQueueHook", (PFN *)&Xlib_InputQueueHook);
DosQueryProcAddr(hk_module, 0, "Xlib_XInternAtom", (PFN *)&Xlib_XInternAtom);
DosQueryProcAddr(hk_module, 0, "Xlib_GetAtomName", (PFN *)&Xlib_GetAtomName);
if (!WinSetHook(pmctls_hab, NULLHANDLE, HK_INPUT, Xlib_InputQueueHook, hk_module))
x11_console_notice("Could not set PM input hook, XGrab* API will not function.\n");
else
DosExitList(EXLST_ADD,(PFNEXITLIST)Xlib_ExitHandler);
}
}
ulAccelLen = sizeof( acctable ) + sizeof( ACCELTABLE );
pacctAccelTable = (PACCELTABLE) malloc ( ulAccelLen );
pacctAccelTable->cAccel = 15; /* Number of ACCEL entries */
pacctAccelTable->codepage = 437; /* Code page */
for(z=0;z<pacctAccelTable->cAccel;z++)
pacctAccelTable->aaccel[z] = acctable[z];
holdaccel = WinQueryAccelTable(mainhab, NULLHANDLE);
/* Clear all accellerators */
WinSetAccelTable(pmctls_hab, 0, NULLHANDLE);
/* Delete the old accellerator */
WinDestroyAccelTable(holdaccel);
/* Create the new accellerator */
haccel = WinCreateAccelTable(pmctls_hab, pacctAccelTable);
/* Set it as the default for the queue */
WinSetAccelTable(pmctls_hab, haccel, NULLHANDLE);
xinitialized = TRUE;
while (WinGetMsg(pmctls_hab, &qmsg, 0, 0, 0)) {
WinDispatchMsg(pmctls_hab, &qmsg);
}
if (hk_module && !WinReleaseHook(pmctls_hab, NULLHANDLE, HK_INPUT, Xlib_InputQueueHook, hk_module))
x11_console_notice("Error removing the input hook!\n");
else
{
/* I want to make sure the hook is getting removed. */
x11_console_notice("Xlib/PM successfully shutdown. (pm_thread)\n");
if (hk_module) {
DosFreeModule(hk_module); /* Decrement the DLL usage count*/
hk_module = NULLHANDLE;
DosExitList(EXLST_REMOVE,(PFNEXITLIST)Xlib_ExitHandler);
}
}
WinDestroyWindow(mainhwnd);
WinDestroyMsgQueue(hmq);
WinTerminate(pmctls_hab);
xinitialized = FALSE;
return NULL;
}