2 * AmigaOS D-BUS connection handling using a slave process as the main
6 #include <dos/dostags.h>
7 #include <exec/tasks.h>
9 #include <clib/alib_protos.h>
10 #define DBUS_API_SUBJECT_TO_CHANGE
11 #include <proto/dbus.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
16 #include <aros/debug.h>
18 #include "dbus-amiga.h"
26 struct ConnectionData
{
30 struct MinList watches
;
31 DBusConnection
* connection
;
34 static dbus_int32_t Slot
= -1;
36 static void DeleteConnectionData(struct ConnectionData
* c
);
37 static void CleanupAmigaConnection(void* data
);
39 static void MainLoop() {
40 struct ConnectionData
* c
= (struct ConnectionData
*) FindTask(NULL
)->tc_UserData
;
41 kprintf("MainLoop started %08lx (cd %08lx)\n", FindTask(NULL
), c
);
43 c
->signal
= AllocSignal(-1);
45 if (c
->signal
== -1) {
49 Signal(c
->creator
, SIGF_SINGLE
);
52 ULONG signals
= Wait(SIGBREAKF_CTRL_C
| (1UL << c
->signal
));
54 kprintf("MainLoop got a signal %lx\n", signals
);
56 if (signals
& SIGBREAKF_CTRL_C
) {
60 if (signals
& (1UL << c
->signal
)) {
63 // dbus_connection_ref(c->connection);
65 kprintf("Checking watches\n");
66 for(w
= (struct WatchData
*) c
->watches
.mlh_Head
;
67 w
->node
.mln_Succ
!= NULL
;
68 w
= (struct WatchData
*) w
->node
.mln_Succ
) {
69 kprintf("%s watch on fd %ld, flags %lx\n",
70 w
->enabled
? "Enabled" : "Disabled",
71 dbus_watch_get_fd(w
->watch
), dbus_watch_get_flags(w
->watch
));
73 dbus_watch_handle(w
->watch
, dbus_watch_get_flags(w
->watch
));
77 kprintf("Dispatching messages\n");
78 /* Dispatch messages */
79 while (dbus_connection_dispatch(c
->connection
) == DBUS_DISPATCH_DATA_REMAINS
) {
80 kprintf("More messages available\n");
83 // dbus_connection_unref(c->connection);
89 Signal(c
->creator
, SIGF_SINGLE
);
90 kprintf("MainLoop terminating\n");
93 static void* CreateWatchData(DBusWatch
* watch
) {
94 struct WatchData
* w
= AllocVec(sizeof(struct WatchData
), MEMF_ANY
|MEMF_CLEAR
);
97 w
->enabled
= dbus_watch_get_enabled(watch
);
105 static void DeleteWatchData(void* memory
) {
106 struct WatchData
* w
= (struct WatchData
*) memory
;
109 if (w
->node
.mln_Succ
!= NULL
) {
110 Remove((struct Node
*) w
);
117 static void* CreateConnectionData(DBusConnection
* connection
) {
118 struct ConnectionData
* c
= AllocVec(sizeof(struct ConnectionData
), MEMF_ANY
|MEMF_CLEAR
);
120 kprintf("CreateConnectionData %08lx\n", c
);
123 c
->connection
= connection
;
124 c
->creator
= FindTask(NULL
);
125 NewList((struct List
*) &c
->watches
);
128 kprintf("creating mainloop\n");
129 c
->main
= (struct Task
*) CreateNewProcTags(NP_Entry
, (ULONG
) MainLoop
,
130 NP_Name
, (ULONG
) "dbus.library main loop",
133 kprintf("created mainloop %08lx\n", c
->main
);
134 if (c
->main
!= NULL
) {
135 c
->main
->tc_UserData
= c
;
138 SetSignal(0, SIGF_SINGLE
);
143 if (c
->main
== NULL
) {
144 DeleteConnectionData(c
);
153 static void DeleteConnectionData(struct ConnectionData
* c
) {
154 kprintf("DeleteConnectionData %08lx\n", c
);
157 if (c
->main
!= NULL
) {
158 SetSignal(0, SIGF_SINGLE
);
159 Signal(c
->main
, SIGBREAKF_CTRL_C
);
167 static dbus_bool_t
AddWatchFunction(DBusWatch
* watch
,
169 struct ConnectionData
* c
= (struct ConnectionData
*) data
;
172 kprintf("AddWatchFunction\n");
174 w
= CreateWatchData(watch
);
180 AddTail((struct List
*) &c
->watches
, (struct Node
*) w
);
181 dbus_watch_set_data(watch
, w
, NULL
);
186 static void WatchToggledFunction(DBusWatch
* watch
,
188 struct ConnectionData
* c
= (struct ConnectionData
*) data
;
189 struct WatchData
* w
= (struct WatchData
*) dbus_watch_get_data(watch
);
191 kprintf("WatchToggledFunction %lx\n", w
);
193 w
->enabled
= dbus_watch_get_enabled(watch
);
196 static void RemoveWatchFunction(DBusWatch
* watch
,
198 struct ConnectionData
* c
= (struct ConnectionData
*) data
;
199 struct WatchData
* w
= (struct WatchData
*) dbus_watch_get_data(watch
);
201 kprintf("RemoveWatchFunction %lx\n", w
);
203 dbus_watch_set_data(watch
, NULL
, NULL
);
207 static dbus_bool_t
AddTimeoutFunction(DBusTimeout
* timeout
,
209 struct ConnectionData
* c
= (struct ConnectionData
*) data
;
211 kprintf("AddTimeoutFunction\n");
215 static void TimeoutToggledFunction(DBusTimeout
* timeout
,
217 struct ConnectionData
* c
= (struct ConnectionData
*) data
;
219 kprintf("TimeoutToggledFunction\n");
222 static void RemoveTimeoutFunction(DBusTimeout
* timeout
,
224 struct ConnectionData
* c
= (struct ConnectionData
*) data
;
226 kprintf("RemoveTimeoutFunction\n");
230 static void DispatchStatusFunction(DBusConnection
* connection
,
231 DBusDispatchStatus new_status
,
233 struct ConnectionData
* c
= (struct ConnectionData
*) data
;
235 kprintf("DispatchStatusFunction %d\n", new_status
);
237 if (new_status
== DBUS_DISPATCH_DATA_REMAINS
) {
238 Signal(c
->main
, 1UL << c
->signal
);
242 static void WakeupMainFunction(void* data
) {
243 struct ConnectionData
* c
= (struct ConnectionData
*) data
;
245 kprintf("WakeupMainFunction\n");
246 Signal(c
->main
, 1UL << c
->signal
);
249 dbus_bool_t
dbus_a_setup_connection(DBusConnection
* connection
) {
250 struct ConnectionData
* c
;
252 c
= CreateConnectionData(connection
);
255 dbus_connection_set_watch_functions(connection
,
258 WatchToggledFunction
,
261 dbus_connection_set_timeout_functions(connection
,
263 RemoveTimeoutFunction
,
264 TimeoutToggledFunction
,
267 dbus_connection_set_dispatch_status_function(connection
, DispatchStatusFunction
,
270 dbus_connection_set_wakeup_main_function(connection
, WakeupMainFunction
,
273 kprintf("Slot A: %ld\n", Slot
);
274 if (dbus_connection_allocate_data_slot(&Slot
)) {
275 kprintf("Slot B: %ld\n", Slot
);
276 if (dbus_connection_set_data(connection
, Slot
, c
, DeleteConnectionData
)) {
277 kprintf("Slot C: %ld\n", Slot
);
283 DeleteConnectionData(c
);
287 void dbus_a_cleanup_connection(DBusConnection
* connection
) {
288 struct ConnectionData
* c
;
290 kprintf("CleanupAmigaConnection\n");
292 kprintf("Slot X: %ld\n", Slot
);
293 c
= dbus_connection_get_data(connection
, Slot
);
296 dbus_connection_set_data(connection
, Slot
, NULL
, NULL
);
297 dbus_connection_free_data_slot(&Slot
);
298 kprintf("Slot Y: %ld\n", Slot
);
301 dbus_connection_set_dispatch_status_function(connection
, NULL
, NULL
, NULL
);
302 dbus_connection_set_wakeup_main_function(connection
, NULL
, NULL
, NULL
);
303 dbus_connection_set_watch_functions(connection
, NULL
, NULL
, NULL
, NULL
, NULL
);
304 dbus_connection_set_timeout_functions(connection
, NULL
, NULL
, NULL
, NULL
, NULL
);
306 kprintf("Slot X: %ld\n", Slot
);