mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
Fix accidentally exposed private headers.
Implement code to handle windows messages on a per-window basis. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@21916 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
0257194cdc
commit
02c7ccf532
10 changed files with 94 additions and 28 deletions
|
@ -119,8 +119,6 @@ GNUstep.h \
|
|||
behavior.h \
|
||||
preface.h \
|
||||
objc-gnu2next.h \
|
||||
GSRunLoopCtxt.h \
|
||||
GSRunLoopWatcher.h
|
||||
|
||||
GNU_HEADERS = $(ADD_HEADERS)
|
||||
|
||||
|
|
70
Source/GSRunLoopCtxt.h
Normal file
70
Source/GSRunLoopCtxt.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
#ifndef __GSRunLoopCtxt_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __GSRunLoopCtxt_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include "config.h"
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSMapTable.h>
|
||||
#include <Foundation/NSRunLoop.h>
|
||||
|
||||
/*
|
||||
* Setup for inline operation of arrays.
|
||||
*/
|
||||
|
||||
#define GSI_ARRAY_TYPES GSUNION_OBJ
|
||||
|
||||
#if GS_WITH_GC == 0
|
||||
#define GSI_ARRAY_RELEASE(A, X) [(X).obj release]
|
||||
#define GSI_ARRAY_RETAIN(A, X) [(X).obj retain]
|
||||
#else
|
||||
#define GSI_ARRAY_RELEASE(A, X)
|
||||
#define GSI_ARRAY_RETAIN(A, X)
|
||||
#endif
|
||||
|
||||
#include "GNUstepBase/GSIArray.h"
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
typedef struct{
|
||||
int limit;
|
||||
short *index;
|
||||
}pollextra;
|
||||
#endif
|
||||
|
||||
@class NSString;
|
||||
|
||||
@interface GSRunLoopCtxt : NSObject
|
||||
{
|
||||
@public
|
||||
void *extra; /** Copy of the RunLoop ivar. */
|
||||
NSString *mode; /** The mode for this context. */
|
||||
GSIArray performers; /** The actions to perform regularly. */
|
||||
GSIArray timers; /** The timers set for the runloop mode */
|
||||
GSIArray watchers; /** The inputs set for the runloop mode */
|
||||
#if defined(__MINGW32__)
|
||||
id msgTarget; /** Target to raise a win32 message */
|
||||
SEL msgSelector; /** method of target */
|
||||
#endif
|
||||
@private
|
||||
#if defined(__MINGW32__)
|
||||
NSMapTable *handleMap;
|
||||
NSMapTable *winMsgMap;
|
||||
#else
|
||||
NSMapTable *_efdMap;
|
||||
NSMapTable *_rfdMap;
|
||||
NSMapTable *_wfdMap;
|
||||
int fairStart; // For trying to ensure fair handling.
|
||||
#endif
|
||||
BOOL completed; // To mark operation as completed.
|
||||
#ifdef HAVE_POLL
|
||||
unsigned int pollfds_capacity;
|
||||
unsigned int pollfds_count;
|
||||
struct pollfd *pollfds;
|
||||
#endif
|
||||
}
|
||||
- (void) endEvent: (void*)data
|
||||
type: (RunLoopEventType)type;
|
||||
- (void) endPoll;
|
||||
- (id) initWithMode: (NSString*)theMode extra: (void*)e;
|
||||
- (BOOL) pollUntil: (int)milliseconds within: (NSArray*)contexts;
|
||||
@end
|
||||
|
||||
#endif /* __GSRunLoopCtxt_h_GNUSTEP_BASE_INCLUDE */
|
76
Source/GSRunLoopWatcher.h
Normal file
76
Source/GSRunLoopWatcher.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
#ifndef __GSRunLoopWatcher_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __GSRunLoopWatcher_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
/*
|
||||
* The 'GSRunLoopWatcher' class was written to permit the (relatively)
|
||||
* easy addition of new events to be watched for in the runloop.
|
||||
*
|
||||
* To add a new type of event, the 'RunLoopEventType' enumeration must be
|
||||
* extended, and the methods must be modified to handle the new type.
|
||||
*
|
||||
* The internal variables if the GSRunLoopWatcher are used as follows -
|
||||
*
|
||||
* The '_date' variable contains a date after which the event is useless
|
||||
* and the watcher can be removed from the runloop.
|
||||
*
|
||||
* If '_invalidated' is set, the watcher should be disabled and should
|
||||
* be removed from the runloop when next encountered.
|
||||
*
|
||||
* The 'data' variable is used to identify the resource/event that the
|
||||
* watcher is interested in.
|
||||
*
|
||||
* The 'receiver' is the object which should be told when the event
|
||||
* occurs. This object is retained so that we know it will continue
|
||||
* to exist and can handle a callback.
|
||||
*
|
||||
* The 'type' variable indentifies the type of event watched for.
|
||||
* NSRunLoops [-acceptInputForMode: beforeDate: ] method MUST contain
|
||||
* code to watch for events of each type.
|
||||
*
|
||||
* To set this variable, the method adding the GSRunLoopWatcher to the
|
||||
* runloop must ask the 'receiver' (or its delegate) to supply a date
|
||||
* using the '[-limitDateForMode: ]' message.
|
||||
*
|
||||
* NB. This class is private to NSRunLoop and must not be subclassed.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "GNUstepBase/preface.h"
|
||||
#include <Foundation/NSRunLoop.h>
|
||||
|
||||
@class NSDate;
|
||||
|
||||
extern SEL eventSel; /* Initialized in [NSRunLoop +initialize] */
|
||||
|
||||
@interface GSRunLoopWatcher: NSObject
|
||||
{
|
||||
@public
|
||||
NSDate *_date; /* First to match layout of NSTimer */
|
||||
BOOL _invalidated; /* 2nd to match layout of NSTimer */
|
||||
IMP handleEvent; /* New-style event handling */
|
||||
void *data;
|
||||
id receiver;
|
||||
RunLoopEventType type;
|
||||
unsigned count;
|
||||
}
|
||||
- (id) initWithType: (RunLoopEventType)type
|
||||
receiver: (id)anObj
|
||||
data: (void*)data;
|
||||
@end
|
||||
|
||||
/*
|
||||
* Two optimisation functions that depend on a hack that the layout of
|
||||
* the NSTimer class is known to be the same as GSRunLoopWatcher for the
|
||||
* first two elements.
|
||||
*/
|
||||
static inline NSDate* timerDate(NSTimer* timer)
|
||||
{
|
||||
return ((GSRunLoopWatcher*)timer)->_date;
|
||||
}
|
||||
|
||||
static inline BOOL timerInvalidated(NSTimer* timer)
|
||||
{
|
||||
return ((GSRunLoopWatcher*)timer)->_invalidated;
|
||||
}
|
||||
|
||||
#endif /* __GSRunLoopWatcher_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -40,8 +40,8 @@
|
|||
#include "Foundation/NSRunLoop.h"
|
||||
#include "Foundation/NSThread.h"
|
||||
#include "Foundation/NSDebug.h"
|
||||
#include "GNUstepBase/GSRunLoopCtxt.h"
|
||||
#include "GNUstepBase/GSRunLoopWatcher.h"
|
||||
#include "GSRunLoopCtxt.h"
|
||||
#include "GSRunLoopWatcher.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "GNUstepBase/preface.h"
|
||||
#include "GNUstepBase/GSRunLoopCtxt.h"
|
||||
#include "GNUstepBase/GSRunLoopWatcher.h"
|
||||
#include "../GSRunLoopCtxt.h"
|
||||
#include "../GSRunLoopWatcher.h"
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSNotificationQueue.h>
|
||||
#include <Foundation/NSPort.h>
|
||||
|
@ -59,6 +59,10 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
|||
{
|
||||
NSFreeMapTable(handleMap);
|
||||
}
|
||||
if (winMsgMap != 0)
|
||||
{
|
||||
NSFreeMapTable(winMsgMap);
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -122,6 +126,8 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
|||
|
||||
handleMap = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
WatcherMapValueCallBacks, 0);
|
||||
winMsgMap = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
WatcherMapValueCallBacks, 0);
|
||||
|
||||
msgTarget = nil;
|
||||
}
|
||||
|
@ -134,6 +140,7 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
|||
GSRunLoopWatcher *watcher;
|
||||
HANDLE *handleArray;
|
||||
int num_handles;
|
||||
int num_winMsgs;
|
||||
unsigned i;
|
||||
void *handle;
|
||||
int wait_timeout;
|
||||
|
@ -151,9 +158,11 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
|||
}
|
||||
|
||||
NSResetMapTable(handleMap);
|
||||
NSResetMapTable(winMsgMap);
|
||||
|
||||
i = GSIArrayCount(watchers);
|
||||
num_handles = 0;
|
||||
num_winMsgs = 0;
|
||||
while (i-- > 0)
|
||||
{
|
||||
GSRunLoopWatcher *info;
|
||||
|
@ -196,6 +205,11 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
|||
}
|
||||
}
|
||||
break;
|
||||
case ET_WINMSG:
|
||||
winMsgMap = (HANDLE)(int)info->data;
|
||||
NSMapInsert(winMsgMap, (void*)handle, info);
|
||||
num_winMsgs++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,25 +226,66 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
|||
|
||||
handleArray = (HANDLE*)NSZoneMalloc(NSDefaultMallocZone(),
|
||||
sizeof(HANDLE) * num_handles);
|
||||
hEnum = NSEnumerateMapTable(handleMap);
|
||||
|
||||
i = 0;
|
||||
hEnum = NSEnumerateMapTable(handleMap);
|
||||
while (NSNextMapEnumeratorPair(&hEnum, &handle, (void**)&watcher))
|
||||
{
|
||||
handleArray[i++] = (HANDLE)handle;
|
||||
}
|
||||
NSEndMapTableEnumeration(&hEnum);
|
||||
|
||||
do_wait = YES;
|
||||
do
|
||||
{
|
||||
num_handles = i;
|
||||
wait_return = MsgWaitForMultipleObjects(num_handles, handleArray,
|
||||
NO, wait_timeout, QS_ALLEVENTS);
|
||||
NO, wait_timeout, QS_ALLINPUT);
|
||||
NSDebugMLLog(@"NSRunLoop", @"wait returned %d", wait_return);
|
||||
|
||||
// if there are windows message
|
||||
if (wait_return == WAIT_OBJECT_0 + num_handles)
|
||||
{
|
||||
MSG msg;
|
||||
INT bRet;
|
||||
|
||||
if (num_winMsgs > 0)
|
||||
{
|
||||
hEnum = NSEnumerateMapTable(winMsgMap);
|
||||
while (NSNextMapEnumeratorPair(&hEnum, &handle, (void**)&watcher))
|
||||
{
|
||||
if (watcher->_invalidated == NO)
|
||||
{
|
||||
bRet = PeekMessage(&msg, handle, 0, 0, PM_NOREMOVE);
|
||||
if (bRet != 0)
|
||||
{
|
||||
i = [contexts count];
|
||||
while (i-- > 0)
|
||||
{
|
||||
GSRunLoopCtxt *c = [contexts objectAtIndex: i];
|
||||
|
||||
if (c != self)
|
||||
{
|
||||
[c endEvent: (void*)handle type: ET_WINMSG];
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The watcher is still valid - so call its receivers
|
||||
* event handling method.
|
||||
*/
|
||||
(*watcher->handleEvent)(watcher->receiver,
|
||||
eventSel, watcher->data, watcher->type,
|
||||
(void*)(gsaddr)handle, mode);
|
||||
NSEndMapTableEnumeration(&hEnum);
|
||||
NSZoneFree(NSDefaultMallocZone(), handleArray);
|
||||
completed = YES;
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
NSEndMapTableEnumeration(&hEnum);
|
||||
}
|
||||
|
||||
if (msgTarget != nil)
|
||||
{
|
||||
[msgTarget performSelector: msgSelector withObject: nil];
|
||||
|
@ -238,23 +293,18 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
|||
completed = YES;
|
||||
return NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG msg;
|
||||
INT bRet;
|
||||
|
||||
while ((bRet = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) != 0)
|
||||
{
|
||||
if (bRet == -1)
|
||||
{
|
||||
// handle the error and possibly exit
|
||||
}
|
||||
else
|
||||
{
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((bRet = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) != 0)
|
||||
{
|
||||
if (bRet == -1)
|
||||
{
|
||||
// handle the error and possibly exit
|
||||
}
|
||||
else
|
||||
{
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
--wait_timeout;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "GNUstepBase/preface.h"
|
||||
#include "GNUstepBase/GSRunLoopWatcher.h"
|
||||
#include "../GSRunLoopWatcher.h"
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSPort.h>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "config.h"
|
||||
#include "GNUstepBase/preface.h"
|
||||
#include "Foundation/NSRunLoop.h"
|
||||
#include "GNUstepBase/GSRunLoopCtxt.h"
|
||||
#include "../GSRunLoopCtxt.h"
|
||||
|
||||
@implementation NSRunLoop (mingw32)
|
||||
/**
|
||||
|
|
|
@ -365,11 +365,13 @@ struct NSUserDefaultsWin32_DomainInfo
|
|||
|
||||
NSLog(@"Failed to query modify time on registry %@ (%x)",
|
||||
dName, rc);
|
||||
NSEndMapTableEnumeration(&iter);
|
||||
return YES;
|
||||
}
|
||||
ti = -12622780800.0 + lasttime.QuadPart / 10000000.0;
|
||||
if ([lastSyncDate timeIntervalSinceReferenceDate] < ti)
|
||||
{
|
||||
NSEndMapTableEnumeration(&iter);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
@ -395,6 +397,7 @@ struct NSUserDefaultsWin32_DomainInfo
|
|||
}
|
||||
else
|
||||
{
|
||||
NSEndMapTableEnumeration(&iter);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
@ -407,11 +410,13 @@ struct NSUserDefaultsWin32_DomainInfo
|
|||
{
|
||||
NSLog(@"Failed to query time on HKEY_LOCAL_MACHINE\\%@ (%x)",
|
||||
dPath, rc);
|
||||
NSEndMapTableEnumeration(&iter);
|
||||
return YES;
|
||||
}
|
||||
ti = -12622780800.0 + lasttime.QuadPart / 10000000.0;
|
||||
if ([lastSyncDate timeIntervalSinceReferenceDate] < ti)
|
||||
{
|
||||
NSEndMapTableEnumeration(&iter);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
@ -434,6 +439,7 @@ struct NSUserDefaultsWin32_DomainInfo
|
|||
}
|
||||
else
|
||||
{
|
||||
NSEndMapTableEnumeration(&iter);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue