summaryrefslogtreecommitdiff
path: root/src/lib/evas/cserve2/evas_cs2_client.c
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2013-06-04 19:40:36 +0900
committerCedric Bail <cedric.bail@samsung.com>2013-06-04 20:20:55 +0900
commita5329fc680101df9234df44f61b0db2fc42f8a7c (patch)
treeabfe6dc16d51f1985c4ffa4ff393cc2a7af08e4c /src/lib/evas/cserve2/evas_cs2_client.c
parent20834f09251c41c1e06ff2d2ff9c4c2e31ffd890 (diff)
evas/cserve2: add lots of error checks in the client side.
It seems some images are fully loaded even when we request only preload. The load handler will take care of both cases anyway. Signed-off-by: Cedric Bail <cedric.bail@samsung.com>
Diffstat (limited to 'src/lib/evas/cserve2/evas_cs2_client.c')
-rw-r--r--src/lib/evas/cserve2/evas_cs2_client.c380
1 files changed, 257 insertions, 123 deletions
diff --git a/src/lib/evas/cserve2/evas_cs2_client.c b/src/lib/evas/cserve2/evas_cs2_client.c
index b1997a8e6b..646cd83229 100644
--- a/src/lib/evas/cserve2/evas_cs2_client.c
+++ b/src/lib/evas/cserve2/evas_cs2_client.c
@@ -17,7 +17,7 @@
17 17
18#ifdef EVAS_CSERVE2 18#ifdef EVAS_CSERVE2
19 19
20typedef void (*Op_Callback)(void *data, const void *msg); 20typedef void (*Op_Callback)(void *data, const void *msg, int size);
21 21
22struct _File_Entry { 22struct _File_Entry {
23 unsigned int file_id; 23 unsigned int file_id;
@@ -92,7 +92,7 @@ _server_connect(void)
92 92
93 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 93 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
94 { 94 {
95 ERR("socket"); 95 ERR("cserve2 socket creation failed with error [%d] %s", errno, strerror(errno));
96 return EINA_FALSE; 96 return EINA_FALSE;
97 } 97 }
98 98
@@ -108,8 +108,15 @@ _server_connect(void)
108 for (;;) 108 for (;;)
109 { 109 {
110 if (connect(s, (struct sockaddr *)&remote, len) != -1) break; 110 if (connect(s, (struct sockaddr *)&remote, len) != -1) break;
111 ERR("cserve connect failed. retrying."); 111 ERR("cserve2 connect failed: [%d] %s. Retrying...", errno, strerror(errno));
112
112 usleep(1000); 113 usleep(1000);
114
115 /* FIXME: Here we should identify the error, maybe signal the daemon manager
116 * that we need cserve2 to [re]start or just quit and return false.
117 * There probably should be a timeout of some sort also...
118 * -- jpeg
119 */
113 } 120 }
114 121
115 fcntl(s, F_SETFL, O_NONBLOCK); 122 fcntl(s, F_SETFL, O_NONBLOCK);
@@ -123,7 +130,8 @@ _server_connect(void)
123static void 130static void
124_server_disconnect(void) 131_server_disconnect(void)
125{ 132{
126 close(socketfd); 133 if (socketfd != -1)
134 close(socketfd);
127 socketfd = -1; 135 socketfd = -1;
128} 136}
129 137
@@ -154,6 +162,7 @@ _server_safe_send(int fd, const void *data, int size)
154 { 162 {
155 if ((errno == EAGAIN) || (errno == EINTR)) 163 if ((errno == EAGAIN) || (errno == EINTR))
156 continue; 164 continue;
165 DBG("send() failed with error [%d] %s", errno, strerror(errno));
157 return EINA_FALSE; 166 return EINA_FALSE;
158 } 167 }
159 sent += ret; 168 sent += ret;
@@ -276,7 +285,7 @@ _next_rid(void)
276} 285}
277 286
278static unsigned int 287static unsigned int
279_server_dispatch(void) 288_server_dispatch(Eina_Bool *failed)
280{ 289{
281 int size; 290 int size;
282 unsigned int rid; 291 unsigned int rid;
@@ -286,7 +295,11 @@ _server_dispatch(void)
286 295
287 msg = _server_read(&size); 296 msg = _server_read(&size);
288 if (!msg) 297 if (!msg)
289 return 0; 298 {
299 *failed = EINA_TRUE;
300 return 0;
301 }
302 *failed = EINA_FALSE;
290 303
291 EINA_LIST_FOREACH_SAFE(_requests, l, l_next, cr) 304 EINA_LIST_FOREACH_SAFE(_requests, l, l_next, cr)
292 { 305 {
@@ -295,7 +308,7 @@ _server_dispatch(void)
295 308
296 _requests = eina_list_remove_list(_requests, l); 309 _requests = eina_list_remove_list(_requests, l);
297 if (cr->cb) 310 if (cr->cb)
298 cr->cb(cr->data, msg); 311 cr->cb(cr->data, msg, size);
299 free(cr); 312 free(cr);
300 } 313 }
301 314
@@ -305,32 +318,75 @@ _server_dispatch(void)
305 return rid; 318 return rid;
306} 319}
307 320
308static void 321static Eina_Bool
309_server_dispatch_until(unsigned int rid) 322_server_dispatch_until(unsigned int rid)
310{ 323{
311 Eina_Bool done = EINA_FALSE; 324 Eina_Bool failed;
325 fd_set rfds;
326 unsigned int rrid;
327 struct timeval tv;
312 328
313 while (!done) 329 while (1)
314 { 330 {
315 if (_server_dispatch() == rid) 331 rrid = _server_dispatch(&failed);
316 done = EINA_TRUE; 332 if (rrid == rid) break;
333 else if (failed)
334 {
335 int sel;
336
337 //DBG("Waiting for request %d...", rid);
338 FD_ZERO(&rfds);
339 FD_SET(socketfd, &rfds);
340 tv.tv_sec = 1;
341 tv.tv_usec = 0;
342 sel = select(socketfd + 1, &rfds, NULL, NULL, &tv);
343 if (sel == -1)
344 {
345 ERR("select() failed: [%d] %s", errno, strerror(errno));
346 /* FIXME: Depending on the error, we should probably try to reconnect to the server.
347 * Or even ask to [re]start the daemon.
348 * Or maybe just return EINA_FALSE after some timeout?
349 * -- jpeg
350 */
351 }
352 }
317 } 353 }
354 return EINA_TRUE;
318} 355}
319 356
320static void 357static void
321_image_opened_cb(void *data, const void *msg_received) 358_image_opened_cb(void *data, const void *msg_received, int size)
322{ 359{
323 const Msg_Base *answer = msg_received; 360 const Msg_Base *answer = msg_received;
324 const Msg_Opened *msg = msg_received; 361 const Msg_Opened *msg = msg_received;
325 Image_Entry *ie = data; 362 Image_Entry *ie = data;
326 363
364 /* FIXME: Maybe we could have more asynchronous loading in the server side
365 * and so we would have to check that open_rid is equal to answer->rid.
366 * -- jpeg
367 */
368 //DBG("Received OPENED for RID: %d [open_rid: %d]", answer->rid, ie->open_rid);
369 if (answer->rid != ie->open_rid)
370 WRN("Message rid (%d) differs from expected rid (open_rid: %d)", answer->rid, ie->open_rid);
327 ie->open_rid = 0; 371 ie->open_rid = 0;
328 372
329 if (answer->type == CSERVE2_ERROR) 373 if (answer->type != CSERVE2_OPENED)
330 { 374 {
331 const Msg_Error *msg_error = msg_received; 375 if (answer->type == CSERVE2_ERROR)
332 ERR("Couldn't open image: '%s':'%s'; error: %d", 376 {
333 ie->file, ie->key, msg_error->error); 377 const Msg_Error *msg_error = msg_received;
378 ERR("Couldn't open image: '%s':'%s'; error: %d",
379 ie->file, ie->key, msg_error->error);
380 }
381 else
382 ERR("Invalid message type received: %d (%s)", answer->type, __FUNCTION__);
383 free(ie->data1);
384 ie->data1 = NULL;
385 return;
386 }
387 else if (size < (int) sizeof(*msg))
388 {
389 ERR("Received message is too small");
334 free(ie->data1); 390 free(ie->data1);
335 ie->data1 = NULL; 391 ie->data1 = NULL;
336 return; 392 return;
@@ -345,12 +401,16 @@ _image_opened_cb(void *data, const void *msg_received)
345} 401}
346 402
347static void 403static void
348_loaded_handle(Image_Entry *ie, const Msg_Loaded *msg) 404_loaded_handle(Image_Entry *ie, const Msg_Loaded *msg, int size)
349{ 405{
350 Data_Entry *dentry = ie->data2; 406 Data_Entry *dentry = ie->data2;
407 RGBA_Image *im = (RGBA_Image *)ie;
351 const char *shmpath; 408 const char *shmpath;
352 409
353 shmpath = ((const char *)msg) + sizeof(*msg); 410 shmpath = ((const char *)msg) + sizeof(*msg);
411 if ((size < (int) sizeof(*msg) + 1)
412 || (strnlen(shmpath, size - sizeof(*msg)) >= (size - sizeof(*msg))))
413 goto fail;
354 414
355 // dentry->shm.path = strdup(shmpath); 415 // dentry->shm.path = strdup(shmpath);
356 dentry->shm.mmap_offset = msg->shm.mmap_offset; 416 dentry->shm.mmap_offset = msg->shm.mmap_offset;
@@ -360,11 +420,7 @@ _loaded_handle(Image_Entry *ie, const Msg_Loaded *msg)
360 420
361 dentry->shm.f = eina_file_open(shmpath, EINA_TRUE); 421 dentry->shm.f = eina_file_open(shmpath, EINA_TRUE);
362 if (!dentry->shm.f) 422 if (!dentry->shm.f)
363 { 423 goto fail;
364 free(dentry);
365 ie->data2 = NULL;
366 return;
367 }
368 424
369 dentry->shm.data = eina_file_map_new(dentry->shm.f, EINA_FILE_WILLNEED, 425 dentry->shm.data = eina_file_map_new(dentry->shm.f, EINA_FILE_WILLNEED,
370 dentry->shm.mmap_offset, 426 dentry->shm.mmap_offset,
@@ -373,67 +429,95 @@ _loaded_handle(Image_Entry *ie, const Msg_Loaded *msg)
373 if (!dentry->shm.data) 429 if (!dentry->shm.data)
374 { 430 {
375 eina_file_close(dentry->shm.f); 431 eina_file_close(dentry->shm.f);
376 free(dentry); 432 goto fail;
377 ie->data2 = NULL;
378 } 433 }
379 434
380 if (ie->data2) 435 im->image.data = evas_cserve2_image_data_get(ie);
381 { 436 ie->flags.alpha_sparse = msg->alpha_sparse;
382 RGBA_Image *im = (RGBA_Image *)ie; 437 ie->flags.loaded = EINA_TRUE;
383 im->image.data = evas_cserve2_image_data_get(ie); 438 im->image.no_free = 1;
384 ie->flags.alpha_sparse = msg->alpha_sparse; 439 return;
385 ie->flags.loaded = EINA_TRUE; 440
386 im->image.no_free = 1; 441fail:
387 } 442 ERR("Failed in %s", __FUNCTION__);
443 free(ie->data2);
444 ie->data2 = NULL;
388} 445}
389 446
390static void 447static void
391_image_loaded_cb(void *data, const void *msg_received) 448_image_loaded_cb(void *data, const void *msg_received, int size)
392{ 449{
393 const Msg_Base *answer = msg_received; 450 const Msg_Base *answer = msg_received;
394 const Msg_Loaded *msg = msg_received; 451 const Msg_Loaded *msg = msg_received;
395 Image_Entry *ie = data; 452 Image_Entry *ie = data;
396 453
454 //DBG("Received LOADED for RID: %d [load_rid: %d]", answer->rid, ie->load_rid);
455 if (answer->rid != ie->load_rid)
456 WRN("Message rid (%d) differs from expected rid (load_rid: %d)", answer->rid, ie->load_rid);
397 ie->load_rid = 0; 457 ie->load_rid = 0;
398 458
399 if (!ie->data2) 459 if (!ie->data2)
400 return; 460 {
461 ERR("No data2 for loaded file");
462 return;
463 }
401 464
402 if (answer->type == CSERVE2_ERROR) 465 if (answer->type != CSERVE2_LOADED)
403 { 466 {
404 const Msg_Error *msg_error = msg_received; 467 if (answer->type == CSERVE2_ERROR)
405 ERR("Couldn't load image: '%s':'%s'; error: %d", 468 {
406 ie->file, ie->key, msg_error->error); 469 const Msg_Error *msg_error = msg_received;
470 ERR("Couldn't load image: '%s':'%s'; error: %d",
471 ie->file, ie->key, msg_error->error);
472 }
473 else
474 ERR("Invalid message type received: %d (%s)", answer->type, __FUNCTION__);
407 free(ie->data2); 475 free(ie->data2);
408 ie->data2 = NULL; 476 ie->data2 = NULL;
409 return; 477 return;
410 } 478 }
411 479
412 _loaded_handle(ie, msg); 480 _loaded_handle(ie, msg, size);
413} 481}
414 482
415static void 483static void
416_image_preloaded_cb(void *data, const void *msg_received) 484_image_preloaded_cb(void *data, const void *msg_received, int size)
417{ 485{
418 const Msg_Base *answer = msg_received; 486 const Msg_Base *answer = msg_received;
419 Image_Entry *ie = data; 487 Image_Entry *ie = data;
420 Data_Entry *dentry = ie->data2; 488 Data_Entry *dentry = ie->data2;
421 489
422 DBG("Received PRELOADED for RID: %d", answer->rid); 490 //DBG("Received PRELOADED for RID: %d [preload_rid: %d]", answer->rid, ie->preload_rid);
491 if (answer->rid != ie->preload_rid)
492 WRN("Message rid (%d) differs from expected rid (preload_rid: %d)", answer->rid, ie->preload_rid);
423 ie->preload_rid = 0; 493 ie->preload_rid = 0;
424 494
425 if (answer->type == CSERVE2_ERROR) 495 if (!ie->data2)
496 {
497 ERR("No data2 for preloaded file");
498 return;
499 }
500
501 if (answer->type != CSERVE2_PRELOAD &&
502 answer->type != CSERVE2_LOADED)
426 { 503 {
427 const Msg_Error *msg_error = msg_received; 504 if (answer->type == CSERVE2_ERROR)
428 ERR("Couldn't preload image: '%s':'%s'; error: %d", 505 {
429 ie->file, ie->key, msg_error->error); 506 const Msg_Error *msg_error = msg_received;
430 dentry->preloaded_cb(data, EINA_FALSE); 507 ERR("Couldn't preload image: '%s':'%s'; error: %d",
508 ie->file, ie->key, msg_error->error);
509 }
510 else
511 ERR("Invalid message type received: %d (%s)", answer->type, __FUNCTION__);
512 if (dentry->preloaded_cb)
513 dentry->preloaded_cb(data, EINA_FALSE);
431 dentry->preloaded_cb = NULL; 514 dentry->preloaded_cb = NULL;
432 return; 515 return;
433 } 516 }
434 517
435 _loaded_handle(ie, msg_received); 518 _loaded_handle(ie, msg_received, size);
436 519
520 dentry = ie->data2;
437 if (dentry && (dentry->preloaded_cb)) 521 if (dentry && (dentry->preloaded_cb))
438 { 522 {
439 dentry->preloaded_cb(data, EINA_TRUE); 523 dentry->preloaded_cb(data, EINA_TRUE);
@@ -441,45 +525,46 @@ _image_preloaded_cb(void *data, const void *msg_received)
441 } 525 }
442} 526}
443 527
444static const char * 528static int
445_build_absolute_path(const char *path, char buf[], int size) 529_build_absolute_path(const char *path, char buf[], int size)
446{ 530{
447 char *p; 531 char *p;
448 int len; 532 int len;
449 533
450 if (!path) 534 if (!path)
451 return NULL; 535 return 0;
452 536
453 p = buf; 537 p = buf;
454 538
455 if (path[0] == '/') 539 if (path[0] == '/')
456 strncpy(p, path, size); 540 len = eina_strlcpy(p, path, size);
457 else if (path[0] == '~') 541 else if (path[0] == '~')
458 { 542 {
459 const char *home = getenv("HOME"); 543 const char *home = getenv("HOME");
460 if (!home) 544 if (!home)
461 return NULL; 545 return 0;
462 strncpy(p, home, size); 546 len = eina_strlcpy(p, home, size);
463 len = strlen(p);
464 size -= len + 1; 547 size -= len + 1;
465 p += len; 548 p += len;
466 p[0] = '/'; 549 p[0] = '/';
467 p++; 550 p++;
468 strncpy(p, path + 2, size); 551 len++;
552 len += eina_strlcpy(p, path + 2, size);
469 } 553 }
470 else 554 else
471 { 555 {
472 if (!getcwd(p, size)) 556 if (!getcwd(p, size))
473 return NULL; 557 return 0;
474 len = strlen(p); 558 len = strlen(p);
475 size -= len + 1; 559 size -= len + 1;
476 p += len; 560 p += len;
477 p[0] = '/'; 561 p[0] = '/';
478 p++; 562 p++;
479 strncpy(p, path, size); 563 len++;
564 len += eina_strlcpy(p, path, size);
480 } 565 }
481 566
482 return buf; 567 return len;
483} 568}
484 569
485static unsigned int 570static unsigned int
@@ -498,19 +583,21 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key, Evas
498 return 0; 583 return 0;
499 } 584 }
500 585
501 if (!key) key = ""; 586 flen = _build_absolute_path(file, filebuf, sizeof(filebuf));
587 if (!flen)
588 {
589 ERR("Could not find absolute path for %s", file);
590 return 0;
591 }
592 flen++;
502 593
503 _build_absolute_path(file, filebuf, sizeof(filebuf)); 594 if (!key) key = "";
504 595
505 fentry = calloc(1, sizeof(*fentry)); 596 fentry = calloc(1, sizeof(*fentry));
506 597
507 memset(&msg_open, 0, sizeof(msg_open)); 598 memset(&msg_open, 0, sizeof(msg_open));
508 599
509 fentry->file_id = ++_file_id; 600 fentry->file_id = ++_file_id;
510 if (fentry->file_id == 0)
511 fentry->file_id = ++_file_id;
512
513 flen = strlen(filebuf) + 1;
514 klen = strlen(key) + 1; 601 klen = strlen(key) + 1;
515 602
516 msg_open.base.rid = _next_rid(); 603 msg_open.base.rid = _next_rid();
@@ -581,7 +668,7 @@ _image_setopts_server_send(Image_Entry *ie)
581 msg.opts.scale_hint = ie->load_opts.scale_load.scale_hint; 668 msg.opts.scale_hint = ie->load_opts.scale_load.scale_hint;
582 msg.opts.orientation = ie->load_opts.orientation; 669 msg.opts.orientation = ie->load_opts.orientation;
583 670
584 if (!_server_send(&msg, sizeof(msg), 0, NULL)) 671 if (!_server_send(&msg, sizeof(msg), NULL, NULL))
585 return 0; 672 return 0;
586 673
587 ie->data2 = dentry; 674 ie->data2 = dentry;
@@ -600,7 +687,7 @@ _image_load_server_send(Image_Entry *ie)
600 687
601 if (!ie->data1) 688 if (!ie->data1)
602 { 689 {
603 ERR("No data for opened file."); 690 ERR("No data1 for opened file.");
604 return 0; 691 return 0;
605 } 692 }
606 693
@@ -731,6 +818,9 @@ evas_cserve2_image_load(Image_Entry *ie, const char *file, const char *key, Evas
731{ 818{
732 unsigned int rid; 819 unsigned int rid;
733 820
821 if (!ie)
822 return EINA_FALSE;
823
734 rid = _image_open_server_send(ie, file, key, lopt); 824 rid = _image_open_server_send(ie, file, key, lopt);
735 if (!rid) 825 if (!rid)
736 return EINA_FALSE; 826 return EINA_FALSE;
@@ -750,15 +840,18 @@ evas_cserve2_image_load(Image_Entry *ie, const char *file, const char *key, Evas
750int 840int
751evas_cserve2_image_load_wait(Image_Entry *ie) 841evas_cserve2_image_load_wait(Image_Entry *ie)
752{ 842{
843 if (!ie)
844 return CSERVE2_GENERIC;
845
753 if (ie->open_rid) 846 if (ie->open_rid)
754 { 847 {
755 _server_dispatch_until(ie->open_rid); 848 if (!_server_dispatch_until(ie->open_rid))
849 return CSERVE2_GENERIC;
756 if (!ie->data1) 850 if (!ie->data1)
757 return CSERVE2_GENERIC; 851 return CSERVE2_GENERIC;
758 return CSERVE2_NONE;
759 } 852 }
760 else 853
761 return CSERVE2_GENERIC; 854 return CSERVE2_NONE;
762} 855}
763 856
764Eina_Bool 857Eina_Bool
@@ -766,6 +859,9 @@ evas_cserve2_image_data_load(Image_Entry *ie)
766{ 859{
767 unsigned int rid; 860 unsigned int rid;
768 861
862 if (!ie)
863 return EINA_FALSE;
864
769 rid = _image_load_server_send(ie); 865 rid = _image_load_server_send(ie);
770 if (!rid) 866 if (!rid)
771 return EINA_FALSE; 867 return EINA_FALSE;
@@ -778,11 +874,21 @@ evas_cserve2_image_data_load(Image_Entry *ie)
778 return EINA_FALSE; 874 return EINA_FALSE;
779} 875}
780 876
781void 877int
782evas_cserve2_image_load_data_wait(Image_Entry *ie) 878evas_cserve2_image_load_data_wait(Image_Entry *ie)
783{ 879{
880 if (!ie)
881 return CSERVE2_GENERIC;
882
784 if (ie->load_rid) 883 if (ie->load_rid)
785 _server_dispatch_until(ie->load_rid); 884 {
885 if (!_server_dispatch_until(ie->load_rid))
886 return CSERVE2_GENERIC;
887 if (!ie->data2)
888 return CSERVE2_GENERIC;
889 }
890
891 return CSERVE2_NONE;
786} 892}
787 893
788Eina_Bool 894Eina_Bool
@@ -790,7 +896,7 @@ evas_cserve2_image_preload(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_
790{ 896{
791 unsigned int rid; 897 unsigned int rid;
792 898
793 if (!ie->data1) 899 if (!ie || !ie->data1)
794 return EINA_FALSE; 900 return EINA_FALSE;
795 901
796 rid = _image_preload_server_send(ie, preloaded_cb); 902 rid = _image_preload_server_send(ie, preloaded_cb);
@@ -805,7 +911,7 @@ evas_cserve2_image_preload(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_
805void 911void
806evas_cserve2_image_free(Image_Entry *ie) 912evas_cserve2_image_free(Image_Entry *ie)
807{ 913{
808 if (!ie->data1) 914 if (!ie || !ie->data1)
809 return; 915 return;
810 916
811 if (!_image_close_server_send(ie)) 917 if (!_image_close_server_send(ie))
@@ -815,7 +921,7 @@ evas_cserve2_image_free(Image_Entry *ie)
815void 921void
816evas_cserve2_image_unload(Image_Entry *ie) 922evas_cserve2_image_unload(Image_Entry *ie)
817{ 923{
818 if (!ie->data2) 924 if (!ie || !ie->data2)
819 return; 925 return;
820 926
821 if (!_image_unload_server_send(ie)) 927 if (!_image_unload_server_send(ie))
@@ -876,21 +982,6 @@ struct _CS_Glyph_Out
876}; 982};
877 983
878static void 984static void
879_font_entry_free(Font_Entry *fe)
880{
881 int i;
882
883 for (i = 0; i < 3; i++)
884 if (fe->fash[i])
885 fash_gl_free(fe->fash[i]);
886
887 eina_stringshare_del(fe->source);
888 eina_stringshare_del(fe->name);
889 eina_hash_free(fe->glyphs_maps);
890 free(fe);
891}
892
893static void
894_glyphs_map_free(Glyph_Map *m) 985_glyphs_map_free(Glyph_Map *m)
895{ 986{
896 eina_file_map_free(m->map, m->data); 987 eina_file_map_free(m->map, m->data);
@@ -906,6 +997,7 @@ _glyph_out_free(void *gl)
906 997
907 if (glout->map) 998 if (glout->map)
908 { 999 {
1000 // FIXME: Invalid write of size 8 here (64 bit machine)
909 eina_clist_remove(&glout->map_entry); 1001 eina_clist_remove(&glout->map_entry);
910 if (eina_clist_empty(&glout->map->glyphs)) 1002 if (eina_clist_empty(&glout->map->glyphs))
911 { 1003 {
@@ -918,15 +1010,41 @@ _glyph_out_free(void *gl)
918 free(glout); 1010 free(glout);
919} 1011}
920 1012
1013static Eina_Bool
1014_glyphs_maps_foreach_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
1015{
1016 Glyph_Map *m = data;
1017
1018 _glyphs_map_free(m);
1019 return EINA_TRUE;
1020}
1021
1022static void
1023_font_entry_free(Font_Entry *fe)
1024{
1025 int i;
1026
1027 for (i = 0; i < 3; i++)
1028 if (fe->fash[i])
1029 fash_gl_free(fe->fash[i]);
1030
1031 eina_stringshare_del(fe->source);
1032 eina_stringshare_del(fe->name);
1033 eina_hash_foreach(fe->glyphs_maps, _glyphs_maps_foreach_free, NULL);
1034 eina_hash_free(fe->glyphs_maps);
1035 free(fe);
1036}
1037
921static void 1038static void
922_font_loaded_cb(void *data, const void *msg) 1039_font_loaded_cb(void *data, const void *msg, int size)
923{ 1040{
924 const Msg_Base *m = msg; 1041 const Msg_Base *m = msg;
925 Font_Entry *fe = data; 1042 Font_Entry *fe = data;
926 1043
927 fe->rid = 0; 1044 fe->rid = 0;
928 1045
929 if (m->type == CSERVE2_ERROR) 1046 if ((size < (int) sizeof(*m))
1047 || (m->type == CSERVE2_ERROR))
930 fe->failed = EINA_TRUE; 1048 fe->failed = EINA_TRUE;
931} 1049}
932 1050
@@ -937,7 +1055,7 @@ _font_load_server_send(Font_Entry *fe, Message_Type type)
937 int source_len, path_len, size; 1055 int source_len, path_len, size;
938 char *buf; 1056 char *buf;
939 unsigned int ret = 0; 1057 unsigned int ret = 0;
940 void (*cb)(void *data, const void *msg) = NULL; 1058 Op_Callback cb = NULL;
941 1059
942 if (!cserve2_init) 1060 if (!cserve2_init)
943 return 0; 1061 return 0;
@@ -1005,9 +1123,11 @@ evas_cserve2_font_load(const char *source, const char *name, int size, int dpi,
1005int 1123int
1006evas_cserve2_font_load_wait(Font_Entry *fe) 1124evas_cserve2_font_load_wait(Font_Entry *fe)
1007{ 1125{
1008 _server_dispatch_until(fe->rid); 1126 if (!_server_dispatch_until(fe->rid))
1127 return CSERVE2_GENERIC;
1009 1128
1010 if (fe->failed) return CSERVE2_GENERIC; 1129 if (fe->failed)
1130 return CSERVE2_GENERIC;
1011 1131
1012 return CSERVE2_NONE; 1132 return CSERVE2_NONE;
1013} 1133}
@@ -1020,7 +1140,7 @@ evas_cserve2_font_free(Font_Entry *fe)
1020 if (!fe) return; 1140 if (!fe) return;
1021 1141
1022 ret = evas_cserve2_font_load_wait(fe); 1142 ret = evas_cserve2_font_load_wait(fe);
1023 if (ret == CSERVE2_GENERIC) 1143 if (ret != CSERVE2_NONE)
1024 { 1144 {
1025 ERR("Failed to wait loading font '%s'.", fe->name); 1145 ERR("Failed to wait loading font '%s'.", fe->name);
1026 return; 1146 return;
@@ -1039,31 +1159,40 @@ typedef struct
1039} Glyph_Request_Data; 1159} Glyph_Request_Data;
1040 1160
1041static void 1161static void
1042_glyph_request_cb(void *data, const void *msg) 1162_glyph_request_cb(void *data, const void *msg, int size)
1043{ 1163{
1044 const Msg_Font_Glyphs_Loaded *resp = msg; 1164 const Msg_Font_Glyphs_Loaded *resp = msg;
1045 Glyph_Request_Data *grd = data; 1165 Glyph_Request_Data *grd = data;
1046 Font_Entry *fe = grd->fe; 1166 Font_Entry *fe = grd->fe;
1047 unsigned int ncaches = 0; 1167 unsigned int ncaches;
1048 const char *buf; 1168 const char *buf;
1049 1169
1050 if (resp->base.type == CSERVE2_ERROR) 1170 if (resp->base.type == CSERVE2_ERROR)
1051 { 1171 goto end;
1052 free(grd); 1172
1053 return; 1173 if (!fe->fash[grd->hints])
1054 } 1174 goto end;
1175
1176 if (size <= (int) sizeof(*resp)) goto end;
1055 1177
1056 buf = (const char *)resp + sizeof(*resp); 1178 buf = (const char *)resp + sizeof(*resp);
1057 while (ncaches < resp->ncaches) 1179 for (ncaches = 0; ncaches < resp->ncaches; ncaches++)
1058 { 1180 {
1059 int i = 0, nglyphs; 1181 int i, nglyphs;
1060 int namelen; 1182 int namelen;
1061 const char *name; 1183 const char *name;
1062 Glyph_Map *map; 1184 Glyph_Map *map;
1185 int pos = buf - (const char*) resp;
1186
1187 pos += sizeof(int);
1188 if (pos > size) goto end;
1063 1189
1064 memcpy(&namelen, buf, sizeof(int)); 1190 memcpy(&namelen, buf, sizeof(int));
1065 buf += sizeof(int); 1191 buf += sizeof(int);
1066 1192
1193 pos += namelen + sizeof(int);
1194 if (pos > size) goto end;
1195
1067 name = eina_stringshare_add_length(buf, namelen); 1196 name = eina_stringshare_add_length(buf, namelen);
1068 buf += namelen; 1197 buf += namelen;
1069 1198
@@ -1084,12 +1213,16 @@ _glyph_request_cb(void *data, const void *msg)
1084 else 1213 else
1085 eina_stringshare_del(name); 1214 eina_stringshare_del(name);
1086 1215
1087 while (i < nglyphs) 1216 for (i = 0; i < nglyphs; i++)
1088 { 1217 {
1089 unsigned int idx, offset, glsize; 1218 unsigned int idx, offset, glsize;
1090 int rows, width, pitch, num_grays, pixel_mode; 1219 int rows, width, pitch, num_grays, pixel_mode;
1091 CS_Glyph_Out *gl; 1220 CS_Glyph_Out *gl;
1092 1221
1222 pos = buf - (const char*) resp;
1223 pos += 8 * sizeof(int);
1224 if (pos > size) goto end;
1225
1093 memcpy(&idx, buf, sizeof(int)); 1226 memcpy(&idx, buf, sizeof(int));
1094 buf += sizeof(int); 1227 buf += sizeof(int);
1095 memcpy(&offset, buf, sizeof(int)); 1228 memcpy(&offset, buf, sizeof(int));
@@ -1108,26 +1241,25 @@ _glyph_request_cb(void *data, const void *msg)
1108 buf += sizeof(int); 1241 buf += sizeof(int);
1109 1242
1110 gl = fash_gl_find(fe->fash[grd->hints], idx); 1243 gl = fash_gl_find(fe->fash[grd->hints], idx);
1111 gl->map = map; 1244 if (gl)
1112 gl->offset = offset; 1245 {
1113 gl->size = glsize; 1246 gl->map = map;
1114 gl->base.bitmap.rows = rows; 1247 gl->offset = offset;
1115 gl->base.bitmap.width = width; 1248 gl->size = glsize;
1116 gl->base.bitmap.pitch = pitch; 1249 gl->base.bitmap.rows = rows;
1117 gl->base.bitmap.buffer = map->data + gl->offset; 1250 gl->base.bitmap.width = width;
1118 gl->base.bitmap.num_grays = num_grays; 1251 gl->base.bitmap.pitch = pitch;
1119 gl->base.bitmap.pixel_mode = pixel_mode; 1252 gl->base.bitmap.buffer = map->data + gl->offset;
1120 1253 gl->base.bitmap.num_grays = num_grays;
1121 gl->rid = 0; 1254 gl->base.bitmap.pixel_mode = pixel_mode;
1122 1255 gl->rid = 0;
1123 eina_clist_add_head(&map->glyphs, &gl->map_entry); 1256
1124 1257 eina_clist_add_head(&map->glyphs, &gl->map_entry);
1125 i++; 1258 }
1126 } 1259 }
1127
1128 ncaches++;
1129 } 1260 }
1130 1261
1262end:
1131 free(grd); 1263 free(grd);
1132} 1264}
1133 1265
@@ -1266,7 +1398,7 @@ evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flag
1266 glyph->used = EINA_TRUE; 1398 glyph->used = EINA_TRUE;
1267 } 1399 }
1268 1400
1269 /* crude way to manage a queue, but it will work for now */ 1401 /* FIXME crude way to manage a queue, but it will work for now */
1270 if (fe->glyphs_queue_count == 50) 1402 if (fe->glyphs_queue_count == 50)
1271 _glyph_request_server_send(fe, hints, EINA_FALSE); 1403 _glyph_request_server_send(fe, hints, EINA_FALSE);
1272 1404
@@ -1331,6 +1463,7 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_F
1331 if (!fash) 1463 if (!fash)
1332 { 1464 {
1333 // this should not happen really, so let the user know he fucked up 1465 // this should not happen really, so let the user know he fucked up
1466 ERR("%s was called with a hinting value that was not requested!", __FUNCTION__);
1334 return NULL; 1467 return NULL;
1335 } 1468 }
1336 1469
@@ -1339,6 +1472,7 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_F
1339 { 1472 {
1340 // again, if we are asking for a bitmap we were supposed to already 1473 // again, if we are asking for a bitmap we were supposed to already
1341 // have requested the glyph, it must be there 1474 // have requested the glyph, it must be there
1475 ERR("%s was called with a glyph index that was not requested!", __FUNCTION__);
1342 return NULL; 1476 return NULL;
1343 } 1477 }
1344 if (out->rid) 1478 if (out->rid)