Getting ready for GSoC: Import old and current D-Bus projects.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/dbuskit/trunk@30331 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Niels Grewe 2010-05-09 18:19:11 +00:00
commit f84a07139e
11 changed files with 1096 additions and 0 deletions

41
GNUmakefile Normal file
View File

@ -0,0 +1,41 @@
#
# GNUmakefile for DBusKit
#
include $(GNUSTEP_MAKEFILES)/common.make
# config.make will be generated by configure (see GNUmakefile.postamble)
-include config.make
DBusKit_SUBPROJECTS = Source
#
# Public headers (will be installed)
#
DBusKit_HEADER_FILES_DIR = Headers
DBusKit_HEADER_FILES = \
DBusKit.h \
DKPort.h
#
# Makefiles
#
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/aggregate.make
ifeq ($(test), yes)
# Bundle
BUNDLE_NAME = DBusKit
include $(GNUSTEP_MAKEFILES)/bundle.make
all:: ${BUNDLE_NAME}
ukrun ${BUNDLE_NAME}.bundle
else
# Framework
FRAMEWORK_NAME = DBusKit
VERSION = 0.1
include $(GNUSTEP_MAKEFILES)/framework.make
endif
-include GNUmakefile.postamble

63
GNUmakefile.postamble Normal file
View File

@ -0,0 +1,63 @@
#
# GNUmakefile.postamble for DBusKit
#
# Things to do before compiling
# before-all::
# Things to do after compiling
#after-all::
# Things to do before installing
# before-install::
# Things to do after installing
# after-install::
# Things to do before uninstalling
# before-uninstall::
# Things to do after uninstalling
# after-uninstall::
# Things to do before cleaning
# before-clean::
# Things to do after cleaning
after-clean::
@-$(RM) -rf DBusKit.bundle
@-$(RM) -rf DBusKit.framework
@-$(RM) -rf derived_src
@-$(RM) config.make
@-$(RM) Headers/config.h
# Things to do before distcleaning
# before-distclean::
# Things to do after distcleaning
after-distclean::
@-$(RM) configure aclocal.m4 config.log config.status
@-$(RM) -rf autom4te.cache
# Things to do before checking
# before-check::
# Things to do after checking
# after-check::
# Rule to generate configuration data:
configure: aclocal.m4 configure.ac
autoconf
aclocal.m4: configure.ac
aclocal
config.make: config.make.in configure
./configure
Headers/config.h: Headers/config.h.in configure
./configure

23
Headers/DBusKit.h Normal file
View File

@ -0,0 +1,23 @@
/** Umbrella header for DBusKit.
Copyright (C) 2010 Free Software Foundation, Inc.
Written by: Niels Grewe <niels.grewe@halbordnung.de>
Created: May 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
#import <DBusKit/DKPort.h>

57
Headers/DKPort.h Normal file
View File

@ -0,0 +1,57 @@
/** Interface for DKPort for NSConnection integration.
Copyright (C) 2010 Free Software Foundation, Inc.
Written by: Niels Grewe <niels.grewe@halbordnung.de>
Created: May 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
#import <Foundation/NSPort.h>
@class DKEndpoint;
/**
* DKPort is used by the Distributed Objects system to communicate with
* D-Bus. Unless you have special needs, don't create DKPort instances
* yourself, but use the interfaces provided by NSConnection instead.
*
* This is a class cluster that will return subclass instances connected to
* specific busses or peers, depending on the way it is initialized. The default
* +port message will return a port connected to the session bus.
*/
@interface DKPort: NSPort
{
/** The endpoint doing the connection handling. */
DKEndpoint *endpoint;
/**
* The remote side of the port. Will not be specified for peer-to-peer
* connections bypassing the bus and for ports used in service connections.
*/
NSString *remote;
}
@end
@interface DKSessionBusPort: DKPort
{
}
@end
@interface DKSystemBusPort: DKPort
{
}
@end

0
Headers/config.h.in Normal file
View File

52
Source/DKEndpoint.h Normal file
View File

