aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/cserve/evas_cs_client.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-04 18:41:13 +1000
committerDavid Walter Seikel2012-01-04 18:41:13 +1000
commitdd7595a3475407a7fa96a97393bae8c5220e8762 (patch)
treee341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/lib/cserve/evas_cs_client.c
parentAdd the skeleton. (diff)
downloadSledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/evas/src/lib/cserve/evas_cs_client.c')
-rw-r--r--libraries/evas/src/lib/cserve/evas_cs_client.c528
1 files changed, 528 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/cserve/evas_cs_client.c b/libraries/evas/src/lib/cserve/evas_cs_client.c
new file mode 100644
index 0000000..b24848d
--- /dev/null
+++ b/libraries/evas/src/lib/cserve/evas_cs_client.c
@@ -0,0 +1,528 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <signal.h>
6
7#include "evas_cs.h"
8
9#ifdef EVAS_CSERVE
10
11static Server *cserve = NULL;
12static int csrve_init = 0;
13static int connect_num = 0;
14static int cserve_discon = 0;
15
16static void
17pipe_handler(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
18{
19}
20
21static void
22pipe_handle(int push)
23{
24 static struct sigaction old_action;
25 struct sigaction action;
26
27 if (push)
28 {
29 action.sa_handler = NULL;
30 action.sa_sigaction = pipe_handler;
31 action.sa_flags = SA_RESTART | SA_SIGINFO;
32 sigemptyset(&action.sa_mask);
33 sigaction(SIGPIPE, &action, &old_action);
34 }
35 else
36 {
37 sigaction(SIGPIPE, &old_action, &action);
38 }
39}
40
41static Server *
42server_connect(void)
43{
44 Server *s;
45 char buf[PATH_MAX];
46 int curstate = 0;
47 struct sockaddr_un socket_unix;
48 int socket_unix_len;
49
50 s = calloc(1, sizeof(Server));
51 if (!s) return NULL;
52 s->ch[0].fd = -1;
53 s->ch[1].fd = -1;
54 snprintf(buf, sizeof(buf), "/tmp/.evas-cserve-%x", getuid());
55 s->socket_path = strdup(buf);
56 if (!s->socket_path)
57 {
58 free(s);
59 return NULL;
60 }
61 s->ch[0].fd = socket(AF_UNIX, SOCK_STREAM, 0);
62 if (s->ch[0].fd < 0) goto error;
63 if (fcntl(s->ch[0].fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
64 if (setsockopt(s->ch[0].fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0)
65 goto error;
66 socket_unix.sun_family = AF_UNIX;
67 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
68 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
69 if (connect(s->ch[0].fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) goto error;
70
71 s->ch[1].fd = socket(AF_UNIX, SOCK_STREAM, 0);
72 if (s->ch[1].fd < 0) goto error;
73 if (fcntl(s->ch[1].fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
74 if (setsockopt(s->ch[1].fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0)
75 goto error;
76 socket_unix.sun_family = AF_UNIX;
77 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
78 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
79 if (connect(s->ch[1].fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) goto error;
80
81 return s;
82 error:
83 if (s->ch[0].fd >= 0) close(s->ch[0].fd);
84 if (s->ch[1].fd >= 0) close(s->ch[1].fd);
85 free(s->socket_path);
86 free(s);
87 return NULL;
88}
89
90static void
91server_disconnect(Server *s)
92{
93 close(s->ch[0].fd);
94 close(s->ch[1].fd);
95 free(s->socket_path);
96 free(s);
97}
98
99static int
100server_send(Server *s, int channel, int opcode, int size, unsigned char *data)
101{
102 int ints[3];
103 int num;
104
105 pipe_handle(1);
106 ints[0] = size;
107 ints[1] = opcode;
108 s->ch[channel].req_to++;
109 ints[2] = s->ch[channel].req_to;
110 num = write(s->ch[channel].fd, ints, (sizeof(int) * 3));
111 if (num < 0)
112 {
113 pipe_handle(0);
114 if (cserve) server_disconnect(cserve);
115 cserve = NULL;
116 return 0;
117 }
118 num = write(s->ch[channel].fd, data, size);
119 if (num < 0)
120 {
121 pipe_handle(0);
122 if (cserve) server_disconnect(cserve);
123 cserve = NULL;
124 return 0;
125 }
126 pipe_handle(0);
127 return 1;
128}
129
130static unsigned char *
131server_read(Server *s, int channel, int *opcode, int *size)
132{
133 int ints[3], num, left;
134 unsigned char *data;
135
136 num = read(s->ch[channel].fd, ints, sizeof(int) * 3);
137 if (num != (sizeof(int) * 3))
138 {
139 if (cserve) server_disconnect(cserve);
140 cserve = NULL;
141 return NULL;
142 }
143 *size = ints[0];
144 *opcode = ints[1];
145 if ((*size < 0) || (*size > (1024 * 1024))) return NULL;
146 if (ints[2] != (s->ch[channel].req_from + 1))
147 {
148 ERR("EEK! sequence number mismatch from serer with pid: %i. "
149 "---- num %i is not 1 more than %i"
150 ,
151 s->pid, ints[2], s->ch[channel].req_from);
152 return NULL;
153 }
154 s->ch[channel].req_from++;
155 data = malloc(*size);
156 if (!data) return NULL;
157 num = read(s->ch[channel].fd, data, *size);
158 if (num < 0)
159 {
160 free(data);
161 return NULL;
162 }
163 left = *size - num;
164 while (left > 0)
165 {
166 num = read(s->ch[channel].fd, data + (*size - left), left);
167 if (num < 0)
168 {
169 free(data);
170 return NULL;
171 }
172 left -= num;
173 }
174 return data;
175}
176
177static int
178server_init(Server *s)
179{
180 Op_Init msg, *rep;
181 int opcode;
182 int size;
183
184 msg.pid = getpid();
185 msg.server_id = 0;
186 msg.handle = NULL;
187 if (!server_send(s, 0, OP_INIT, sizeof(msg), (unsigned char *)(&msg)))
188 return 0;
189 rep = (Op_Init *)server_read(s, 0, &opcode, &size);
190 if ((rep) && (opcode == OP_INIT) && (size == sizeof(Op_Init)))
191 {
192 s->pid = rep->pid;
193 s->server_id = rep->server_id;
194 s->main_handle = rep->handle;
195 connect_num++;
196 msg.pid = getpid();
197 msg.server_id = 1;
198 msg.handle = rep->handle;
199 free(rep);
200 if (!server_send(s, 1, OP_INIT, sizeof(msg), (unsigned char *)(&msg)))
201 return 0;
202 rep = (Op_Init *)server_read(s, 1, &opcode, &size);
203 if ((rep) && (opcode == OP_INIT) && (size == sizeof(Op_Init)))
204 {
205 free(rep);
206 return 1;
207 }
208 if (rep) free(rep);
209 return 0;
210 }
211 if (rep) free(rep);
212 return 0;
213}
214
215EAPI Eina_Bool
216evas_cserve_init(void)
217{
218 csrve_init++;
219 if (cserve) return 1;
220 cserve = server_connect();
221 if (!cserve) return 0;
222 if (!server_init(cserve))
223 {
224 if (cserve) server_disconnect(cserve);
225 cserve = NULL;
226 return 0;
227 }
228 return 1;
229}
230
231EAPI int
232evas_cserve_use_get(void)
233{
234 return csrve_init;
235}
236
237EAPI Eina_Bool
238evas_cserve_have_get(void)
239{
240 if (cserve) return 1;
241 return 0;
242}
243
244EAPI void
245evas_cserve_shutdown(void)
246{
247 csrve_init--;
248 if (csrve_init > 0) return;
249 if (!cserve) return;
250 server_disconnect(cserve);
251 cserve = NULL;
252}
253
254EAPI void
255evas_cserve_discon(void)
256{
257 if (cserve)
258 {
259 server_disconnect(cserve);
260 cserve = NULL;
261 cserve_discon = 1;
262 }
263}
264
265static void
266server_reinit(void)
267{
268 if (cserve) return;
269 if (cserve_discon) return;
270 cserve = server_connect();
271 if (cserve)
272 {
273 if (!server_init(cserve))
274 {
275 if (cserve) server_disconnect(cserve);
276 cserve = NULL;
277 }
278 }
279}
280
281EAPI Eina_Bool
282evas_cserve_image_load(Image_Entry *ie, const char *file, const char *key, RGBA_Image_Loadopts *lopt)
283{
284 Op_Load msg;
285 Op_Load_Reply *rep;
286 unsigned char *buf;
287 char fbuf[PATH_MAX], wdb[PATH_MAX];
288 int flen, klen;
289 int opcode;
290 int size;
291
292 if (csrve_init > 0) server_reinit();
293 else return 0;
294 if (!cserve) return 0;
295 if (!key) key = "";
296 memset(&msg, 0, sizeof(msg));
297 msg.lopt.scale_down_by = lopt->scale_down_by;
298 msg.lopt.dpi = lopt->dpi;
299 msg.lopt.w = lopt->w;
300 msg.lopt.h = lopt->h;
301 msg.lopt.region.x = lopt->region.x;
302 msg.lopt.region.y = lopt->region.y;
303 msg.lopt.region.w = lopt->region.w;
304 msg.lopt.region.h = lopt->region.h;
305 msg.lopt.orientation = lopt->orientation;
306 if (file[0] != '/')
307 {
308 if (getcwd(wdb, sizeof(wdb)))
309 {
310 snprintf(fbuf, sizeof(buf), "%s/%s", wdb, file);
311 file = fbuf;
312 }
313 }
314 if (!realpath(file, wdb)) file = wdb;
315 flen = strlen(file) + 1;
316 klen = strlen(key) + 1;
317 buf = malloc(sizeof(msg) + flen + klen);
318 if (!buf) return 0;
319 memcpy(buf, &msg, sizeof(msg));
320 memcpy(buf + sizeof(msg), file, flen);
321 memcpy(buf + sizeof(msg) + flen, key, klen);
322 if (!server_send(cserve, ie->channel, OP_LOAD,
323 sizeof(msg) + flen + klen,
324 buf))
325 {
326 free(buf);
327 return 0;
328 }
329 free(buf);
330 if (!cserve) return 0;
331 rep = (Op_Load_Reply *)server_read(cserve, ie->channel, &opcode, &size);
332 if ((rep) && (opcode == OP_LOAD) && (size == sizeof(Op_Load_Reply)))
333 {
334 ie->w = rep->image.w;
335 ie->h = rep->image.h;
336 ie->flags.alpha = rep->image.alpha;
337 ie->data1 = rep->handle;
338 }
339 if (rep) free(rep);
340 if (!ie->data1) return 0;
341 ie->connect_num = connect_num;
342 if (cserve)
343 ie->server_id = cserve->server_id;
344 return 1;
345}
346
347EAPI Eina_Bool
348evas_cserve_image_data_load(Image_Entry *ie)
349{
350 Op_Loaddata msg;
351 Op_Loaddata_Reply *rep;
352 int opcode;
353 int size;
354 if (csrve_init > 0) server_reinit();
355 else return 0;
356 if (!cserve) return 0;
357 if (!ie->data1) return 0;
358 if (cserve->server_id != ie->server_id)
359 {
360 ie->data1 = NULL;
361 if (!evas_cserve_image_load(ie, ie->file, ie->key, &(ie->load_opts)))
362 return 0;
363 }
364 if (ie->connect_num != connect_num) return 0;
365 memset(&msg, 0, sizeof(msg));
366 msg.handle = ie->data1;
367 msg.server_id = cserve->server_id;
368 if (!server_send(cserve, ie->channel, OP_LOADDATA, sizeof(msg), (unsigned char *)(&msg)))
369 return 0;
370 if (!cserve) return 0;
371 rep = (Op_Loaddata_Reply *)server_read(cserve, ie->channel, &opcode, &size);
372 if ((rep) && (opcode == OP_LOADDATA) && (size == sizeof(Op_Loaddata_Reply)))
373 {
374 if (rep->mem.size <= 0)
375 {
376 free(rep);
377 return 0;
378 }
379 ie->data2 = evas_cserve_mem_open(cserve->pid, rep->mem.id, NULL, rep->mem.size, 0);
380 free(rep);
381 return 1;
382 }
383 if (rep) free(rep);
384 return 0;
385}
386
387EAPI void
388evas_cserve_image_free(Image_Entry *ie)
389{
390 Op_Unload msg;
391
392 if (csrve_init > 0) server_reinit();
393 else return;
394 if (!cserve) return;
395 if (!ie->data1) return;
396 memset(&msg, 0, sizeof(msg));
397 msg.handle = ie->data1;
398 msg.server_id = cserve->server_id;
399 if (ie->data2) evas_cserve_image_unload(ie);
400 if (cserve)
401 {
402 if (ie->connect_num == connect_num)
403 {
404 if (ie->server_id == cserve->server_id)
405 server_send(cserve, ie->channel, OP_UNLOAD, sizeof(msg), (unsigned char *)(&msg));
406 }
407 }
408 ie->data1 = NULL;
409 ie->data2 = NULL;
410}
411
412EAPI void
413evas_cserve_image_unload(Image_Entry *ie)
414{
415 Op_Unloaddata msg;
416
417 if (csrve_init > 0) server_reinit();
418 else return;
419 if (!cserve) return;
420 if (!ie->data1) return;
421 if (ie->connect_num != connect_num) return;
422 memset(&msg, 0, sizeof(msg));
423 msg.handle = ie->data1;
424 msg.server_id = cserve->server_id;
425 if (ie->data2) evas_cserve_mem_close(ie->data2);
426 ie->data2 = NULL;
427 if (ie->connect_num == connect_num)
428 {
429 if (ie->server_id == cserve->server_id)
430 server_send(cserve, ie->channel, OP_UNLOADDATA, sizeof(msg), (unsigned char *)(&msg));
431 }
432}
433
434EAPI void
435evas_cserve_image_useless(Image_Entry *ie)
436{
437 Op_Unloaddata msg;
438
439 if (csrve_init > 0) server_reinit();
440 else return;
441 if (!cserve) return;
442 if (!ie->data1) return;
443 if (ie->connect_num != connect_num) return;
444 memset(&msg, 0, sizeof(msg));
445 msg.handle = ie->data1;
446 msg.server_id = cserve->server_id;
447 if (ie->data2) evas_cserve_mem_close(ie->data2);
448 ie->data2 = NULL;
449 if (ie->connect_num == connect_num)
450 {
451 if (ie->server_id == cserve->server_id)
452 server_send(cserve, ie->channel, OP_USELESSDATA, sizeof(msg), (unsigned char *)(&msg));
453 }
454}
455
456EAPI Eina_Bool
457evas_cserve_raw_config_get(Op_Getconfig_Reply *config)
458{
459 Op_Getconfig_Reply *rep;
460 int opcode;
461 int size;
462 if (csrve_init > 0) server_reinit();
463 else return 0;
464 if (!cserve) return 0;
465 if (!server_send(cserve, 0, OP_GETCONFIG, 0, NULL)) return 0;
466 rep = (Op_Getconfig_Reply *)server_read(cserve, 0, &opcode, &size);
467 if ((rep) && (opcode == OP_GETCONFIG) && (size == sizeof(Op_Getconfig_Reply)))
468 {
469 memcpy(config, rep, sizeof(Op_Getconfig_Reply));
470 free(rep);
471 return 1;
472 }
473 if (rep) free(rep);
474 return 0;
475}
476
477EAPI Eina_Bool
478evas_cserve_raw_config_set(Op_Setconfig *config)
479{
480 if (csrve_init > 0) server_reinit();
481 else return 0;
482 if (!cserve) return 0;
483 if (!server_send(cserve, 0, OP_SETCONFIG, sizeof(Op_Setconfig), (unsigned char *)config)) return 0;
484 return 1;
485}
486
487EAPI Eina_Bool
488evas_cserve_raw_stats_get(Op_Getstats_Reply *stats)
489{
490 Op_Getstats_Reply *rep;
491 int opcode;
492 int size;
493 if (csrve_init > 0) server_reinit();
494 else return 0;
495 if (!cserve) return 0;
496 if (!server_send(cserve, 0, OP_GETSTATS, 0, NULL)) return 0;
497 rep = (Op_Getstats_Reply *)server_read(cserve, 0, &opcode, &size);
498 if ((rep) && (opcode == OP_GETSTATS) && (size == sizeof(Op_Getstats_Reply)))
499 {
500 memcpy(stats, rep, sizeof(Op_Getstats_Reply));
501 free(rep);
502 return 1;
503 }
504 if (rep) free(rep);
505 return 0;
506}
507
508EAPI Op_Getinfo_Reply *
509evas_cserve_raw_info_get(void)
510{
511 Op_Getinfo_Reply *rep;
512 int opcode;
513 int size;
514 if (csrve_init > 0) server_reinit();
515 else return NULL;
516 if (!cserve) return NULL;
517 if (!server_send(cserve, 0, OP_GETINFO, 0, NULL)) return NULL;
518 rep = (Op_Getinfo_Reply *)server_read(cserve, 0, &opcode, &size);
519 if ((rep) && (opcode == OP_GETINFO) &&
520 (size >= (int)sizeof(Op_Getinfo_Reply)))
521 {
522 return rep;
523 }
524 if (rep) free(rep);
525 return NULL;
526}
527
528#endif