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 /* XXX: Achtung! Too DC-specific! */
88 if((p = strrchr(mbspath, '\\')) == NULL)
97 static void dtfreecb(struct dc_transfer *dt)
101 if((dtd = dt->udata) == NULL)
104 freetransfer(dtd->ct);
110 static int lstrargcb(struct dc_response *resp)
112 struct dc_transfer *dt;
114 struct dc_intresp *ires;
118 if(resp->code == 200)
120 while((dtd->tag == NULL) && ((ires = dc_interpret(resp)) != NULL))
122 if(!wcscmp(ires->argv[0].val.str, L"tag"))
125 dtd->tag = icwcstombs(ires->argv[1].val.str, "UTF-8");
131 dtd->tag = gettag(dt);
132 dtd->ct = newtransfer(dtd->conduit, dtd->tag, dt->size, dt->curpos);
136 static void inittrans(struct conduit *conduit, struct dc_transfer *dt)
140 dtd = smalloc(sizeof(*dtd));
141 memset(dtd, 0, sizeof(*dtd));
142 dtd->conduit = conduit;
144 dt->destroycb = dtfreecb;
145 dc_queuecmd(lstrargcb, dt, L"lstrarg", L"%%i", dt->id, NULL);
148 static void trlistcb(int resp, struct conduit *conduit)
151 struct dc_transfer *dt;
153 data = conduit->cdata;
156 for(dt = dc_transfers; dt != NULL; dt = dt->next)
158 if(dt->dir != DC_TRNSD_DOWN)
160 inittrans(conduit, dt);
164 static void logincb(int err, wchar_t *reason, struct conduit *conduit)
168 data = conduit->cdata;
169 if(err != DC_LOGIN_ERR_SUCCESS)
172 disconnected(conduit);
175 condconnected(conduit);
176 dc_gettrlistasync((void (*)(int, void *))trlistcb, conduit);
177 dc_queuecmd(NULL, NULL, L"notify", L"trans:act", L"on", L"trans:prog", L"on", NULL);
180 static void dcfdcb(struct conduit *conduit, int fd, GdkInputCondition condition)
183 struct dc_response *resp;
184 struct dc_intresp *ires;
185 struct dc_transfer *dt;
188 data = conduit->cdata;
189 if(((condition & GDK_INPUT_READ) && dc_handleread()) || ((condition & GDK_INPUT_WRITE) && dc_handlewrite()))
191 disconnected(conduit);
194 while((resp = dc_getresp()) != NULL)
196 if(!wcscmp(resp->cmdname, L".connect"))
198 if(resp->code == 200)
200 dc_loginasync(NULL, 1, noconv, (void (*)(int, wchar_t *, void *))logincb, conduit);
203 disconnected(conduit);
205 } else if(!wcscmp(resp->cmdname, L".notify")) {
206 dc_uimisc_handlenotify(resp);
210 if((ires = dc_interpret(resp)) != NULL)
212 if((dt = dc_findtransfer(ires->argv[0].val.num)) != NULL)
214 if(dt->dir == DC_TRNSD_DOWN)
215 inittrans(conduit, dt);
221 if((ires = dc_interpret(resp)) != NULL)
223 if((dt = dc_findtransfer(ires->argv[0].val.num)) != NULL)
225 if(((dtd = dt->udata) != NULL) && (dtd->ct != NULL))
227 if(dtd->ct->size != dt->size)
228 transfersetsize(dtd->ct, dt->size);
235 if((ires = dc_interpret(resp)) != NULL)
237 if((dt = dc_findtransfer(ires->argv[0].val.num)) != NULL)
239 if(((dtd = dt->udata) != NULL) && (dtd->ct != NULL))
241 if(dtd->ct->pos != dt->curpos)
242 transfersetpos(dtd->ct, dt->curpos);
252 updatewrite(conduit);
255 static int init(struct conduit *conduit)
257 static int inited = 0;
265 data = smalloc(sizeof(*data));
266 memset(data, 0, sizeof(*data));
268 data->gdkread = data->gdkwrite = -1;
269 conduit->cdata = data;
273 static int connect(struct conduit *conduit)
278 data = conduit->cdata;
281 if((host = getenv("DCSERVER")) == NULL)
283 if((data->fd = dc_connect(host, -1)) < 0)
285 data->gdkread = gdk_input_add(data->fd, GDK_INPUT_READ, (void (*)(gpointer, int, GdkInputCondition))dcfdcb, conduit);
286 updatewrite(conduit);
291 static void destroy(struct conduit *conduit)
295 data = conduit->cdata;
296 if(data->gdkread != -1)
297 gdk_input_remove(data->gdkread);
298 if(data->gdkwrite != -1)
299 gdk_input_remove(data->gdkwrite);
307 static struct conduitiface st_conduit_dclib =
314 struct conduitiface *conduit_dclib = &st_conduit_dclib;