fix for segementation violation accessing window of another app

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@26226 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2008-03-06 13:48:40 +00:00
parent 70843be41c
commit cef51849f7
4 changed files with 58 additions and 46 deletions

View file

@ -1,3 +1,14 @@
2008-03-06 Richard Frith-Macdonald <rfm@gnu.org>
* Headers\win32\WIN32Server.h: make 'orderedIn' and 'level' 32bit
fields at start of structure so that we can easily use GetWindowLong()
and SetWindowLong() with them.
* Source\win32\w32_movesize.m:
* Source\win32\WIN32Server.m:
Change to accessing 'orderedIn' and 'level' directly using
GetWindowLong() and SetWindowLong() so that code weorks when windows
are owned by another app.
2008-03-06 Richard Frith-Macdonald <rfm@gnu.org>
* Source\win32\w32_movesize.m: Bypass all existing code to send a

View file

@ -198,13 +198,16 @@ typedef struct w32serverFlags {
@end
typedef struct _win_intern {
int32_t level;
#define OFF_LEVEL 0
int32_t orderedIn;
#define OFF_ORDERED sizeof(int32_t)
BOOL useHDC;
BOOL backingStoreEmpty;
BOOL orderedIn;
HDC hdc;
HGDIOBJ old;
MINMAXINFO minmax;
int level;
} WIN_INTERN;
#endif /* _WIN32Server_h_INCLUDE */

View file

@ -1007,10 +1007,10 @@ NSLog(@"Callback");
- (void) orderwindow: (int) op : (int) otherWin : (int) winNum
{
WIN_INTERN *win;
WIN_INTERN *other;
int flag;
int foreground = 0;
int otherLevel;
int level;
NSDebugLLog(@"WTrace", @"orderwindow: %d : %d : %d", op, otherWin, winNum);
@ -1041,16 +1041,15 @@ NSLog(@"Callback");
flag = SW_RESTORE;
ShowWindow((HWND)winNum, flag);
win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
if (op == NSWindowOut)
{
win->orderedIn = NO;
SetWindowLong((HWND)winNum, OFF_ORDERED, 0);
SetWindowPos((HWND)winNum, NULL, 0, 0, 0, 0,
SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);
return;
}
win->orderedIn = YES;
SetWindowLong((HWND)winNum, OFF_ORDERED, 1);
level = GetWindowLong((HWND)winNum, OFF_LEVEL);
if (otherWin <= 0)
{
@ -1075,22 +1074,23 @@ NSLog(@"Callback");
/* Put this on the same window level as the window we are ordering
* it against.
*/
other = (WIN_INTERN *)GetWindowLong((HWND)otherWin, GWL_USERDATA);
if (win->level != other->level)
otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL);
if (level != otherLevel)
{
NSDebugLLog(@"WTrace",
@"orderwindow: implicitly set level of %d (%d) to that of %d (%d)",
winNum, win->level, otherWin, other->level);
win->level = other->level;
winNum, level, otherWin, otherLevel);
level = otherLevel;
SetWindowLong((HWND)winNum, OFF_LEVEL, level);
}
}
if (win->level <= NSDesktopWindowLevel)
if (level <= NSDesktopWindowLevel)
{
// For desktop level, put this at the bottom of the z-order
otherWin = (int)HWND_BOTTOM;
NSDebugLLog(@"WTrace",
@"orderwindow: set %i (%i) to bottom", winNum, win->level);
@"orderwindow: set %i (%i) to bottom", winNum, level);
}
else if (otherWin == 0 || op == NSWindowAbove)
{
@ -1108,7 +1108,7 @@ NSLog(@"Callback");
}
NSDebugLLog(@"WTrace",
@"orderwindow: traverse for %d (%d) starting at %d",
winNum, win->level, otherWin);
winNum, level, otherWin);
while (otherWin > 0)
{
TCHAR buf[32];
@ -1127,15 +1127,15 @@ NSLog(@"Callback");
&& GetClassName((HWND)otherWin, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
{
other = (WIN_INTERN *)GetWindowLong((HWND)otherWin, GWL_USERDATA);
if (other->orderedIn == YES)
if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1)
{
otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL);
NSDebugLLog(@"WTrace",
@"orderwindow: found gnustep window %d (%d)",
otherWin, other->level);
if (other->level >= win->level)
otherWin, otherLevel);
if (otherLevel >= level)
{
if (other->level > win->level)
if (otherLevel > level)
{
/* On windows, there is no notion of levels, so
* native apps will automatically move to the
@ -1169,17 +1169,17 @@ NSLog(@"Callback");
{
otherWin = (int)HWND_TOP;
NSDebugLLog(@"WTrace",
@"orderwindow: set %i (%i) to top", winNum, win->level);
@"orderwindow: set %i (%i) to top", winNum, level);
}
else if (otherWin == (int)HWND_BOTTOM)
{
NSDebugLLog(@"WTrace",
@"orderwindow: set %i (%i) to bottom", winNum, win->level);
@"orderwindow: set %i (%i) to bottom", winNum, level);
}
else
{
NSDebugLLog(@"WTrace",
@"orderwindow: set %i (%i) below %d", winNum, win->level, otherWin);
@"orderwindow: set %i (%i) below %d", winNum, level, otherWin);
}
SetWindowPos((HWND)winNum, (HWND)otherWin, 0, 0, 0, 0,
@ -1207,11 +1207,11 @@ NSLog(@"Callback");
&& GetClassName((HWND)otherWin, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
{
other = (WIN_INTERN *)GetWindowLong((HWND)otherWin, GWL_USERDATA);
if (other->orderedIn == YES)
if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1)
{
otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL);
s = [s stringByAppendingFormat:
@"%d (%d)\n", otherWin, other->level];
@"%d (%d)\n", otherWin, otherLevel];
}
}
}
@ -1288,12 +1288,12 @@ NSLog(@"Callback");
- (void) setwindowlevel: (int) level : (int) winNum
{
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)winNum, GWLP_USERDATA);
NSDebugLLog(@"WTrace", @"setwindowlevel: %d : %d", level, winNum);
if (win->level != level)
{
win->level = level;
SetWindowLong((HWND)winNum, OFF_LEVEL, level);
if (win->orderedIn == YES)
{
[self orderwindow: NSWindowAbove : 0 : winNum];
@ -1303,7 +1303,7 @@ NSLog(@"Callback");
- (int) windowlevel: (int) winNum
{
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)winNum, GWLP_USERDATA);
return win->level;
}

View file

@ -280,8 +280,8 @@
{
HWND hi;
HWND lo;
WIN_INTERN *hInf;
WIN_INTERN *lInf;
int hl;
int ll;
/* For debugging, log current window stack.
*/
@ -305,11 +305,10 @@
&& GetClassName(hi, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
{
hInf = (WIN_INTERN *)GetWindowLong(hi, GWL_USERDATA);
if (hInf->orderedIn == YES)
if (GetWindowLong(hi, OFF_ORDERED) == 1)
{
s = [s stringByAppendingFormat:
@"%d (%d)\n", hi, hInf->level];
hl = GetWindowLong(hi, OFF_LEVEL);
s = [s stringByAppendingFormat: @"%d (%d)\n", hi, hl];
}
}
}
@ -336,9 +335,9 @@
{
if (GetClassName(hi, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0
&& (hInf = (WIN_INTERN *)GetWindowLong(hi, GWL_USERDATA))
&& hInf->level > NSDesktopWindowLevel
&& hInf->orderedIn == YES)
&& GetWindowLong(hi, OFF_ORDERED) == 1
&& (hl = GetWindowLong(hi, OFF_LEVEL))
> NSDesktopWindowLevel)
{
break;
}
@ -347,7 +346,7 @@
if (hi > 0)
{
NSDebugLLog(@"WTrace", @"sort hi %d (%d)", hi, hInf->level);
NSDebugLLog(@"WTrace", @"sort hi %d (%d)", hi, hl);
/* Find the next (lower in z-order) GNUstep window which
* is ordered in and above desktop
*/
@ -356,9 +355,9 @@
{
if (GetClassName(lo, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0
&& (lInf = (WIN_INTERN *)GetWindowLong(lo, GWL_USERDATA))
&& lInf->level > NSDesktopWindowLevel
&& lInf->orderedIn == YES)
&& GetWindowLong(lo, OFF_ORDERED) == 1
&& (ll = GetWindowLong(lo, OFF_LEVEL))
> NSDesktopWindowLevel)
{
break;
}
@ -367,11 +366,11 @@
if (lo > 0)
{
NSDebugLLog(@"WTrace", @"sort lo %d (%d)", lo, lInf->level);
NSDebugLLog(@"WTrace", @"sort lo %d (%d)", lo, ll);
/* Check to see if the higher of the two windows should
* actually be lower.
*/
if (hInf->level < lInf->level)
if (hl < ll)
{
HWND higher;
@ -383,8 +382,7 @@
{
higher = HWND_TOP;
}
NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)",
hi, hInf->level, lo, lInf->level);
NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", hi, hl, lo, ll);
SetWindowPos(lo, higher, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);