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:
rfm 2008-03-06 13:48:40 +00:00
parent e17f579971
commit 46a1bbe6fa
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> 2008-03-06 Richard Frith-Macdonald <rfm@gnu.org>
* Source\win32\w32_movesize.m: Bypass all existing code to send a * Source\win32\w32_movesize.m: Bypass all existing code to send a

View file

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

View file

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

View file

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