1 #ifndef EVRY_API_H
2 #define EVRY_API_H
3 
4 #include "evry_types.h"
5 
6 #define EVRY_API_VERSION     31
7 
8 #define EVRY_ACTION_OTHER    0
9 #define EVRY_ACTION_FINISHED 1
10 #define EVRY_ACTION_CONTINUE 2
11 #define EVRY_ACTION_CLEAR    3
12 
13 #define EVRY_UPDATE_ADD	     0
14 #define EVRY_UPDATE_CLEAR    1
15 #define EVRY_UPDATE_REFRESH  2
16 
17 #define EVRY_COMPLETE_NONE   0
18 #define EVRY_COMPLETE_INPUT  1
19 #define EVRY_COMPLETE_BROWSE 2
20 
21 #define VIEW_MODE_NONE	    -1
22 #define VIEW_MODE_LIST	     0
23 #define VIEW_MODE_DETAIL     1
24 #define VIEW_MODE_THUMB	     2
25 
26 #define EVRY_PLUGIN_SUBJECT  0
27 #define EVRY_PLUGIN_ACTION   1
28 #define EVRY_PLUGIN_OBJECT   2
29 
30 #define EVRY_TYPE_NONE	     0
31 #define EVRY_TYPE_FILE	     1
32 #define EVRY_TYPE_DIR	     2
33 #define EVRY_TYPE_APP	     3
34 #define EVRY_TYPE_ACTION     4
35 #define EVRY_TYPE_PLUGIN     5
36 #define EVRY_TYPE_CLIENT     6
37 #define EVRY_TYPE_TEXT	     7
38 #define NUM_EVRY_TYPES	     8
39 
40 #define EVRY_EVENT_ITEM_SELECTED	0
41 #define EVRY_EVENT_ITEM_CHANGED		1
42 #define EVRY_EVENT_ITEMS_UPDATE		2
43 #define EVRY_EVENT_ACTION_PERFORMED	3
44 #define EVRY_EVENT_PLUGIN_SELECTED	4
45 #define NUM_EVRY_EVENTS			5
46 
47 typedef struct _Evry_API Evry_API;
48 typedef struct _Evry_Module Evry_Module;
49 
50 typedef struct _Evry_Event_Item_Changed     Evry_Event_Item_Changed;
51 typedef struct _Evry_Event_Item_Selected    Evry_Event_Item_Selected;
52 typedef struct _Evry_Event_Action_Performed Evry_Event_Action_Performed;
53 typedef void (*Evry_Item_Free_Cb) (Evry_Item *it);
54 
55 struct _Evry_Module
56 {
57   Eina_Bool active;
58 
59   int  (*init)(const Evry_API *api);
60   void (*shutdown)(void);
61 };
62 
63 struct _Evry_API
64 {
65   int  (*api_version_check)(int version);
66 
67   Evry_Item *(*item_new)(Evry_Item *base, Evry_Plugin *p, const char *label,
68 			Evas_Object *(*icon_get) (Evry_Item *it, Evas *e),
69 			Evry_Item_Free_Cb item_free);
70 
71   void (*item_free)(Evry_Item *it);
72   void (*item_ref)(Evry_Item *it);
73   /* sends EVRY_EVENT_ITEM_CHANGED event */
74   void  (*item_changed)(Evry_Item *it, int change_icon, int change_selected);
75 
76   Evry_Plugin *(*plugin_new)(Evry_Plugin *base, const char *name,
77 				  const char *label, const char *icon,
78 				  Evry_Type item_type,
79 				  Evry_Plugin *(*begin) (Evry_Plugin *p, const Evry_Item *item),
80 				  void (*cleanup) (Evry_Plugin *p),
81 				  int  (*fetch)   (Evry_Plugin *p, const char *input));
82 
83   void (*plugin_free)(Evry_Plugin *p);
84   /* when a new plugin config was created return val is 1. in this
85      case you can set defaults of p->config */
86   int  (*plugin_register)(Evry_Plugin *p, int type, int priority);
87   void (*plugin_unregister)(Evry_Plugin *p);
88   void (*plugin_update)(Evry_Plugin *plugin, int state);
89   Evry_Plugin *(*plugin_find)(const char *name);
90 
91   Evry_Action *(*action_new)(const char *name, const char *label,
92 				  Evry_Type type1, Evry_Type type2,
93 				  const char *icon,
94 				  int  (*action)     (Evry_Action *act),
95 				  int  (*check_item) (Evry_Action *act, const Evry_Item *it));
96 
97   void (*action_free)(Evry_Action *act);
98   void (*action_register)(Evry_Action *act, int priority);
99   void (*action_unregister)(Evry_Action *act);
100   Evry_Action *(*action_find)(const char *name);
101   Evry_Type (*type_register)(const char *type);
102 
103   /* evry_util.c */
104   Evas_Object *(*icon_theme_get)(const char *icon, Evas *e);
105 
106   int   (*fuzzy_match)(const char *str, const char *match);
107   int   (*util_exec_app)(const Evry_Item *it_app, const Evry_Item *it_file);
108   char *(*util_url_escape)(const char *string, int inlength);
109   char *(*util_url_unescape)(const char *string, int length);
110   void  (*util_file_detail_set)(Evry_Item_File *file);
111   int   (*util_plugin_items_add)(Evry_Plugin *p, Eina_List *items, const char *input, int match_detail, int set_usage);
112   char *(*util_md5_sum)(const char *str);
113   Evas_Object *(*util_icon_get)(Evry_Item *it, Evas *e);
114 
115   const char *(*file_path_get)(Evry_Item_File *file);
116   const char *(*file_url_get)(Evry_Item_File *file);
117 
118   History_Item  *(*history_item_add)(Evry_Item *it, const char *ctxt, const char *input);
119   History_Types *(*history_types_get)(Evry_Type type);
120   int  (*history_item_usage_set)(Evry_Item *it, const char *input, const char *ctxt);
121 
122   Ecore_Event_Handler *(*event_handler_add)(int type, Eina_Bool (*func) (void *data, int type, void *event), const void *data);
123 };
124 
125 struct _Evry_Event_Item_Changed
126 {
127   Evry_Item *item;
128   int changed_selection;
129   int changed_icon;
130 };
131 
132 struct _Evry_Event_Item_Selected
133 {
134   Evry_Item *item;
135 };
136 
137 struct _Evry_Event_Action_Performed
138 {
139   const char *action;
140   const Evry_Item *it1;
141   const Evry_Item *it2;
142 };
143 
144 
145 /*** cast default types ***/
146 #define EVRY_ITEM(_item) ((Evry_Item *)_item)
147 #define EVRY_ACTN(_item) ((Evry_Action *) _item)
148 #define EVRY_PLUGIN(_plugin) ((Evry_Plugin *) _plugin)
149 #define EVRY_VIEW(_view) ((Evry_View *) _view)
150 #define EVRY_FILE(_it) ((Evry_Item_File *) _it)
151 
152 #define GET_APP(_app, _item) Evry_Item_App *_app = (Evry_Item_App *) _item
153 #define GET_CMD(_app, _item) Evry_Item_App *_app = (Evry_Item_App *) _item
154 #define GET_FILE(_file, _item) Evry_Item_File *_file = (Evry_Item_File *) _item
155 #define GET_EVRY_PLUGIN(_p, _plugin) Evry_Plugin *_p = (Evry_Plugin*) _plugin
156 #define GET_PLUGIN(_p, _plugin) Plugin *_p = (Plugin*) _plugin
157 #define GET_VIEW(_v, _view) View *_v = (View*) _view
158 #define GET_ACTION(_act, _item) Evry_Action *_act = (Evry_Action *) _item
159 #define GET_ITEM(_it, _any) Evry_Item *_it = (Evry_Item *) _any
160 
161 /*** Evry_Item macros ***/
162 
163 /* */
164 #define EVRY_ITEM_NEW(_base, _plugin, _label, _icon_get, _free) \
165   (_base *) evry->item_new(EVRY_ITEM(E_NEW(_base, 1)),		\
166 			   EVRY_PLUGIN(_plugin),		\
167 			   _label, _icon_get, (Evry_Item_Free_Cb)_free)
168 
169 #define EVRY_ITEM_FREE(_item) evry->item_free((Evry_Item *)_item)
170 #define EVRY_ITEM_REF(_item) evry->item_ref((Evry_Item *)_item)
171 
172 #define EVRY_ITEM_DATA_INT_SET(_item, _data) \
173   ((Evry_Item *)_item)->data = (void*)(long) _data
174 
175 #define EVRY_ITEM_DATA_INT_GET(_item) (long) \
176   ((Evry_Item *)_item)->data
177 
178 #define EVRY_ITEM_DETAIL_SET(_it, _detail)			\
179   eina_stringshare_replace(&(EVRY_ITEM(_it)->detail), _detail);
180 
181 #define EVRY_ITEM_LABEL_SET(_it, _label)			\
182   eina_stringshare_replace(&(EVRY_ITEM(_it)->label), _label);
183 
184 #define EVRY_ITEM_CONTEXT_SET(_it, _context)			\
185   eina_stringshare_replace(&(EVRY_ITEM(_it)->context), _context);
186 
187 #define EVRY_ITEM_ICON_SET(_it, _icon)				\
188   eina_stringshare_replace(&(EVRY_ITEM(_it)->icon), _icon);
189 
190 #define CHECK_TYPE(_item, _type) \
191   (((Evry_Item *)_item)->type == _type)
192 
193 #define CHECK_SUBTYPE(_item, _type) \
194   (((Evry_Item *)_item)->subtype == _type)
195 
196 #define IS_BROWSEABLE(_item) ((Evry_Item *)_item)->browseable
197 
198 /*** Evry_Plugin macros ***/
199 
200 /* creates a Evry_Plugin to be registered with evry */
201 #define EVRY_PLUGIN_BASE(_name, _icon, _item_type, _begin, _finish, _fetch) \
202   evry->plugin_new(EVRY_PLUGIN(E_NEW(Evry_Plugin, 1)), _name, _(_name), _icon, _item_type, \
203 		   _begin, _finish, _fetch)
204 
205 /* creates the plugin instance '_p' for the Evry_Plugin '_plugin' */
206 #define EVRY_PLUGIN_INSTANCE(_p, _plugin) {				\
207      _p			   = E_NEW(Plugin, 1);				\
208      _p->base              = *_plugin;					\
209      _p->base.items        = NULL;					\
210      _p->base.base.ref     = 1;						\
211      _p->base.base.plugin  = (Evry_Plugin*)_p;				\
212      _p->base.base.free    = (Evry_Item_Free_Cb)_p->base.finish;	\
213      _p->base.base.label   = eina_stringshare_ref(_plugin->base.label);	\
214      _p->base.base.detail  = eina_stringshare_ref(_plugin->base.detail); \
215      _p->base.base.icon    = eina_stringshare_ref(_plugin->base.icon);	\
216      _p->base.base.context = eina_stringshare_ref(_plugin->base.context); \
217      _p->base.base.id      = eina_stringshare_ref(_plugin->base.id);	\
218 }
219 
220 /* free the plugin instance '_p' */
221 #define EVRY_PLUGIN_FREE(_p) if (_p) evry->plugin_free(EVRY_PLUGIN(_p))
222 
223 /* call free on all items provided by plugin instance '_p' */
224 #define EVRY_PLUGIN_ITEMS_FREE(_p) {				\
225      Evry_Item *_it;						\
226      EINA_LIST_FREE(EVRY_PLUGIN(_p)->items, _it)		\
227        evry->item_free(_it); }
228 
229 /* append '_item' to list of items provided by plugin instance '_p' */
230 #define EVRY_PLUGIN_ITEM_APPEND(_p, _item)                              \
231   EVRY_PLUGIN(_p)->items = eina_list_append(EVRY_PLUGIN(_p)->items, EVRY_ITEM(_item))
232 
233 /* */
234 #define EVRY_PLUGIN_ITEMS_ADD(_plugin, _items, _input, _match_detail, _set_usage) \
235   evry->util_plugin_items_add(EVRY_PLUGIN(_plugin), _items, _input, _match_detail, _set_usage)
236 
237 /* call EVRY_PLUGIN_UPDATE when the list of items provided by plugin '_p' has
238  * changed. e.g. for files plugin when files were created or deleted
239  * while evry is active.
240  * '_action' can be EVRY_UPDATE_ADD (new items were added),
241  * EVRY_UPDATE_CLEAR (plugin does not provide any items) or
242  * EVRY_UPDATE_REFRESH (items have changed) */
243 #define EVRY_PLUGIN_UPDATE(_p, _action)                 \
244   if (_p) evry->plugin_update(EVRY_PLUGIN(_p), _action)
245 
246 #define EVRY_PLUGIN_ITEMS_SORT(_p, _sortcb)			\
247   EVRY_PLUGIN(_p)->items = eina_list_sort			\
248     (EVRY_PLUGIN(_p)->items, eina_list_count(EVRY_PLUGIN(_p)->items), _sortcb)
249 
250 
251 #define EVRY_PLUGIN_MIN_QUERY(_p, _input)				\
252   if (!(EVRY_PLUGIN(_p)->config->min_query) ||				\
253       (_input && ((int) strlen(_input) >= EVRY_PLUGIN(_p)->config->min_query)))
254 
255 #define EVRY_PLUGIN_ITEMS_CLEAR(_p) {				\
256      Evry_Item *_it;						\
257      EINA_LIST_FREE(EVRY_PLUGIN(_p)->items, _it)		\
258        if (_it) _it->fuzzy_match = 0; }
259 
260 #define EVRY_PLUGIN_HAS_ITEMS(_p) !!(EVRY_PLUGIN(_p)->items)
261 
262 /*** Evry_Action macros ***/
263 #define EVRY_ACTION_NEW(_name, _in1, _in2, _icon, _action, _check) \
264   evry->action_new(N_(_name), _(_name), _in1, _in2, _icon, _action, _check)
265 
266 #define EVRY_ACTION_FREE(_act) if (_act) evry->action_free(EVRY_ACTN(_act))
267 
268 /* register */
269 #define EVRY_MODULE_NEW(_module, _evry, _init, _shutdown)	\
270   {								\
271      _module = E_NEW(Evry_Module, 1);				\
272      _module->init     = &_init;				\
273      _module->shutdown = &_shutdown;				\
274      Eina_List *_l = e_datastore_get("evry_modules");		\
275      _l = eina_list_append(_l, _module);			\
276      e_datastore_set("evry_modules", _l);			\
277      if ((_evry = e_datastore_get("evry_api")))			\
278        _module->active = _init(_evry);				\
279   }
280 
281 #define EVRY_MODULE_FREE(_module)			\
282   {							\
283      if (_module->active) _module->shutdown();		\
284      _module->active = EINA_FALSE;			\
285      Eina_List *_l = e_datastore_get("evry_modules");	\
286      _l = eina_list_remove(_l, _module);		\
287      if (_l) e_datastore_set("evry_modules", _l);	\
288      else e_datastore_del("evry_modules");		\
289      E_FREE(_module);					\
290   }
291 
292 
293 /*** handy macros ***/
294 
295 #define IF_RELEASE(x) do {					\
296      if (x) {							\
297 	const char *__tmp; __tmp = (x);				\
298 	(x) = NULL; eina_stringshare_del(__tmp);		\
299      }								\
300      (x) = NULL;						\
301   } while (0)
302 
303 
304 #endif
305