diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/lib/cserve/evas_cs_client.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-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.c | 528 |
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 | |||
11 | static Server *cserve = NULL; | ||
12 | static int csrve_init = 0; | ||
13 | static int connect_num = 0; | ||
14 | static int cserve_discon = 0; | ||
15 | |||
16 | static void | ||
17 | pipe_handler(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__) | ||
18 | { | ||
19 | } | ||
20 | |||
21 | static void | ||
22 | pipe_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 | |||
41 | static Server * | ||
42 | server_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 | |||
90 | static void | ||
91 | server_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 | |||
99 | static int | ||
100 | server_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 | |||
130 | static unsigned char * | ||
131 | server_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 | |||
177 | static int | ||
178 | server_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 | |||
215 | EAPI Eina_Bool | ||
216 | evas_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 | |||
231 | EAPI int | ||
232 | evas_cserve_use_get(void) | ||
233 | { | ||
234 | return csrve_init; | ||
235 | } | ||
236 | |||
237 | EAPI Eina_Bool | ||
238 | evas_cserve_have_get(void) | ||
239 | { | ||
240 | if (cserve) return 1; | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | EAPI void | ||
245 | evas_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 | |||
254 | EAPI void | ||
255 | evas_cserve_discon(void) | ||
256 | { | ||
257 | if (cserve) | ||
258 | { | ||
259 | server_disconnect(cserve); | ||
260 | cserve = NULL; | ||
261 | cserve_discon = 1; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | static void | ||
266 | server_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 | |||
281 | EAPI Eina_Bool | ||
282 | evas_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 | |||
347 | EAPI Eina_Bool | ||
348 | evas_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 | |||
387 | EAPI void | ||
388 | evas_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 | |||
412 | EAPI void | ||
413 | evas_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 | |||
434 | EAPI void | ||
435 | evas_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 | |||
456 | EAPI Eina_Bool | ||
457 | evas_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 | |||
477 | EAPI Eina_Bool | ||
478 | evas_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 | |||
487 | EAPI Eina_Bool | ||
488 | evas_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 | |||
508 | EAPI Op_Getinfo_Reply * | ||
509 | evas_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 | ||