4 * This is the client-server thumbnail library, see @ref
5 * tutorial_ethumb_client.
7 * Copyright (C) 2009 by ProFUSION embedded systems
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or (at your
12 * option) any later version.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
24 * @author Rafael Antognolli <antognolli@profusion.mobi>
25 * @author Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
29 * @page tutorial_ethumb_client Client-Server Thumbnailing Tutorial
31 * @section tutorial_ethumb_client_intro Introduction
33 * Ethumb provides both in process and client-server generation
34 * methods. The advantage of the client-server method is that current
35 * process will not do the heavy operations that may block, stopping
36 * animations and other user interactions. Instead the client library
37 * will configure a local #Ethumb instance and mirrors/controls a
38 * remote process using DBus. The simple operations like most setters
39 * and getters as well as checking for thumbnail existence
40 * (ethumb_client_thumb_exists()) is done locally, while expensive
41 * (ethumb_client_generate()) are done on server and then reported
42 * back to application when it is finished (both success or failure).
44 * @section tutorial_ethumb_client_connect Connecting to Server
48 * @section tutorial_ethumb_client_generate Requesting Thumbnail Generation
52 * @section tutorial_ethumb_client_setup Setup Extra Thumbnail Parameters
56 * @section tutorial_ethumb_client_server_died Handle Server Disconnection
69 #include <eina_safety_checks.h>
71 #include "Ethumb_Client.h"
78 #include <sys/types.h>
87 #define MAX_ID 2000000
89 static int _log_dom = -1;
90 #define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
91 #define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
92 #define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
93 #define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
100 E_DBus_Connection *conn;
101 E_DBus_Signal_Handler *name_owner_changed_handler;
102 E_DBus_Signal_Handler *generated_signal;
103 DBusPendingCall *pending_get_name_owner;
104 DBusPendingCall *pending_start_service_by_name;
105 const char *unique_name;
106 DBusPendingCall *pending_new;
108 Ethumb_Client_Connect_Cb cb;
110 Eina_Free_Cb free_data;
112 Eina_List *pending_add;
113 Eina_List *pending_remove;
114 Eina_List *pending_gen;
115 DBusPendingCall *pending_clear;
116 DBusPendingCall *pending_setup;
118 Ethumb_Client_Die_Cb cb;
120 Eina_Free_Cb free_data;
122 const char *object_path;
124 Eina_Bool ethumb_dirty : 1;
125 Eina_Bool connected : 1;
126 Eina_Bool server_started : 1;
129 struct _ethumb_pending_add
135 const char *thumb_key;
136 Ethumb_Client_Generate_Cb generated_cb;
138 Eina_Free_Cb free_data;
139 DBusPendingCall *pending_call;
140 Ethumb_Client *client;
143 struct _ethumb_pending_remove
146 Ethumb_Client_Generate_Cancel_Cb cancel_cb;
148 Eina_Free_Cb free_data;
149 DBusPendingCall *pending_call;
150 Ethumb_Client *client;
153 struct _ethumb_pending_gen
159 const char *thumb_key;
160 Ethumb_Client_Generate_Cb generated_cb;
162 Eina_Free_Cb free_data;
165 static const char _ethumb_dbus_bus_name[] = "org.enlightenment.Ethumb";
166 static const char _ethumb_dbus_interface[] = "org.enlightenment.Ethumb";
167 static const char _ethumb_dbus_objects_interface[] = "org.enlightenment.Ethumb.objects";
168 static const char _ethumb_dbus_path[] = "/org/enlightenment/Ethumb";
169 static const char fdo_interface[] = "org.freedesktop.DBus";
170 static const char fdo_bus_name[] = "org.freedesktop.DBus";
171 static const char fdo_path[] = "/org/freedesktop/DBus";
173 static int _initcount = 0;
175 static void _ethumb_client_generated_cb(void *data, DBusMessage *msg);
176 static void _ethumb_client_get_name_owner(void *data, DBusMessage *msg, DBusError *err);
179 __dbus_callback_check_and_init(const char *file, int line, const char *function, DBusMessage *msg, DBusMessageIter *itr, DBusError *err)
183 ERR("%s:%d:%s() callback without message arguments!\n",
184 file, line, function);
187 ERR("%s:%d:%s() an error was reported by server: "
188 "name=\"%s\", message=\"%s\"\n",
189 file, line, function, err->name, err->message);
194 if (!dbus_message_iter_init(msg, itr))
196 ERR("%s:%d:%s() could not init iterator.\n",
197 file, line, function);
204 #define _dbus_callback_check_and_init(msg, itr, err) \
205 __dbus_callback_check_and_init(__FILE__, __LINE__, __FUNCTION__, \
209 __dbus_iter_type_check(int type, int expected, const char *expected_name)
211 if (type == expected)
214 ERR("expected type %s (%c) but got %c instead!\n",
215 expected_name, expected, type);
219 #define _dbus_iter_type_check(t, e) __dbus_iter_type_check(t, e, #e)
221 #define CHECK_NULL_RETURN(ptr, ...) \
226 ERR("%s == NULL!\n", #ptr); \
227 return __VA_ARGS__; \
233 _ethumb_client_name_owner_changed(void *data, DBusMessage *msg)
236 const char *name, *from, *to;
237 Ethumb_Client *client = data;
239 dbus_error_init(&err);
240 if (!dbus_message_get_args(msg, &err,
241 DBUS_TYPE_STRING, &name,
242 DBUS_TYPE_STRING, &from,
243 DBUS_TYPE_STRING, &to,
246 ERR("could not get NameOwnerChanged arguments: %s: %s\n",
247 err.name, err.message);
248 dbus_error_free(&err);
252 if (strcmp(name, _ethumb_dbus_bus_name) != 0)
255 DBG("NameOwnerChanged from=[%s] to=[%s]\n", from, to);
257 if (from[0] != '\0' && to[0] == '\0')
259 DBG("exit ethumbd at %s\n", from);
260 if (strcmp(client->unique_name, from) != 0)
261 WRN("%s was not the known name %s, ignored.\n",
262 from, client->unique_name);
265 ERR("server exit!!!\n");
268 client->die.cb(client->die.data, client);
269 client->die.cb = NULL;
271 if (client->die.free_data)
273 client->die.free_data(client->die.data);
274 client->die.free_data = NULL;
275 client->die.data = NULL;
280 DBG("unknown change from %s to %s\n", from, to);
284 _ethumb_client_report_connect(Ethumb_Client *client, Eina_Bool success)
286 if (!client->connect.cb)
288 ERR("already called?!");
292 client->connect.cb(client->connect.data, client, success);
293 if (client->connect.free_data)
295 client->connect.free_data(client->connect.data);
296 client->connect.free_data = NULL;
298 client->connect.cb = NULL;
299 client->connect.data = NULL;
303 _ethumb_client_new_cb(void *data, DBusMessage *msg, DBusError *error)
305 DBusMessageIter iter;
308 Ethumb_Client *client = data;
310 client->pending_new = NULL;
312 if (!_dbus_callback_check_and_init(msg, &iter, error))
314 t = dbus_message_iter_get_arg_type(&iter);
315 if (!_dbus_iter_type_check(t, DBUS_TYPE_OBJECT_PATH))
318 dbus_message_iter_get_basic(&iter, &opath);
319 if (opath[0] == '\0')
322 client->object_path = eina_stringshare_add(opath);
324 client->generated_signal = e_dbus_signal_handler_add(
325 client->conn, _ethumb_dbus_bus_name, opath,
326 _ethumb_dbus_objects_interface, "generated",
327 _ethumb_client_generated_cb, client);
329 _ethumb_client_report_connect(client, 1);
333 _ethumb_client_report_connect(client, 0);
337 _ethumb_client_call_new(Ethumb_Client *client)
341 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name, _ethumb_dbus_path,
342 _ethumb_dbus_interface, "new");
343 client->pending_new = e_dbus_message_send(client->conn, msg,
344 _ethumb_client_new_cb, -1,
346 dbus_message_unref(msg);
350 _ethumb_client_start_server_cb(void *data, DBusMessage *msg, DBusError *err)
352 Ethumb_Client *client = data;
353 DBusMessageIter iter;
357 client->pending_start_service_by_name = NULL;
359 if (!_dbus_callback_check_and_init(msg, &iter, err))
362 t = dbus_message_iter_get_arg_type(&iter);
363 if (!_dbus_iter_type_check(t, DBUS_TYPE_UINT32))
366 dbus_message_iter_get_basic(&iter, &ret);
367 if ((ret != 1) && (ret != 2))
369 ERR("Error starting Ethumbd DBus service by its name: retcode %u\n",
374 client->server_started = 1;
375 DBG("Ethumbd DBus service started successfully (%d), now request its name\n",
378 if (client->pending_get_name_owner)
380 DBG("already requesting name owner, cancel and try again\n");
381 dbus_pending_call_cancel(client->pending_get_name_owner);
384 client->pending_get_name_owner = e_dbus_get_name_owner
385 (client->conn, _ethumb_dbus_bus_name, _ethumb_client_get_name_owner,
387 if (!client->pending_get_name_owner)
389 ERR("could not create a get_name_owner request.\n");
396 ERR("failed to start Ethumbd DBus service by its name.\n");
397 _ethumb_client_report_connect(client, 0);
401 _ethumb_client_start_server(Ethumb_Client *client)
403 if (client->pending_start_service_by_name)
405 DBG("already pending start service by name.\n");
409 client->server_started = 0;
410 client->pending_start_service_by_name = e_dbus_start_service_by_name
411 (client->conn, _ethumb_dbus_bus_name, 0, _ethumb_client_start_server_cb,
413 if (!client->pending_start_service_by_name)
415 ERR("could not start service by name!\n");
416 _ethumb_client_report_connect(client, 0);
421 _ethumb_client_get_name_owner(void *data, DBusMessage *msg, DBusError *err)
423 DBusMessageIter iter;
425 Ethumb_Client *client = data;
428 client->pending_get_name_owner = NULL;
430 if (dbus_error_is_set(err) && (!client->server_started))
432 DBG("could not find server (%s), try to start it...\n", err->message);
433 _ethumb_client_start_server(client);
437 if (!_dbus_callback_check_and_init(msg, &iter, err))
440 t = dbus_message_iter_get_arg_type(&iter);
441 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
444 dbus_message_iter_get_basic(&iter, &uid);
447 ERR("no name owner!\n");
451 DBG("unique name = %s\n", uid);
452 client->unique_name = eina_stringshare_add(uid);
454 _ethumb_client_call_new(client);
455 client->connected = 1;
459 _ethumb_client_report_connect(client, 0);
467 ethumb_client_init(void)
474 fprintf(stderr, "ERROR: Could not initialize log module.\n");
477 _log_dom = eina_log_domain_register("ethumb_client", EINA_COLOR_YELLOW);
480 EINA_LOG_ERR("Could not register log domain: ethumb_client");
492 ethumb_client_shutdown(void)
500 eina_log_domain_unregister(_log_dom);
507 * Connects to Ethumb server and return the client instance.
509 * This is the "constructor" of Ethumb_Client, where everything
512 * If server was down, it is tried to start it using DBus activation,
513 * then the connection is retried.
515 * This call is asynchronous and will not block, instead it will be in
516 * "not connected" state until @a connect_cb is called with either
517 * success or failure. On failure, then no methods should be
518 * called. On success you're now able to setup and then ask generation
521 * Usually you should listen for server death/disconenction with
522 * ethumb_client_on_server_die_callback_set().
524 * @param connect_cb function to call to report connection success or
525 * failure. Do not call any other ethumb_client method until
526 * this function returns. The first received parameter is the
527 * given argument @a data. Must @b not be @c NULL. This
528 * function will not be called if user explicitly calls
529 * ethumb_client_disconnect().
530 * @param data context to give back to @a connect_cb. May be @c NULL.
531 * @param free_data function used to release @a data resources, if
532 * any. May be @c NULL. If this function exists, it will be
533 * called immediately after @a connect_cb is called or if user
534 * explicitly calls ethumb_client_disconnect() before such
535 * (that is, don't rely on @a data after @a connect_cb was
538 * @return client instance or NULL if failed. If @a connect_cb is
539 * missing it returns @c NULL. If it fail for other
540 * conditions, @c NULL is also returned and @a connect_cb is
541 * called with @c success=EINA_FALSE. The client instance is
542 * not ready to be used until @a connect_cb is called.
545 ethumb_client_connect(Ethumb_Client_Connect_Cb connect_cb, const void *data, Eina_Free_Cb free_data)
547 Ethumb_Client *eclient;
549 EINA_SAFETY_ON_NULL_RETURN_VAL(connect_cb, NULL);
551 eclient = calloc(1, sizeof(*eclient));
554 ERR("could not allocate Ethumb_Client structure.\n");
558 eclient->connect.cb = connect_cb;
559 eclient->connect.data = (void *)data;
560 eclient->connect.free_data = free_data;
562 eclient->ethumb = ethumb_new();
563 if (!eclient->ethumb)
565 ERR("could not create ethumb handler.\n");
569 eclient->conn = e_dbus_bus_get(DBUS_BUS_SESSION);
572 ERR("could not connect to session bus.\n");
576 eclient->name_owner_changed_handler = e_dbus_signal_handler_add(
577 eclient->conn, fdo_bus_name, fdo_path, fdo_interface,
578 "NameOwnerChanged", _ethumb_client_name_owner_changed, eclient);
580 eclient->pending_get_name_owner = e_dbus_get_name_owner(
581 eclient->conn, _ethumb_dbus_bus_name, _ethumb_client_get_name_owner,
583 if (!eclient->pending_get_name_owner)
585 ERR("could not create a get_name_owner request.\n");
592 ethumb_free(eclient->ethumb);
596 connect_cb((void *)data, NULL, EINA_FALSE);
598 free_data((void *)data);
603 * Disconnect the client, releasing all client resources.
605 * This is the destructor of Ethumb_Client, after it's disconnected
606 * the client handle is now gone and should not be used.
609 ethumb_client_disconnect(Ethumb_Client *client)
613 EINA_SAFETY_ON_NULL_RETURN(client);
615 if (!client->connected)
618 EINA_LIST_FREE(client->pending_add, data)
620 struct _ethumb_pending_add *pending = data;
621 eina_stringshare_del(pending->file);
622 eina_stringshare_del(pending->key);
623 eina_stringshare_del(pending->thumb);
624 eina_stringshare_del(pending->thumb_key);
625 dbus_pending_call_cancel(pending->pending_call);
626 dbus_pending_call_unref(pending->pending_call);
627 if (pending->free_data)
628 pending->free_data(pending->data);
632 EINA_LIST_FREE(client->pending_gen, data)
634 struct _ethumb_pending_gen *pending = data;
635 eina_stringshare_del(pending->file);
636 eina_stringshare_del(pending->key);
637 eina_stringshare_del(pending->thumb);
638 eina_stringshare_del(pending->thumb_key);
639 if (pending->free_data)
640 pending->free_data(pending->data);
644 EINA_LIST_FREE(client->pending_remove, data)
646 struct _ethumb_pending_remove *pending = data;
647 dbus_pending_call_cancel(pending->pending_call);
648 dbus_pending_call_unref(pending->pending_call);
649 if (pending->free_data)
650 pending->free_data(pending->data);
654 if (client->pending_clear)
656 dbus_pending_call_cancel(client->pending_clear);
657 dbus_pending_call_unref(client->pending_clear);
661 if (client->object_path)
662 eina_stringshare_del(client->object_path);
664 if (client->pending_new)
665 dbus_pending_call_cancel(client->pending_new);
667 if (client->unique_name)
668 eina_stringshare_del(client->unique_name);
670 if (client->pending_get_name_owner)
671 dbus_pending_call_cancel(client->pending_get_name_owner);
673 if (client->pending_start_service_by_name)
674 dbus_pending_call_cancel(client->pending_start_service_by_name);
676 ethumb_free(client->ethumb);
678 e_dbus_signal_handler_del(client->conn, client->name_owner_changed_handler);
679 if (client->connected)
680 e_dbus_signal_handler_del(client->conn, client->generated_signal);
681 e_dbus_connection_close(client->conn);
683 if (client->connect.free_data)
684 client->connect.free_data(client->connect.data);
685 if (client->die.free_data)
686 client->die.free_data(client->die.data);
692 * Sets the callback to report server died.
694 * When server dies there is nothing you can do, just release
695 * resources with ethumb_client_disconnect() and probably try to
698 * Usually you should set this callback and handle this case, it does
701 * @param client the client instance to monitor. Must @b not be @c
703 * @param server_die_cb function to call back when server dies. The
704 * first parameter will be the argument @a data. May be @c
706 * @param data context to give back to @a server_die_cb. May be @c
708 * @param free_data used to release @a data resources after @a
709 * server_die_cb is called or user calls
710 * ethumb_client_disconnect().
713 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)
715 EINA_SAFETY_ON_NULL_RETURN(client);
717 if (client->die.free_data)
718 client->die.free_data(client->die.data);
720 client->die.cb = server_die_cb;
721 client->die.data = (void *)data;
722 client->die.free_data = free_data;
730 _ethumb_client_ethumb_setup_cb(void *data, DBusMessage *msg, DBusError *error)
732 DBusMessageIter iter;
734 dbus_bool_t result = 0;
735 Ethumb_Client *client = data;
737 client->pending_setup = NULL;
739 if (!_dbus_callback_check_and_init(msg, &iter, error))
742 t = dbus_message_iter_get_arg_type(&iter);
743 if (!_dbus_iter_type_check(t, DBUS_TYPE_BOOLEAN))
746 dbus_message_iter_get_basic(&iter, &result);
750 _ethumb_client_dbus_get_bytearray(DBusMessageIter *iter)
754 DBusMessageIter riter;
757 el_type = dbus_message_iter_get_element_type(iter);
758 if (el_type != DBUS_TYPE_BYTE)
760 ERR("not an byte array element.\n");
764 dbus_message_iter_recurse(iter, &riter);
765 dbus_message_iter_get_fixed_array(&riter, &result, &length);
767 if (result[0] == '\0')
770 return eina_stringshare_add(result);
774 _ethumb_client_dbus_append_bytearray(DBusMessageIter *iter, const char *string)
776 DBusMessageIter viter;
781 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &viter);
782 dbus_message_iter_append_fixed_array(&viter, DBUS_TYPE_BYTE, &string,
784 dbus_message_iter_close_container(iter, &viter);
792 * Send setup to server.
794 * This method is called automatically by ethumb_client_generate() if
795 * any property was changed. No need to call it manually.
797 * @param client client instance. Must @b not be @c NULL and client
798 * must be connected (after connected_cb is called).
801 ethumb_client_ethumb_setup(Ethumb_Client *client)
804 DBusMessageIter iter, aiter, diter, viter, vaiter;
805 Ethumb *e = client->ethumb;
807 dbus_int32_t tw, th, format, aspect, quality, compress;
810 const char *theme_file, *group, *swallow;
811 const char *directory, *category;
812 double video_time, video_start, video_interval;
813 dbus_int32_t video_ntimes, video_fps, document_page;
815 EINA_SAFETY_ON_NULL_RETURN(client);
816 EINA_SAFETY_ON_FALSE_RETURN(client->connected);
817 client->ethumb_dirty = 0;
819 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
821 _ethumb_dbus_objects_interface,
823 dbus_message_iter_init_append(msg, &iter);
824 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &aiter);
829 #define _open_variant_iter(str_entry, str_type, end_iter) \
831 dbus_message_iter_open_container(&aiter, DBUS_TYPE_DICT_ENTRY, NULL, &diter); \
832 dbus_message_iter_append_basic(&diter, DBUS_TYPE_STRING, &entry); \
833 dbus_message_iter_open_container(&diter, DBUS_TYPE_VARIANT, str_type, \
836 #define _close_variant_iter(end_iter) \
837 dbus_message_iter_close_container(&diter, &end_iter); \
838 dbus_message_iter_close_container(&aiter, &diter);
843 /* starting array elements */
845 _open_variant_iter("size", "(ii)", viter);
846 dbus_message_iter_open_container(&viter, DBUS_TYPE_STRUCT, NULL, &vaiter);
847 ethumb_thumb_size_get(e, &tw, &th);
848 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_INT32, &tw);
849 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_INT32, &th);
850 dbus_message_iter_close_container(&viter, &vaiter);
851 _close_variant_iter(viter);
853 _open_variant_iter("format", "i", viter);
854 format = ethumb_thumb_format_get(e);
855 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &format);
856 _close_variant_iter(viter);
858 _open_variant_iter("aspect", "i", viter);
859 aspect = ethumb_thumb_aspect_get(e);
860 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &aspect);
861 _close_variant_iter(viter);
863 _open_variant_iter("crop", "(dd)", viter);
864 dbus_message_iter_open_container(&viter, DBUS_TYPE_STRUCT, NULL, &vaiter);
865 ethumb_thumb_crop_align_get(e, &cx, &cy);
867 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_DOUBLE, &t);
869 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_DOUBLE, &t);
870 dbus_message_iter_close_container(&viter, &vaiter);
871 _close_variant_iter(viter);
873 _open_variant_iter("quality", "i", viter);
874 quality = ethumb_thumb_quality_get(e);
875 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &quality);
876 _close_variant_iter(viter);
878 _open_variant_iter("compress", "i", viter);
879 compress = ethumb_thumb_compress_get(e);
880 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &compress);
881 _close_variant_iter(viter);
883 _open_variant_iter("frame", "(ayayay)", viter);
884 dbus_message_iter_open_container(&viter, DBUS_TYPE_STRUCT, NULL, &vaiter);
885 ethumb_frame_get(e, &theme_file, &group, &swallow);
886 _ethumb_client_dbus_append_bytearray(&vaiter, theme_file);
887 _ethumb_client_dbus_append_bytearray(&vaiter, group);
888 _ethumb_client_dbus_append_bytearray(&vaiter, swallow);
889 dbus_message_iter_close_container(&viter, &vaiter);
890 _close_variant_iter(viter);
892 _open_variant_iter("directory", "ay", viter);
893 directory = ethumb_thumb_dir_path_get(e);
894 _ethumb_client_dbus_append_bytearray(&viter, directory);
895 _close_variant_iter(viter);
897 _open_variant_iter("category", "ay", viter);
898 category = ethumb_thumb_category_get(e);
899 _ethumb_client_dbus_append_bytearray(&viter, category);
900 _close_variant_iter(viter);
902 _open_variant_iter("video_time", "d", viter);
903 video_time = ethumb_video_time_get(e);
904 dbus_message_iter_append_basic(&viter, DBUS_TYPE_DOUBLE, &video_time);
905 _close_variant_iter(viter);
907 _open_variant_iter("video_start", "d", viter);
908 video_start = ethumb_video_start_get(e);
909 dbus_message_iter_append_basic(&viter, DBUS_TYPE_DOUBLE, &video_start);
910 _close_variant_iter(viter);
912 _open_variant_iter("video_interval", "d", viter);
913 video_interval = ethumb_video_interval_get(e);
914 dbus_message_iter_append_basic(&viter, DBUS_TYPE_DOUBLE, &video_interval);
915 _close_variant_iter(viter);
917 _open_variant_iter("video_ntimes", "i", viter);
918 video_ntimes = ethumb_video_ntimes_get(e);
919 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &video_ntimes);
920 _close_variant_iter(viter);
922 _open_variant_iter("video_fps", "i", viter);
923 video_fps = ethumb_video_fps_get(e);
924 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &video_fps);
925 _close_variant_iter(viter);
927 _open_variant_iter("document_page", "i", viter);
928 document_page = ethumb_document_page_get(e);
929 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &document_page);
930 _close_variant_iter(viter);
932 #undef _open_variant_iter
933 #undef _close_variant_iter
935 dbus_message_iter_close_container(&iter, &aiter);
937 client->pending_setup = e_dbus_message_send(client->conn, msg,
938 _ethumb_client_ethumb_setup_cb,
940 dbus_message_unref(msg);
948 _ethumb_client_generated_cb(void *data, DBusMessage *msg)
950 DBusMessageIter iter;
951 dbus_int32_t id = -1;
953 const char *thumb_key;
954 Ethumb_Client *client = data;
959 struct _ethumb_pending_gen *pending;
961 dbus_message_iter_init(msg, &iter);
963 t = dbus_message_iter_get_arg_type(&iter);
964 if (!_dbus_iter_type_check(t, DBUS_TYPE_INT32))
966 dbus_message_iter_get_basic(&iter, &id);
967 dbus_message_iter_next(&iter);
969 t = dbus_message_iter_get_arg_type(&iter);
970 if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
972 thumb = _ethumb_client_dbus_get_bytearray(&iter);
973 dbus_message_iter_next(&iter);
975 t = dbus_message_iter_get_arg_type(&iter);
976 if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
978 thumb_key = _ethumb_client_dbus_get_bytearray(&iter);
979 dbus_message_iter_next(&iter);
981 t = dbus_message_iter_get_arg_type(&iter);
982 if (!_dbus_iter_type_check(t, DBUS_TYPE_BOOLEAN))
984 dbus_message_iter_get_basic(&iter, &success);
987 l = client->pending_gen;
991 if (pending->id == id)
1001 client->pending_gen = eina_list_remove_list(client->pending_gen, l);
1002 pending->generated_cb(pending->data, client, id,
1003 pending->file, pending->key,
1004 pending->thumb, pending->thumb_key,
1006 if (pending->free_data)
1007 pending->free_data(pending->data);
1008 eina_stringshare_del(pending->file);
1009 eina_stringshare_del(pending->key);
1010 eina_stringshare_del(pending->thumb);
1011 eina_stringshare_del(pending->thumb_key);
1016 eina_stringshare_del(thumb);
1017 eina_stringshare_del(thumb_key);
1021 _ethumb_client_queue_add_cb(void *data, DBusMessage *msg, DBusError *error)
1023 DBusMessageIter iter;
1025 dbus_int32_t id = -1;
1026 struct _ethumb_pending_add *pending = data;
1027 struct _ethumb_pending_gen *generating;
1028 Ethumb_Client *client = pending->client;
1030 client->pending_add = eina_list_remove(client->pending_add, pending);
1032 if (!_dbus_callback_check_and_init(msg, &iter, error))
1035 t = dbus_message_iter_get_arg_type(&iter);
1036 if (!_dbus_iter_type_check(t, DBUS_TYPE_INT32))
1039 dbus_message_iter_get_basic(&iter, &id);
1041 generating = calloc(1, sizeof(*generating));
1042 generating->id = id;
1043 generating->file = pending->file;
1044 generating->key = pending->key;
1045 generating->thumb = pending->thumb;
1046 generating->thumb_key = pending->thumb_key;
1047 generating->generated_cb = pending->generated_cb;
1048 generating->data = pending->data;
1049 generating->free_data = pending->free_data;
1050 client->pending_gen = eina_list_append(client->pending_gen, generating);
1057 _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)
1060 DBusMessageIter iter;
1061 struct _ethumb_pending_add *pending;
1063 pending = calloc(1, sizeof(*pending));
1064 pending->id = client->id_count;
1065 pending->file = eina_stringshare_add(file);
1066 pending->key = eina_stringshare_add(key);
1067 pending->thumb = eina_stringshare_add(thumb);
1068 pending->thumb_key = eina_stringshare_add(thumb_key);
1069 pending->generated_cb = generated_cb;
1070 pending->data = (void *)data;
1071 pending->free_data = free_data;
1072 pending->client = client;
1074 client->id_count = (client->id_count + 1) % MAX_ID;
1076 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
1077 client->object_path,
1078 _ethumb_dbus_objects_interface,
1081 dbus_message_iter_init_append(msg, &iter);
1082 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &pending->id);
1083 _ethumb_client_dbus_append_bytearray(&iter, file);
1084 _ethumb_client_dbus_append_bytearray(&iter, key);
1085 _ethumb_client_dbus_append_bytearray(&iter, thumb);
1086 _ethumb_client_dbus_append_bytearray(&iter, thumb_key);
1088 pending->pending_call = e_dbus_message_send(client->conn, msg,
1089 _ethumb_client_queue_add_cb,
1091 client->pending_add = eina_list_append(client->pending_add, pending);
1092 dbus_message_unref(msg);
1098 _ethumb_client_queue_remove_cb(void *data, DBusMessage *msg, DBusError *error)
1100 DBusMessageIter iter;
1102 dbus_bool_t success = 0;
1103 struct _ethumb_pending_remove *pending = data;
1104 Ethumb_Client *client = pending->client;
1106 client->pending_remove = eina_list_remove(client->pending_remove, pending);
1108 if (!_dbus_callback_check_and_init(msg, &iter, error))
1111 t = dbus_message_iter_get_arg_type(&iter);
1112 if (!_dbus_iter_type_check(t, DBUS_TYPE_BOOLEAN))
1115 dbus_message_iter_get_basic(&iter, &success);
1118 if (pending->cancel_cb)
1119 pending->cancel_cb(pending->data, success);
1120 if (pending->free_data)
1121 pending->free_data(pending->data);
1129 * Ask server to cancel generation of thumbnail.
1131 * @param client client instance. Must @b not be @c NULL and client
1132 * must be connected (after connected_cb is called).
1133 * @param id valid id returned by ethumb_client_generate()
1134 * @param cancel_cb function to report cancellation results.
1135 * @param data context argument to give back to @a cancel_cb. May be
1137 * @param data context to give back to @a cancel_cb. May be @c
1139 * @param free_data used to release @a data resources after @a
1140 * cancel_cb is called or user calls
1141 * ethumb_client_disconnect().
1144 ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Generate_Cancel_Cb cancel_cb, const void *data, Eina_Free_Cb free_data)
1147 struct _ethumb_pending_remove *pending;
1150 dbus_int32_t id32 = id;
1151 EINA_SAFETY_ON_NULL_RETURN(client);
1152 EINA_SAFETY_ON_FALSE_RETURN(id >= 0);
1154 pending = calloc(1, sizeof(*pending));
1156 pending->cancel_cb = cancel_cb;
1157 pending->data = (void *)data;
1158 pending->free_data = free_data;
1159 pending->client = client;
1161 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
1162 client->object_path,
1163 _ethumb_dbus_objects_interface,
1166 dbus_message_append_args(msg, DBUS_TYPE_INT32, &id32, DBUS_TYPE_INVALID);
1167 pending->pending_call = e_dbus_message_send(client->conn, msg,
1168 _ethumb_client_queue_remove_cb,
1170 client->pending_remove = eina_list_append(client->pending_remove, pending);
1173 l = client->pending_add;
1176 struct _ethumb_pending_add *pending = l->data;
1177 if (pending->id != id32)
1182 client->pending_add = eina_list_remove_list(client->pending_add, l);
1183 eina_stringshare_del(pending->file);
1184 eina_stringshare_del(pending->key);
1185 eina_stringshare_del(pending->thumb);
1186 eina_stringshare_del(pending->thumb_key);
1187 dbus_pending_call_cancel(pending->pending_call);
1188 dbus_pending_call_unref(pending->pending_call);
1189 if (pending->free_data)
1190 pending->free_data(pending->data);
1199 l = client->pending_gen;
1202 struct _ethumb_pending_gen *pending = l->data;
1203 if (pending->id != id32)
1208 client->pending_gen = eina_list_remove_list(client->pending_gen, l);
1209 eina_stringshare_del(pending->file);
1210 eina_stringshare_del(pending->key);
1211 eina_stringshare_del(pending->thumb);
1212 eina_stringshare_del(pending->thumb_key);
1213 if (pending->free_data)
1214 pending->free_data(pending->data);
1221 dbus_message_unref(msg);
1228 _ethumb_client_queue_clear_cb(void *data, DBusMessage *msg __UNUSED__, DBusError *error __UNUSED__)
1230 Ethumb_Client *client = data;
1232 client->pending_clear = NULL;
1239 * Ask server to cancel generation of all thumbnails.
1241 * @param client client instance. Must @b not be @c NULL and client
1242 * must be connected (after connected_cb is called).
1244 * @see ethumb_client_generate_cancel()
1247 ethumb_client_generate_cancel_all(Ethumb_Client *client)
1251 EINA_SAFETY_ON_NULL_RETURN(client);
1253 if (client->pending_clear)
1256 EINA_LIST_FREE(client->pending_add, data)
1258 struct _ethumb_pending_add *pending = data;
1259 eina_stringshare_del(pending->file);
1260 eina_stringshare_del(pending->key);
1261 eina_stringshare_del(pending->thumb);
1262 eina_stringshare_del(pending->thumb_key);
1263 dbus_pending_call_cancel(pending->pending_call);
1264 dbus_pending_call_unref(pending->pending_call);
1265 if (pending->free_data)
1266 pending->free_data(pending->data);
1270 EINA_LIST_FREE(client->pending_gen, data)
1272 struct _ethumb_pending_gen *pending = data;
1273 eina_stringshare_del(pending->file);
1274 eina_stringshare_del(pending->key);
1275 eina_stringshare_del(pending->thumb);
1276 eina_stringshare_del(pending->thumb_key);
1277 if (pending->free_data)
1278 pending->free_data(pending->data);
1282 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
1283 client->object_path,
1284 _ethumb_dbus_objects_interface,
1287 client->pending_clear = e_dbus_message_send(client->conn, msg,
1288 _ethumb_client_queue_clear_cb,
1291 dbus_message_unref(msg);
1295 * Configure future requests to use FreeDesktop.Org preset.
1297 * This is a preset to provide freedesktop.org (fdo) standard
1298 * compliant thumbnails. That is, files are stored as JPEG under
1299 * ~/.thumbnails/SIZE, with size being either normal (128x128) or
1302 * @param s size identifier, either #ETHUMB_THUMB_NORMAL (0) or
1303 * #ETHUMB_THUMB_LARGE (1).
1305 * @see ethumb_client_size_set()
1306 * @see ethumb_client_aspect_set()
1307 * @see ethumb_client_crop_align_set()
1308 * @see ethumb_client_category_set()
1309 * @see ethumb_client_dir_path_set()
1312 ethumb_client_fdo_set(Ethumb_Client *client, Ethumb_Thumb_FDO_Size s)
1314 EINA_SAFETY_ON_NULL_RETURN(client);
1316 client->ethumb_dirty = 1;
1317 ethumb_thumb_fdo_set(client->ethumb, s);
1321 * Configure future request to use custom size.
1323 * @param w width, default is 128.
1324 * @param h height, default is 128.
1327 ethumb_client_size_set(Ethumb_Client *client, int tw, int th)
1329 EINA_SAFETY_ON_NULL_RETURN(client);
1331 client->ethumb_dirty = 1;
1332 ethumb_thumb_size_set(client->ethumb, tw, th);
1336 * Retrieve future request to use custom size.
1338 * @param w where to return width. May be #NULL.
1339 * @param h where to return height. May be #NULL.
1342 ethumb_client_size_get(const Ethumb_Client *client, int *tw, int *th)
1346 EINA_SAFETY_ON_NULL_RETURN(client);
1348 ethumb_thumb_size_get(client->ethumb, tw, th);
1352 * Configure format to use for future requests.
1354 * @param f format identifier to use, either #ETHUMB_THUMB_FDO (0),
1355 * #ETHUMB_THUMB_JPEG (1) or #ETHUMB_THUMB_EET (2). Default is FDO.
1358 ethumb_client_format_set(Ethumb_Client *client, Ethumb_Thumb_Format f)
1360 EINA_SAFETY_ON_NULL_RETURN(client);
1362 client->ethumb_dirty = 1;
1363 ethumb_thumb_format_set(client->ethumb, f);
1367 * Retrieve format to use for future requests.
1369 * @return format identifier to use, either #ETHUMB_THUMB_FDO (0),
1370 * #ETHUMB_THUMB_JPEG (1) or #ETHUMB_THUMB_EET (2).
1372 EAPI Ethumb_Thumb_Format
1373 ethumb_client_format_get(const Ethumb_Client *client)
1375 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1377 return ethumb_thumb_format_get(client->ethumb);
1381 * Configure aspect mode to use.
1383 * If aspect is kept (#ETHUMB_THUMB_KEEP_ASPECT), then image will be
1384 * rescaled so the largest dimension is not bigger than it's specified
1385 * size (see ethumb_client_size_get()) and the other dimension is
1386 * resized in the same proportion. Example: size is 256x256, image is
1387 * 1000x500, resulting thumbnail is 256x128.
1389 * If aspect is ignored (#ETHUMB_THUMB_IGNORE_ASPECT), then image will
1390 * be distorted to match required thumbnail size. Example: size is
1391 * 256x256, image is 1000x500, resulting thumbnail is 256x256.
1393 * If crop is required (#ETHUMB_THUMB_CROP), then image will be
1394 * cropped so the smallest dimension is not bigger than its specified
1395 * size (see ethumb_client_size_get()) and the other dimension will
1396 * overflow, not being visible in the final image. How it will
1397 * overflow is speficied by ethumb_client_crop_align_set()
1398 * alignment. Example: size is 256x256, image is 1000x500, crop
1399 * alignment is 0.5, 0.5, resulting thumbnail is 256x256 with 250
1400 * pixels from left and 250 pixels from right being lost, that is just
1401 * the 500x500 central pixels of image will be considered for scaling.
1403 * @param a aspect mode identifier, either #ETHUMB_THUMB_KEEP_ASPECT (0),
1404 * #ETHUMB_THUMB_IGNORE_ASPECT (1) or #ETHUMB_THUMB_CROP (2).
1407 ethumb_client_aspect_set(Ethumb_Client *client, Ethumb_Thumb_Aspect a)
1409 EINA_SAFETY_ON_NULL_RETURN(client);
1411 client->ethumb_dirty = 1;
1412 ethumb_thumb_aspect_set(client->ethumb, a);
1416 * Get current aspect in use for requests.
1418 * @return aspect in use for future requests.
1420 EAPI Ethumb_Thumb_Aspect
1421 ethumb_client_aspect_get(const Ethumb_Client *client)
1423 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1425 return ethumb_thumb_aspect_get(client->ethumb);
1429 * Configure crop alignment in use for future requests.
1431 * @param x horizontal alignment. 0.0 means left side will be visible
1432 * or right side is being lost. 1.0 means right side will be
1433 * visible or left side is being lost. 0.5 means just center is
1434 * visible, both sides will be lost. Default is 0.5.
1435 * @param y vertical alignment. 0.0 is top visible, 1.0 is bottom
1436 * visible, 0.5 is center visible. Default is 0.5
1439 ethumb_client_crop_align_set(Ethumb_Client *client, float x, float y)
1441 EINA_SAFETY_ON_NULL_RETURN(client);
1443 client->ethumb_dirty = 1;
1444 ethumb_thumb_crop_align_set(client->ethumb, x, y);
1448 * Get current crop alignment in use for requests.
1450 * @param x where to return horizontal alignment. May be #NULL.
1451 * @param y where to return vertical alignment. May be #NULL.
1454 ethumb_client_crop_align_get(const Ethumb_Client *client, float *x, float *y)
1458 EINA_SAFETY_ON_NULL_RETURN(client);
1460 ethumb_thumb_crop_align_get(client->ethumb, x, y);
1464 * Configure quality to be used in thumbnails.
1466 * @param quality value from 0 to 100, default is 80. The effect
1467 * depends on the format being used, PNG will not use it.
1470 ethumb_client_quality_set(Ethumb_Client *client, int quality)
1472 EINA_SAFETY_ON_NULL_RETURN(client);
1474 ethumb_thumb_quality_set(client->ethumb, quality);
1478 * Get quality to be used in thumbnails.
1480 * @return quality value from 0 to 100, default is 80. The effect
1481 * depends on the format being used, PNG will not use it.
1484 ethumb_client_quality_get(const Ethumb_Client *client)
1486 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1488 return ethumb_thumb_quality_get(client->ethumb);
1492 * Configure compression level used in requests.
1494 * @param compress value from 0 to 9, default is 9. The effect
1495 * depends on the format being used, JPEG will not use it.
1498 ethumb_client_compress_set(Ethumb_Client *client, int compress)
1500 EINA_SAFETY_ON_NULL_RETURN(client);
1502 ethumb_thumb_compress_set(client->ethumb, compress);
1506 * Get compression level used in requests.
1508 * @return compress value from 0 to 9, default is 9. The effect
1509 * depends on the format being used, JPEG will not use it.
1512 ethumb_client_compress_get(const Ethumb_Client *client)
1514 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1516 return ethumb_thumb_compress_get(client->ethumb);
1520 * Set frame to apply to future thumbnails.
1522 * This will create an edje object that will have image swallowed
1523 * in. This can be used to simulate Polaroid or wood frames in the
1524 * generated image. Remeber it is bad to modify the original contents
1525 * of thumbnails, but sometimes it's useful to have it composited and
1526 * avoid runtime overhead.
1528 * @param file file path to edje.
1529 * @param group group inside edje to use.
1530 * @param swallow name of swallow part.
1533 ethumb_client_frame_set(Ethumb_Client *client, const char *file, const char *group, const char *swallow)
1535 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1537 client->ethumb_dirty = 1;
1538 return ethumb_frame_set(client->ethumb, file, group, swallow);
1542 * Configure where to store thumbnails in future requests.
1544 * Note that this is the base, a category is added to this path as a
1547 * @param path base directory where to store thumbnails. Default is
1551 ethumb_client_dir_path_set(Ethumb_Client *client, const char *path)
1553 EINA_SAFETY_ON_NULL_RETURN(client);
1555 client->ethumb_dirty = 1;
1556 ethumb_thumb_dir_path_set(client->ethumb, path);
1560 ethumb_client_dir_path_get(const Ethumb_Client *client)
1562 EINA_SAFETY_ON_NULL_RETURN_VAL(client, NULL);
1564 return ethumb_thumb_dir_path_get(client->ethumb);
1568 * Category directory to store thumbnails.
1570 * @param category category sub directory to store thumbnail. Default
1571 * is either "normal" or "large" for FDO compliant thumbnails
1572 * or WIDTHxHEIGHT-ASPECT[-FRAMED]-FORMAT. It can be a string
1573 * or None to use auto generated names.
1576 ethumb_client_category_set(Ethumb_Client *client, const char *category)
1578 EINA_SAFETY_ON_NULL_RETURN(client);
1580 client->ethumb_dirty = 1;
1581 ethumb_thumb_category_set(client->ethumb, category);
1585 ethumb_client_category_get(const Ethumb_Client *client)
1587 EINA_SAFETY_ON_NULL_RETURN_VAL(client, NULL);
1589 return ethumb_thumb_category_get(client->ethumb);
1593 ethumb_client_video_time_set(Ethumb_Client *client, float time)
1595 EINA_SAFETY_ON_NULL_RETURN(client);
1597 client->ethumb_dirty = 1;
1598 ethumb_video_time_set(client->ethumb, time);
1602 ethumb_client_video_start_set(Ethumb_Client *client, float start)
1604 EINA_SAFETY_ON_NULL_RETURN(client);
1606 client->ethumb_dirty = 1;
1607 ethumb_video_start_set(client->ethumb, start);
1611 ethumb_client_video_interval_set(Ethumb_Client *client, float interval)
1613 EINA_SAFETY_ON_NULL_RETURN(client);
1615 client->ethumb_dirty = 1;
1616 ethumb_video_interval_set(client->ethumb, interval);
1620 ethumb_client_video_ntimes_set(Ethumb_Client *client, int ntimes)
1622 EINA_SAFETY_ON_NULL_RETURN(client);
1624 client->ethumb_dirty = 1;
1625 ethumb_video_ntimes_set(client->ethumb, ntimes);
1629 ethumb_client_video_fps_set(Ethumb_Client *client, int fps)
1631 EINA_SAFETY_ON_NULL_RETURN(client);
1633 client->ethumb_dirty = 1;
1634 ethumb_video_fps_set(client->ethumb, fps);
1638 ethumb_client_document_page_set(Ethumb_Client *client, int page)
1640 EINA_SAFETY_ON_NULL_RETURN(client);
1642 client->ethumb_dirty = 1;
1643 ethumb_document_page_set(client->ethumb, page);
1647 * Set source file to be thumbnailed.
1649 * Calling this function has the side effect of resetting values set
1650 * with ethumb_client_thumb_path_set() or auto-generated with
1651 * ethumb_client_thumb_exists().
1653 * @param client the client instance to use. Must @b not be @c
1654 * NULL. May be pending connected (can be called before @c
1656 * @param path the filesystem path to use. May be @c NULL.
1657 * @param key the extra argument/key inside @a path to read image
1658 * from. This is only used for formats that allow multiple
1659 * resources in one file, like EET or Edje (group name).
1661 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
1664 ethumb_client_file_set(Ethumb_Client *client, const char *path, const char *key)
1666 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1668 return ethumb_file_set(client->ethumb, path, key);
1672 * Get values set with ethumb_client_file_get()
1675 ethumb_client_file_get(Ethumb_Client *client, const char **path, const char **key)
1677 if (path) *path = NULL;
1678 if (key) *key = NULL;
1679 EINA_SAFETY_ON_NULL_RETURN(client);
1681 ethumb_file_get(client->ethumb, path, key);
1685 * Reset previously set file to @c NULL.
1687 * @param client the client instance to use. Must @b not be @c
1688 * NULL. May be pending connected (can be called before @c
1692 ethumb_client_file_free(Ethumb_Client *client)
1694 EINA_SAFETY_ON_NULL_RETURN(client);
1696 ethumb_file_free(client->ethumb);
1700 * Set a defined path and key to store the thumbnail.
1702 * If not explicitly given, the thumbnail path will be auto-generated
1703 * by ethumb_client_thumb_exists() or server using configured
1704 * parameters like size, aspect and category.
1706 * Set these to @c NULL to forget previously given values. After
1707 * ethumb_client_file_set() these values will be reset to @c NULL.
1710 ethumb_client_thumb_path_set(Ethumb_Client *client, const char *path, const char *key)
1712 EINA_SAFETY_ON_NULL_RETURN(client);
1714 ethumb_thumb_path_set(client->ethumb, path, key);
1718 * Get the configured thumbnail path.
1720 * This returns the value set with ethumb_client_thumb_path_set() or
1721 * auto-generated by ethumb_client_thumb_exists() if it was not set.
1723 * @param path where to return configured path. May be @c NULL. If
1724 * there was no path configured with
1725 * ethumb_client_thumb_path_set() and
1726 * ethumb_client_thumb_exists() was not called, then it will
1727 * probably return @c NULL. If not @c NULL, then it will be a
1728 * pointer to a stringshared instance, but @b no references are
1729 * added (do it with eina_stringshare_ref())!
1730 * @param key where to return configured key. May be @c NULL. If
1731 * there was no key configured with
1732 * ethumb_client_thumb_key_set() and
1733 * ethumb_client_thumb_exists() was not called, then it will
1734 * probably return @c NULL. If not @c NULL, then it will be a
1735 * pointer to a stringshared instance, but @b no references are
1736 * added (do it with eina_stringshare_ref())!
1739 ethumb_client_thumb_path_get(Ethumb_Client *client, const char **path, const char **key)
1741 if (path) *path = NULL;
1742 if (key) *key = NULL;
1743 EINA_SAFETY_ON_NULL_RETURN(client);
1745 ethumb_thumb_path_get(client->ethumb, path, key);
1749 * Checks whenever file already exists (locally!)
1751 * This will check locally (not calling server) if thumbnail already
1752 * exists or not, also calculating the thumbnail path. See
1753 * ethumb_client_thumb_path_get(). Path must be configured with
1754 * ethumb_client_file_set() before using it and the last set file will
1757 * @param client client instance. Must @b not be @c NULL and client
1758 * must be configured with ethumb_client_file_set().
1760 * @return #EINA_TRUE if it exists, #EINA_FALSE otherwise.
1763 ethumb_client_thumb_exists(Ethumb_Client *client)
1765 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1767 return ethumb_exists(client->ethumb);
1771 * Ask server to generate thumbnail.
1773 * This process is asynchronous and will report back from main loop
1774 * using @a generated_cb. One can cancel this request by calling
1775 * ethumb_client_generate_cancel() or
1776 * ethumb_client_generate_cancel_all(), but not that request might be
1777 * processed by server already and no generated files will be removed
1778 * if that is the case.
1780 * This will not check if file already exists, this should be done by
1781 * explicitly calling ethumb_client_thumb_exists(). That is, this
1782 * function will override any existing thumbnail.
1784 * @param client client instance. Must @b not be @c NULL and client
1785 * must be connected (after connected_cb is called).
1786 * @param generated_cb function to report generation results.
1787 * @param data context argument to give back to @a generated_cb. May
1789 * @param data context to give back to @a generate_cb. May be @c
1791 * @param free_data used to release @a data resources after @a
1792 * generated_cb is called or user calls
1793 * ethumb_client_disconnect().
1795 * @return identifier or -1 on error. If -1 is returned (error) then
1796 * @a free_data is @b not called!
1798 * @see ethumb_client_connect()
1799 * @see ethumb_client_file_set()
1800 * @see ethumb_client_thumb_exists()
1801 * @see ethumb_client_generate_cancel()
1802 * @see ethumb_client_generate_cancel_all()
1805 ethumb_client_generate(Ethumb_Client *client, Ethumb_Client_Generate_Cb generated_cb, const void *data, Eina_Free_Cb free_data)
1807 const char *file, *key, *thumb, *thumb_key;
1809 EINA_SAFETY_ON_NULL_RETURN_VAL(client, -1);
1810 EINA_SAFETY_ON_FALSE_RETURN_VAL(client->connected, -1);
1812 ethumb_file_get(client->ethumb, &file, &key);
1815 ERR("no file set.\n");
1819 ethumb_thumb_path_get(client->ethumb, &thumb, &thumb_key);
1821 if (client->ethumb_dirty)
1822 ethumb_client_ethumb_setup(client);
1823 id = _ethumb_client_queue_add(client, file, key, thumb, thumb_key,
1824 generated_cb, data, free_data);