4 * Copyright (C) 2009 by ProFUSION embedded systems
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or (at your
9 * option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * @author Rafael Antognolli <antognolli@profusion.mobi>
27 #include <eina_safety_checks.h>
29 #include "Ethumb_Client.h"
36 #include <sys/types.h>
45 #define MAX_ID 2000000
47 static int _log_dom = -1;
48 #define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
49 #define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
50 #define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
51 #define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
58 E_DBus_Connection *conn;
59 E_DBus_Signal_Handler *name_owner_changed_handler;
60 E_DBus_Signal_Handler *generated_signal;
61 DBusPendingCall *pending_get_name_owner;
62 DBusPendingCall *pending_start_service_by_name;
63 const char *unique_name;
64 DBusPendingCall *pending_new;
66 Ethumb_Client_Connect_Cb cb;
68 Eina_Free_Cb free_data;
70 Eina_List *pending_add;
71 Eina_List *pending_remove;
72 Eina_List *pending_gen;
73 DBusPendingCall *pending_clear;
74 DBusPendingCall *pending_setup;
76 Ethumb_Client_Die_Cb cb;
78 Eina_Free_Cb free_data;
80 const char *object_path;
82 Eina_Bool ethumb_dirty : 1;
83 Eina_Bool connected : 1;
84 Eina_Bool server_started : 1;
87 struct _ethumb_pending_add
93 const char *thumb_key;
94 Ethumb_Client_Generate_Cb generated_cb;
96 Eina_Free_Cb free_data;
97 DBusPendingCall *pending_call;
98 Ethumb_Client *client;
101 struct _ethumb_pending_remove
104 Ethumb_Client_Generate_Cancel_Cb cancel_cb;
106 Eina_Free_Cb free_data;
107 DBusPendingCall *pending_call;
108 Ethumb_Client *client;
111 struct _ethumb_pending_gen
117 const char *thumb_key;
118 Ethumb_Client_Generate_Cb generated_cb;
120 Eina_Free_Cb free_data;
123 static const char _ethumb_dbus_bus_name[] = "org.enlightenment.Ethumb";
124 static const char _ethumb_dbus_interface[] = "org.enlightenment.Ethumb";
125 static const char _ethumb_dbus_objects_interface[] = "org.enlightenment.Ethumb.objects";
126 static const char _ethumb_dbus_path[] = "/org/enlightenment/Ethumb";
127 static const char fdo_interface[] = "org.freedesktop.DBus";
128 static const char fdo_bus_name[] = "org.freedesktop.DBus";
129 static const char fdo_path[] = "/org/freedesktop/DBus";
131 static int _initcount = 0;
133 static void _ethumb_client_generated_cb(void *data, DBusMessage *msg);
134 static void _ethumb_client_get_name_owner(void *data, DBusMessage *msg, DBusError *err);
137 __dbus_callback_check_and_init(const char *file, int line, const char *function, DBusMessage *msg, DBusMessageIter *itr, DBusError *err)
141 ERR("%s:%d:%s() callback without message arguments!\n",
142 file, line, function);
145 ERR("%s:%d:%s() an error was reported by server: "
146 "name=\"%s\", message=\"%s\"\n",
147 file, line, function, err->name, err->message);
152 if (!dbus_message_iter_init(msg, itr))
154 ERR("%s:%d:%s() could not init iterator.\n",
155 file, line, function);
162 #define _dbus_callback_check_and_init(msg, itr, err) \
163 __dbus_callback_check_and_init(__FILE__, __LINE__, __FUNCTION__, \
167 __dbus_iter_type_check(int type, int expected, const char *expected_name)
169 if (type == expected)
172 ERR("expected type %s (%c) but got %c instead!\n",
173 expected_name, expected, type);
177 #define _dbus_iter_type_check(t, e) __dbus_iter_type_check(t, e, #e)
179 #define CHECK_NULL_RETURN(ptr, ...) \
184 ERR("%s == NULL!\n", #ptr); \
185 return __VA_ARGS__; \
191 _ethumb_client_name_owner_changed(void *data, DBusMessage *msg)
194 const char *name, *from, *to;
195 Ethumb_Client *client = data;
197 dbus_error_init(&err);
198 if (!dbus_message_get_args(msg, &err,
199 DBUS_TYPE_STRING, &name,
200 DBUS_TYPE_STRING, &from,
201 DBUS_TYPE_STRING, &to,
204 ERR("could not get NameOwnerChanged arguments: %s: %s\n",
205 err.name, err.message);
206 dbus_error_free(&err);
210 if (strcmp(name, _ethumb_dbus_bus_name) != 0)
213 DBG("NameOwnerChanged from=[%s] to=[%s]\n", from, to);
215 if (from[0] != '\0' && to[0] == '\0')
217 DBG("exit ethumbd at %s\n", from);
218 if (strcmp(client->unique_name, from) != 0)
219 WRN("%s was not the known name %s, ignored.\n",
220 from, client->unique_name);
223 ERR("server exit!!!\n");
226 client->die.cb(client->die.data, client);
227 client->die.cb = NULL;
229 if (client->die.free_data)
231 client->die.free_data(client->die.data);
232 client->die.free_data = NULL;
233 client->die.data = NULL;
238 DBG("unknown change from %s to %s\n", from, to);
242 _ethumb_client_report_connect(Ethumb_Client *client, Eina_Bool success)
244 if (!client->connect.cb)
246 ERR("already called?!");
250 client->connect.cb(client->connect.data, client, success);
251 if (client->connect.free_data)
253 client->connect.free_data(client->connect.data);
254 client->connect.free_data = NULL;
256 client->connect.cb = NULL;
257 client->connect.data = NULL;
261 _ethumb_client_new_cb(void *data, DBusMessage *msg, DBusError *error)
263 DBusMessageIter iter;
266 Ethumb_Client *client = data;
268 client->pending_new = NULL;
270 if (!_dbus_callback_check_and_init(msg, &iter, error))
272 t = dbus_message_iter_get_arg_type(&iter);
273 if (!_dbus_iter_type_check(t, DBUS_TYPE_OBJECT_PATH))
276 dbus_message_iter_get_basic(&iter, &opath);
277 if (opath[0] == '\0')
280 client->object_path = eina_stringshare_add(opath);
282 client->generated_signal = e_dbus_signal_handler_add(
283 client->conn, _ethumb_dbus_bus_name, opath,
284 _ethumb_dbus_objects_interface, "generated",
285 _ethumb_client_generated_cb, client);
287 _ethumb_client_report_connect(client, 1);
291 _ethumb_client_report_connect(client, 0);
295 _ethumb_client_call_new(Ethumb_Client *client)
299 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name, _ethumb_dbus_path,
300 _ethumb_dbus_interface, "new");
301 client->pending_new = e_dbus_message_send(client->conn, msg,
302 _ethumb_client_new_cb, -1,
304 dbus_message_unref(msg);
308 _ethumb_client_start_server_cb(void *data, DBusMessage *msg, DBusError *err)
310 Ethumb_Client *client = data;
311 DBusMessageIter iter;
315 client->pending_start_service_by_name = NULL;
317 if (!_dbus_callback_check_and_init(msg, &iter, err))
320 t = dbus_message_iter_get_arg_type(&iter);
321 if (!_dbus_iter_type_check(t, DBUS_TYPE_UINT32))
324 dbus_message_iter_get_basic(&iter, &ret);
325 if ((ret != 1) && (ret != 2))
327 ERR("Error starting Ethumbd DBus service by its name: retcode %u\n",
332 client->server_started = 1;
333 DBG("Ethumbd DBus service started successfully (%d), now request its name\n",
336 if (client->pending_get_name_owner)
338 DBG("already requesting name owner, cancel and try again\n");
339 dbus_pending_call_cancel(client->pending_get_name_owner);
342 client->pending_get_name_owner = e_dbus_get_name_owner
343 (client->conn, _ethumb_dbus_bus_name, _ethumb_client_get_name_owner,
345 if (!client->pending_get_name_owner)
347 ERR("could not create a get_name_owner request.\n");
354 ERR("failed to start Ethumbd DBus service by its name.\n");
355 _ethumb_client_report_connect(client, 0);
359 _ethumb_client_start_server(Ethumb_Client *client)
361 if (client->pending_start_service_by_name)
363 DBG("already pending start service by name.\n");
367 client->server_started = 0;
368 client->pending_start_service_by_name = e_dbus_start_service_by_name
369 (client->conn, _ethumb_dbus_bus_name, 0, _ethumb_client_start_server_cb,
371 if (!client->pending_start_service_by_name)
373 ERR("could not start service by name!\n");
374 _ethumb_client_report_connect(client, 0);
379 _ethumb_client_get_name_owner(void *data, DBusMessage *msg, DBusError *err)
381 DBusMessageIter iter;
383 Ethumb_Client *client = data;
386 client->pending_get_name_owner = NULL;
388 if (dbus_error_is_set(err) && (!client->server_started))
390 DBG("could not find server (%s), try to start it...\n", err->message);
391 _ethumb_client_start_server(client);
395 if (!_dbus_callback_check_and_init(msg, &iter, err))
398 t = dbus_message_iter_get_arg_type(&iter);
399 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
402 dbus_message_iter_get_basic(&iter, &uid);
405 ERR("no name owner!\n");
409 DBG("unique name = %s\n", uid);
410 client->unique_name = eina_stringshare_add(uid);
412 _ethumb_client_call_new(client);
413 client->connected = 1;
417 _ethumb_client_report_connect(client, 0);
421 ethumb_client_init(void)
428 fprintf(stderr, "ERROR: Could not initialize log module.\n");
431 _log_dom = eina_log_domain_register("ethumb_client", EINA_COLOR_YELLOW);
434 EINA_LOG_ERR("Could not register log domain: ethumb_client");
446 ethumb_client_shutdown(void)
454 eina_log_domain_unregister(_log_dom);
461 * Connects to Ethumb server and return the client instance.
463 * This is the "constructor" of Ethumb_Client, where everything
466 * If server was down, it is tried to start it using DBus activation,
467 * then the connection is retried.
469 * This call is asynchronous and will not block, instead it will be in
470 * "not connected" state until @a connect_cb is called with either
471 * success or failure. On failure, then no methods should be
472 * called. On success you're now able to setup and then ask generation
475 * Usually you should listen for server death/disconenction with
476 * ethumb_client_on_server_die_callback_set().
478 * @param connect_cb function to call to report connection success or
479 * failure. Do not call any other ethumb_client method until
480 * this function returns. The first received parameter is the
481 * given argument @a data. Must @b not be @c NULL. This
482 * function will not be called if user explicitly calls
483 * ethumb_client_disconnect().
484 * @param data context to give back to @a connect_cb. May be @c NULL.
485 * @param free_data function used to release @a data resources, if
486 * any. May be @c NULL. If this function exists, it will be
487 * called immediately after @a connect_cb is called or if user
488 * explicitly calls ethumb_client_disconnect() before such
489 * (that is, don't rely on @a data after @a connect_cb was
492 * @return client instance or NULL if failed. If @a connect_cb is
493 * missing it returns @c NULL. If it fail for other
494 * conditions, @c NULL is also returned and @a connect_cb is
495 * called with @c success=EINA_FALSE. The client instance is
496 * not ready to be used until @a connect_cb is called.
499 ethumb_client_connect(Ethumb_Client_Connect_Cb connect_cb, const void *data, Eina_Free_Cb free_data)
501 Ethumb_Client *eclient;
503 EINA_SAFETY_ON_NULL_RETURN_VAL(connect_cb, NULL);
505 eclient = calloc(1, sizeof(*eclient));
508 ERR("could not allocate Ethumb_Client structure.\n");
512 eclient->connect.cb = connect_cb;
513 eclient->connect.data = (void *)data;
514 eclient->connect.free_data = free_data;
516 eclient->ethumb = ethumb_new();
517 if (!eclient->ethumb)
519 ERR("could not create ethumb handler.\n");
523 eclient->conn = e_dbus_bus_get(DBUS_BUS_SESSION);
526 ERR("could not connect to session bus.\n");
530 eclient->name_owner_changed_handler = e_dbus_signal_handler_add(
531 eclient->conn, fdo_bus_name, fdo_path, fdo_interface,
532 "NameOwnerChanged", _ethumb_client_name_owner_changed, eclient);
534 eclient->pending_get_name_owner = e_dbus_get_name_owner(
535 eclient->conn, _ethumb_dbus_bus_name, _ethumb_client_get_name_owner,
537 if (!eclient->pending_get_name_owner)
539 ERR("could not create a get_name_owner request.\n");
546 ethumb_free(eclient->ethumb);
550 connect_cb((void *)data, NULL, EINA_FALSE);
552 free_data((void *)data);
557 * Disconnect the client, releasing all client resources.
559 * This is the destructor of Ethumb_Client, after it's disconnected
560 * the client handle is now gone and should not be used.
563 ethumb_client_disconnect(Ethumb_Client *client)
567 EINA_SAFETY_ON_NULL_RETURN(client);
569 if (!client->connected)
572 EINA_LIST_FREE(client->pending_add, data)
574 struct _ethumb_pending_add *pending = data;
575 eina_stringshare_del(pending->file);
576 eina_stringshare_del(pending->key);
577 eina_stringshare_del(pending->thumb);
578 eina_stringshare_del(pending->thumb_key);
579 dbus_pending_call_cancel(pending->pending_call);
580 dbus_pending_call_unref(pending->pending_call);
581 if (pending->free_data)
582 pending->free_data(pending->data);
586 EINA_LIST_FREE(client->pending_gen, data)
588 struct _ethumb_pending_gen *pending = data;
589 eina_stringshare_del(pending->file);
590 eina_stringshare_del(pending->key);
591 eina_stringshare_del(pending->thumb);
592 eina_stringshare_del(pending->thumb_key);
593 if (pending->free_data)
594 pending->free_data(pending->data);
598 EINA_LIST_FREE(client->pending_remove, data)
600 struct _ethumb_pending_remove *pending = data;
601 dbus_pending_call_cancel(pending->pending_call);
602 dbus_pending_call_unref(pending->pending_call);
603 if (pending->free_data)
604 pending->free_data(pending->data);
608 if (client->pending_clear)
610 dbus_pending_call_cancel(client->pending_clear);
611 dbus_pending_call_unref(client->pending_clear);
615 if (client->object_path)
616 eina_stringshare_del(client->object_path);
618 if (client->pending_new)
619 dbus_pending_call_cancel(client->pending_new);
621 if (client->unique_name)
622 eina_stringshare_del(client->unique_name);
624 if (client->pending_get_name_owner)
625 dbus_pending_call_cancel(client->pending_get_name_owner);
627 if (client->pending_start_service_by_name)
628 dbus_pending_call_cancel(client->pending_start_service_by_name);
630 ethumb_free(client->ethumb);
632 e_dbus_signal_handler_del(client->conn, client->name_owner_changed_handler);
633 if (client->connected)
634 e_dbus_signal_handler_del(client->conn, client->generated_signal);
635 e_dbus_connection_close(client->conn);
637 if (client->connect.free_data)
638 client->connect.free_data(client->connect.data);
639 if (client->die.free_data)
640 client->die.free_data(client->die.data);
646 * Sets the callback to report server died.
648 * When server dies there is nothing you can do, just release
649 * resources with ethumb_client_disconnect() and probably try to
652 * Usually you should set this callback and handle this case, it does
655 * @param client the client instance to monitor. Must @b not be @c
657 * @param server_die_cb function to call back when server dies. The
658 * first parameter will be the argument @a data. May be @c
660 * @param data context to give back to @a server_die_cb. May be @c
662 * @param free_data used to release @a data resources after @a
663 * server_die_cb is called or user calls
664 * ethumb_client_disconnect().
667 ethumb_client_on_server_die_callback_set(Ethumb_Client *client, Ethumb_Client_Die_Cb server_die_cb, const void *data, Eina_Free_Cb free_data)
669 EINA_SAFETY_ON_NULL_RETURN(client);
671 if (client->die.free_data)
672 client->die.free_data(client->die.data);
674 client->die.cb = server_die_cb;
675 client->die.data = (void *)data;
676 client->die.free_data = free_data;
680 _ethumb_client_ethumb_setup_cb(void *data, DBusMessage *msg, DBusError *error)
682 DBusMessageIter iter;
684 dbus_bool_t result = 0;
685 Ethumb_Client *client = data;
687 client->pending_setup = NULL;
689 if (!_dbus_callback_check_and_init(msg, &iter, error))
692 t = dbus_message_iter_get_arg_type(&iter);
693 if (!_dbus_iter_type_check(t, DBUS_TYPE_BOOLEAN))
696 dbus_message_iter_get_basic(&iter, &result);
700 _ethumb_client_dbus_get_bytearray(DBusMessageIter *iter)
704 DBusMessageIter riter;
707 el_type = dbus_message_iter_get_element_type(iter);
708 if (el_type != DBUS_TYPE_BYTE)
710 ERR("not an byte array element.\n");
714 dbus_message_iter_recurse(iter, &riter);
715 dbus_message_iter_get_fixed_array(&riter, &result, &length);
717 if (result[0] == '\0')
720 return eina_stringshare_add(result);
724 _ethumb_client_dbus_append_bytearray(DBusMessageIter *iter, const char *string)
726 DBusMessageIter viter;
731 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &viter);
732 dbus_message_iter_append_fixed_array(&viter, DBUS_TYPE_BYTE, &string,
734 dbus_message_iter_close_container(iter, &viter);
738 * Send setup to server.
740 * This method is called automatically by ethumb_client_generate() if
741 * any property was changed. No need to call it manually.
743 * @param client client instance. Must @b not be @c NULL and client
744 * must be connected (after connected_cb is called).
747 ethumb_client_ethumb_setup(Ethumb_Client *client)
750 DBusMessageIter iter, aiter, diter, viter, vaiter;
751 Ethumb *e = client->ethumb;
753 dbus_int32_t tw, th, format, aspect, quality, compress;
756 const char *theme_file, *group, *swallow;
757 const char *directory, *category;
758 double video_time, video_start, video_interval;
759 dbus_int32_t video_ntimes, video_fps, document_page;
761 EINA_SAFETY_ON_NULL_RETURN(client);
762 EINA_SAFETY_ON_FALSE_RETURN(client->connected);
763 client->ethumb_dirty = 0;
765 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
767 _ethumb_dbus_objects_interface,
769 dbus_message_iter_init_append(msg, &iter);
770 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &aiter);
772 #define _open_variant_iter(str_entry, str_type, end_iter) \
774 dbus_message_iter_open_container(&aiter, DBUS_TYPE_DICT_ENTRY, NULL, &diter); \
775 dbus_message_iter_append_basic(&diter, DBUS_TYPE_STRING, &entry); \
776 dbus_message_iter_open_container(&diter, DBUS_TYPE_VARIANT, str_type, \
779 #define _close_variant_iter(end_iter) \
780 dbus_message_iter_close_container(&diter, &end_iter); \
781 dbus_message_iter_close_container(&aiter, &diter);
783 /* starting array elements */
785 _open_variant_iter("size", "(ii)", viter);
786 dbus_message_iter_open_container(&viter, DBUS_TYPE_STRUCT, NULL, &vaiter);
787 ethumb_thumb_size_get(e, &tw, &th);
788 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_INT32, &tw);
789 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_INT32, &th);
790 dbus_message_iter_close_container(&viter, &vaiter);
791 _close_variant_iter(viter);
793 _open_variant_iter("format", "i", viter);
794 format = ethumb_thumb_format_get(e);
795 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &format);
796 _close_variant_iter(viter);
798 _open_variant_iter("aspect", "i", viter);
799 aspect = ethumb_thumb_aspect_get(e);
800 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &aspect);
801 _close_variant_iter(viter);
803 _open_variant_iter("crop", "(dd)", viter);
804 dbus_message_iter_open_container(&viter, DBUS_TYPE_STRUCT, NULL, &vaiter);
805 ethumb_thumb_crop_align_get(e, &cx, &cy);
807 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_DOUBLE, &t);
809 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_DOUBLE, &t);
810 dbus_message_iter_close_container(&viter, &vaiter);
811 _close_variant_iter(viter);
813 _open_variant_iter("quality", "i", viter);
814 quality = ethumb_thumb_quality_get(e);
815 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &quality);
816 _close_variant_iter(viter);
818 _open_variant_iter("compress", "i", viter);
819 compress = ethumb_thumb_compress_get(e);
820 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &compress);
821 _close_variant_iter(viter);
823 _open_variant_iter("frame", "(ayayay)", viter);
824 dbus_message_iter_open_container(&viter, DBUS_TYPE_STRUCT, NULL, &vaiter);
825 ethumb_frame_get(e, &theme_file, &group, &swallow);
826 _ethumb_client_dbus_append_bytearray(&vaiter, theme_file);
827 _ethumb_client_dbus_append_bytearray(&vaiter, group);
828 _ethumb_client_dbus_append_bytearray(&vaiter, swallow);
829 dbus_message_iter_close_container(&viter, &vaiter);
830 _close_variant_iter(viter);
832 _open_variant_iter("directory", "ay", viter);
833 directory = ethumb_thumb_dir_path_get(e);
834 _ethumb_client_dbus_append_bytearray(&viter, directory);
835 _close_variant_iter(viter);
837 _open_variant_iter("category", "ay", viter);
838 category = ethumb_thumb_category_get(e);
839 _ethumb_client_dbus_append_bytearray(&viter, category);
840 _close_variant_iter(viter);
842 _open_variant_iter("video_time", "d", viter);
843 video_time = ethumb_video_time_get(e);
844 dbus_message_iter_append_basic(&viter, DBUS_TYPE_DOUBLE, &video_time);
845 _close_variant_iter(viter);
847 _open_variant_iter("video_start", "d", viter);
848 video_start = ethumb_video_start_get(e);
849 dbus_message_iter_append_basic(&viter, DBUS_TYPE_DOUBLE, &video_start);
850 _close_variant_iter(viter);
852 _open_variant_iter("video_interval", "d", viter);
853 video_interval = ethumb_video_interval_get(e);
854 dbus_message_iter_append_basic(&viter, DBUS_TYPE_DOUBLE, &video_interval);
855 _close_variant_iter(viter);
857 _open_variant_iter("video_ntimes", "i", viter);
858 video_ntimes = ethumb_video_ntimes_get(e);
859 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &video_ntimes);
860 _close_variant_iter(viter);
862 _open_variant_iter("video_fps", "i", viter);
863 video_fps = ethumb_video_fps_get(e);
864 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &video_fps);
865 _close_variant_iter(viter);
867 _open_variant_iter("document_page", "i", viter);
868 document_page = ethumb_document_page_get(e);
869 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &document_page);
870 _close_variant_iter(viter);
872 #undef _open_variant_iter
873 #undef _close_variant_iter
875 dbus_message_iter_close_container(&iter, &aiter);
877 client->pending_setup = e_dbus_message_send(client->conn, msg,
878 _ethumb_client_ethumb_setup_cb,
880 dbus_message_unref(msg);
884 _ethumb_client_generated_cb(void *data, DBusMessage *msg)
886 DBusMessageIter iter;
887 dbus_int32_t id = -1;
889 const char *thumb_key;
890 Ethumb_Client *client = data;
895 struct _ethumb_pending_gen *pending;
897 dbus_message_iter_init(msg, &iter);
899 t = dbus_message_iter_get_arg_type(&iter);
900 if (!_dbus_iter_type_check(t, DBUS_TYPE_INT32))
902 dbus_message_iter_get_basic(&iter, &id);
903 dbus_message_iter_next(&iter);
905 t = dbus_message_iter_get_arg_type(&iter);
906 if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
908 thumb = _ethumb_client_dbus_get_bytearray(&iter);
909 dbus_message_iter_next(&iter);
911 t = dbus_message_iter_get_arg_type(&iter);
912 if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
914 thumb_key = _ethumb_client_dbus_get_bytearray(&iter);
915 dbus_message_iter_next(&iter);
917 t = dbus_message_iter_get_arg_type(&iter);
918 if (!_dbus_iter_type_check(t, DBUS_TYPE_BOOLEAN))
920 dbus_message_iter_get_basic(&iter, &success);
923 l = client->pending_gen;
927 if (pending->id == id)
937 client->pending_gen = eina_list_remove_list(client->pending_gen, l);
938 pending->generated_cb(pending->data, client, id,
939 pending->file, pending->key,
940 pending->thumb, pending->thumb_key,
942 if (pending->free_data)
943 pending->free_data(pending->data);
944 eina_stringshare_del(pending->file);
945 eina_stringshare_del(pending->key);
946 eina_stringshare_del(pending->thumb);
947 eina_stringshare_del(pending->thumb_key);
952 eina_stringshare_del(thumb);
953 eina_stringshare_del(thumb_key);
957 _ethumb_client_queue_add_cb(void *data, DBusMessage *msg, DBusError *error)
959 DBusMessageIter iter;
961 dbus_int32_t id = -1;
962 struct _ethumb_pending_add *pending = data;
963 struct _ethumb_pending_gen *generating;
964 Ethumb_Client *client = pending->client;
966 client->pending_add = eina_list_remove(client->pending_add, pending);
968 if (!_dbus_callback_check_and_init(msg, &iter, error))
971 t = dbus_message_iter_get_arg_type(&iter);
972 if (!_dbus_iter_type_check(t, DBUS_TYPE_INT32))
975 dbus_message_iter_get_basic(&iter, &id);
977 generating = calloc(1, sizeof(*generating));
979 generating->file = pending->file;
980 generating->key = pending->key;
981 generating->thumb = pending->thumb;
982 generating->thumb_key = pending->thumb_key;
983 generating->generated_cb = pending->generated_cb;
984 generating->data = pending->data;
985 generating->free_data = pending->free_data;
986 client->pending_gen = eina_list_append(client->pending_gen, generating);
993 _ethumb_client_queue_add(Ethumb_Client *client, const char *file, const char *key, const char *thumb, const char *thumb_key, Ethumb_Client_Generate_Cb generated_cb, const void *data, Eina_Free_Cb free_data)
996 DBusMessageIter iter;
997 struct _ethumb_pending_add *pending;
999 pending = calloc(1, sizeof(*pending));
1000 pending->id = client->id_count;
1001 pending->file = eina_stringshare_add(file);
1002 pending->key = eina_stringshare_add(key);
1003 pending->thumb = eina_stringshare_add(thumb);
1004 pending->thumb_key = eina_stringshare_add(thumb_key);
1005 pending->generated_cb = generated_cb;
1006 pending->data = (void *)data;
1007 pending->free_data = free_data;
1008 pending->client = client;
1010 client->id_count = (client->id_count + 1) % MAX_ID;
1012 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
1013 client->object_path,
1014 _ethumb_dbus_objects_interface,
1017 dbus_message_iter_init_append(msg, &iter);
1018 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &pending->id);
1019 _ethumb_client_dbus_append_bytearray(&iter, file);
1020 _ethumb_client_dbus_append_bytearray(&iter, key);
1021 _ethumb_client_dbus_append_bytearray(&iter, thumb);
1022 _ethumb_client_dbus_append_bytearray(&iter, thumb_key);
1024 pending->pending_call = e_dbus_message_send(client->conn, msg,
1025 _ethumb_client_queue_add_cb,
1027 client->pending_add = eina_list_append(client->pending_add, pending);
1028 dbus_message_unref(msg);
1034 _ethumb_client_queue_remove_cb(void *data, DBusMessage *msg, DBusError *error)
1036 DBusMessageIter iter;
1038 dbus_bool_t success = 0;
1039 struct _ethumb_pending_remove *pending = data;
1040 Ethumb_Client *client = pending->client;
1042 client->pending_remove = eina_list_remove(client->pending_remove, pending);
1044 if (!_dbus_callback_check_and_init(msg, &iter, error))
1047 t = dbus_message_iter_get_arg_type(&iter);
1048 if (!_dbus_iter_type_check(t, DBUS_TYPE_BOOLEAN))
1051 dbus_message_iter_get_basic(&iter, &success);
1054 if (pending->cancel_cb)
1055 pending->cancel_cb(pending->data, success);
1056 if (pending->free_data)
1057 pending->free_data(pending->data);
1062 * Ask server to cancel generation of thumbnail.
1064 * @param client client instance. Must @b not be @c NULL and client
1065 * must be connected (after connected_cb is called).
1066 * @param id valid id returned by ethumb_client_generate()
1067 * @param cancel_cb function to report cancellation results.
1068 * @param data context argument to give back to @a cancel_cb. May be
1070 * @param data context to give back to @a cancel_cb. May be @c
1072 * @param free_data used to release @a data resources after @a
1073 * cancel_cb is called or user calls
1074 * ethumb_client_disconnect().
1077 ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Generate_Cancel_Cb cancel_cb, const void *data, Eina_Free_Cb free_data)
1080 struct _ethumb_pending_remove *pending;
1083 dbus_int32_t id32 = id;
1084 EINA_SAFETY_ON_NULL_RETURN(client);
1085 EINA_SAFETY_ON_FALSE_RETURN(id >= 0);
1087 pending = calloc(1, sizeof(*pending));
1089 pending->cancel_cb = cancel_cb;
1090 pending->data = (void *)data;
1091 pending->free_data = free_data;
1092 pending->client = client;
1094 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
1095 client->object_path,
1096 _ethumb_dbus_objects_interface,
1099 dbus_message_append_args(msg, DBUS_TYPE_INT32, &id32, DBUS_TYPE_INVALID);
1100 pending->pending_call = e_dbus_message_send(client->conn, msg,
1101 _ethumb_client_queue_remove_cb,
1103 client->pending_remove = eina_list_append(client->pending_remove, pending);
1106 l = client->pending_add;
1109 struct _ethumb_pending_add *pending = l->data;
1110 if (pending->id != id32)
1115 client->pending_add = eina_list_remove_list(client->pending_add, l);
1116 eina_stringshare_del(pending->file);
1117 eina_stringshare_del(pending->key);
1118 eina_stringshare_del(pending->thumb);
1119 eina_stringshare_del(pending->thumb_key);
1120 dbus_pending_call_cancel(pending->pending_call);
1121 dbus_pending_call_unref(pending->pending_call);
1122 if (pending->free_data)
1123 pending->free_data(pending->data);
1132 l = client->pending_gen;
1135 struct _ethumb_pending_gen *pending = l->data;
1136 if (pending->id != id32)
1141 client->pending_gen = eina_list_remove_list(client->pending_gen, l);
1142 eina_stringshare_del(pending->file);
1143 eina_stringshare_del(pending->key);
1144 eina_stringshare_del(pending->thumb);
1145 eina_stringshare_del(pending->thumb_key);
1146 if (pending->free_data)
1147 pending->free_data(pending->data);
1154 dbus_message_unref(msg);
1158 _ethumb_client_queue_clear_cb(void *data, DBusMessage *msg __UNUSED__, DBusError *error __UNUSED__)
1160 Ethumb_Client *client = data;
1162 client->pending_clear = NULL;
1166 * Ask server to cancel generation of all thumbnails.
1168 * @param client client instance. Must @b not be @c NULL and client
1169 * must be connected (after connected_cb is called).
1171 * @see ethumb_client_generate_cancel()
1174 ethumb_client_generate_cancel_all(Ethumb_Client *client)
1178 EINA_SAFETY_ON_NULL_RETURN(client);
1180 if (client->pending_clear)
1183 EINA_LIST_FREE(client->pending_add, data)
1185 struct _ethumb_pending_add *pending = data;
1186 eina_stringshare_del(pending->file);
1187 eina_stringshare_del(pending->key);
1188 eina_stringshare_del(pending->thumb);
1189 eina_stringshare_del(pending->thumb_key);
1190 dbus_pending_call_cancel(pending->pending_call);
1191 dbus_pending_call_unref(pending->pending_call);
1192 if (pending->free_data)
1193 pending->free_data(pending->data);
1197 EINA_LIST_FREE(client->pending_gen, data)
1199 struct _ethumb_pending_gen *pending = data;
1200 eina_stringshare_del(pending->file);
1201 eina_stringshare_del(pending->key);
1202 eina_stringshare_del(pending->thumb);
1203 eina_stringshare_del(pending->thumb_key);
1204 if (pending->free_data)
1205 pending->free_data(pending->data);
1209 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
1210 client->object_path,
1211 _ethumb_dbus_objects_interface,
1214 client->pending_clear = e_dbus_message_send(client->conn, msg,
1215 _ethumb_client_queue_clear_cb,
1218 dbus_message_unref(msg);
1222 * Configure future requests to use FreeDesktop.Org preset.
1224 * This is a preset to provide freedesktop.org (fdo) standard
1225 * compliant thumbnails. That is, files are stored as JPEG under
1226 * ~/.thumbnails/SIZE, with size being either normal (128x128) or
1229 * @param s size identifier, either #ETHUMB_THUMB_NORMAL (0) or
1230 * #ETHUMB_THUMB_LARGE (1).
1232 * @see ethumb_client_size_set()
1233 * @see ethumb_client_aspect_set()
1234 * @see ethumb_client_crop_align_set()
1235 * @see ethumb_client_category_set()
1236 * @see ethumb_client_dir_path_set()
1239 ethumb_client_fdo_set(Ethumb_Client *client, Ethumb_Thumb_FDO_Size s)
1241 EINA_SAFETY_ON_NULL_RETURN(client);
1243 client->ethumb_dirty = 1;
1244 ethumb_thumb_fdo_set(client->ethumb, s);
1248 * Configure future request to use custom size.
1250 * @param w width, default is 128.
1251 * @param h height, default is 128.
1254 ethumb_client_size_set(Ethumb_Client *client, int tw, int th)
1256 EINA_SAFETY_ON_NULL_RETURN(client);
1258 client->ethumb_dirty = 1;
1259 ethumb_thumb_size_set(client->ethumb, tw, th);
1263 * Retrieve future request to use custom size.
1265 * @param w where to return width. May be #NULL.
1266 * @param h where to return height. May be #NULL.
1269 ethumb_client_size_get(const Ethumb_Client *client, int *tw, int *th)
1273 EINA_SAFETY_ON_NULL_RETURN(client);
1275 ethumb_thumb_size_get(client->ethumb, tw, th);
1279 * Configure format to use for future requests.
1281 * @param f format identifier to use, either #ETHUMB_THUMB_FDO (0),
1282 * #ETHUMB_THUMB_JPEG (1) or #ETHUMB_THUMB_EET (2). Default is FDO.
1285 ethumb_client_format_set(Ethumb_Client *client, Ethumb_Thumb_Format f)
1287 EINA_SAFETY_ON_NULL_RETURN(client);
1289 client->ethumb_dirty = 1;
1290 ethumb_thumb_format_set(client->ethumb, f);
1294 * Retrieve format to use for future requests.
1296 * @return format identifier to use, either #ETHUMB_THUMB_FDO (0),
1297 * #ETHUMB_THUMB_JPEG (1) or #ETHUMB_THUMB_EET (2).
1299 EAPI Ethumb_Thumb_Format
1300 ethumb_client_format_get(const Ethumb_Client *client)
1302 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1304 return ethumb_thumb_format_get(client->ethumb);
1308 * Configure aspect mode to use.
1310 * If aspect is kept (#ETHUMB_THUMB_KEEP_ASPECT), then image will be
1311 * rescaled so the largest dimension is not bigger than it's specified
1312 * size (see ethumb_client_size_get()) and the other dimension is
1313 * resized in the same proportion. Example: size is 256x256, image is
1314 * 1000x500, resulting thumbnail is 256x128.
1316 * If aspect is ignored (#ETHUMB_THUMB_IGNORE_ASPECT), then image will
1317 * be distorted to match required thumbnail size. Example: size is
1318 * 256x256, image is 1000x500, resulting thumbnail is 256x256.
1320 * If crop is required (#ETHUMB_THUMB_CROP), then image will be
1321 * cropped so the smallest dimension is not bigger than its specified
1322 * size (see ethumb_client_size_get()) and the other dimension will
1323 * overflow, not being visible in the final image. How it will
1324 * overflow is speficied by ethumb_client_crop_align_set()
1325 * alignment. Example: size is 256x256, image is 1000x500, crop
1326 * alignment is 0.5, 0.5, resulting thumbnail is 256x256 with 250
1327 * pixels from left and 250 pixels from right being lost, that is just
1328 * the 500x500 central pixels of image will be considered for scaling.
1330 * @param a aspect mode identifier, either #ETHUMB_THUMB_KEEP_ASPECT (0),
1331 * #ETHUMB_THUMB_IGNORE_ASPECT (1) or #ETHUMB_THUMB_CROP (2).
1334 ethumb_client_aspect_set(Ethumb_Client *client, Ethumb_Thumb_Aspect a)
1336 EINA_SAFETY_ON_NULL_RETURN(client);
1338 client->ethumb_dirty = 1;
1339 ethumb_thumb_aspect_set(client->ethumb, a);
1343 * Get current aspect in use for requests.
1345 * @return aspect in use for future requests.
1347 EAPI Ethumb_Thumb_Aspect
1348 ethumb_client_aspect_get(const Ethumb_Client *client)
1350 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1352 return ethumb_thumb_aspect_get(client->ethumb);
1356 * Configure crop alignment in use for future requests.
1358 * @param x horizontal alignment. 0.0 means left side will be visible
1359 * or right side is being lost. 1.0 means right side will be
1360 * visible or left side is being lost. 0.5 means just center is
1361 * visible, both sides will be lost. Default is 0.5.
1362 * @param y vertical alignment. 0.0 is top visible, 1.0 is bottom
1363 * visible, 0.5 is center visible. Default is 0.5
1366 ethumb_client_crop_align_set(Ethumb_Client *client, float x, float y)
1368 EINA_SAFETY_ON_NULL_RETURN(client);
1370 client->ethumb_dirty = 1;
1371 ethumb_thumb_crop_align_set(client->ethumb, x, y);
1375 * Get current crop alignment in use for requests.
1377 * @param x where to return horizontal alignment. May be #NULL.
1378 * @param y where to return vertical alignment. May be #NULL.
1381 ethumb_client_crop_align_get(const Ethumb_Client *client, float *x, float *y)
1385 EINA_SAFETY_ON_NULL_RETURN(client);
1387 ethumb_thumb_crop_align_get(client->ethumb, x, y);
1391 * Configure quality to be used in thumbnails.
1393 * @param quality value from 0 to 100, default is 80. The effect
1394 * depends on the format being used, PNG will not use it.
1397 ethumb_client_quality_set(Ethumb_Client *client, int quality)
1399 EINA_SAFETY_ON_NULL_RETURN(client);
1401 ethumb_thumb_quality_set(client->ethumb, quality);
1405 * Get quality to be used in thumbnails.
1407 * @return quality value from 0 to 100, default is 80. The effect
1408 * depends on the format being used, PNG will not use it.
1411 ethumb_client_quality_get(const Ethumb_Client *client)
1413 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1415 return ethumb_thumb_quality_get(client->ethumb);
1419 * Configure compression level used in requests.
1421 * @param compress value from 0 to 9, default is 9. The effect
1422 * depends on the format being used, JPEG will not use it.
1425 ethumb_client_compress_set(Ethumb_Client *client, int compress)
1427 EINA_SAFETY_ON_NULL_RETURN(client);
1429 ethumb_thumb_compress_set(client->ethumb, compress);
1433 * Get compression level used in requests.
1435 * @return compress value from 0 to 9, default is 9. The effect
1436 * depends on the format being used, JPEG will not use it.
1439 ethumb_client_compress_get(const Ethumb_Client *client)
1441 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1443 return ethumb_thumb_compress_get(client->ethumb);
1447 * Set frame to apply to future thumbnails.
1449 * This will create an edje object that will have image swallowed
1450 * in. This can be used to simulate Polaroid or wood frames in the
1451 * generated image. Remeber it is bad to modify the original contents
1452 * of thumbnails, but sometimes it's useful to have it composited and
1453 * avoid runtime overhead.
1455 * @param file file path to edje.
1456 * @param group group inside edje to use.
1457 * @param swallow name of swallow part.
1460 ethumb_client_frame_set(Ethumb_Client *client, const char *file, const char *group, const char *swallow)
1462 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1464 client->ethumb_dirty = 1;
1465 return ethumb_frame_set(client->ethumb, file, group, swallow);
1469 * Configure where to store thumbnails in future requests.
1471 * Note that this is the base, a category is added to this path as a
1474 * @param path base directory where to store thumbnails. Default is
1478 ethumb_client_dir_path_set(Ethumb_Client *client, const char *path)
1480 EINA_SAFETY_ON_NULL_RETURN(client);
1482 client->ethumb_dirty = 1;
1483 ethumb_thumb_dir_path_set(client->ethumb, path);
1487 ethumb_client_dir_path_get(const Ethumb_Client *client)
1489 EINA_SAFETY_ON_NULL_RETURN_VAL(client, NULL);
1491 return ethumb_thumb_dir_path_get(client->ethumb);
1495 * Category directory to store thumbnails.
1497 * @param category category sub directory to store thumbnail. Default
1498 * is either "normal" or "large" for FDO compliant thumbnails
1499 * or WIDTHxHEIGHT-ASPECT[-FRAMED]-FORMAT. It can be a string
1500 * or None to use auto generated names.
1503 ethumb_client_category_set(Ethumb_Client *client, const char *category)
1505 EINA_SAFETY_ON_NULL_RETURN(client);
1507 client->ethumb_dirty = 1;
1508 ethumb_thumb_category_set(client->ethumb, category);
1512 ethumb_client_category_get(const Ethumb_Client *client)
1514 EINA_SAFETY_ON_NULL_RETURN_VAL(client, NULL);
1516 return ethumb_thumb_category_get(client->ethumb);
1520 ethumb_client_video_time_set(Ethumb_Client *client, float time)
1522 EINA_SAFETY_ON_NULL_RETURN(client);
1524 client->ethumb_dirty = 1;
1525 ethumb_video_time_set(client->ethumb, time);
1529 ethumb_client_video_start_set(Ethumb_Client *client, float start)
1531 EINA_SAFETY_ON_NULL_RETURN(client);
1533 client->ethumb_dirty = 1;
1534 ethumb_video_start_set(client->ethumb, start);
1538 ethumb_client_video_interval_set(Ethumb_Client *client, float interval)
1540 EINA_SAFETY_ON_NULL_RETURN(client);
1542 client->ethumb_dirty = 1;
1543 ethumb_video_interval_set(client->ethumb, interval);
1547 ethumb_client_video_ntimes_set(Ethumb_Client *client, int ntimes)
1549 EINA_SAFETY_ON_NULL_RETURN(client);
1551 client->ethumb_dirty = 1;
1552 ethumb_video_ntimes_set(client->ethumb, ntimes);
1556 ethumb_client_video_fps_set(Ethumb_Client *client, int fps)
1558 EINA_SAFETY_ON_NULL_RETURN(client);
1560 client->ethumb_dirty = 1;
1561 ethumb_video_fps_set(client->ethumb, fps);
1565 ethumb_client_document_page_set(Ethumb_Client *client, int page)
1567 EINA_SAFETY_ON_NULL_RETURN(client);
1569 client->ethumb_dirty = 1;
1570 ethumb_document_page_set(client->ethumb, page);
1574 * Set source file to be thumbnailed.
1576 * Calling this function has the side effect of resetting values set
1577 * with ethumb_client_thumb_path_set() or auto-generated with
1578 * ethumb_client_thumb_exists().
1580 * @param client the client instance to use. Must @b not be @c
1581 * NULL. May be pending connected (can be called before @c
1583 * @param path the filesystem path to use. May be @c NULL.
1584 * @param key the extra argument/key inside @a path to read image
1585 * from. This is only used for formats that allow multiple
1586 * resources in one file, like EET or Edje (group name).
1588 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
1591 ethumb_client_file_set(Ethumb_Client *client, const char *path, const char *key)
1593 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1595 return ethumb_file_set(client->ethumb, path, key);
1599 * Get values set with ethumb_client_file_get()
1602 ethumb_client_file_get(Ethumb_Client *client, const char **path, const char **key)
1604 if (path) *path = NULL;
1605 if (key) *key = NULL;
1606 EINA_SAFETY_ON_NULL_RETURN(client);
1608 ethumb_file_get(client->ethumb, path, key);
1612 * Reset previously set file to @c NULL.
1614 * @param client the client instance to use. Must @b not be @c
1615 * NULL. May be pending connected (can be called before @c
1619 ethumb_client_file_free(Ethumb_Client *client)
1621 EINA_SAFETY_ON_NULL_RETURN(client);
1623 ethumb_file_free(client->ethumb);
1627 * Set a defined path and key to store the thumbnail.
1629 * If not explicitly given, the thumbnail path will be auto-generated
1630 * by ethumb_client_thumb_exists() or server using configured
1631 * parameters like size, aspect and category.
1633 * Set these to @c NULL to forget previously given values. After
1634 * ethumb_client_file_set() these values will be reset to @c NULL.
1637 ethumb_client_thumb_path_set(Ethumb_Client *client, const char *path, const char *key)
1639 EINA_SAFETY_ON_NULL_RETURN(client);
1641 ethumb_thumb_path_set(client->ethumb, path, key);
1645 * Get the configured thumbnail path.
1647 * This returns the value set with ethumb_client_thumb_path_set() or
1648 * auto-generated by ethumb_client_thumb_exists() if it was not set.
1650 * @param path where to return configured path. May be @c NULL. If
1651 * there was no path configured with
1652 * ethumb_client_thumb_path_set() and
1653 * ethumb_client_thumb_exists() was not called, then it will
1654 * probably return @c NULL. If not @c NULL, then it will be a
1655 * pointer to a stringshared instance, but @b no references are
1656 * added (do it with eina_stringshare_ref())!
1657 * @param key where to return configured key. May be @c NULL. If
1658 * there was no key configured with
1659 * ethumb_client_thumb_key_set() and
1660 * ethumb_client_thumb_exists() was not called, then it will
1661 * probably return @c NULL. If not @c NULL, then it will be a
1662 * pointer to a stringshared instance, but @b no references are
1663 * added (do it with eina_stringshare_ref())!
1666 ethumb_client_thumb_path_get(Ethumb_Client *client, const char **path, const char **key)
1668 if (path) *path = NULL;
1669 if (key) *key = NULL;
1670 EINA_SAFETY_ON_NULL_RETURN(client);
1672 ethumb_thumb_path_get(client->ethumb, path, key);
1676 * Checks whenever file already exists (locally!)
1678 * This will check locally (not calling server) if thumbnail already
1679 * exists or not, also calculating the thumbnail path. See
1680 * ethumb_client_thumb_path_get(). Path must be configured with
1681 * ethumb_client_file_set() before using it and the last set file will
1684 * @param client client instance. Must @b not be @c NULL and client
1685 * must be configured with ethumb_client_file_set().
1687 * @return #EINA_TRUE if it exists, #EINA_FALSE otherwise.
1690 ethumb_client_thumb_exists(Ethumb_Client *client)
1692 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1694 return ethumb_exists(client->ethumb);
1698 * Ask server to generate thumbnail.
1700 * This process is asynchronous and will report back from main loop
1701 * using @a generated_cb. One can cancel this request by calling
1702 * ethumb_client_generate_cancel() or
1703 * ethumb_client_generate_cancel_all(), but not that request might be
1704 * processed by server already and no generated files will be removed
1705 * if that is the case.
1707 * This will not check if file already exists, this should be done by
1708 * explicitly calling ethumb_client_thumb_exists(). That is, this
1709 * function will override any existing thumbnail.
1711 * @param client client instance. Must @b not be @c NULL and client
1712 * must be connected (after connected_cb is called).
1713 * @param generated_cb function to report generation results.
1714 * @param data context argument to give back to @a generated_cb. May
1716 * @param data context to give back to @a generate_cb. May be @c
1718 * @param free_data used to release @a data resources after @a
1719 * generated_cb is called or user calls
1720 * ethumb_client_disconnect().
1722 * @return identifier or -1 on error. If -1 is returned (error) then
1723 * @a free_data is @b not called!
1725 * @see ethumb_client_connect()
1726 * @see ethumb_client_file_set()
1727 * @see ethumb_client_thumb_exists()
1728 * @see ethumb_client_generate_cancel()
1729 * @see ethumb_client_generate_cancel_all()
1732 ethumb_client_generate(Ethumb_Client *client, Ethumb_Client_Generate_Cb generated_cb, const void *data, Eina_Free_Cb free_data)
1734 const char *file, *key, *thumb, *thumb_key;
1736 EINA_SAFETY_ON_NULL_RETURN_VAL(client, -1);
1737 EINA_SAFETY_ON_FALSE_RETURN_VAL(client->connected, -1);
1739 ethumb_file_get(client->ethumb, &file, &key);
1742 ERR("no file set.\n");
1746 ethumb_thumb_path_get(client->ethumb, &thumb, &thumb_key);
1748 if (client->ethumb_dirty)
1749 ethumb_client_ethumb_setup(client);
1750 id = _ethumb_client_queue_add(client, file, key, thumb, thumb_key,
1751 generated_cb, data, free_data);