diff --git a/config/illume-home/e.src b/config/illume-home/e.src index 02a8ec00a..7292cae4a 100644 --- a/config/illume-home/e.src +++ b/config/illume-home/e.src @@ -1059,6 +1059,13 @@ group "E_Config" struct { value "params" string: "3"; value "any_mod" uchar: 0; } + group "E_Config_Binding_Key" struct { + value "context" int: 9; + value "modifiers" int: 0; + value "key" string: "Print"; + value "action" string: "shot"; + value "any_mod" uchar: 0; + } } group "mouse_bindings" list { group "E_Config_Binding_Mouse" struct { @@ -1222,6 +1229,12 @@ group "E_Config" struct { value "delayed" uchar: 0; value "priority" int: -1000; } + group "E_Config_Module" struct { + value "name" string: "shot"; + value "enabled" uchar: 1; + value "delayed" uchar: 1; + value "priority" int: 0; + } } value "config_version" int: 65847; value "show_splash" int: 1; diff --git a/config/minimalist/e.src b/config/minimalist/e.src index a1e9a1154..c9e5d6ffa 100644 --- a/config/minimalist/e.src +++ b/config/minimalist/e.src @@ -185,6 +185,14 @@ group "E_Config" struct { value "priority" int: 0; } } + group "modules" list { + group "E_Config_Module" struct { + value "name" string: "shot"; + value "enabled" uchar: 1; + value "delayed" uchar: 1; + value "priority" int: 0; + } + } group "themes" list { group "E_Config_Theme" struct { value "category" string: "theme"; @@ -705,6 +713,15 @@ group "E_Config" struct { value "any_mod" uchar: 0; } } + group "key_bindings" list { + group "E_Config_Binding_Key" struct { + value "context" int: 9; + value "modifiers" int: 0; + value "key" string: "Print"; + value "action" string: "shot"; + value "any_mod" uchar: 0; + } + } group "edge_bindings" list { group "E_Config_Binding_Edge" struct { value "context" int: 3; diff --git a/config/netbook/e.src b/config/netbook/e.src index a6e8b18bc..199e3a7cd 100644 --- a/config/netbook/e.src +++ b/config/netbook/e.src @@ -241,6 +241,14 @@ group "E_Config" struct { value "priority" int: 0; } } + group "modules" list { + group "E_Config_Module" struct { + value "name" string: "shot"; + value "enabled" uchar: 1; + value "delayed" uchar: 1; + value "priority" int: 0; + } + } group "themes" list { group "E_Config_Theme" struct { value "category" string: "theme"; @@ -761,6 +769,15 @@ group "E_Config" struct { value "any_mod" uchar: 0; } } + group "key_bindings" list { + group "E_Config_Binding_Key" struct { + value "context" int: 9; + value "modifiers" int: 0; + value "key" string: "Print"; + value "action" string: "shot"; + value "any_mod" uchar: 0; + } + } group "edge_bindings" list { group "E_Config_Binding_Edge" struct { value "context" int: 3; diff --git a/config/scaleable/e.src b/config/scaleable/e.src index b5c69ab31..66892c9ed 100644 --- a/config/scaleable/e.src +++ b/config/scaleable/e.src @@ -264,6 +264,14 @@ group "E_Config" struct { value "priority" int: 0; } } + group "modules" list { + group "E_Config_Module" struct { + value "name" string: "shot"; + value "enabled" uchar: 1; + value "delayed" uchar: 1; + value "priority" int: 0; + } + } group "themes" list { group "E_Config_Theme" struct { value "category" string: "theme"; @@ -784,6 +792,15 @@ group "E_Config" struct { value "any_mod" uchar: 0; } } + group "key_bindings" list { + group "E_Config_Binding_Key" struct { + value "context" int: 9; + value "modifiers" int: 0; + value "key" string: "Print"; + value "action" string: "shot"; + value "any_mod" uchar: 0; + } + } group "edge_bindings" list { group "E_Config_Binding_Edge" struct { value "context" int: 3; diff --git a/config/standard/e.src b/config/standard/e.src index 0e37ab16f..b417d34c2 100644 --- a/config/standard/e.src +++ b/config/standard/e.src @@ -272,6 +272,14 @@ group "E_Config" struct { value "priority" int: -1000; } } + group "modules" list { + group "E_Config_Module" struct { + value "name" string: "shot"; + value "enabled" uchar: 1; + value "delayed" uchar: 1; + value "priority" int: 0; + } + } group "themes" list { group "E_Config_Theme" struct { value "category" string: "theme"; @@ -828,6 +836,15 @@ group "E_Config" struct { value "any_mod" uchar: 0; } } + group "key_bindings" list { + group "E_Config_Binding_Key" struct { + value "context" int: 9; + value "modifiers" int: 0; + value "key" string: "Print"; + value "action" string: "shot"; + value "any_mod" uchar: 0; + } + } group "edge_bindings" list { group "E_Config_Binding_Edge" struct { value "context" int: 3; diff --git a/configure.ac b/configure.ac index e86b7d7bd..fd803224f 100644 --- a/configure.ac +++ b/configure.ac @@ -712,6 +712,7 @@ AC_E_OPTIONAL_MODULE([everything], true) AC_E_OPTIONAL_MODULE([everything-as-modules], false) AC_E_OPTIONAL_MODULE([systray], true) AC_E_OPTIONAL_MODULE([comp], true) +AC_E_OPTIONAL_MODULE([shot], true) SUSPEND="" HIBERNATE="" @@ -869,6 +870,8 @@ src/modules/systray/Makefile src/modules/systray/module.desktop src/modules/comp/Makefile src/modules/comp/module.desktop +src/modules/shot/Makefile +src/modules/shot/module.desktop src/preload/Makefile data/Makefile data/images/Makefile diff --git a/src/bin/e_widget_fsel.c b/src/bin/e_widget_fsel.c index 98847726a..c318d3294 100644 --- a/src/bin/e_widget_fsel.c +++ b/src/bin/e_widget_fsel.c @@ -562,9 +562,13 @@ EAPI const char * e_widget_fsel_selection_path_get(Evas_Object *obj) { E_Widget_Data *wd; - + const char *s; + if (!obj) return NULL; wd = e_widget_data_get(obj); + E_FREE(wd->path); + s = e_widget_entry_text_get(wd->o_entry); + if (s) wd->path = strdup(s); return wd->path; } diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index b4990bef4..8db61aa02 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -183,3 +183,8 @@ endif if USE_MODULE_OFONO SUBDIRS += ofono endif + +if USE_MODULE_SHOT +SUBDIRS += shot +endif + diff --git a/src/modules/clock/e_mod_main.c b/src/modules/clock/e_mod_main.c index efaa921f0..4dea9a0f3 100644 --- a/src/modules/clock/e_mod_main.c +++ b/src/modules/clock/e_mod_main.c @@ -26,11 +26,45 @@ typedef struct _Instance Instance; struct _Instance { E_Gadcon_Client *gcc; - Evas_Object *o_clock; + Evas_Object *o_clock, *o_cal; + E_Gadcon_Popup *popup; }; static E_Module *clock_module = NULL; +static void +_clock_popup_new(Instance *inst) +{ + Evas *evas; + + if (inst->popup) return; + inst->popup = e_gadcon_popup_new(inst->gcc); + evas = inst->popup->win->evas; + inst->o_cal = e_widget_table_add(evas, 0); + e_widget_size_min_set(inst->o_cal, 100, 100); + e_gadcon_popup_content_set(inst->popup, inst->o_cal); + e_gadcon_popup_show(inst->popup); +} + +static void +_clock_popup_free(Instance *inst) +{ + if (!inst->popup) return; + if (inst->popup) e_object_del(E_OBJECT(inst->popup)); + inst->popup = NULL; +} + +static void +_clock_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event) +{ + Instance *inst = data; + Evas_Event_Mouse_Down *ev = event; + + if (ev->button != 1) return; + if (inst->popup) _clock_popup_free(inst); + else _clock_popup_new(inst); +} + static E_Gadcon_Client * _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) { @@ -50,6 +84,11 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) inst->gcc = gcc; inst->o_clock = o; + + evas_object_event_callback_add(inst->o_clock, + EVAS_CALLBACK_MOUSE_DOWN, + _clock_cb_mouse_down, + inst); e_gadcon_client_util_menu_attach(gcc); @@ -63,6 +102,7 @@ _gc_shutdown(E_Gadcon_Client *gcc) inst = gcc->data; evas_object_del(inst->o_clock); + _clock_popup_free(inst); free(inst); } diff --git a/src/modules/shot/.cvsignore b/src/modules/shot/.cvsignore new file mode 100644 index 000000000..06d064a84 --- /dev/null +++ b/src/modules/shot/.cvsignore @@ -0,0 +1,7 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +module.la +module.desktop diff --git a/src/modules/shot/Makefile.am b/src/modules/shot/Makefile.am new file mode 100644 index 000000000..3bf6d9448 --- /dev/null +++ b/src/modules/shot/Makefile.am @@ -0,0 +1,28 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = shot + +# data files for the module +filesdir = $(libdir)/enlightenment/modules/$(MODULE) +files_DATA = \ +e-module-$(MODULE).edj module.desktop + +EXTRA_DIST = $(files_DATA) + +# the module .so file +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src/modules/$(MODULE) \ + -I$(top_srcdir)/src/bin \ + -I$(top_builddir)/src/bin \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ +pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la +module_la_SOURCES = e_mod_main.c \ + e_mod_main.h +module_la_LIBADD = @e_libs@ @dlopen_libs@ +module_la_LDFLAGS = -module -avoid-version +module_la_DEPENDENCIES = $(top_builddir)/config.h + +uninstall: + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE) diff --git a/src/modules/shot/e-module-shot.edj b/src/modules/shot/e-module-shot.edj new file mode 100644 index 000000000..a25237bdf Binary files /dev/null and b/src/modules/shot/e-module-shot.edj differ diff --git a/src/modules/shot/e_mod_main.c b/src/modules/shot/e_mod_main.c new file mode 100644 index 000000000..1a842a324 --- /dev/null +++ b/src/modules/shot/e_mod_main.c @@ -0,0 +1,799 @@ +#include "e.h" +#include "e_mod_main.h" + +static E_Module *shot_module = NULL; + +static E_Action *act = NULL; +static E_Int_Menu_Augmentation *maug = NULL; +static Ecore_Timer *timer = NULL; +static E_Win *win = NULL; +static Evas_Object *o_bg = NULL, *o_box = NULL, *o_content = NULL; +static Evas_Object *o_event = NULL, *o_img = NULL, *o_hlist = NULL; +static E_Manager *sman = NULL; +static E_Container *scon = NULL; +static int quality = 90; +static int screen = -1; +#define MAXZONES 64 +static Evas_Object *o_rectdim[MAXZONES] = { NULL }; +static Evas_Object *o_fsel = NULL; +static Evas_Object *o_label = NULL; +static Evas_Object *o_entry = NULL; +static unsigned char *fdata = NULL; +static int fsize = 0; +static Ecore_Con_Url *url_up = NULL; +static Eina_List *handlers = NULL; +static char *url_ret = NULL; + +static void +_win_delete_cb(E_Win *w __UNUSED__) +{ + if (win) + { + e_object_del(E_OBJECT(win)); + win = NULL; + } +} + +static void +_win_resize_cb(E_Win *w __UNUSED__) +{ + evas_object_resize(o_bg, win->w, win->h); +} + +static void +_on_focus_cb(void *data __UNUSED__, Evas_Object *obj) +{ + if (obj == o_content) e_widget_focused_object_clear(o_box); + else if (o_content) e_widget_focused_object_clear(o_content); +} + +static void +_key_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event) +{ + Evas_Event_Key_Down *ev = event; + + if (!strcmp(ev->keyname, "Tab")) + { + if (evas_key_modifier_is_set(evas_key_modifier_get(e_win_evas_get(win)), "Shift")) + { + if (e_widget_focus_get(o_box)) + { + if (!e_widget_focus_jump(o_box, 0)) + { + e_widget_focus_set(o_content, 0); + if (!e_widget_focus_get(o_content)) + e_widget_focus_set(o_box, 0); + } + } + else + { + if (!e_widget_focus_jump(o_content, 0)) + e_widget_focus_set(o_box, 0); + } + } + else + { + if (e_widget_focus_get(o_box)) + { + if (!e_widget_focus_jump(o_box, 1)) + { + e_widget_focus_set(o_content, 1); + if (!e_widget_focus_get(o_content)) + e_widget_focus_set(o_box, 1); + } + } + else + { + if (!e_widget_focus_jump(o_content, 1)) + e_widget_focus_set(o_box, 1); + } + } + } + else if (((!strcmp(ev->keyname, "Return")) || + (!strcmp(ev->keyname, "KP_Enter")) || + (!strcmp(ev->keyname, "space")))) + { + Evas_Object *o = NULL; + + if ((o_content) && (e_widget_focus_get(o_content))) + o = e_widget_focused_object_get(o_content); + else + o = e_widget_focused_object_get(o_box); + if (o) e_widget_activate(o); + } +} + +static void +_screen_change_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Eina_List *l; + E_Zone *z; + + EINA_LIST_FOREACH(scon->zones, l, z) + { + if (screen == -1) + evas_object_color_set(o_rectdim[z->num], 0, 0, 0, 0); + else if (screen == (int)z->num) + evas_object_color_set(o_rectdim[z->num], 0, 0, 0, 0); + else + evas_object_color_set(o_rectdim[z->num], 0, 0, 0, 128); + } +} + +static void +_save_to(const char *file) +{ + char *extn = strrchr(file, '.'); + char opts[256]; + + if (!extn) + { + e_util_dialog_show + (_("Error - Unknown format"), + _("File has an unspecified extension.
" + "Please use '.jpg' or '.png' extensions
" + "only as other formats are not
" + "supported currently.")); + return; + } + if (!((!strcasecmp(extn, ".png")) || + (!strcasecmp(extn, ".jpg")) || + (!strcasecmp(extn, ".jpeg")))) + { + e_util_dialog_show + (_("Error - Unknown format"), + _("File has an unrecognized extension.
" + "Please use '.jpg' or '.png' extensions
" + "only as other formats are not
" + "supported currently.")); + return; + } + if (!strcasecmp(extn, ".png")) + snprintf(opts, sizeof(opts), "compress=%i", 9); + else + snprintf(opts, sizeof(opts), "quality=%i", quality); + if (screen == -1) + { + evas_object_image_save(o_img, file, NULL, opts); + } + else + { + Evas_Object *o; + Eina_List *l; + E_Zone *z = NULL; + + EINA_LIST_FOREACH(scon->zones, l, z) + { + if (screen == (int)z->num) break; + z = NULL; + } + if (z) + { + unsigned char *src, *dst, *s, *d; + int sstd, dstd, y; + + o = evas_object_image_add(evas_object_evas_get(o_img)); + evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888); + evas_object_image_alpha_set(o, EINA_FALSE); + evas_object_image_size_set(o, z->w, z->h); + src = evas_object_image_data_get(o_img, EINA_FALSE); + sstd = evas_object_image_stride_get(o_img); + dst = evas_object_image_data_get(o, EINA_TRUE); + dstd = evas_object_image_stride_get(o); + d = dst; + for (y = 0; y < z->h; y++) + { + s = src + (sstd * y) + (z->x * 4); + memcpy(d, s, z->w * 4); + d += z->w * 4; + } + evas_object_image_save(o, file, NULL, opts); + evas_object_del(o); + } + } +} + +static void +_file_select_ok_cb(void *data __UNUSED__, E_Dialog *dia) +{ + const char *file; + + file = e_widget_fsel_selection_path_get(o_fsel); + if (file) _save_to(file); + if (dia) e_util_defer_object_del(E_OBJECT(dia)); + if (win) + { + e_object_del(E_OBJECT(win)); + win = NULL; + } +} + +static void +_file_select_cancel_cb(void *data __UNUSED__, E_Dialog *dia) +{ + if (dia) e_util_defer_object_del(E_OBJECT(dia)); + if (win) + { + e_object_del(E_OBJECT(win)); + win = NULL; + } +} + +static void +_win_save_cb(void *data __UNUSED__, void *data2 __UNUSED__) +{ + E_Dialog *dia; + Evas_Object *o; + Evas_Coord mw, mh; + + dia = e_dialog_new(scon, "E", "_e_shot_fsel"); + e_dialog_title_set(dia, _("Select screenshot save location")); + o = e_widget_fsel_add(dia->win->evas, "~/", "/", NULL, NULL, + NULL, NULL, + NULL, NULL, 1); + o_fsel = o; + evas_object_show(o); + e_widget_size_min_get(o, &mw, &mh); + e_dialog_content_set(dia, o, mw, mh); + e_dialog_button_add(dia, _("OK"), NULL, + _file_select_ok_cb, NULL); + e_dialog_button_add(dia, _("Cancel"), NULL, + _file_select_cancel_cb, NULL); + e_dialog_resizable_set(dia, 1); + e_win_centered_set(dia->win, 1); + e_dialog_show(dia); +} + +static void +_share_done(void) +{ + Ecore_Event_Handler *h; + + EINA_LIST_FREE(handlers, h) ecore_event_handler_del(h); + o_label = NULL; + if (url_ret) + { + free(url_ret); + url_ret = NULL; + } + if (url_up) + { + ecore_con_url_free(url_up); + url_up = NULL; + } + ecore_con_url_shutdown(); +} + +static void +_upload_ok_cb(void *data __UNUSED__, E_Dialog *dia) +{ + // ok just hides dialog and does background upload + o_label = NULL; + if (dia) e_util_defer_object_del(E_OBJECT(dia)); + if (win) + { + e_object_del(E_OBJECT(win)); + win = NULL; + } + _share_done(); +} + +static void +_upload_cancel_cb(void *data __UNUSED__, E_Dialog *dia) +{ + if (dia) e_util_defer_object_del(E_OBJECT(dia)); + if (win) + { + e_object_del(E_OBJECT(win)); + win = NULL; + } +} + +static Eina_Bool +_upload_data_cb(void *data __UNUSED__, int ev_type __UNUSED__, void *event) +{ + Ecore_Con_Event_Url_Data *ev = event; + if (ev->url_con != url_up) return EINA_TRUE; + if ((o_label) && (ev->size < 1024)) + { + char *txt = alloca(ev->size + 1); + + memcpy(txt, ev->data, ev->size); + txt[ev->size] = 0; + if (!url_ret) url_ret = strdup(txt); + else + { + char *n; + + n = malloc(strlen(url_ret) + ev->size + 1); + if (n) + { + free(url_ret); + strcpy(n, url_ret); + strcat(n, txt); + url_ret = n; + } + } + } + return EINA_FALSE; +} + +static Eina_Bool +_upload_progress_cb(void *data __UNUSED__, int ev_type __UNUSED__, void *event) +{ + Ecore_Con_Event_Url_Progress *ev = event; + if (ev->url_con != url_up) return EINA_TRUE; + if (o_label) + { + char buf[1024]; + + snprintf(buf, sizeof(buf), + "Uploaded %1.1fKB / %1.1fKB", + ev->up.now / 1024, + ev->up.total / 1024); + e_widget_label_text_set(o_label, buf); + } + return EINA_FALSE; +} + +static Eina_Bool +_upload_complete_cb(void *data __UNUSED__, int ev_type __UNUSED__, void *event) +{ + Ecore_Con_Event_Url_Complete *ev = event; + if (ev->url_con != url_up) return EINA_TRUE; + if (ev->status != 200) + { + e_util_dialog_show + (_("Error - Upload Failed"), + _("Upload failed with status code:\n" + "%i"), + ev->status); + _share_done(); + return EINA_FALSE; + } + if ((o_entry) && (url_ret)) + e_widget_entry_text_set(o_entry, url_ret); + _share_done(); + return EINA_FALSE; +} + +static void +_win_share_cb(void *data __UNUSED__, void *data2 __UNUSED__) +{ + E_Dialog *dia; + Evas_Object *o, *ol; + Evas_Coord mw, mh; + char buf[PATH_MAX]; + FILE *f; + + if (quality == 100) snprintf(buf, sizeof(buf), "/tmp/e-shot-XXXXXX.png"); + else snprintf(buf, sizeof(buf), "/tmp/e-shot-XXXXXX.jpg"); + if (!mkstemp(buf)) + { + e_util_dialog_show + (_("Error - Can't create File"), + _("Cannot create temporary file:\n" + "%s"), + buf); + if (win) + { + e_object_del(E_OBJECT(win)); + win = NULL; + } + return; + } + _save_to(buf); + if (win) + { + e_object_del(E_OBJECT(win)); + win = NULL; + } + f = fopen(buf, "rb"); + if (!f) + { + // FIXME: error disp + return; + } + fseek(f, 0, SEEK_END); + fsize = ftell(f); + if (fsize < 1) + { + // FIXME: error disp + fclose(f); + return; + } + rewind(f); + if (fdata) free(fdata); + fdata = malloc(fsize); + if (!fdata) + { + // FIXME: error disp + fclose(f); + return; + } + if (fread(fdata, fsize, 1, f) != 1) + { + // FIXME: error disp + free(fdata); + fdata = NULL; + fclose(f); + return; + } + fclose(f); + ecore_file_unlink(buf); + + _share_done(); + + if (!ecore_con_url_init()) + { + // FIXME: error disp + free(fdata); + fdata = NULL; + return; + } + + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_CON_EVENT_URL_DATA, _upload_data_cb, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_CON_EVENT_URL_PROGRESS, _upload_progress_cb, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_CON_EVENT_URL_COMPLETE, _upload_complete_cb, NULL)); + + url_up = ecore_con_url_new("http://www.enlightenment.org/shot.php"); + ecore_con_url_post(url_up, fdata, fsize, "application/x-e-shot"); + + dia = e_dialog_new(scon, "E", "_e_shot_share"); + e_dialog_title_set(dia, _("Uploading screenshot")); + + o = e_widget_list_add(dia->win->evas, 0, 0); + ol = o; + + o = e_widget_label_add(dia->win->evas, _("Uploading ...")); + o_label = o; + e_widget_list_object_append(ol, o, 0, 0, 0.5); + + o = e_widget_label_add(dia->win->evas, + _("Screenshot is available at this location:")); + e_widget_list_object_append(ol, o, 0, 0, 0.5); + + o = e_widget_entry_add(dia->win->evas, NULL, NULL, NULL, NULL); + o_entry = o; + e_widget_list_object_append(ol, o, 1, 0, 0.5); + + e_widget_size_min_get(ol, &mw, &mh); + e_dialog_content_set(dia, ol, mw, mh); + e_dialog_button_add(dia, _("OK"), NULL, _upload_ok_cb, NULL); + e_dialog_button_add(dia, _("Cancel"), NULL, _upload_cancel_cb, NULL); + e_dialog_resizable_set(dia, 1); + e_win_centered_set(dia->win, 1); + e_dialog_show(dia); + + // FIXME: start upload + // FIXME: on upload complete, show URL + // FIXME: cleanup tmp file +} + +static void +_win_cancel_cb(void *data __UNUSED__, void *data2 __UNUSED__) +{ + if (win) + { + e_object_del(E_OBJECT(win)); + win = NULL; + } +} + +static void +_shot_now(E_Zone *zone) +{ + Ecore_X_Image *img; + Ecore_X_Window_Attributes att; + unsigned char *src; + unsigned int *dst; + int bpl = 0, rows = 0, bpp = 0; + Evas *evas, *evas2; + Evas_Object *o, *oa, *op, *ol; + Evas_Coord w, h; + Evas_Modifier_Mask mask; + E_Radio_Group *rg; + + sman = zone->container->manager; + scon = zone->container; + memset(&att, 0, sizeof(Ecore_X_Window_Attributes)); + ecore_x_window_attributes_get(sman->root, &att); + img = ecore_x_image_new(sman->w, sman->h, att.visual, att.depth); + ecore_x_image_get(img, sman->root, 0, 0, 0, 0, sman->w, sman->h); + src = ecore_x_image_data_get(img, &bpl, &rows, &bpp); + if (!ecore_x_image_is_argb32_get(img)) + { + dst = malloc(sman->w * sman->h * sizeof(int)); + ecore_x_image_to_argb_convert(src, bpp, bpl, att.colormap, att.visual, + 0, 0, sman->w, sman->h, + dst, (sman->w * sizeof(int)), 0, 0); + } + else + dst = (unsigned int *)src; + + if (win) e_object_del(E_OBJECT(win)); + win = e_win_new(e_container_current_get(e_manager_current_get())); + + evas = e_win_evas_get(win); + e_win_title_set(win, _("Where to put Screenshot...")); + e_win_delete_callback_set(win, _win_delete_cb); + e_win_resize_callback_set(win, _win_resize_cb); + e_win_dialog_set(win, 1); + e_win_centered_set(win, 1); + e_win_name_class_set(win, "E", "_shot_dialog"); + + o = edje_object_add(evas); + o_bg = o;; + e_theme_edje_object_set(o, "base/theme/dialog", "e/widgets/dialog/main"); + evas_object_move(o, 0, 0); + evas_object_show(o); + + o = e_widget_list_add(evas, 0, 0); + o_content = o; + e_widget_size_min_get(o, &w, &h); + edje_extern_object_min_size_set(o, w, h); + edje_object_part_swallow(o_bg, "e.swallow.content", o); + evas_object_show(o); + + w = sman->w / 4; + if (w < 220) w = 220; + h = (w * sman->h) / sman->w; + + o = e_widget_aspect_add(evas, w, h); + oa = o; + o = e_widget_preview_add(evas, w, h); + op = o; + + evas2 = e_widget_preview_evas_get(op); + + o = evas_object_image_filled_add(evas2); + o_img = o; + evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888); + evas_object_image_alpha_set(o, EINA_FALSE); + evas_object_image_size_set(o, sman->w, sman->h); + evas_object_image_data_copy_set(o, dst); + if (dst != (unsigned int *)src) free(dst); + ecore_x_image_free(img); + evas_object_image_data_update_add(o, 0, 0, sman->w, sman->h); + e_widget_preview_extern_object_set(op, o); + evas_object_show(o); + + evas_object_show(op); + evas_object_show(oa); + + e_widget_aspect_child_set(oa, op); + e_widget_list_object_append(o_content, oa, 0, 0, 0.5); + + o = e_widget_list_add(evas, 1, 1); + o_hlist = o; + + o = e_widget_framelist_add(evas, _("Quality"), 0); + ol = o; + + rg = e_widget_radio_group_new(&quality); + o = e_widget_radio_add(evas, _("Perfect"), 100, rg); + e_widget_framelist_object_append(ol, o); + o = e_widget_radio_add(evas, _("High"), 90, rg); + e_widget_framelist_object_append(ol, o); + o = e_widget_radio_add(evas, _("Medium"), 70, rg); + e_widget_framelist_object_append(ol, o); + o = e_widget_radio_add(evas, _("Low"), 50, rg); + e_widget_framelist_object_append(ol, o); + + e_widget_list_object_append(o_hlist, ol, 1, 0, 0.5); + + screen = -1; + if (eina_list_count(scon->zones) > 1) + { + Eina_List *l; + E_Zone *z; + int i; + + o = e_widget_framelist_add(evas, _("Screen"), 0); + ol = o; + + rg = e_widget_radio_group_new(&screen); + o = e_widget_radio_add(evas, _("All"), -1, rg); + evas_object_smart_callback_add(o, "changed", _screen_change_cb, NULL); + e_widget_framelist_object_append(ol, o); + i = 0; + EINA_LIST_FOREACH(scon->zones, l, z) + { + char buf[32]; + + if (z->num >= MAXZONES) continue; + snprintf(buf, sizeof(buf), "%i", z->num); + o = e_widget_radio_add(evas, buf, z->num, rg); + evas_object_smart_callback_add(o, "changed", _screen_change_cb, NULL); + e_widget_framelist_object_append(ol, o); + + o = evas_object_rectangle_add(evas2); + o_rectdim[z->num] = o; + evas_object_color_set(o, 0, 0, 0, 0); + evas_object_show(o); + evas_object_geometry_get(o_img, NULL, NULL, &w, &h); + evas_object_move(o, + (z->x * w) / sman->w, + (z->y * h) / sman->h); + evas_object_resize(o, + (z->w * w) / sman->w, + (z->h * h) / sman->h); + i++; + } + + e_widget_list_object_append(o_hlist, ol, 1, 0, 0.5); + } + + e_widget_list_object_append(o_content, o_hlist, 0, 0, 0.5); + + o = o_content; + e_widget_size_min_get(o, &w, &h); + edje_extern_object_min_size_set(o, w, h); + edje_object_part_swallow(o_bg, "e.swallow.content", o); + evas_object_show(o); + + /////////////////////////////////////////////////////////////////////// + + o = e_widget_list_add(evas, 1, 1); + o_box = o; + e_widget_on_focus_hook_set(o, _on_focus_cb, NULL); + edje_object_part_swallow(o_bg, "e.swallow.buttons", o); + + o = e_widget_button_add(evas, _("Save"), NULL, _win_save_cb, win, NULL); + e_widget_list_object_append(o_box, o, 1, 0, 0.5); + o = e_widget_button_add(evas, _("Share"), NULL, _win_share_cb, win, NULL); + e_widget_list_object_append(o_box, o, 1, 0, 0.5); + o = e_widget_button_add(evas, _("Cancel"), NULL, _win_cancel_cb, win, NULL); + e_widget_list_object_append(o_box, o, 1, 0, 0.5); + + o = o_box; + e_widget_size_min_get(o, &w, &h); + edje_extern_object_min_size_set(o, w, h); + edje_object_part_swallow(o_bg, "e.swallow.buttons", o); + + o = evas_object_rectangle_add(evas); + o_event = o; + mask = 0; + if (!evas_object_key_grab(o, "Tab", mask, ~mask, 0)) printf("grab err\n"); + mask = evas_key_modifier_mask_get(evas, "Shift"); + if (!evas_object_key_grab(o, "Tab", mask, ~mask, 0)) printf("grab err\n"); + mask = 0; + if (!evas_object_key_grab(o, "Return", mask, ~mask, 0)) printf("grab err\n"); + mask = 0; + if (!evas_object_key_grab(o, "KP_Enter", mask, ~mask, 0)) printf("grab err\n"); + evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, NULL); + + edje_object_size_min_calc(o_bg, &w, &h); + evas_object_resize(o_bg, w, h); + e_win_resize(win, w, h); + e_win_size_min_set(win, w, h); + e_win_size_max_set(win, 99999, 99999); + e_win_show(win); + e_win_border_icon_set(win, "enlightenment/shot"); + + if (!e_widget_focus_get(o_bg)) e_widget_focus_set(o_box, 1); +} + +static Eina_Bool +_shot_delay(void *data) +{ + timer = NULL; + _shot_now(data); + return EINA_FALSE; +} + +static void +_shot(E_Zone *zone) +{ + if (timer) ecore_timer_del(timer); + timer = ecore_timer_add(1.0, _shot_delay, zone); +} + +static void +_e_mod_menu_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__) +{ + if (m->zone) _shot(m->zone); +} + +static void +_e_mod_action_cb(E_Object *obj, const char *params __UNUSED__) +{ + E_Zone *zone = NULL; + + if (obj) + { + if (obj->type == E_MANAGER_TYPE) + zone = e_util_zone_current_get((E_Manager *)obj); + else if (obj->type == E_CONTAINER_TYPE) + zone = e_util_zone_current_get(((E_Container *)obj)->manager); + else if (obj->type == E_ZONE_TYPE) + zone = ((E_Zone *)obj); + else + zone = e_util_zone_current_get(e_manager_current_get()); + } + if (!zone) zone = e_util_zone_current_get(e_manager_current_get()); + if (!zone) return; + if (timer) + { + ecore_timer_del(timer); + timer = NULL; + } + _shot_now(zone); +} + +static void +_e_mod_menu_add(void *data __UNUSED__, E_Menu *m) +{ + E_Menu_Item *mi; + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Take Screenshot")); + e_util_menu_item_theme_icon_set(mi, "screenshot"); + e_menu_item_callback_set(mi, _e_mod_menu_cb, NULL); +} + +/* module setup */ +EAPI E_Module_Api e_modapi = +{ + E_MODULE_API_VERSION, + "Shot" +}; + +EAPI void * +e_modapi_init(E_Module *m) +{ + e_module_delayed_set(m, 1); + + shot_module = m; + act = e_action_add("shot"); + if (act) + { + act->func.go = _e_mod_action_cb; + e_action_predef_name_set(_("Screen"), _("Take Screenshot"), + "shot", NULL, NULL, 0); + } + maug = e_int_menus_menu_augmentation_add_sorted + ("main/2", _("Take Screenshot"), _e_mod_menu_add, NULL, NULL, NULL); + return m; +} + +EAPI int +e_modapi_shutdown(E_Module *m __UNUSED__) +{ + _share_done(); + if (win) + { + e_object_del(E_OBJECT(win)); + win = NULL; + } + if (timer) + { + ecore_timer_del(timer); + timer = NULL; + } + if (maug) + { + e_int_menus_menu_augmentation_del("main/2", maug); + maug = NULL; + } + if (act) + { + e_action_predef_name_del(_("Screen"), _("Take Screenshot")); + e_action_del("shot"); + act = NULL; + } + shot_module = NULL; + return 1; +} + +EAPI int +e_modapi_save(E_Module *m __UNUSED__) +{ + return 1; +} diff --git a/src/modules/shot/e_mod_main.h b/src/modules/shot/e_mod_main.h new file mode 100644 index 000000000..4adf2f1fb --- /dev/null +++ b/src/modules/shot/e_mod_main.h @@ -0,0 +1,10 @@ +#ifndef E_MOD_MAIN_H +#define E_MOD_MAIN_H + +EAPI extern E_Module_Api e_modapi; + +EAPI void *e_modapi_init (E_Module *m); +EAPI int e_modapi_shutdown (E_Module *m); +EAPI int e_modapi_save (E_Module *m); + +#endif diff --git a/src/modules/shot/module.desktop.in b/src/modules/shot/module.desktop.in new file mode 100644 index 000000000..e94699770 --- /dev/null +++ b/src/modules/shot/module.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Link +Name=Shot +Icon=e-module-shot +X-Enlightenment-ModuleType=utils +Comment=Simple screenshot+save/upload module