8 #include <panel-applet.h>
9 #include <doldaconnect/uilib.h>
10 #include <doldaconnect/uimisc.h>
11 #include <doldaconnect/utils.h>
18 int gdkread, gdkwrite;
23 struct conduit *conduit;
29 static struct conduit *inuse = NULL;
31 static void dcfdcb(struct conduit *conduit, int fd, GdkInputCondition condition);
33 static void updatewrite(struct conduit *conduit)
37 data = conduit->cdata;
42 if(data->gdkwrite == -1)
43 data->gdkwrite = gdk_input_add(data->fd, GDK_INPUT_WRITE, (void (*)(gpointer, int, GdkInputCondition))dcfdcb, conduit);
45 if(data->gdkwrite != -1)
47 gdk_input_remove(data->gdkwrite);
53 static void disconnected(struct conduit *conduit)
57 data = conduit->cdata;
60 if(data->gdkread != -1)
62 gdk_input_remove(data->gdkread);
65 if(data->gdkwrite != -1)
67 gdk_input_remove(data->gdkwrite);
74 static int noconv(int type, wchar_t *text, char **resp, void *data)
79 static char *gettag(struct dc_transfer *dt)
81 char *mbspath, *p, *buf;
85 if((mbspath = icwcstombs(dt->path, "UTF-8")) == NULL)
87 if((p = strrchr(mbspath, '/')) == NULL)
96 static void dtfreecb(struct dc_transfer *dt)
100 if((dtd = dt->udata) == NULL)
103 freetransfer(dtd->ct);
109 static int lstrargcb(struct dc_response *resp)
111 struct dc_transfer *dt;
113 struct dc_intresp *ires;
117 if(resp->code == 200)
119 while((dtd->tag == NULL) && ((ires = dc_interpret(resp)) != NULL))
121 if(!wcscmp(ires->argv[0].val.str, L"tag"))
124 dtd->tag = icwcstombs(ires->argv[1].val.str, "UTF-8");
130 dtd->tag = gettag(dt);
131 dtd->ct = newtransfer(dtd->conduit, dtd->tag, dt->size, dt->curpos);
135 static void inittrans(struct conduit *conduit, struct dc_transfer *dt)
139 dtd = smalloc(sizeof(*dtd));
140 memset(dtd, 0, sizeof(*dtd));
141 dtd->conduit = conduit;
143 dt->destroycb = dtfreecb;
144 dc_queuecmd(lstrargcb, dt, L"lstrarg", L"%i", dt->id, NULL);
147 static void trlistcb(int resp, struct conduit *conduit)
150 struct dc_transfer *dt;
152 data = conduit->cdata;
155 for(dt = dc_transfers; dt != NULL; dt = dt->next)
157 if(dt->dir != DC_TRNSD_DOWN)
159 inittrans(conduit, dt);
163 static void logincb(int err, wchar_t *reason, struct conduit *conduit)
167 data = conduit->cdata;
168 if(err != DC_LOGIN_ERR_SUCCESS)
171 disconnected(conduit);
174 condconnected(conduit);
175 dc_gettrlistasync((void (*)(int, void *))trlistcb, conduit);
176 dc_queuecmd(NULL, NULL, L"notify", L"trans:act", L"on", L"trans:prog", L"on", NULL);
179 static void dcfdcb(struct conduit *conduit, int fd, GdkInputCondition condition)
182 struct dc_response *resp;
183 struct dc_intresp *ires;
184 struct dc_transfer *dt;
187 data = conduit->cdata;
188 if(((condition & GDK_INPUT_READ) && dc_handleread()) || ((condition & GDK_INPUT_WRITE) && dc_handlewrite()))
190 disconnected(conduit);
193 while((resp = dc_getresp()) != NULL)
195 if(!wcscmp(resp->cmdname, L".connect"))
197 if(dc_checkprotocol(resp, DC_LATEST))
200 disconnected(conduit);
202 dc_loginasync(NULL, 1, noconv, (void (*)(int, wchar_t *, void *))logincb, conduit);
204 } else if(!wcscmp(resp->cmdname, L".notify")) {
205 dc_uimisc_handlenotify(resp);
209 if((ires = dc_interpret(resp)) != NULL)
211 if((dt = dc_findtransfer(ires->argv[0].val.num)) != NULL)
213 if(dt->dir == DC_TRNSD_DOWN)
214 inittrans(conduit, dt);
220 if((ires = dc_interpret(resp)) != NULL)
222 if((dt = dc_findtransfer(ires->argv[0].val.num)) != NULL)
224 if(((dtd = dt->udata) != NULL) && (dtd->ct != NULL))
226 if(dtd->ct->size != dt->size)
227 transfersetsize(dtd->ct, dt->size);
234 if((ires = dc_interpret(resp)) != NULL)
236 if((dt = dc_findtransfer(ires->argv[0].val.num)) != NULL)
238 if(((dtd = dt->udata) != NULL) && (dtd->ct != NULL))
240 if(dtd->ct->pos != dt->curpos)
241 transfersetpos(dtd->ct, dt->curpos);
251 updatewrite(conduit);
254 static int init(struct conduit *conduit)
256 static int inited = 0;
264 data = smalloc(sizeof(*data));
265 memset(data, 0, sizeof(*data));
267 data->gdkread = data->gdkwrite = -1;
268 conduit->cdata = data;
272 static int connect(struct conduit *conduit)
276 data = conduit->cdata;
279 if((data->fd = dc_connect(NULL)) < 0)
281 data->gdkread = gdk_input_add(data->fd, GDK_INPUT_READ, (void (*)(gpointer, int, GdkInputCondition))dcfdcb, conduit);
282 updatewrite(conduit);
287 static void destroy(struct conduit *conduit)
291 data = conduit->cdata;
292 if(data->gdkread != -1)
293 gdk_input_remove(data->gdkread);
294 if(data->gdkwrite != -1)
295 gdk_input_remove(data->gdkwrite);
303 static int cancel(struct conduit *conduit, struct transfer *transfer)
307 struct dc_transfer *dt;
309 data = conduit->cdata;
310 for(dt = dc_transfers; dt != NULL; dt = dt->next)
312 if(((dtd = dt->udata) != NULL) && (dtd->ct == transfer))
314 dc_queuecmd(NULL, NULL, L"cancel", L"%i", dt->id, NULL);
322 static struct conduitiface st_conduit_dclib =
330 struct conduitiface *conduit_dclib = &st_conduit_dclib;