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
75 #include <sys/types.h>
79 #include <eina_safety_checks.h>
83 #include "Ethumb_Client.h"
89 #define MAX_ID 2000000
91 static int _log_dom = -1;
92 #define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
93 #define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
94 #define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__)
95 #define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__)
96 #define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__)
103 E_DBus_Connection *conn;
104 E_DBus_Signal_Handler *name_owner_changed_handler;
105 E_DBus_Signal_Handler *generated_signal;
106 DBusPendingCall *pending_get_name_owner;
107 DBusPendingCall *pending_start_service_by_name;
108 const char *unique_name;
109 DBusPendingCall *pending_new;
111 Ethumb_Client_Connect_Cb cb;
113 Eina_Free_Cb free_data;
115 Eina_List *pending_add;
116 Eina_List *pending_remove;
117 Eina_List *pending_gen;
118 DBusPendingCall *pending_clear;
119 DBusPendingCall *pending_setup;
121 Ethumb_Client_Die_Cb cb;
123 Eina_Free_Cb free_data;
125 const char *object_path;
127 Eina_Bool ethumb_dirty : 1;
128 Eina_Bool connected : 1;
129 Eina_Bool server_started : 1;
132 struct _ethumb_pending_add
138 const char *thumb_key;
139 Ethumb_Client_Generate_Cb generated_cb;
141 Eina_Free_Cb free_data;
142 DBusPendingCall *pending_call;
143 Ethumb_Client *client;
146 struct _ethumb_pending_remove
149 Ethumb_Client_Generate_Cancel_Cb cancel_cb;
151 Eina_Free_Cb free_data;
152 DBusPendingCall *pending_call;
153 Ethumb_Client *client;
156 struct _ethumb_pending_gen
162 const char *thumb_key;
163 Ethumb_Client_Generate_Cb generated_cb;
165 Eina_Free_Cb free_data;
168 static const char _ethumb_dbus_bus_name[] = "org.enlightenment.Ethumb";
169 static const char _ethumb_dbus_interface[] = "org.enlightenment.Ethumb";
170 static const char _ethumb_dbus_objects_interface[] = "org.enlightenment.Ethumb.objects";
171 static const char _ethumb_dbus_path[] = "/org/enlightenment/Ethumb";
172 static const char fdo_interface[] = "org.freedesktop.DBus";
173 static const char fdo_bus_name[] = "org.freedesktop.DBus";
174 static const char fdo_path[] = "/org/freedesktop/DBus";
176 static int _initcount = 0;
178 static void _ethumb_client_generated_cb(void *data, DBusMessage *msg);
179 static void _ethumb_client_get_name_owner(void *data, DBusMessage *msg, DBusError *err);
182 __dbus_callback_check_and_init(const char *file, int line, const char *function, DBusMessage *msg, DBusMessageIter *itr, DBusError *err)
186 ERR("%s:%d:%s() callback without message arguments!",
187 file, line, function);
190 ERR("%s:%d:%s() an error was reported by server: "
191 "name=\"%s\", message=\"%s\"",
192 file, line, function, err->name, err->message);
197 if (!dbus_message_iter_init(msg, itr))
199 ERR("%s:%d:%s() could not init iterator.",
200 file, line, function);
207 #define _dbus_callback_check_and_init(msg, itr, err) \
208 __dbus_callback_check_and_init(__FILE__, __LINE__, __FUNCTION__, \
212 __dbus_iter_type_check(int type, int expected, const char *expected_name)
214 if (type == expected)
217 ERR("expected type %s (%c) but got %c instead!",
218 expected_name, expected, type);
222 #define _dbus_iter_type_check(t, e) __dbus_iter_type_check(t, e, #e)
224 #define CHECK_NULL_RETURN(ptr, ...) \
229 CRITICAL("%s == NULL!", #ptr); \
230 return __VA_ARGS__; \
236 _ethumb_client_name_owner_changed(void *data, DBusMessage *msg)
239 const char *name, *from, *to;
240 Ethumb_Client *client = data;
242 dbus_error_init(&err);
243 if (!dbus_message_get_args(msg, &err,
244 DBUS_TYPE_STRING, &name,
245 DBUS_TYPE_STRING, &from,
246 DBUS_TYPE_STRING, &to,
249 ERR("could not get NameOwnerChanged arguments: %s: %s",
250 err.name, err.message);
251 dbus_error_free(&err);
257 if (strcmp(name, _ethumb_dbus_bus_name) != 0)
260 DBG("NameOwnerChanged from=[%s] to=[%s]", from, to);
262 if (from[0] != '\0' && to[0] == '\0')
264 DBG("exit ethumbd at %s", from);
265 if (client->unique_name && strcmp(client->unique_name, from) != 0)
266 WRN("%s was not the known name %s, ignored.",
267 from, client->unique_name);
268 else if(client->unique_name)
270 ERR("server exit!!!");
273 client->die.cb(client->die.data, client);
274 client->die.cb = NULL;
276 if (client->die.free_data)
278 client->die.free_data(client->die.data);
279 client->die.free_data = NULL;
280 client->die.data = NULL;
285 DBG("unknown change from %s to %s", from, to);
289 _ethumb_client_report_connect(Ethumb_Client *client, Eina_Bool success)
291 if (!client->connect.cb)
293 ERR("already called?!");
297 client->connect.cb(client->connect.data, client, success);
298 if (client->connect.free_data)
300 client->connect.free_data(client->connect.data);
301 client->connect.free_data = NULL;
303 client->connect.cb = NULL;
304 client->connect.data = NULL;
308 _ethumb_client_new_cb(void *data, DBusMessage *msg, DBusError *error)
310 DBusMessageIter iter;
313 Ethumb_Client *client = data;
315 client->pending_new = NULL;
317 if (!_dbus_callback_check_and_init(msg, &iter, error))
319 t = dbus_message_iter_get_arg_type(&iter);
320 if (!_dbus_iter_type_check(t, DBUS_TYPE_OBJECT_PATH))
323 dbus_message_iter_get_basic(&iter, &opath);
324 if (opath[0] == '\0')
327 client->object_path = eina_stringshare_add(opath);
329 client->generated_signal = e_dbus_signal_handler_add(
330 client->conn, _ethumb_dbus_bus_name, opath,
331 _ethumb_dbus_objects_interface, "generated",
332 _ethumb_client_generated_cb, client);
334 _ethumb_client_report_connect(client, 1);
338 _ethumb_client_report_connect(client, 0);
342 _ethumb_client_call_new(Ethumb_Client *client)
346 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name, _ethumb_dbus_path,
347 _ethumb_dbus_interface, "new");
348 client->pending_new = e_dbus_message_send(client->conn, msg,
349 _ethumb_client_new_cb, -1,
351 dbus_message_unref(msg);
355 _ethumb_client_start_server_cb(void *data, DBusMessage *msg, DBusError *err)
357 Ethumb_Client *client = data;
358 DBusMessageIter iter;
362 client->pending_start_service_by_name = NULL;
364 if (!_dbus_callback_check_and_init(msg, &iter, err))
367 t = dbus_message_iter_get_arg_type(&iter);
368 if (!_dbus_iter_type_check(t, DBUS_TYPE_UINT32))
371 dbus_message_iter_get_basic(&iter, &ret);
372 if ((ret != 1) && (ret != 2))
374 ERR("Error starting Ethumbd DBus service by its name: retcode %u",
379 client->server_started = 1;
380 DBG("Ethumbd DBus service started successfully (%d), now request its name",
383 if (client->pending_get_name_owner)
385 DBG("already requesting name owner, cancel and try again");
386 dbus_pending_call_cancel(client->pending_get_name_owner);
389 client->pending_get_name_owner = e_dbus_get_name_owner
390 (client->conn, _ethumb_dbus_bus_name, _ethumb_client_get_name_owner,
392 if (!client->pending_get_name_owner)
394 ERR("could not create a get_name_owner request.");
401 ERR("failed to start Ethumbd DBus service by its name.");
402 _ethumb_client_report_connect(client, 0);
406 _ethumb_client_start_server(Ethumb_Client *client)
408 if (client->pending_start_service_by_name)
410 DBG("already pending start service by name.");
414 client->server_started = 0;
415 client->pending_start_service_by_name = e_dbus_start_service_by_name
416 (client->conn, _ethumb_dbus_bus_name, 0, _ethumb_client_start_server_cb,
418 if (!client->pending_start_service_by_name)
420 ERR("could not start service by name!");
421 _ethumb_client_report_connect(client, 0);
426 _ethumb_client_get_name_owner(void *data, DBusMessage *msg, DBusError *err)
428 DBusMessageIter iter;
430 Ethumb_Client *client = data;
433 client->pending_get_name_owner = NULL;
435 if (dbus_error_is_set(err) && (!client->server_started))
437 DBG("could not find server (%s), try to start it...", err->message);
438 _ethumb_client_start_server(client);
442 if (!_dbus_callback_check_and_init(msg, &iter, err))
445 t = dbus_message_iter_get_arg_type(&iter);
446 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
449 dbus_message_iter_get_basic(&iter, &uid);
452 ERR("no name owner!");
456 DBG("unique name = %s", uid);
457 client->unique_name = eina_stringshare_add(uid);
459 _ethumb_client_call_new(client);
460 client->connected = 1;
464 _ethumb_client_report_connect(client, 0);
472 * @brief Initialize the Ethumb_Client library.
474 * @return 1 or greater on success, 0 on error.
476 * This function sets up all the Ethumb_Client module dependencies. It
477 * returns 0 on failure (that is, when one of the dependency fails to
478 * initialize), otherwise it returns the number of times it has
479 * already been called.
481 * When Ethumb_Client is not used anymore, call
482 * ethumb_client_shutdown() to shut down the Ethumb_Client library.
484 * @see ethumb_client_shutdown()
485 * @see ethumb_client_connect()
486 * @see @ref tutorial_ethumb_client
489 ethumb_client_init(void)
496 fprintf(stderr, "ERROR: Could not initialize log module.\n");
499 _log_dom = eina_log_domain_register("ethumb_client", EINA_COLOR_YELLOW);
502 EINA_LOG_ERR("Could not register log domain: ethumb_client");
514 * @brief Shut down the Ethumb_Client library.
516 * @return 0 when everything is shut down, 1 or greater if there are
517 * other users of the Ethumb_Client library pending shutdown.
519 * This function shuts down the Ethumb_Client library. It returns 0
520 * when it has been called the same number of times than
521 * ethumb_client_init(). In that case it shut down all the
522 * Ethumb_Client modules dependencies.
524 * Once this function succeeds (that is, @c 0 is returned), you must
525 * not call any of the Eina function anymore. You must call
526 * ethumb_client_init() again to use the Ethumb_Client functions
530 ethumb_client_shutdown(void)
538 eina_log_domain_unregister(_log_dom);
545 * Connects to Ethumb server and return the client instance.
547 * This is the "constructor" of Ethumb_Client, where everything
550 * If server was down, it is tried to start it using DBus activation,
551 * then the connection is retried.
553 * This call is asynchronous and will not block, instead it will be in
554 * "not connected" state until @a connect_cb is called with either
555 * success or failure. On failure, then no methods should be
556 * called. On success you're now able to setup and then ask generation
559 * Usually you should listen for server death/disconenction with
560 * ethumb_client_on_server_die_callback_set().
562 * @param connect_cb function to call to report connection success or
563 * failure. Do not call any other ethumb_client method until
564 * this function returns. The first received parameter is the
565 * given argument @a data. Must @b not be @c NULL. This
566 * function will not be called if user explicitly calls
567 * ethumb_client_disconnect().
568 * @param data context to give back to @a connect_cb. May be @c NULL.
569 * @param free_data function used to release @a data resources, if
570 * any. May be @c NULL. If this function exists, it will be
571 * called immediately after @a connect_cb is called or if user
572 * explicitly calls ethumb_client_disconnect() before such
573 * (that is, don't rely on @a data after @a connect_cb was
576 * @return client instance or NULL if failed. If @a connect_cb is
577 * missing it returns @c NULL. If it fail for other
578 * conditions, @c NULL is also returned and @a connect_cb is
579 * called with @c success=EINA_FALSE. The client instance is
580 * not ready to be used until @a connect_cb is called.
583 ethumb_client_connect(Ethumb_Client_Connect_Cb connect_cb, const void *data, Eina_Free_Cb free_data)
585 Ethumb_Client *eclient;
587 EINA_SAFETY_ON_NULL_RETURN_VAL(connect_cb, NULL);
589 eclient = calloc(1, sizeof(*eclient));
592 ERR("could not allocate Ethumb_Client structure.");
596 eclient->connect.cb = connect_cb;
597 eclient->connect.data = (void *)data;
598 eclient->connect.free_data = free_data;
600 eclient->ethumb = ethumb_new();
601 if (!eclient->ethumb)
603 ERR("could not create ethumb handler.");
607 eclient->conn = e_dbus_bus_get(DBUS_BUS_SESSION);
610 ERR("could not connect to session bus.");
614 eclient->name_owner_changed_handler = e_dbus_signal_handler_add(
615 eclient->conn, fdo_bus_name, fdo_path, fdo_interface,
616 "NameOwnerChanged", _ethumb_client_name_owner_changed, eclient);
618 eclient->pending_get_name_owner = e_dbus_get_name_owner(
619 eclient->conn, _ethumb_dbus_bus_name, _ethumb_client_get_name_owner,
621 if (!eclient->pending_get_name_owner)
623 ERR("could not create a get_name_owner request.");
630 ethumb_free(eclient->ethumb);
634 connect_cb((void *)data, NULL, EINA_FALSE);
636 free_data((void *)data);
641 * Disconnect the client, releasing all client resources.
643 * This is the destructor of Ethumb_Client, after it's disconnected
644 * the client handle is now gone and should not be used.
646 * @param client client instance to be destroyed. Must @b not be @c
650 ethumb_client_disconnect(Ethumb_Client *client)
654 EINA_SAFETY_ON_NULL_RETURN(client);
656 if (!client->connected)
659 EINA_LIST_FREE(client->pending_add, data)
661 struct _ethumb_pending_add *pending = data;
662 eina_stringshare_del(pending->file);
663 eina_stringshare_del(pending->key);
664 eina_stringshare_del(pending->thumb);
665 eina_stringshare_del(pending->thumb_key);
666 dbus_pending_call_cancel(pending->pending_call);
667 dbus_pending_call_unref(pending->pending_call);
668 if (pending->free_data)
669 pending->free_data(pending->data);
673 EINA_LIST_FREE(client->pending_gen, data)
675 struct _ethumb_pending_gen *pending = data;
676 eina_stringshare_del(pending->file);
677 eina_stringshare_del(pending->key);
678 eina_stringshare_del(pending->thumb);
679 eina_stringshare_del(pending->thumb_key);
680 if (pending->free_data)
681 pending->free_data(pending->data);
685 EINA_LIST_FREE(client->pending_remove, data)
687 struct _ethumb_pending_remove *pending = data;
688 dbus_pending_call_cancel(pending->pending_call);
689 dbus_pending_call_unref(pending->pending_call);
690 if (pending->free_data)
691 pending->free_data(pending->data);
695 if (client->pending_clear)
697 dbus_pending_call_cancel(client->pending_clear);
698 dbus_pending_call_unref(client->pending_clear);
702 if (client->object_path)
703 eina_stringshare_del(client->object_path);
705 if (client->pending_new)
706 dbus_pending_call_cancel(client->pending_new);
708 if (client->unique_name)
709 eina_stringshare_del(client->unique_name);
711 if (client->pending_get_name_owner)
712 dbus_pending_call_cancel(client->pending_get_name_owner);
714 if (client->pending_start_service_by_name)
715 dbus_pending_call_cancel(client->pending_start_service_by_name);
717 ethumb_free(client->ethumb);
719 e_dbus_signal_handler_del(client->conn, client->name_owner_changed_handler);
720 if (client->connected)
721 e_dbus_signal_handler_del(client->conn, client->generated_signal);
722 e_dbus_connection_close(client->conn);
724 if (client->connect.free_data)
725 client->connect.free_data(client->connect.data);
726 if (client->die.free_data)
727 client->die.free_data(client->die.data);
733 * Sets the callback to report server died.
735 * When server dies there is nothing you can do, just release
736 * resources with ethumb_client_disconnect() and probably try to
739 * Usually you should set this callback and handle this case, it does
742 * @param client the client instance to monitor. Must @b not be @c
744 * @param server_die_cb function to call back when server dies. The
745 * first parameter will be the argument @a data. May be @c
747 * @param data context to give back to @a server_die_cb. May be @c
749 * @param free_data used to release @a data resources after @a
750 * server_die_cb is called or user calls
751 * ethumb_client_disconnect().
754 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)
756 EINA_SAFETY_ON_NULL_RETURN(client);
758 if (client->die.free_data)
759 client->die.free_data(client->die.data);
761 client->die.cb = server_die_cb;
762 client->die.data = (void *)data;
763 client->die.free_data = free_data;
771 _ethumb_client_ethumb_setup_cb(void *data, DBusMessage *msg, DBusError *error)
773 DBusMessageIter iter;
775 dbus_bool_t result = 0;
776 Ethumb_Client *client = data;
778 client->pending_setup = NULL;
780 if (!_dbus_callback_check_and_init(msg, &iter, error))
783 t = dbus_message_iter_get_arg_type(&iter);
784 if (!_dbus_iter_type_check(t, DBUS_TYPE_BOOLEAN))
787 dbus_message_iter_get_basic(&iter, &result);
791 _ethumb_client_dbus_get_bytearray(DBusMessageIter *iter)
795 DBusMessageIter riter;
798 el_type = dbus_message_iter_get_element_type(iter);
799 if (el_type != DBUS_TYPE_BYTE)
801 ERR("not an byte array element.");
805 dbus_message_iter_recurse(iter, &riter);
806 dbus_message_iter_get_fixed_array(&riter, &result, &length);
808 if (result[0] == '\0')
811 return eina_stringshare_add(result);
815 _ethumb_client_dbus_append_bytearray(DBusMessageIter *iter, const char *string)
817 DBusMessageIter viter;
822 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &viter);
823 dbus_message_iter_append_fixed_array(&viter, DBUS_TYPE_BYTE, &string,
825 dbus_message_iter_close_container(iter, &viter);
833 * Send setup to server.
835 * This method is called automatically by ethumb_client_generate() if
836 * any property was changed. No need to call it manually.
838 * @param client client instance. Must @b not be @c NULL and client
839 * must be connected (after connected_cb is called).
842 ethumb_client_ethumb_setup(Ethumb_Client *client)
845 DBusMessageIter iter, aiter, diter, viter, vaiter;
846 Ethumb *e = client->ethumb;
848 dbus_int32_t tw, th, format, aspect, quality, compress;
851 const char *theme_file, *group, *swallow;
852 const char *directory, *category;
853 double video_time, video_start, video_interval;
854 dbus_int32_t video_ntimes, video_fps, document_page;
856 EINA_SAFETY_ON_NULL_RETURN(client);
857 EINA_SAFETY_ON_FALSE_RETURN(client->connected);
858 client->ethumb_dirty = 0;
860 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
862 _ethumb_dbus_objects_interface,
864 dbus_message_iter_init_append(msg, &iter);
865 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &aiter);
870 #define _open_variant_iter(str_entry, str_type, end_iter) \
872 dbus_message_iter_open_container(&aiter, DBUS_TYPE_DICT_ENTRY, NULL, &diter); \
873 dbus_message_iter_append_basic(&diter, DBUS_TYPE_STRING, &entry); \
874 dbus_message_iter_open_container(&diter, DBUS_TYPE_VARIANT, str_type, \
877 #define _close_variant_iter(end_iter) \
878 dbus_message_iter_close_container(&diter, &end_iter); \
879 dbus_message_iter_close_container(&aiter, &diter);
884 /* starting array elements */
886 _open_variant_iter("size", "(ii)", viter);
887 dbus_message_iter_open_container(&viter, DBUS_TYPE_STRUCT, NULL, &vaiter);
888 ethumb_thumb_size_get(e, &tw, &th);
889 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_INT32, &tw);
890 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_INT32, &th);
891 dbus_message_iter_close_container(&viter, &vaiter);
892 _close_variant_iter(viter);
894 _open_variant_iter("format", "i", viter);
895 format = ethumb_thumb_format_get(e);
896 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &format);
897 _close_variant_iter(viter);
899 _open_variant_iter("aspect", "i", viter);
900 aspect = ethumb_thumb_aspect_get(e);
901 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &aspect);
902 _close_variant_iter(viter);
904 _open_variant_iter("crop", "(dd)", viter);
905 dbus_message_iter_open_container(&viter, DBUS_TYPE_STRUCT, NULL, &vaiter);
906 ethumb_thumb_crop_align_get(e, &cx, &cy);
908 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_DOUBLE, &t);
910 dbus_message_iter_append_basic(&vaiter, DBUS_TYPE_DOUBLE, &t);
911 dbus_message_iter_close_container(&viter, &vaiter);
912 _close_variant_iter(viter);
914 _open_variant_iter("quality", "i", viter);
915 quality = ethumb_thumb_quality_get(e);
916 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &quality);
917 _close_variant_iter(viter);
919 _open_variant_iter("compress", "i", viter);
920 compress = ethumb_thumb_compress_get(e);
921 dbus_message_iter_append_basic(&viter, DBUS_TYPE_INT32, &compress);
922 _close_variant_iter(viter);
924 _open_variant_iter("frame", "(ayayay)", viter);
925 dbus_message_iter_open_container(&viter, DBUS_TYPE_STRUCT, NULL, &vaiter);
926 ethumb_frame_get(e, &theme_file, &group, &swallow);
927 _ethumb_client_dbus_append_bytearray(&vaiter, theme_file);
928 _ethumb_client_dbus_append_bytearray(&vaiter, group);
929 _ethumb_client_dbus_append_bytearray(&vaiter, swallow);
930 dbus_message_iter_close_container(&viter, &vaiter);
931 _close_variant_iter(viter);
933 _open_variant_iter("directory", "ay", viter);
934 directory = ethumb_thumb_dir_path_get(e);
935 _ethumb_client_dbus_append_bytearray(&viter, directory);
936 _close_variant_iter(viter);
938 _open_variant_iter("category", "ay", viter);
939 category = ethumb_thumb_category_get(e);
940 _ethumb_client_dbus_append_bytearray(&viter, category);
941 _close_variant_iter(viter);
943 _open_variant_iter("video_time", "d", viter);
944 video_time = ethumb_video_time_get(e);
945 dbus_message_iter_append_basic(&viter, DBUS_TYPE_DOUBLE, &video_time);
946 _close_variant_iter(viter);
948 _open_variant_iter("video_start", "d", viter);
949 video_start = ethumb_video_start_get(e);
950 dbus_message_iter_append_basic(&viter, DBUS_TYPE_DOUBLE, &video_start);
951 _close_variant_iter(viter);
953 _open_variant_iter("video_interval", "d", viter);
954 video_interval = ethumb_video_interval_get(e);
955 dbus_message_iter_append_basic(&viter, DBUS_TYPE_DOUBLE, &video_interval);
956 _close_variant_iter(viter);
958 _open_variant_iter("video_ntimes", "u", viter);
959 video_ntimes = ethumb_video_ntimes_get(e);
960 dbus_message_iter_append_basic(&viter, DBUS_TYPE_UINT32, &video_ntimes);
961 _close_variant_iter(viter);
963 _open_variant_iter("video_fps", "u", viter);
964 video_fps = ethumb_video_fps_get(e);
965 dbus_message_iter_append_basic(&viter, DBUS_TYPE_UINT32, &video_fps);
966 _close_variant_iter(viter);
968 _open_variant_iter("document_page", "u", viter);
969 document_page = ethumb_document_page_get(e);
970 dbus_message_iter_append_basic(&viter, DBUS_TYPE_UINT32, &document_page);
971 _close_variant_iter(viter);
973 #undef _open_variant_iter
974 #undef _close_variant_iter
976 dbus_message_iter_close_container(&iter, &aiter);
978 client->pending_setup = e_dbus_message_send(client->conn, msg,
979 _ethumb_client_ethumb_setup_cb,
981 dbus_message_unref(msg);
989 _ethumb_client_generated_cb(void *data, DBusMessage *msg)
991 DBusMessageIter iter;
992 dbus_int32_t id = -1;
994 const char *thumb_key;
995 Ethumb_Client *client = data;
1000 struct _ethumb_pending_gen *pending;
1002 dbus_message_iter_init(msg, &iter);
1004 t = dbus_message_iter_get_arg_type(&iter);
1005 if (!_dbus_iter_type_check(t, DBUS_TYPE_INT32))
1007 dbus_message_iter_get_basic(&iter, &id);
1008 dbus_message_iter_next(&iter);
1010 t = dbus_message_iter_get_arg_type(&iter);
1011 if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
1013 thumb = _ethumb_client_dbus_get_bytearray(&iter);
1014 dbus_message_iter_next(&iter);
1016 t = dbus_message_iter_get_arg_type(&iter);
1017 if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
1019 thumb_key = _ethumb_client_dbus_get_bytearray(&iter);
1020 dbus_message_iter_next(&iter);
1022 t = dbus_message_iter_get_arg_type(&iter);
1023 if (!_dbus_iter_type_check(t, DBUS_TYPE_BOOLEAN))
1025 dbus_message_iter_get_basic(&iter, &success);
1028 l = client->pending_gen;
1032 if (pending->id == id)
1042 client->pending_gen = eina_list_remove_list(client->pending_gen, l);
1043 pending->generated_cb(pending->data, client, id,
1044 pending->file, pending->key,
1045 pending->thumb, pending->thumb_key,
1047 if (pending->free_data)
1048 pending->free_data(pending->data);
1049 eina_stringshare_del(pending->file);
1050 eina_stringshare_del(pending->key);
1051 eina_stringshare_del(pending->thumb);
1052 eina_stringshare_del(pending->thumb_key);
1057 eina_stringshare_del(thumb);
1058 eina_stringshare_del(thumb_key);
1062 _ethumb_client_queue_add_cb(void *data, DBusMessage *msg, DBusError *error)
1064 DBusMessageIter iter;
1066 dbus_int32_t id = -1;
1067 struct _ethumb_pending_add *pending = data;
1068 struct _ethumb_pending_gen *generating;
1069 Ethumb_Client *client = pending->client;
1071 client->pending_add = eina_list_remove(client->pending_add, pending);
1073 if (!_dbus_callback_check_and_init(msg, &iter, error))
1076 t = dbus_message_iter_get_arg_type(&iter);
1077 if (!_dbus_iter_type_check(t, DBUS_TYPE_INT32))
1080 dbus_message_iter_get_basic(&iter, &id);
1082 generating = calloc(1, sizeof(*generating));
1083 generating->id = id;
1084 generating->file = pending->file;
1085 generating->key = pending->key;
1086 generating->thumb = pending->thumb;
1087 generating->thumb_key = pending->thumb_key;
1088 generating->generated_cb = pending->generated_cb;
1089 generating->data = pending->data;
1090 generating->free_data = pending->free_data;
1091 client->pending_gen = eina_list_append(client->pending_gen, generating);
1098 _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)
1101 DBusMessageIter iter;
1102 struct _ethumb_pending_add *pending;
1104 pending = calloc(1, sizeof(*pending));
1105 pending->id = client->id_count;
1106 pending->file = eina_stringshare_add(file);
1107 pending->key = eina_stringshare_add(key);
1108 pending->thumb = eina_stringshare_add(thumb);
1109 pending->thumb_key = eina_stringshare_add(thumb_key);
1110 pending->generated_cb = generated_cb;
1111 pending->data = (void *)data;
1112 pending->free_data = free_data;
1113 pending->client = client;
1115 client->id_count = (client->id_count + 1) % MAX_ID;
1117 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
1118 client->object_path,
1119 _ethumb_dbus_objects_interface,
1122 dbus_message_iter_init_append(msg, &iter);
1123 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &pending->id);
1124 _ethumb_client_dbus_append_bytearray(&iter, file);
1125 _ethumb_client_dbus_append_bytearray(&iter, key);
1126 _ethumb_client_dbus_append_bytearray(&iter, thumb);
1127 _ethumb_client_dbus_append_bytearray(&iter, thumb_key);
1129 pending->pending_call = e_dbus_message_send(client->conn, msg,
1130 _ethumb_client_queue_add_cb,
1132 client->pending_add = eina_list_append(client->pending_add, pending);
1133 dbus_message_unref(msg);
1139 _ethumb_client_queue_remove_cb(void *data, DBusMessage *msg, DBusError *error)
1141 DBusMessageIter iter;
1143 dbus_bool_t success = 0;
1144 struct _ethumb_pending_remove *pending = data;
1145 Ethumb_Client *client = pending->client;
1147 client->pending_remove = eina_list_remove(client->pending_remove, pending);
1149 if (!_dbus_callback_check_and_init(msg, &iter, error))
1152 t = dbus_message_iter_get_arg_type(&iter);
1153 if (!_dbus_iter_type_check(t, DBUS_TYPE_BOOLEAN))
1156 dbus_message_iter_get_basic(&iter, &success);
1159 if (pending->cancel_cb)
1160 pending->cancel_cb(pending->data, success);
1161 if (pending->free_data)
1162 pending->free_data(pending->data);
1170 * Ask server to cancel generation of thumbnail.
1172 * @param client client instance. Must @b not be @c NULL and client
1173 * must be connected (after connected_cb is called).
1174 * @param id valid id returned by ethumb_client_generate()
1175 * @param cancel_cb function to report cancellation results.
1176 * @param data context argument to give back to @a cancel_cb. May be
1178 * @param data context to give back to @a cancel_cb. May be @c
1180 * @param free_data used to release @a data resources after @a
1181 * cancel_cb is called or user calls
1182 * ethumb_client_disconnect().
1185 ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Generate_Cancel_Cb cancel_cb, const void *data, Eina_Free_Cb free_data)
1188 struct _ethumb_pending_remove *pending;
1191 dbus_int32_t id32 = id;
1192 EINA_SAFETY_ON_NULL_RETURN(client);
1193 EINA_SAFETY_ON_FALSE_RETURN(id >= 0);
1195 pending = calloc(1, sizeof(*pending));
1197 pending->cancel_cb = cancel_cb;
1198 pending->data = (void *)data;
1199 pending->free_data = free_data;
1200 pending->client = client;
1202 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
1203 client->object_path,
1204 _ethumb_dbus_objects_interface,
1207 dbus_message_append_args(msg, DBUS_TYPE_INT32, &id32, DBUS_TYPE_INVALID);
1208 pending->pending_call = e_dbus_message_send(client->conn, msg,
1209 _ethumb_client_queue_remove_cb,
1211 client->pending_remove = eina_list_append(client->pending_remove, pending);
1214 l = client->pending_add;
1217 struct _ethumb_pending_add *pending = l->data;
1218 if (pending->id != id32)
1223 client->pending_add = eina_list_remove_list(client->pending_add, l);
1224 eina_stringshare_del(pending->file);
1225 eina_stringshare_del(pending->key);
1226 eina_stringshare_del(pending->thumb);
1227 eina_stringshare_del(pending->thumb_key);
1228 dbus_pending_call_cancel(pending->pending_call);
1229 dbus_pending_call_unref(pending->pending_call);
1230 if (pending->free_data)
1231 pending->free_data(pending->data);
1240 l = client->pending_gen;
1243 struct _ethumb_pending_gen *pending = l->data;
1244 if (pending->id != id32)
1249 client->pending_gen = eina_list_remove_list(client->pending_gen, l);
1250 eina_stringshare_del(pending->file);
1251 eina_stringshare_del(pending->key);
1252 eina_stringshare_del(pending->thumb);
1253 eina_stringshare_del(pending->thumb_key);
1254 if (pending->free_data)
1255 pending->free_data(pending->data);
1262 dbus_message_unref(msg);
1269 _ethumb_client_queue_clear_cb(void *data, DBusMessage *msg __UNUSED__, DBusError *error __UNUSED__)
1271 Ethumb_Client *client = data;
1273 client->pending_clear = NULL;
1280 * Ask server to cancel generation of all thumbnails.
1282 * @param client client instance. Must @b not be @c NULL and client
1283 * must be connected (after connected_cb is called).
1285 * @see ethumb_client_generate_cancel()
1288 ethumb_client_generate_cancel_all(Ethumb_Client *client)
1292 EINA_SAFETY_ON_NULL_RETURN(client);
1294 if (client->pending_clear)
1297 EINA_LIST_FREE(client->pending_add, data)
1299 struct _ethumb_pending_add *pending = data;
1300 eina_stringshare_del(pending->file);
1301 eina_stringshare_del(pending->key);
1302 eina_stringshare_del(pending->thumb);
1303 eina_stringshare_del(pending->thumb_key);
1304 dbus_pending_call_cancel(pending->pending_call);
1305 dbus_pending_call_unref(pending->pending_call);
1306 if (pending->free_data)
1307 pending->free_data(pending->data);
1311 EINA_LIST_FREE(client->pending_gen, data)
1313 struct _ethumb_pending_gen *pending = data;
1314 eina_stringshare_del(pending->file);
1315 eina_stringshare_del(pending->key);
1316 eina_stringshare_del(pending->thumb);
1317 eina_stringshare_del(pending->thumb_key);
1318 if (pending->free_data)
1319 pending->free_data(pending->data);
1323 msg = dbus_message_new_method_call(_ethumb_dbus_bus_name,
1324 client->object_path,
1325 _ethumb_dbus_objects_interface,
1328 client->pending_clear = e_dbus_message_send(client->conn, msg,
1329 _ethumb_client_queue_clear_cb,
1332 dbus_message_unref(msg);
1336 * Configure future requests to use FreeDesktop.Org preset.
1338 * This is a preset to provide freedesktop.org (fdo) standard
1339 * compliant thumbnails. That is, files are stored as JPEG under
1340 * ~/.thumbnails/SIZE, with size being either normal (128x128) or
1343 * @param client the client instance to use. Must @b not be @c
1344 * NULL. May be pending connected (can be called before @c
1346 * @param s size identifier, either #ETHUMB_THUMB_NORMAL (0) or
1347 * #ETHUMB_THUMB_LARGE (1).
1349 * @see ethumb_client_size_set()
1350 * @see ethumb_client_aspect_set()
1351 * @see ethumb_client_crop_align_set()
1352 * @see ethumb_client_category_set()
1353 * @see ethumb_client_dir_path_set()
1356 ethumb_client_fdo_set(Ethumb_Client *client, Ethumb_Thumb_FDO_Size s)
1358 EINA_SAFETY_ON_NULL_RETURN(client);
1360 client->ethumb_dirty = 1;
1361 ethumb_thumb_fdo_set(client->ethumb, s);
1365 * Configure future request to use custom size.
1367 * @param client the client instance to use. Must @b not be @c
1368 * NULL. May be pending connected (can be called before @c
1370 * @param tw width, default is 128.
1371 * @param th height, default is 128.
1374 ethumb_client_size_set(Ethumb_Client *client, int tw, int th)
1376 EINA_SAFETY_ON_NULL_RETURN(client);
1378 client->ethumb_dirty = 1;
1379 ethumb_thumb_size_set(client->ethumb, tw, th);
1383 * Retrieve future request to use custom size.
1385 * @param client the client instance to use. Must @b not be @c
1386 * NULL. May be pending connected (can be called before @c
1388 * @param tw where to return width. May be @c NULL.
1389 * @param th where to return height. May be @c NULL.
1392 ethumb_client_size_get(const Ethumb_Client *client, int *tw, int *th)
1396 EINA_SAFETY_ON_NULL_RETURN(client);
1398 ethumb_thumb_size_get(client->ethumb, tw, th);
1402 * Configure format to use for future requests.
1404 * @param client the client instance to use. Must @b not be @c
1405 * NULL. May be pending connected (can be called before @c
1407 * @param f format identifier to use, either #ETHUMB_THUMB_FDO (0),
1408 * #ETHUMB_THUMB_JPEG (1) or #ETHUMB_THUMB_EET (2). Default is FDO.
1411 ethumb_client_format_set(Ethumb_Client *client, Ethumb_Thumb_Format f)
1413 EINA_SAFETY_ON_NULL_RETURN(client);
1415 client->ethumb_dirty = 1;
1416 ethumb_thumb_format_set(client->ethumb, f);
1420 * Retrieve format to use for future requests.
1422 * @param client the client instance to use. Must @b not be @c
1423 * NULL. May be pending connected (can be called before @c
1426 * @return format identifier to use, either #ETHUMB_THUMB_FDO (0),
1427 * #ETHUMB_THUMB_JPEG (1) or #ETHUMB_THUMB_EET (2).
1429 EAPI Ethumb_Thumb_Format
1430 ethumb_client_format_get(const Ethumb_Client *client)
1432 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1434 return ethumb_thumb_format_get(client->ethumb);
1438 * Configure aspect mode to use.
1440 * If aspect is kept (#ETHUMB_THUMB_KEEP_ASPECT), then image will be
1441 * rescaled so the largest dimension is not bigger than it's specified
1442 * size (see ethumb_client_size_get()) and the other dimension is
1443 * resized in the same proportion. Example: size is 256x256, image is
1444 * 1000x500, resulting thumbnail is 256x128.
1446 * If aspect is ignored (#ETHUMB_THUMB_IGNORE_ASPECT), then image will
1447 * be distorted to match required thumbnail size. Example: size is
1448 * 256x256, image is 1000x500, resulting thumbnail is 256x256.
1450 * If crop is required (#ETHUMB_THUMB_CROP), then image will be
1451 * cropped so the smallest dimension is not bigger than its specified
1452 * size (see ethumb_client_size_get()) and the other dimension will
1453 * overflow, not being visible in the final image. How it will
1454 * overflow is speficied by ethumb_client_crop_align_set()
1455 * alignment. Example: size is 256x256, image is 1000x500, crop
1456 * alignment is 0.5, 0.5, resulting thumbnail is 256x256 with 250
1457 * pixels from left and 250 pixels from right being lost, that is just
1458 * the 500x500 central pixels of image will be considered for scaling.
1460 * @param client the client instance to use. Must @b not be @c
1461 * NULL. May be pending connected (can be called before @c
1463 * @param a aspect mode identifier, either #ETHUMB_THUMB_KEEP_ASPECT (0),
1464 * #ETHUMB_THUMB_IGNORE_ASPECT (1) or #ETHUMB_THUMB_CROP (2).
1467 ethumb_client_aspect_set(Ethumb_Client *client, Ethumb_Thumb_Aspect a)
1469 EINA_SAFETY_ON_NULL_RETURN(client);
1471 client->ethumb_dirty = 1;
1472 ethumb_thumb_aspect_set(client->ethumb, a);
1476 * Get current aspect in use for requests.
1478 * @param client the client instance to use. Must @b not be @c
1479 * NULL. May be pending connected (can be called before @c
1482 * @return aspect in use for future requests.
1484 EAPI Ethumb_Thumb_Aspect
1485 ethumb_client_aspect_get(const Ethumb_Client *client)
1487 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1489 return ethumb_thumb_aspect_get(client->ethumb);
1493 * Configure crop alignment in use for future requests.
1495 * @param client the client instance to use. Must @b not be @c
1496 * NULL. May be pending connected (can be called before @c
1498 * @param x horizontal alignment. 0.0 means left side will be visible
1499 * or right side is being lost. 1.0 means right side will be
1500 * visible or left side is being lost. 0.5 means just center is
1501 * visible, both sides will be lost. Default is 0.5.
1502 * @param y vertical alignment. 0.0 is top visible, 1.0 is bottom
1503 * visible, 0.5 is center visible. Default is 0.5
1506 ethumb_client_crop_align_set(Ethumb_Client *client, float x, float y)
1508 EINA_SAFETY_ON_NULL_RETURN(client);
1510 client->ethumb_dirty = 1;
1511 ethumb_thumb_crop_align_set(client->ethumb, x, y);
1515 * Get current crop alignment in use for requests.
1517 * @param client the client instance to use. Must @b not be @c
1518 * NULL. May be pending connected (can be called before @c
1520 * @param x where to return horizontal alignment. May be @c NULL.
1521 * @param y where to return vertical alignment. May be @c NULL.
1524 ethumb_client_crop_align_get(const Ethumb_Client *client, float *x, float *y)
1528 EINA_SAFETY_ON_NULL_RETURN(client);
1530 ethumb_thumb_crop_align_get(client->ethumb, x, y);
1534 * Configure quality to be used in thumbnails.
1536 * @param client the client instance to use. Must @b not be @c
1537 * NULL. May be pending connected (can be called before @c
1539 * @param quality value from 0 to 100, default is 80. The effect
1540 * depends on the format being used, PNG will not use it.
1543 ethumb_client_quality_set(Ethumb_Client *client, int quality)
1545 EINA_SAFETY_ON_NULL_RETURN(client);
1547 ethumb_thumb_quality_set(client->ethumb, quality);
1551 * Get quality to be used in thumbnails.
1553 * @param client the client instance to use. Must @b not be @c
1554 * NULL. May be pending connected (can be called before @c
1557 * @return quality value from 0 to 100, default is 80. The effect
1558 * depends on the format being used, PNG will not use it.
1561 ethumb_client_quality_get(const Ethumb_Client *client)
1563 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1565 return ethumb_thumb_quality_get(client->ethumb);
1569 * Configure compression level used in requests.
1571 * @param client the client instance to use. Must @b not be @c
1572 * NULL. May be pending connected (can be called before @c
1574 * @param compress value from 0 to 9, default is 9. The effect
1575 * depends on the format being used, JPEG will not use it.
1578 ethumb_client_compress_set(Ethumb_Client *client, int compress)
1580 EINA_SAFETY_ON_NULL_RETURN(client);
1582 ethumb_thumb_compress_set(client->ethumb, compress);
1586 * Get compression level used in requests.
1588 * @param client the client instance to use. Must @b not be @c
1589 * NULL. May be pending connected (can be called before @c
1592 * @return compress value from 0 to 9, default is 9. The effect
1593 * depends on the format being used, JPEG will not use it.
1596 ethumb_client_compress_get(const Ethumb_Client *client)
1598 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1600 return ethumb_thumb_compress_get(client->ethumb);
1604 * Set frame to apply to future thumbnails.
1606 * This will create an edje object that will have image swallowed
1607 * in. This can be used to simulate Polaroid or wood frames in the
1608 * generated image. Remeber it is bad to modify the original contents
1609 * of thumbnails, but sometimes it's useful to have it composited and
1610 * avoid runtime overhead.
1612 * @param client the client instance to use. Must @b not be @c
1613 * NULL. May be pending connected (can be called before @c
1615 * @param file file path to edje.
1616 * @param group group inside edje to use.
1617 * @param swallow name of swallow part.
1620 ethumb_client_frame_set(Ethumb_Client *client, const char *file, const char *group, const char *swallow)
1622 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1624 client->ethumb_dirty = 1;
1625 return ethumb_frame_set(client->ethumb, file, group, swallow);
1629 * Configure where to store thumbnails in future requests.
1631 * This value will be used to generate thumbnail paths, that is, it
1632 * will be used when ethumb_client_thumb_path_set() was not called
1633 * after last ethumb_client_file_set().
1635 * Note that this is the base, a category is added to this path as a
1636 * sub directory. This is not the final directory where files are
1637 * stored, the thumbnail system will account @b category as well, see
1638 * ethumb_client_category_set().
1640 * As other options, this value will only be applied to future
1643 * @param client the client instance to use. Must @b not be @c
1644 * NULL. May be pending connected (can be called before @c
1646 * @param path base directory where to store thumbnails. Default is
1649 * @see ethumb_client_category_set()
1652 ethumb_client_dir_path_set(Ethumb_Client *client, const char *path)
1654 EINA_SAFETY_ON_NULL_RETURN(client);
1656 client->ethumb_dirty = 1;
1657 ethumb_thumb_dir_path_set(client->ethumb, path);
1661 * Get base directory path where to store thumbnails.
1663 * @param client the client instance to use. Must @b not be @c
1664 * NULL. May be pending connected (can be called before @c
1667 * @return pointer to internal string with current path. This string
1668 * should not be modified or freed.
1670 * @see ethumb_client_dir_path_set()
1673 ethumb_client_dir_path_get(const Ethumb_Client *client)
1675 EINA_SAFETY_ON_NULL_RETURN_VAL(client, NULL);
1677 return ethumb_thumb_dir_path_get(client->ethumb);
1681 * Category directory to store thumbnails.
1683 * This value will be used to generate thumbnail paths, that is, it
1684 * will be used when ethumb_client_thumb_path_set() was not called
1685 * after last ethumb_client_file_set().
1687 * This is a sub-directory inside base directory
1688 * (ethumb_client_dir_path_set()) that creates a namespace to avoid
1689 * different options resulting in the same file.
1691 * As other options, this value will only be applied to future
1694 * @param client the client instance to use. Must @b not be @c
1695 * NULL. May be pending connected (can be called before @c
1697 * @param category category sub directory to store thumbnail. Default
1698 * is either "normal" or "large" for FDO compliant thumbnails
1699 * or WIDTHxHEIGHT-ASPECT[-FRAMED]-FORMAT. It can be a string
1700 * or @c NULL to use auto generated names.
1702 * @see ethumb_client_dir_path_set()
1705 ethumb_client_category_set(Ethumb_Client *client, const char *category)
1707 EINA_SAFETY_ON_NULL_RETURN(client);
1709 client->ethumb_dirty = 1;
1710 ethumb_thumb_category_set(client->ethumb, category);
1714 * Get category sub-directory where to store thumbnails.
1716 * @param client the client instance to use. Must @b not be @c
1717 * NULL. May be pending connected (can be called before @c
1720 * @return pointer to internal string with current path. This string
1721 * should not be modified or freed.
1723 * @see ethumb_client_category_set()
1726 ethumb_client_category_get(const Ethumb_Client *client)
1728 EINA_SAFETY_ON_NULL_RETURN_VAL(client, NULL);
1730 return ethumb_thumb_category_get(client->ethumb);
1734 * Set the video time (duration) in seconds.
1736 * @param client the client instance to use. Must @b not be @c
1737 * NULL. May be pending connected (can be called before @c
1739 * @param time duration (in seconds). Defaults to 3 seconds.
1742 ethumb_client_video_time_set(Ethumb_Client *client, float time)
1744 EINA_SAFETY_ON_NULL_RETURN(client);
1746 client->ethumb_dirty = 1;
1747 ethumb_video_time_set(client->ethumb, time);
1751 * Set initial video position to start thumbnailing, in percentage.
1753 * This is useful to avoid thumbnailing the company/producer logo or
1756 * @param client the client instance to use. Must @b not be @c
1757 * NULL. May be pending connected (can be called before @c
1759 * @param start initial video positon to thumbnail, in percentage (0.0
1760 * to 1.0, inclusive). Defaults to 10% (0.1).
1763 ethumb_client_video_start_set(Ethumb_Client *client, float start)
1765 EINA_SAFETY_ON_NULL_RETURN(client);
1766 EINA_SAFETY_ON_FALSE_RETURN(start >= 0.0);
1767 EINA_SAFETY_ON_FALSE_RETURN(start <= 1.0);
1769 client->ethumb_dirty = 1;
1770 ethumb_video_start_set(client->ethumb, start);
1774 * Set the video frame interval, in seconds.
1776 * This is useful for animated thumbnail and will define skip time
1777 * before going to the next frame. Note that video backends might not
1778 * be able to precisely skip that amount as it will depend on various
1779 * factors, including video encoding.
1781 * Although this seems similar to ethumb_client_video_fps_set(), this
1782 * one is the time that will be used to seek. The math is simple, for
1783 * each new frame the video position will be set to:
1784 * ((video_length * start_time) + (interval * current_frame_number)).
1786 * @param client the client instance to use. Must @b not be @c
1787 * NULL. May be pending connected (can be called before @c
1789 * @param interval time between frames, in seconds. Defaults to 0.05
1793 ethumb_client_video_interval_set(Ethumb_Client *client, float interval)
1795 EINA_SAFETY_ON_NULL_RETURN(client);
1797 client->ethumb_dirty = 1;
1798 ethumb_video_interval_set(client->ethumb, interval);
1802 * Set the number of frames to thumbnail.
1804 * This is useful for animated thumbnail and will define how many
1805 * frames the generated file will have.
1807 * @param client the client instance to use. Must @b not be @c
1808 * NULL. May be pending connected (can be called before @c
1810 * @param ntimes number of times, must be greater than zero.
1814 ethumb_client_video_ntimes_set(Ethumb_Client *client, unsigned int ntimes)
1816 EINA_SAFETY_ON_NULL_RETURN(client);
1817 EINA_SAFETY_ON_FALSE_RETURN(ntimes > 0);
1819 client->ethumb_dirty = 1;
1820 ethumb_video_ntimes_set(client->ethumb, ntimes);
1824 * Set the number of frames per second to thumbnail the video.
1826 * This configures the number of times per seconds the thumbnail will
1827 * use to create thumbnails.
1829 * Although this is similar to ethumb_client_video_interval_set(), it
1830 * is the delay used between calling functions thata generates frames,
1831 * while the other is the time used to skip inside the video.
1833 * @param client the client instance to use. Must @b not be @c
1834 * NULL. May be pending connected (can be called before @c
1836 * @param fps number of frames per second to thumbnail. Must be greater
1837 * than zero. Defaults to 10.
1840 ethumb_client_video_fps_set(Ethumb_Client *client, unsigned int fps)
1842 EINA_SAFETY_ON_NULL_RETURN(client);
1843 EINA_SAFETY_ON_FALSE_RETURN(fps > 0);
1845 client->ethumb_dirty = 1;
1846 ethumb_video_fps_set(client->ethumb, fps);
1850 * Set the page number to thumbnail in paged documents.
1852 * @param client the client instance to use. Must @b not be @c
1853 * NULL. May be pending connected (can be called before @c
1855 * @param page page number, defaults to 0 (first).
1858 ethumb_client_document_page_set(Ethumb_Client *client, unsigned int page)
1860 EINA_SAFETY_ON_NULL_RETURN(client);
1862 client->ethumb_dirty = 1;
1863 ethumb_document_page_set(client->ethumb, page);
1867 * Set source file to be thumbnailed.
1869 * Calling this function has the side effect of resetting values set
1870 * with ethumb_client_thumb_path_set() or auto-generated with
1871 * ethumb_client_thumb_exists().
1873 * @param client the client instance to use. Must @b not be @c
1874 * NULL. May be pending connected (can be called before @c
1876 * @param path the filesystem path to use. May be @c NULL.
1877 * @param key the extra argument/key inside @a path to read image
1878 * from. This is only used for formats that allow multiple
1879 * resources in one file, like EET or Edje (group name).
1881 * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
1884 ethumb_client_file_set(Ethumb_Client *client, const char *path, const char *key)
1886 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
1888 return ethumb_file_set(client->ethumb, path, key);
1892 * Get values set with ethumb_client_file_get()
1894 * @param client the client instance to use. Must @b not be @c
1895 * NULL. May be pending connected (can be called before @c
1897 * @param path where to return configured path. May be @c NULL. If
1898 * not @c NULL, then it will be a pointer to a stringshared
1899 * instance, but @b no references are added (do it with
1900 * eina_stringshare_ref())!
1901 * @param key where to return configured key. May be @c NULL.If not @c
1902 * NULL, then it will be a pointer to a stringshared instance,
1903 * but @b no references are added (do it with
1904 * eina_stringshare_ref())!
1907 ethumb_client_file_get(Ethumb_Client *client, const char **path, const char **key)
1909 if (path) *path = NULL;
1910 if (key) *key = NULL;
1911 EINA_SAFETY_ON_NULL_RETURN(client);
1913 ethumb_file_get(client->ethumb, path, key);
1917 * Reset previously set file to @c NULL.
1919 * @param client the client instance to use. Must @b not be @c
1920 * NULL. May be pending connected (can be called before @c
1924 ethumb_client_file_free(Ethumb_Client *client)
1926 EINA_SAFETY_ON_NULL_RETURN(client);
1928 ethumb_file_free(client->ethumb);
1932 * Set a defined path and key to store the thumbnail.
1934 * If not explicitly given, the thumbnail path will be auto-generated
1935 * by ethumb_client_thumb_exists() or server using configured
1936 * parameters like size, aspect and category.
1938 * Set these to @c NULL to forget previously given values. After
1939 * ethumb_client_file_set() these values will be reset to @c NULL.
1941 * @param client the client instance to use. Must @b not be @c
1942 * NULL. May be pending connected (can be called before @c
1944 * @param path force generated thumbnail to the exact given path. If
1945 * @c NULL, then reverts back to auto-generation.
1946 * @param key force generated thumbnail to the exact given key. If
1947 * @c NULL, then reverts back to auto-generation.
1950 ethumb_client_thumb_path_set(Ethumb_Client *client, const char *path, const char *key)
1952 EINA_SAFETY_ON_NULL_RETURN(client);
1954 ethumb_thumb_path_set(client->ethumb, path, key);
1958 * Get the configured thumbnail path.
1960 * This returns the value set with ethumb_client_thumb_path_set() or
1961 * auto-generated by ethumb_client_thumb_exists() if it was not set.
1963 * @param client the client instance to use. Must @b not be @c
1964 * NULL. May be pending connected (can be called before @c
1966 * @param path where to return configured path. May be @c NULL. If
1967 * there was no path configured with
1968 * ethumb_client_thumb_path_set() and
1969 * ethumb_client_thumb_exists() was not called, then it will
1970 * probably return @c NULL. If not @c NULL, then it will be a
1971 * pointer to a stringshared instance, but @b no references are
1972 * added (do it with eina_stringshare_ref())!
1973 * @param key where to return configured key. May be @c NULL. If
1974 * there was no key configured with
1975 * ethumb_client_thumb_key_set() and
1976 * ethumb_client_thumb_exists() was not called, then it will
1977 * probably return @c NULL. If not @c NULL, then it will be a
1978 * pointer to a stringshared instance, but @b no references are
1979 * added (do it with eina_stringshare_ref())!
1982 ethumb_client_thumb_path_get(Ethumb_Client *client, const char **path, const char **key)
1984 if (path) *path = NULL;
1985 if (key) *key = NULL;
1986 EINA_SAFETY_ON_NULL_RETURN(client);
1988 ethumb_thumb_path_get(client->ethumb, path, key);
1992 * Checks whenever file already exists (locally!)
1994 * This will check locally (not calling server) if thumbnail already
1995 * exists or not, also calculating the thumbnail path. See
1996 * ethumb_client_thumb_path_get(). Path must be configured with
1997 * ethumb_client_file_set() before using it and the last set file will
2000 * @param client client instance. Must @b not be @c NULL and client
2001 * must be configured with ethumb_client_file_set().
2003 * @return @c EINA_TRUE if it exists, @c EINA_FALSE otherwise.
2006 ethumb_client_thumb_exists(Ethumb_Client *client)
2008 EINA_SAFETY_ON_NULL_RETURN_VAL(client, 0);
2010 return ethumb_exists(client->ethumb);
2014 * Ask server to generate thumbnail.
2016 * This process is asynchronous and will report back from main loop
2017 * using @a generated_cb. One can cancel this request by calling
2018 * ethumb_client_generate_cancel() or
2019 * ethumb_client_generate_cancel_all(), but not that request might be
2020 * processed by server already and no generated files will be removed
2021 * if that is the case.
2023 * This will not check if file already exists, this should be done by
2024 * explicitly calling ethumb_client_thumb_exists(). That is, this
2025 * function will override any existing thumbnail.
2027 * @param client client instance. Must @b not be @c NULL and client
2028 * must be connected (after connected_cb is called).
2029 * @param generated_cb function to report generation results.
2030 * @param data context argument to give back to @a generated_cb. May
2032 * @param data context to give back to @a generate_cb. May be @c
2034 * @param free_data used to release @a data resources after @a
2035 * generated_cb is called or user calls
2036 * ethumb_client_disconnect().
2038 * @return identifier or -1 on error. If -1 is returned (error) then
2039 * @a free_data is @b not called!
2041 * @see ethumb_client_connect()
2042 * @see ethumb_client_file_set()
2043 * @see ethumb_client_thumb_exists()
2044 * @see ethumb_client_generate_cancel()
2045 * @see ethumb_client_generate_cancel_all()
2048 ethumb_client_generate(Ethumb_Client *client, Ethumb_Client_Generate_Cb generated_cb, const void *data, Eina_Free_Cb free_data)
2050 const char *file, *key, *thumb, *thumb_key;
2052 EINA_SAFETY_ON_NULL_RETURN_VAL(client, -1);
2053 EINA_SAFETY_ON_FALSE_RETURN_VAL(client->connected, -1);
2055 ethumb_file_get(client->ethumb, &file, &key);
2058 ERR("no file set.");
2062 ethumb_thumb_path_get(client->ethumb, &thumb, &thumb_key);
2064 if (client->ethumb_dirty)
2065 ethumb_client_ethumb_setup(client);
2066 id = _ethumb_client_queue_add(client, file, key, thumb, thumb_key,
2067 generated_cb, data, free_data);