1 #include <e.h>
2 #include "e_mod_main.h"
3 #include "e_mod_config.h"
4 #include "e_mod_packagekit.h"
5
6 #define PACKAGEKIT_DOMAIN "module.packagekit"
7
8 static E_Module *packagekit_mod = NULL;
9
10
11 static void
_cfg_menu_cb(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)12 _cfg_menu_cb(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
13 {
14 packagekit_config_show(data);
15 }
16
17 static void
_mouse_down_cb(void * data,Evas * evas EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event)18 _mouse_down_cb(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
19 {
20 E_PackageKit_Instance *inst = data;
21 E_PackageKit_Module_Context *ctxt = packagekit_mod->data;
22 Evas_Event_Mouse_Down *ev = event;
23
24 if (ev->button == 1)
25 {
26 if (inst->popup)
27 packagekit_popup_del(inst);
28 else
29 packagekit_popup_new(inst, EINA_TRUE);
30 }
31 else if (ev->button == 2)
32 {
33 packagekit_create_transaction_and_exec(ctxt, packagekit_get_updates);
34 }
35 else if (ev->button == 3)
36 {
37 E_Menu *m;
38 E_Menu_Item *mi;
39 E_Zone *zone = e_zone_current_get();
40 int x, y;
41
42 if (inst->popup)
43 packagekit_popup_del(inst);
44
45 m = e_menu_new();
46 mi = e_menu_item_new(m);
47 e_menu_item_label_set(mi, _("Settings"));
48 e_util_menu_item_theme_icon_set(mi, "configure");
49 e_menu_item_callback_set(mi, _cfg_menu_cb, inst->ctxt);
50
51 m = e_gadcon_client_util_menu_items_append(inst->gcc, m, 0);
52
53 e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &x, &y, NULL, NULL);
54 e_menu_activate_mouse(m, zone, (x + ev->output.x),(y + ev->output.y),
55 1, 1, E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
56 evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button,
57 EVAS_BUTTON_NONE, ev->timestamp, NULL);
58 }
59 }
60
61 static Eina_Bool
_refresh_timer_cb(void * data)62 _refresh_timer_cb(void *data)
63 {
64 E_PackageKit_Module_Context *ctxt = data;
65 double elapsed;
66
67 if (ctxt->config->update_interval == 0)
68 return ECORE_CALLBACK_RENEW;
69
70 elapsed = (ecore_time_unix_get() - ctxt->config->last_update) / 60;
71 if (elapsed > ctxt->config->update_interval)
72 {
73 ctxt->config->last_update = ecore_time_unix_get();
74 packagekit_create_transaction_and_exec(ctxt, packagekit_refresh_cache);
75 }
76 return ECORE_CALLBACK_RENEW;
77 }
78
79
80 /* Gadget Api Functions */
81 static void
_gadget_mouse_up_cb(void * data,Evas * evas EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event)82 _gadget_mouse_up_cb(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
83 {
84 E_PackageKit_Instance *inst = data;
85 E_PackageKit_Module_Context *ctxt = packagekit_mod->data;
86 Evas_Event_Mouse_Up *ev = event;
87
88 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
89 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
90
91 if (ev->button == 1)
92 {
93 if (inst->ctxpopup)
94 packagekit_popup_del(inst);
95 else
96 packagekit_popup_new(inst, EINA_FALSE);
97 }
98 else if (ev->button == 2)
99 {
100 packagekit_create_transaction_and_exec(ctxt, packagekit_get_updates);
101 }
102 }
103
104 static void
_gadget_del_cb(void * data,Evas * evas EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event EINA_UNUSED)105 _gadget_del_cb(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
106 {
107 E_PackageKit_Instance *inst = data;
108 E_PackageKit_Module_Context *ctxt = packagekit_mod->data;
109
110 if (inst->ctxpopup) packagekit_popup_del(inst);
111 ctxt->instances = eina_list_remove(ctxt->instances, inst);
112 free(inst);
113 }
114
115 static Evas_Object *
_gadget_configure_cb(Evas_Object * gadget)116 _gadget_configure_cb(Evas_Object *gadget)
117 {
118 E_PackageKit_Instance *inst = evas_object_data_get(gadget, "pkit-inst");
119 return packagekit_config_show(inst->ctxt);
120 }
121
122 static void
_gadget_menu1_cb(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)123 _gadget_menu1_cb(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
124 {
125 E_PackageKit_Module_Context *ctxt = data;
126
127 e_exec(e_zone_current_get(), NULL,
128 ctxt->config->manager_command,
129 NULL, NULL);
130 }
131
132 static void
_gadget_menu2_cb(void * data,E_Menu * m EINA_UNUSED,E_Menu_Item * mi EINA_UNUSED)133 _gadget_menu2_cb(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
134 {
135 E_PackageKit_Module_Context *ctxt = data;
136
137 packagekit_create_transaction_and_exec(ctxt, packagekit_refresh_cache);
138 }
139
140 static void
_gadget_menu_populate_cb(Evas_Object * gadget,E_Menu * m)141 _gadget_menu_populate_cb(Evas_Object *gadget, E_Menu *m)
142 {
143 E_PackageKit_Instance *inst = evas_object_data_get(gadget, "pkit-inst");
144 E_Menu_Item *mi;
145
146 mi = e_menu_item_new(m);
147 e_menu_item_separator_set(mi, 1);
148
149 mi = e_menu_item_new(m);
150 e_menu_item_label_set(mi, _("Refresh package list"));
151 e_util_menu_item_theme_icon_set(mi, "view-refresh");
152 e_menu_item_callback_set(mi, _gadget_menu2_cb, inst->ctxt);
153
154 if (inst->ctxt->config->manager_command && inst->ctxt->config->manager_command[0])
155 {
156 mi = e_menu_item_new(m);
157 e_menu_item_label_set(mi, _("Run the package manager"));
158 e_util_menu_item_theme_icon_set(mi, "preferences-applications");
159 e_menu_item_callback_set(mi, _gadget_menu1_cb, inst->ctxt);
160 }
161 }
162
163 static void
_gadget_created_cb(void * data,Evas_Object * obj,void * event_data EINA_UNUSED)164 _gadget_created_cb(void *data, Evas_Object *obj, void *event_data EINA_UNUSED)
165 {
166 E_PackageKit_Instance *inst = data;
167
168 evas_object_smart_callback_del_full(obj, "gadget_created",
169 _gadget_created_cb, data);
170 evas_object_event_callback_add(inst->gadget, EVAS_CALLBACK_MOUSE_UP,
171 _gadget_mouse_up_cb, inst);
172 e_gadget_configure_cb_set(inst->gadget, _gadget_configure_cb);
173 e_gadget_menu_populate_cb_set(inst->gadget, _gadget_menu_populate_cb);
174 packagekit_icon_update(inst->ctxt, EINA_FALSE);
175 }
176
177 EINTERN Evas_Object *
_gadget_create_cb(Evas_Object * parent,int * id,E_Gadget_Site_Orient orient EINA_UNUSED)178 _gadget_create_cb(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient EINA_UNUSED)
179 {
180 E_PackageKit_Instance *inst;
181 E_PackageKit_Module_Context *ctxt = packagekit_mod->data;
182
183 inst = E_NEW(E_PackageKit_Instance, 1);
184 inst->ctxt = ctxt;
185 inst->gadget = edje_object_add(evas_object_evas_get(parent));
186 e_theme_edje_object_set(inst->gadget, "base/theme/modules/packagekit",
187 "e/modules/packagekit/main");
188 evas_object_event_callback_add(inst->gadget, EVAS_CALLBACK_DEL,
189 _gadget_del_cb, inst);
190 evas_object_data_set(inst->gadget, "pkit-inst", inst);
191 ctxt->instances = eina_list_append(ctxt->instances, inst);
192 if (*id >= 0)
193 { // normal mode
194 evas_object_smart_callback_add(parent, "gadget_created",
195 _gadget_created_cb, inst);
196 }
197 else
198 { // demo mode
199 edje_object_signal_emit(inst->gadget, "packagekit,state,updated", "e");
200 }
201
202 return inst->gadget;
203 }
204
205
206 /* Gadcon Api Functions */
207 static E_Gadcon_Client *
_gc_init(E_Gadcon * gc,const char * name,const char * id,const char * style)208 _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
209 {
210 E_PackageKit_Instance *inst;
211 E_PackageKit_Module_Context *ctxt = packagekit_mod->data;
212
213 inst = E_NEW(E_PackageKit_Instance, 1);
214 inst->ctxt = ctxt;
215 inst->gadget = edje_object_add(gc->evas);
216 e_theme_edje_object_set(inst->gadget, "base/theme/modules/packagekit",
217 "e/modules/packagekit/main");
218 inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->gadget);
219 inst->gcc->data = inst;
220 evas_object_event_callback_add(inst->gadget, EVAS_CALLBACK_MOUSE_DOWN,
221 _mouse_down_cb, inst);
222 ctxt->instances = eina_list_append(ctxt->instances, inst);
223 packagekit_icon_update(ctxt, EINA_FALSE);
224 return inst->gcc;
225 }
226
227 static void
_gc_shutdown(E_Gadcon_Client * gcc)228 _gc_shutdown(E_Gadcon_Client *gcc)
229 {
230 E_PackageKit_Instance *inst = gcc->data;
231 E_PackageKit_Module_Context *ctxt = packagekit_mod->data;
232
233 E_FREE_FUNC(inst->gadget, evas_object_del);
234 if (inst->popup) packagekit_popup_del(inst);
235 ctxt->instances = eina_list_remove(ctxt->instances, inst);
236 free(inst);
237 }
238
239 static void
_gc_orient(E_Gadcon_Client * gcc,E_Gadcon_Orient orient EINA_UNUSED)240 _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient EINA_UNUSED)
241 {
242 e_gadcon_client_aspect_set(gcc, 16, 16);
243 e_gadcon_client_min_size_set(gcc, 16, 16);
244 }
245
246 static const char *
_gc_label(const E_Gadcon_Client_Class * client_class EINA_UNUSED)247 _gc_label(const E_Gadcon_Client_Class *client_class EINA_UNUSED)
248 {
249 return _("System Updates");
250 }
251
252 static Evas_Object *
_gc_icon(const E_Gadcon_Client_Class * client_class EINA_UNUSED,Evas * evas)253 _gc_icon(const E_Gadcon_Client_Class *client_class EINA_UNUSED, Evas *evas)
254 {
255 char buf[PATH_MAX];
256 Evas_Object *o;
257
258 EINA_SAFETY_ON_NULL_RETURN_VAL(packagekit_mod, NULL);
259 snprintf(buf, sizeof(buf), "%s/e-module-packagekit.edj",
260 e_module_dir_get(packagekit_mod));
261 o = edje_object_add(evas);
262 edje_object_file_set(o, buf, "icon");
263 return o;
264 }
265
266 static const char *
_gc_id_new(const E_Gadcon_Client_Class * client_class EINA_UNUSED)267 _gc_id_new(const E_Gadcon_Client_Class *client_class EINA_UNUSED)
268 {
269 E_PackageKit_Module_Context *ctxt = packagekit_mod->data;
270 static char buf[64];
271 snprintf(buf, sizeof(buf), "packagekit.%d", eina_list_count(ctxt->instances));
272 return buf;
273 }
274
275 static const E_Gadcon_Client_Class _gc_class =
276 {
277 GADCON_CLIENT_CLASS_VERSION, "PackageKit",
278 {
279 _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL,
280 e_gadcon_site_is_not_toolbar
281 },
282 E_GADCON_CLIENT_STYLE_PLAIN
283 };
284
285
286 /* E Module Api Functions */
287 E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "PackageKit" };
288
289 E_API void *
e_modapi_init(E_Module * m)290 e_modapi_init(E_Module *m)
291 {
292 E_PackageKit_Module_Context *ctxt;
293
294 ctxt = E_NEW(E_PackageKit_Module_Context, 1);
295 EINA_SAFETY_ON_NULL_RETURN_VAL(ctxt, NULL);
296 ctxt->v_maj = ctxt->v_min = ctxt->v_mic = -1;
297
298 ctxt->conf_edd = E_CONFIG_DD_NEW("packagekit_config", PackageKit_Config);
299 #undef T
300 #undef D
301 #define T PackageKit_Config
302 #define D ctxt->conf_edd
303 E_CONFIG_VAL(D, T, update_interval, INT);
304 E_CONFIG_VAL(D, T, last_update, INT);
305 E_CONFIG_VAL(D, T, manager_command, STR);
306 E_CONFIG_VAL(D, T, show_description, INT);
307 ctxt->config = e_config_domain_load(PACKAGEKIT_DOMAIN, ctxt->conf_edd);
308 if (!ctxt->config)
309 {
310 ctxt->config = E_NEW(PackageKit_Config, 1);
311 ctxt->config->update_interval = 60 * 24; // once a day
312 ctxt->config->show_description = 1; // extended list
313 }
314 m->data = ctxt;
315 ctxt->module = m;
316 packagekit_mod = m;
317
318 // add the gadget to the new E gadgets system
319 // TODO should this name be translated? also on type_del??
320 e_gadget_type_add("PackageKit", _gadget_create_cb, NULL);
321
322 // add the gadget to the old E gadcon system
323 e_gadcon_provider_register(&_gc_class);
324
325 packagekit_dbus_connect(ctxt);
326 ctxt->refresh_timer = ecore_timer_loop_add(60.0, _refresh_timer_cb, ctxt);
327 return ctxt;
328 }
329
330 E_API int
e_modapi_shutdown(E_Module * m)331 e_modapi_shutdown(E_Module *m)
332 {
333 E_PackageKit_Module_Context *ctxt = m->data;
334
335 packagekit_dbus_disconnect(ctxt);
336
337 E_FREE_FUNC(ctxt->refresh_timer, ecore_timer_del);
338 E_FREE_FUNC(ctxt->error, eina_stringshare_del);
339
340 E_FREE_FUNC(ctxt->config->manager_command, eina_stringshare_del);
341 E_FREE(ctxt->config);
342 E_CONFIG_DD_FREE(ctxt->conf_edd);
343
344 // remove the gadget from the new E gadgets system
345 e_gadget_type_del("PackageKit");
346
347 // remove the gadget from the old E gadcon system
348 e_gadcon_provider_unregister(&_gc_class);
349
350 E_PackageKit_Package *pkg;
351 EINA_LIST_FREE(ctxt->packages, pkg)
352 {
353 E_FREE_FUNC(pkg->name, eina_stringshare_del);
354 E_FREE_FUNC(pkg->version, eina_stringshare_del);
355 E_FREE_FUNC(pkg->summary, eina_stringshare_del);
356 }
357
358 E_FREE(ctxt);
359 packagekit_mod = NULL;
360
361 return 1;
362 }
363
364 E_API int
e_modapi_save(E_Module * m)365 e_modapi_save(E_Module *m)
366 {
367 E_PackageKit_Module_Context *ctxt = m->data;
368 e_config_domain_save(PACKAGEKIT_DOMAIN, ctxt->conf_edd, ctxt->config);
369 return 1;
370 }
371
372
373