winmultiwindowwindow.c [plain text]
#include "win.h"
#include "dixevents.h"
#include "winmultiwindowclass.h"
#include "winprefs.h"
extern HICON g_hiconX;
static void
winCreateWindowsWindow (WindowPtr pWin);
static void
winDestroyWindowsWindow (WindowPtr pWin);
static void
winUpdateWindowsWindow (WindowPtr pWin);
static void
winFindWindow (pointer value, XID id, pointer cdata);
#if 0
static void
winRestackXWindow (WindowPtr pWin, int smode);
#endif
#define MOUSE_POLLING_INTERVAL 500
#define SubSend(pWin) \
((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
#define StrSend(pWin) \
((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
Bool
winCreateWindowMultiWindow (WindowPtr pWin)
{
Bool fResult = TRUE;
winWindowPriv(pWin);
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winCreateWindowMultiWindow - pWin: %08x\n", pWin);
#endif
if (winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow)
fResult = winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow (pWin);
pWinPriv->hRgn = NULL;
pWinPriv->hWnd = NULL;
pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
pWinPriv->fXKilled = FALSE;
pWinPriv->fNeedRestore = FALSE;
return fResult;
}
Bool
winDestroyWindowMultiWindow (WindowPtr pWin)
{
Bool fResult = TRUE;
winWindowPriv(pWin);
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winDestroyWindowMultiWindow - pWin: %08x\n", pWin);
#endif
if (winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow)
fResult = winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow (pWin);
pWinPriv->fXKilled = TRUE;
winDestroyWindowsWindow (pWin);
return fResult;
}
Bool
winPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
{
Bool fResult = TRUE;
int iX, iY, iWidth, iHeight, iBorder;
winWindowPriv(pWin);
HWND hWnd = pWinPriv->hWnd;
RECT rcNew;
RECT rcOld;
#if CYGMULTIWINDOW_DEBUG
RECT rcClient;
RECT *lpRc;
#endif
DWORD dwExStyle;
DWORD dwStyle;
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winPositionWindowMultiWindow - pWin: %08x\n", pWin);
#endif
if (winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow)
fResult = winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow (pWin, x, y);
if (!hWnd)
return fResult;
dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
iBorder = wBorderWidth (pWin);
iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
iWidth = pWin->drawable.width;
iHeight = pWin->drawable.height;
SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
#if CYGMULTIWINDOW_DEBUG
lpRc = &rcNew;
ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
#endif
AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
GetWindowRect (hWnd, &rcOld);
#if CYGMULTIWINDOW_DEBUG
GetClientRect (hWnd, &rcClient);
lpRc = &rcNew;
ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
lpRc = &rcOld;
ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
lpRc = &rcClient;
ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
#endif
if (!EqualRect (&rcNew, &rcOld))
{
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winPositionWindowMultiWindow - Need to move\n");
#endif
MoveWindow (hWnd,
rcNew.left, rcNew.top,
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
TRUE);
}
else
{
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winPositionWindowMultiWindow - Not need to move\n");
#endif
}
return fResult;
}
Bool
winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask)
{
Bool fResult = TRUE;
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin);
#endif
if (winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes)
fResult = winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes (pWin, mask);
return fResult;
}
Bool
winUnmapWindowMultiWindow (WindowPtr pWin)
{
Bool fResult = TRUE;
winWindowPriv(pWin);
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin);
#endif
if (winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow)
fResult = winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow (pWin);
pWinPriv->fXKilled = TRUE;
winDestroyWindowsWindow (pWin);
return fResult;
}
Bool
winMapWindowMultiWindow (WindowPtr pWin)
{
Bool fResult = TRUE;
winWindowPriv(pWin);
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin);
#endif
if (winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow)
fResult = winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow (pWin);
pWinPriv->fXKilled = FALSE;
winUpdateWindowsWindow (pWin);
#ifdef SHAPE
winReshapeMultiWindow (pWin);
winUpdateRgnMultiWindow (pWin);
#endif
return fResult;
}
void
winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent)
{
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin);
#endif
if (winGetScreenPriv(pWin->drawable.pScreen)->ReparentWindow)
winGetScreenPriv(pWin->drawable.pScreen)->ReparentWindow (pWin,
pPriorParent);
winUpdateWindowsWindow (pWin);
}
void
winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
{
WindowPtr pPrevWin;
UINT uFlags;
HWND hInsertAfter;
HWND hWnd = NULL;
winWindowPriv(pWin);
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winRestackMultiWindow - %08x\n", pWin);
#endif
if (winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow)
winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow (pWin,
pOldNextSib);
if (winGetScreenPriv(pWin->drawable.pScreen)->fRestacking)
return;
if (!pWinPriv || !pWinPriv->hWnd)
return;
pPrevWin = pWin->prevSib;
while (pPrevWin
&& !winGetWindowPriv(pPrevWin)
&& !winGetWindowPriv(pPrevWin)->hWnd)
pPrevWin = pPrevWin->prevSib;
if (pPrevWin)
{
hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV);
do
{
if (GetProp (hWnd, WIN_WINDOW_PROP))
{
if (hWnd == winGetWindowPriv(pPrevWin)->hWnd)
{
uFlags |= SWP_NOZORDER;
}
break;
}
hWnd = GetNextWindow (hWnd, GW_HWNDPREV);
}
while (hWnd);
}
else
{
hInsertAfter = HWND_TOP;
uFlags = SWP_NOMOVE | SWP_NOSIZE;
}
SetWindowPos (pWinPriv->hWnd,
hInsertAfter,
0, 0,
0, 0,
uFlags);
}
static void
winCreateWindowsWindow (WindowPtr pWin)
{
int iX, iY;
int iWidth;
int iHeight;
int iBorder;
HWND hWnd;
WNDCLASS wc;
winWindowPriv(pWin);
HICON hIcon;
#define CLASS_NAME_LENGTH 512
char pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
char *res_name, *res_class, *res_role;
static int s_iWindowID = 0;
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
#endif
iBorder = wBorderWidth (pWin);
iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
iWidth = pWin->drawable.width;
iHeight = pWin->drawable.height;
if (!g_hiconX)
g_hiconX = (HICON)winOverrideDefaultIcon();
if (!g_hiconX)
g_hiconX = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
hIcon = winXIconToHICON (pWin);
if (!hIcon)
hIcon = g_hiconX;
strncpy (pszClass, WINDOW_CLASS_X, strlen (WINDOW_CLASS_X));
if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
{
strncat (pszClass, "-", 1);
strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass));
strncat (pszClass, "-", 1);
strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass));
if (winMultiWindowGetWindowRole (pWin, &res_role) )
{
strcat (pszClass, "-");
strcat (pszClass, res_role);
free (res_role);
}
free (res_name);
free (res_class);
}
sprintf (pszWindowID, "-%x", s_iWindowID++);
strcat (pszClass, pszWindowID);
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winCreateWindowsWindow - Creating class: %s\n", pszClass);
#endif
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = winTopLevelWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInstance;
wc.hIcon = hIcon;
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = pszClass;
RegisterClass (&wc);
hWnd = CreateWindowExA (WS_EX_TOOLWINDOW,
pszClass,
WINDOW_TITLE_X,
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
iX,
iY,
iWidth,
iHeight,
(HWND) NULL,
(HMENU) NULL,
GetModuleHandle (NULL),
pWin);
if (hWnd == NULL)
{
ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
GetLastError ());
}
pWinPriv->hWnd = hWnd;
PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0);
SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
SetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
}
static void
winDestroyWindowsWindow (WindowPtr pWin)
{
MSG msg;
winWindowPriv(pWin);
HICON hiconClass;
HMODULE hInstance;
int iReturn;
char pszClass[512];
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winDestroyWindowsWindow\n");
#endif
if (pWinPriv->hWnd == NULL)
return;
SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, 0);
hInstance = (HINSTANCE) GetClassLong (pWinPriv->hWnd, GCL_HMODULE);
hiconClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICON);
iReturn = GetClassName (pWinPriv->hWnd, pszClass, 512);
DestroyWindow (pWinPriv->hWnd);
pWinPriv->hWnd = NULL;
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg))
{
DispatchMessage (&msg);
}
}
if (iReturn)
{
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winDestroyWindowsWindow - Unregistering %s: ", pszClass);
#endif
iReturn = UnregisterClass (pszClass, hInstance);
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winDestroyWindowsWindow - %d Deleting Icon: ", iReturn);
#endif
if (hiconClass != g_hiconX &&
!winIconIsOverride((unsigned long)hiconClass))
{
iReturn = DestroyIcon (hiconClass);
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winDestroyWindowsWindow - %d\n", iReturn);
#endif
}
}
#if CYGMULTIWINDOW_DEBUG
ErrorF ("-winDestroyWindowsWindow\n");
#endif
}
static void
winUpdateWindowsWindow (WindowPtr pWin)
{
winWindowPriv(pWin);
HWND hWnd = pWinPriv->hWnd;
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winUpdateWindowsWindow\n");
#endif
if (pWin->parent != NULL
&& pWin->parent->parent == NULL
&& pWin->mapped)
{
if (hWnd == NULL)
{
winCreateWindowsWindow (pWin);
assert (pWinPriv->hWnd != NULL);
}
ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
UpdateWindow (pWinPriv->hWnd);
}
else if (hWnd != NULL)
{
winDestroyWindowsWindow (pWin);
assert (pWinPriv->hWnd == NULL);
}
#if CYGMULTIWINDOW_DEBUG
ErrorF ("-winUpdateWindowsWindow\n");
#endif
}
XID
winGetWindowID (WindowPtr pWin)
{
WindowIDPairRec wi = {pWin, 0};
ClientPtr c = wClient(pWin);
FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi);
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winGetWindowID - Window ID: %d\n", wi.id);
#endif
return wi.id;
}
void
winMoveXWindow (WindowPtr pWin, int x, int y)
{
XID *vlist = malloc(sizeof(long)*2);
(CARD32*)vlist[0] = x;
(CARD32*)vlist[1] = y;
ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
free(vlist);
}
void
winResizeXWindow (WindowPtr pWin, int w, int h)
{
XID *vlist = malloc(sizeof(long)*2);
(CARD32*)vlist[0] = w;
(CARD32*)vlist[1] = h;
ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin));
free(vlist);
}
static void
winFindWindow (pointer value, XID id, pointer cdata)
{
WindowIDPairPtr wi = (WindowIDPairPtr)cdata;
if (value == wi->value)
{
wi->id = id;
}
}
#if 0
static void
winRestackXWindow (WindowPtr pWin, int smode)
{
XID *vlist = malloc(sizeof(unsigned long));
if (vlist == NULL)
{
ErrorF ("winRestackXWindow - malloc () failed\n");
return;
}
if (pWin == NULL)
{
ErrorF ("winRestackXWindow - NULL window\n");
free(vlist);
return;
}
*((unsigned long*)vlist) = smode;
ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin));
free(vlist);
}
#endif
void
winReorderWindowsMultiWindow (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
HWND hwnd = NULL;
WindowPtr pWin = NULL;
WindowPtr pWinSib = NULL;
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winOrderWindowsMultiWindow\n");
#endif
pScreenPriv->fRestacking = TRUE;
if (pScreenPriv->fWindowOrderChanged)
{
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winOrderWindowsMultiWindow - Need to restack\n");
#endif
hwnd = GetTopWindow (NULL);
while (hwnd)
{
if (GetProp (hwnd, WIN_WINDOW_PROP))
{
pWinSib = pWin;
pWin = GetProp (hwnd, WIN_WINDOW_PROP);
if (pWinSib)
{
XID *vlist = malloc (sizeof(long) * 2);
if (vlist == NULL)
{
ErrorF ("winOrderWindowsMultiWindow - malloc () "
"failed\n");
return;
}
((long*)vlist)[0] = winGetWindowID (pWinSib);
((long*)vlist)[1] = Below;
ConfigureWindow (pWin, CWSibling | CWStackMode,
vlist, wClient(pWin));
free (vlist);
}
}
hwnd = GetNextWindow (hwnd, GW_HWNDNEXT);
}
}
pScreenPriv->fRestacking = FALSE;
pScreenPriv->fWindowOrderChanged = FALSE;
}
void
winMinimizeWindow (Window id)
{
WindowPtr pWin;
winPrivWinPtr pWinPriv;
pWin = LookupIDByType (id, RT_WINDOW);
pWinPriv = winGetWindowPriv (pWin);
ShowWindow (pWinPriv->hWnd, SW_MINIMIZE);
}