@ -0,0 +1,52 @@
/** Declaration of DKEndpoint class for integrating DBus into NSRunLoop.
Copyright (C) 2010 Free Software Foundation, Inc.
Written by: Niels Grewe <niels.grewe@halbordnung.de>
Created: May 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
#import <Foundation/NSObject.h>
#include <dbus/dbus.h>
/**
* DKEndpoint is used internally to manage the low level details of a connection
* to a D-Bus peer. This can be a well known bus as well as some special peer.
*/
@interface DKEndpoint: NSObject
{
DBusConnection *connection;
}
/**
* Use this initializer to use a pre-existing DBusConnection. Please note that
* this will increase the reference count of the connection. It will still need
* to be unreferenced by calling code.
*/
- (id) initWithConnection: (DBusConnection*)conn;
- (id) initWithConnectionTo: (NSString*)endpoint;
- (id) initWithWellKnownBus: (DBusBusType)type;
@end
@interface DKSystemBusEndpoint: DKEndpoint;
- (id) init;
@end
@interface DKSessionBusEndpoint: DKEndpoint;
- (id) init;
@end

752
Source/DKEndpoint.m Normal file
View File

@ -0,0 +1,752 @@
/** Implementation of DKEndpoint class for integrating DBus into NSRunLoop.
Copyright (C) 2010 Free Software Foundation, Inc.
Written by: Niels Grewe <niels.grewe@halbordnung.de>
Created: May 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
<title>DKEndpoint class reference</title>
*/
#import "DKEndpoint.h"
#import <Foundation/NSException.h>
#import <Foundation/NSLock.h>
#import <Foundation/NSMapTable.h>
#import <Foundation/NSRunLoop.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimer.h>
#import <Foundation/NSValue.h>
#import <GNUstepBase/NSDebug+GNUstepBase.h>
/*
* Integration functions:
*/
/*
* The DK(Timeout|Watch)* functions do what their names imply.
*/
static dbus_bool_t
DKTimeoutAdd(DBusTimeout *timeout, void *data);
static void
DKTimeoutRemove(DBusTimeout *timeout, void *data);
static void
DKTimeoutToggled(DBusTimeout *timeout, void *data);
static dbus_bool_t
DKWatchAdd(DBusWatch *watch, void *data);
static void
DKWatchRemove(DBusWatch *watch, void *data);
static void
DKWatchToggled(DBusWatch *watch, void *data);
/*
* Informs the run loop that DBus has work for it to do.
*/
static void
DKWakeUp(void *data);
/*
* Will be called to indicate that messages might be waiting.
*/
static void
DKUpdateDispatchStatus(DBusConnection *conn,
DBusDispatchStatus status,
void *data);
/*
* DBus might want to release objects we created, so we wrap -release for it.
*/
static void
DKRelease(void *ptr);
/*
* Global state for referencing connections:
*/
static NSMapTable *activeConnections;
static NSRecursiveLock *activeConnectionLock;
@interface DKEndpoint (DBusEndpointPrivate)
- (void)cleanup;
@end
/**
* Context object to manage runLoop interactions.
*/
@interface DKRunLoopContext: NSObject
{
DBusConnection *connection;
NSMapTable *timers;
NSMapTable *watchers;
}
- (id)initWithConnection: (DBusConnection*)connection;
- (NSRunLoop*)runLoop;
- (NSString*)runLoopMode;
@end
/**
* Watcher object to monitor the file descriptors D-Bus signals on.
*/
@interface DKWatcher: NSObject <RunLoopEvents>
{
DBusWatch *watch;
BOOL callbackInProgress;
int fileDesc;
DKRunLoopContext *ctx;
}
@end
@implementation DKEndpoint
+ (void)initialize
{
if (self != [DKEndpoint class])
{
return;
}
/*
* It might be smart to put DBus into thread-safe mode by default because
* there is a fair chance of missing NSWillBecomeMultiThreadedNotification.
* (This code might be executed pretty late in the application lifecycle.)
* Note: We could define our own hooks and use NSLock and friends, but that's
* pretty pointless because DBus will use pthreads itself, just as NSLock
* would.
*/
dbus_threads_init_default();
/*
* Further initializations unfortunately need to be done on a per-connection
* basis. We can only optimize by reusing existing connections (D-Bus
* will recycle them behind our back anyways). We do this by weakly
* referencing the connections and DKEndpoint objects in a global
* map-table. They will be removed from there prior to deallocation. The
* downside is that we need to protect the table with a lock. (A capacity of
* 3 is a good guess because we will probably at most need a connection to
* the session and one to the system bus).
*/
activeConnections = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSNonRetainedObjectMapValueCallBacks,
3);
activeConnectionLock = [NSRecursiveLock new];
NSAssert((activeConnections && activeConnectionLock),
@"Could not allocate map table and lock for D-Bus connection management");
}
- (id) initWithConnection: (DBusConnection*)conn
{
DKEndpoint *oldConnection = nil;
DKRunLoopContext *ctx = nil;
BOOL initSuccess = NO;
if (nil == (self = [super init]))
{
return nil;
}
/* NULL connections are useless: */
if (NULL == conn)
{
[self release];
return nil;
}
/*
* Reference the connection on the dbus level so that it sticks around until
* -cleanup is called.
*/
dbus_connection_ref(conn);
connection = conn;
[activeConnectionLock lock];
NS_DURING
{
/* Check wether we can reuse an old connection. */
oldConnection = NSMapGet(activeConnections, (void*)connection);
if (nil != oldConnection)
{
// Retain the old connection to make it stick around:
[oldConnection retain];
}
}
NS_HANDLER
{
[activeConnectionLock unlock];
[localException raise];
}
NS_ENDHANDLER
if (nil != oldConnection)
{
[activeConnectionLock unlock];
[self release];
self = oldConnection;
return self;
}
NS_DURING
{
// We keep the lock until we're done initializing.
ctx = [[DKRunLoopContext alloc] initWithConnection: connection];
// Install our runLoop hooks:
if ((initSuccess = (nil != ctx)))
{
initSuccess = (BOOL)dbus_connection_set_timeout_functions(connection,
DKTimeoutAdd,
DKTimeoutRemove,
DKTimeoutToggled,
(void*)ctx,
DKRelease);
}
if (initSuccess)
{
initSuccess = (BOOL)dbus_connection_set_watch_functions(connection,
DKWatchAdd,
DKWatchRemove,
DKWatchToggled,
(void*)ctx,
DKRelease);
}
if (initSuccess)
{
dbus_connection_set_wakeup_main_function(connection,
DKWakeUp,
(void*)ctx,
DKRelease);
dbus_connection_set_dispatch_status_function(connection,
DKUpdateDispatchStatus,
(void*)ctx,
DKRelease);
}
if (!initSuccess)
{
[self cleanup];
}
}
NS_HANDLER
{
[activeConnectionLock unlock];
[localException raise];
}
NS_ENDHANDLER
if (!initSuccess)
{
[activeConnectionLock unlock];
[self release];
return nil;
}
NS_DURING
{
NSMapInsert(activeConnections, connection, self);
}
NS_HANDLER
{
[activeConnectionLock unlock];
[localException raise];
}
NS_ENDHANDLER
[activeConnectionLock unlock];
return self;
}
- (DBusConnection*)connection
{
return connection;
}
/**
* For use with non-well-known buses, not exteremly useful, but generic.
*/
- (id) initWithConnectionTo: (NSString*)endpoint
{
/* Note: dbus_connection_open_private() would be an option here, but would
* require us to take care of the connections ourselves. Right now, this does
* not seem to be worth the effort, so we let D-Bus do this for us (hence we
* call dbus_connection_unref() and not dbus_connection_close() in -cleanup).
*/
DBusConnection *conn = dbus_connection_open([endpoint UTF8String], NULL);
if (NULL == conn)
{
return nil;
}
self = [self initWithConnection: conn];
// -initWithConnection did increase the refcount, we release ownership of the
// connection:
dbus_connection_unref(conn);
return self;
}
- (id) initWithWellKnownBus: (DBusBusType)type
{
DBusConnection *conn = dbus_bus_get(type, NULL);
if (NULL == conn)
{
return nil;
}
self = [self initWithConnection: conn];
// -initWithConnection did increase the refcount, we release ownership of the
// connection:
dbus_connection_unref(conn);
return self;
}
- (void) cleanup
{
if (connection != NULL)
{
// Make this endpoint unavailable to other threads:
[activeConnectionLock lock];
NS_DURING
{
if (connection != NULL)
{
NSMapRemove(activeConnections, connection);
dbus_connection_unref(connection);
connection = NULL;
}
}
NS_HANDLER
{
[activeConnectionLock unlock];
[localException raise];
}
NS_ENDHANDLER
[activeConnectionLock unlock];
}
}
- (void)dealloc
{
[self cleanup];
[super dealloc];
}
@end
@implementation DKSystemBusEndpoint
- (id)init
{
if (nil == (self = [super initWithWellKnownBus: DBUS_BUS_SYSTEM]))
{
return nil;
}
return self;
}
@end
@implementation DKSessionBusEndpoint
- (id)init
{
if (nil == (self = [super initWithWellKnownBus: DBUS_BUS_SESSION]))
{
return nil;
}
return self;
}
@end
@implementation DKWatcher
- (void)monitorForEvents: (NSUInteger)events
{
// Dispatch new events to the runLoop:
if (events & DBUS_WATCH_READABLE)
{
[[ctx runLoop] addEvent: (void*)(intptr_t)fileDesc
type: ET_RDESC
watcher: self
forMode: [ctx runLoopMode]];
}
if (events & DBUS_WATCH_WRITABLE)
{
[[ctx runLoop] addEvent: (void*)(intptr_t)fileDesc
type: ET_WDESC
watcher: self
forMode: [ctx runLoopMode]];
}
}
- (void)unmonitorForEvents: (NSUInteger)events
{
// Remove events to the runLoop:
if (events & DBUS_WATCH_READABLE)
{
[[ctx runLoop] removeEvent: (void*)(intptr_t)fileDesc
type: ET_RDESC
forMode: [ctx runLoopMode]
all: NO];
}
if (events & DBUS_WATCH_WRITABLE)
{
[[ctx runLoop] removeEvent: (void*)(intptr_t)fileDesc
type: ET_WDESC
forMode: [ctx runLoopMode]
all: NO];
}
}
- (id)initWithWatch: (DBusWatch*)_watch
andContext: (DKRunLoopContext*)aCtx
forFd: (int)fd
{
if (nil == (self = [super init]))
{
return nil;
}
fileDesc = fd;
// The context retains its watchers and timers:
ctx = aCtx;
watch = _watch;
[self monitorForEvents: dbus_watch_get_flags(watch)];
return self;
}
- (void)receivedEvent: (void*)data
type: (RunLoopEventType)type
extra: (void*)extra
forMode: (NSString*)mode
{
int fd = (int)(intptr_t)data;
if(fileDesc != fd)
{
//Not good
return;
}
switch (type)
{
case ET_RDESC:
NSLog(@"Handling readable on watch");
dbus_watch_handle(watch, DBUS_WATCH_READABLE);
break;
case ET_WDESC:
NSLog(@"Handling writable on watch");
dbus_watch_handle(watch, DBUS_WATCH_WRITABLE);
break;
default:
return;
}
}
- (void)dealloc
{
[super dealloc];
}
@end
@implementation DKRunLoopContext
- (id) initWithConnection: (DBusConnection*)conn
{
if (nil == (self = [super init]))
{
return nil;
}
connection = conn;
// TODO: Profile wether 10 is a reasonable default capacity.
timers = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSObjectMapValueCallBacks,
10);
watchers = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSObjectMapValueCallBacks,
10);
return self;
}
/*
* TODO: We need to handle different runLoops and runLoopModes.
*/
- (NSRunLoop*)runLoop
{
return [NSRunLoop currentRunLoop];
}
- (NSString*)runLoopMode
{
return NSDefaultRunLoopMode;
}
- (void)dealloc
{
//TODO: Further Cleanup.
NSFreeMapTable(watchers);
NSFreeMapTable(timers);
[super dealloc];
}
- (BOOL)addTimeout: (DBusTimeout*)timeout
withInterval: (int)milliSeconds
{
NSTimer *timer = nil;
NSTimeInterval interval = (milliSeconds / 1000.0);
NSAssert(timeout, @"Missing timeout data during D-Bus event handling.");
// Just return if we already have a timer for this timeout:
if (NSMapGet(timers,timeout))
{
return YES;
}
//Create the timer, saving the DBusTimeout pointer for later use.
timer = [NSTimer timerWithTimeInterval: MAX(interval, 0.1)
target: self
selector: @selector(handleTimeout:)
userInfo: [NSValue valueWithPointer: timeout]
repeats: YES];
if (timer == nil)
{
return NO;
}
else
{
[[self runLoop] addTimer: timer forMode: [self runLoopMode]];
return YES;
}
}
- (void)removeTimeout: (DBusTimeout*)timeout
{
NSTimer *timer = nil;
NSAssert(timeout, @"Missing timeout data during D-Bus event handling.");
timer = NSMapGet(timers,timeout);
if (nil != timer)
{
[timer invalidate];
NSMapRemove(timers,timeout);
}
}
- (void)handleTimeout: (NSTimer*)timer
{
DBusTimeout *timeout = (DBusTimeout*)[(NSValue*)[timer userInfo] pointerValue];
NSAssert(timeout, @"Missing timeout data during D-Bus event handling.");
NSLog(@"Handling timeout");
dbus_timeout_handle(timeout);
/*
* Note: dbus_timeout_handle() returns FALSE on OOM, but the documentation
* specifies we just ignore that and retry the next time the timeout fires.
*/
}
- (void)dispatchForConnection: (NSValue*)value
{
DBusConnection *conn = (DBusConnection*)[value pointerValue];
DBusDispatchStatus status;
// If called with nil, we dispatch for the default connection:
if ((value != nil) && (conn != connection))
{
// This should not happen and could be a sign of some corruption.
NSWarnMLog(@"Called to dispatch for non-local conncetion durng D-Bus event handling.");
return;
}
do
{
// We drain all messages instead of waiting for the next run loop iteration:
status = dbus_connection_dispatch(connection);
} while (DBUS_DISPATCH_DATA_REMAINS == status);
}
- (BOOL)addWatch: (DBusWatch*)watch
{
NSInteger fd = -1;
DKWatcher *watcher = nil;
NSAssert(watch, @"Missing watch data during D-Bus event handling.");
# if defined(__MINGW__)
// As per D-Bus documentation, WinSock is used on Windows platforms.
fd = dbus_watch_get_socket(watch);
# else
fd = dbus_watch_get_unix_fd(watch);
# endif
if (-1 == fd)
{
return NO;
}
else
{
watcher = [[DKWatcher alloc] initWithWatch: watch
andContext: self
forFd: fd];
if (nil == watcher)
{
return NO;
}
NSMapInsert(watchers, watch, watcher);
// The map table has retained the watcher, we can release it:
[watcher release];
}
return YES;
}
- (void)removeWatch: (DBusWatch*)watch
{
DKWatcher *watcher = nil;
NSAssert(watch, @"Missing watch data during D-Bus event handling.");
watcher = NSMapGet(watchers,watch);
if (nil != watcher)
{
[watcher unmonitorForEvents: dbus_watch_get_flags(watch)];
NSMapRemove(watchers, watch);
}
}
@end
#define CTX(x) DKRunLoopContext *ctx = (DKRunLoopContext*)x;\
do { NSCAssert(x, @"Missing context data during D-Bus event handling.");} while (0)
static dbus_bool_t
DKTimeoutAdd(DBusTimeout *timeout, void *data)
{
CTX(data);
NSCAssert(timeout, @"Missing timeout data during D-Bus event handling.");
NSLog(@"Timout added");
if (NO == (BOOL)dbus_timeout_get_enabled(timeout))
{
return TRUE;
}
return (dbus_bool_t)[ctx addTimeout: timeout
withInterval: dbus_timeout_get_interval(timeout)];
}
static void
DKTimeoutRemove(DBusTimeout *timeout, void *data)
{
CTX(data);
NSCAssert(timeout, @"Missing timeout data during D-Bus event handling.");
NSLog(@"Timeout removed");
[ctx removeTimeout: timeout];
}
static void
DKTimeoutToggled(DBusTimeout *timeout, void *data)
{
/*
* Note: This is the easy solution, not sure whether we can be smarter about
* this.
*/
NSLog(@"Timeout toggled");
DKTimeoutRemove(timeout, data);
DKTimeoutAdd(timeout, data);
}
static dbus_bool_t
DKWatchAdd(DBusWatch *watch, void *data)
{
CTX(data);
NSCAssert(watch, @"Missing watch data during D-Bus event handling.");
NSLog(@"Watch added");
if (!dbus_watch_get_enabled(watch))
{
return YES;
}
return (dbus_bool_t)[ctx addWatch: watch];
}
static void
DKWatchRemove(DBusWatch *watch, void *data)
{
CTX(data);
NSCAssert(watch, @"Missing watch data during D-Bus event handling.");
NSLog(@"Removed watch");
[ctx removeWatch: watch];
}
static void
DKWatchToggled(DBusWatch *watch, void *data)
{
/*
* Note: This is the easy solution, not sure whether we can be smarter about
* this.
*/
NSLog(@"Watch toggled");
DKWatchRemove(watch, data);
DKWatchAdd(watch, data);
}
static void
DKRelease(void *data)
{
NSLog(@"D-Bus calls release on something!");
[(id)data release];
}
static void
DKWakeUp(void *data)
{
CTX(data);
NSLog(@"Starting runLoop on D-Bus request");
// If we are woken up, we surely need to dispatch new messages:
[[ctx runLoop] performSelector: @selector(dispatchForConnection:)
target: ctx
argument: nil
order: 0
modes: [NSArray arrayWithObject: [ctx runLoopMode]]];
[[ctx runLoop] runMode: [ctx runLoopMode]
beforeDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]];
}
static void
DKUpdateDispatchStatus(DBusConnection *conn,
DBusDispatchStatus status,
void *data)
{
NSValue *connectionPointer;
CTX(data);
NSCAssert(conn, @"Missing connection data during D-Bus event handling");
NSLog(@"Dispatch status changed to %d", status);
switch (status)
{
case DBUS_DISPATCH_COMPLETE:
NSLog(@"Dispatch complete");
return;
case DBUS_DISPATCH_NEED_MEMORY:
NSLog(@"Insufficient memory for dispatch, will try again later");
return;
case DBUS_DISPATCH_DATA_REMAINS:
NSLog(@"Will schedule handling of messages.");
}
connectionPointer = [NSValue valueWithPointer: conn];
[[ctx runLoop] performSelector: @selector(dispatchForConnection:)
target: ctx
argument: connectionPointer
order: 0
modes: [NSArray arrayWithObject: [ctx runLoopMode]]];
}

57
Source/DKPort.m Normal file
View File

@ -0,0 +1,57 @@
/** Implementation of the DKPort class for NSConnection integration.
Copyright (C) 2010 Free Software Foundation, Inc.
Written by: Niels Grewe <niels.grewe@halbordnung.de>
Created: May 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
#import "DBusKit/DKPort.h"
#import "DKEndpoint.h"
static Class DKPortAbstractClass;
static Class DKPortConcreteClass;
@implementation DKPort
+ (void)initialize
{
/*
* Preload the class pointers to avoid expensive class message sends on every
* +port call.
*/
Class abstractClass = [DKPort class];
if (self == abstractClass)
{
DKPortAbstractClass = abstractClass;
DKPortConcreteClass = [DKSessionBusPort class];
}
}
+ (NSPort*)port
{
if (self == DKPortAbstractClass)
{
return [[[DKPortConcreteClass alloc] init] autorelease];
}
else
{
return [[[self alloc] init] autorelease];
}
}
@end

27
Source/GNUmakefile Normal file
View File

@ -0,0 +1,27 @@
include $(GNUSTEP_MAKEFILES)/common.make
#
# Main framework
#
SUBPROJECT_NAME = libDBusKit
# Include configuration
-include ../config.make
#
# Class files
#
libDBusKit_OBJC_FILES = \
DKEndpoint.m \
DKPort.m
#
# C files
#
libDBusKit_C_FILES =
-include ../GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/subproject.make
-include ../GNUmakefile.postamble

2
config.make.in Normal file
View File

@ -0,0 +1,2 @@
ADDITIONAL_OBJCFLAGS+=@DBUS_CFLAGS@
ADDITIONAL_LIBRARY+=@DBUS_LIBS@

22
configure.ac Normal file
View File

@ -0,0 +1,22 @@
# autoconf template for the configure script
AC_INIT
PKG_PROG_PKG_CONFIG([])
# FIXME: We need a proper test for libobjc2 for some advanced features (e.g.
# the declared-properties - dbus-properties bridge).
# AC_CHECK_FUNCS(objc_setProperty)
# if test $ac_cv_func_objc_setProperty = yes ; then
# HAVE_OBJC2=1
# else
# HAVE_OBJC2=0
# fi
PKG_CHECK_MODULES(DBUS, dbus-1, HAVE_DBUS=1, HAVE_DBUS=0)
AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
AC_CONFIG_FILES([config.make Headers/config.h])
AC_OUTPUT