From 8e26efcc48659395864e93a9977ffcbe853e96e9 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sat, 28 May 2011 06:53:44 +0000 Subject: [PATCH] screenshot module built in now. this is a redo as it actuallly has a full file upload ability on e.org for sharing shot url's, as well as selecting local file tyo save to, selecting which screen to screenshot etc. SVN revision: 59766 --- config/illume-home/e.src | 13 + config/minimalist/e.src | 17 + config/netbook/e.src | 17 + config/scaleable/e.src | 17 + config/standard/e.src | 17 + configure.ac | 3 + src/bin/e_widget_fsel.c | 6 +- src/modules/Makefile.am | 5 + src/modules/clock/e_mod_main.c | 42 +- src/modules/shot/.cvsignore | 7 + src/modules/shot/Makefile.am | 28 + src/modules/shot/e-module-shot.edj | Bin 0 -> 26710 bytes src/modules/shot/e_mod_main.c | 799 +++++++++++++++++++++++++++++ src/modules/shot/e_mod_main.h | 10 + src/modules/shot/module.desktop.in | 6 + 15 files changed, 985 insertions(+), 2 deletions(-) create mode 100644 src/modules/shot/.cvsignore create mode 100644 src/modules/shot/Makefile.am create mode 100644 src/modules/shot/e-module-shot.edj create mode 100644 src/modules/shot/e_mod_main.c create mode 100644 src/modules/shot/e_mod_main.h create mode 100644 src/modules/shot/module.desktop.in 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 0000000000000000000000000000000000000000..a25237bdf0c5837180d642742aca2a2f31afc854 GIT binary patch literal 26710 zcmeFZcUaSD@aUU}8eJ7^D=H-_BDyNbTIgWe)n!ppEU1)FL_|t}&_f7{iYo$kP?`-{ z3r(b#(6LYyq?b^Hh?G!MNW1ewaM?Y-bDwkX--qWJXWmcd?KAWJ2KHHbhSXjR27|+3 zu-h@1jRRoMpOTeHpd~?O182eK>EI@f!K};^b1Vk)OFRanF)}49%cuImznHTz@XvSX z69E3TU@rmzf1AHRKLs-fcqiCDP4RPEK-+`xf%nhgVc<){VCGr^hc#f9fxtMJSs2VJ zw9a|Z{8a=$V9x=z1T^9@VrB(w^^_k*N6b=ztpm0YgeqnYz?7jqAGOgB*!O{{fu1`> zCfNaCI>1oh?P9+PVEWKTd;DF@On{w)w#1CSHo#5;lL0Xl`?&yfgEs5~^NW}%0`rCT z&miZ-4EDb27PQfMDT!Gnun1_wzA=x*j1KG(v=vbs{eWEstOPV3#6!$roK;_;Ed_E% z%%XvfLL1HDCT6hLRRUA+YJaWrDp0*kjNOXY}m? z77uLZco3hfAqFSoG(kKs#QAEJS2O+Y04qfdBtz_X9T?pEB)ctU=$z}s48;tJ%^_fI zpl6;HoWp8#=jbkN#eE_ER(}_>_n^_;`vZgilYWk3KRsYD52_QGSTTd#SdC%>F_M^3 z;5cU^hT7-{>;hm5K+in;LSQTY!#shl1%~3lRor(UFcb%iCkLAv?*K4Z&lCfV_Hz*! zx^vVwTHF`%MaE3bLc|Q>RtD9XpJt3V3z$1%ASh45K@@;dK`#ag6!%pEhT>r6S~`Hm z0F#_C-Y_t9=V&d*#C@%SWkY-ByjH-_e3J|`tOEo4m#G2`F@iZL?rQ-I>eIh!lPNHm zd(tme>~{nhy33h0%oiBS>6r{-PlgXnO56|aa}@?7i|%M<>_T0Wm7d{;?)fON4bx2A zAM!_bCot6CRLmX&+l?4%qaU#0IU#ERdU9SdgL)`?=06N-nylS_`og)$qB=P_9%x+< zh%;HV_L*~h0d^hO%zfAZyAKTA?@bVNwz*#q4F)Ftau^IdL9oY8& zFxaacx)(IwGx2!(z(D@h7uF$n9N5g74dcsMA_nqW+;=rFCuq-%7e!zcV9P;1f}pvu zz#!Kr``!Z$d%$!9iw2Eq;WhDiFMz#-_7aebAZ8%Fz_LL@{9~X7qxi=30fRWgteUak zYrxRiOV42b7>qosb(0MAW{^f;aMqLKrHkizaQ++`@gFxKMw}M^_QY7wQ2MnFd%$f-CBQF59LhQ2wY;$=1K(RFQ&aVJl z18ino#REg1}uL7s~l^uq^3d)cJZl;3AykATfw-z#7s|ElBgtiZz>f8>@r*bsks z8tBRAFX;0iTwo=j(V7dy^LhaLgxHLE$ALl2O#0=E{d|ByUQe<-&?`Y)fenM6jsrM% z%q?K(?0**b+X?n23}y|=b2u~18xXh)j14epG5Y}85JVRkyzBg{)?Ej-UhH=lG^+hS z0fR9o^Q{&%x+~@^TG~Ir)5k1RC9gC$Qf@PsSu@*aOPJHAbMP`(6P1 z39vJu7lEjOJOF|A8Z-uC;UEt|yn(raUJ8PIB0=JTT?Gy6#N>eZfxHHGQ_N7mC=kel zHONMOs9y{S)P*(AKu^BEfJS)>`L_n$Il4F0?O$7BN7Xe}(z(`Q-(Hk^-waE9Mo zu%BQs>!(_!_3W9v-Ag_UK2aWcNeA+=0f$4xo4Ec0` zkbxZljrP_K(h2emm=S0+2l7FC0((6Hv=j*P`3mw77|J`8`^cvo1oaI7y$l5Tpty?z zb{{nILp}_UHNakhUIK!AzJYuImLq1!rxzp;SOsX*7x{b#SqBWQ0rf>beIR&XqoC0l zAfJAaVhGDQpyz@hp8+vLdqoWS41(+iKQtDK7v#eP*$Ye#G>TK?GXw%Tqqr3`${FM{ z3<5c$_&exDAjoF~1Y$!GogbP9`Ji>7@ytM@@sQ6Lh#xRV&}d%dGY$fGsR%L|qS!$U`3ONEh7{2~ptT?$5eUSAB3eJ17ksdwki7vJ zD2BiXi|mKM(3$)^<%69CHuT+~2zuF+4^{%~IAH2xKk&iM273*#L!jaAkPjB!^#@?) zVg^1~bkA^h8;GFM9N>e+fxQmcWw9UlVCR7iF|^?xXgCApgPjj{F))}L#S8MmqJ1M4 zFJ|C_Mf=_jECn>&CGx?dJKYP61{(Hp z4e0z(Kk&h#GeYB`vqj^94;IC&AN*<&`J;IeNB0MJsU!m$^+RU^=ZIoRX_MFw?Qc2Q z8o+jfMsuLEhVw!5D(x0C@WHMC`w1`u&}ePogOvswVo2$fn1K%#_A@!J4QMnz_+VFo z4KbwT2^yUV+Vg6#6Mejm`;d>^iU^hBktl zWZ;8U06P#EI&ah$e6Z`m2EB2E*bjWLieSUI8`VIgGXNhf`W)hAqdsU9L*Ro|5;H?F z10O7!a5wm!0FCYve6Z-g_5!m6jqVnFu)lzP510#Rbe`aY-3)d(u)jc~vjQLN7O>$i zH=^@HX9_;ptze_^9)m{Xfe%(0Y>1(a$)M4^;Dc2G8)9f}Uuv39c~I-%ANjGPE0 zqPwfL4QZ;!IXefNNsI8qQu%l1$v)QBFr=e1IJ;szY+Ok&Fy@?%rJK8}4FTF1J8Pno zva^#d#>UCb)f+Q41;NeR*=E{ywsf_0#Mqt1{EpV3j}}V!&CV4TNp$rl{65(Yb+&_* z{ZB4an;@LEo0@FO=ZK}N8)4s%z5Xu)P7d_Hb((QXljBZ$??(qRd0-ePOGg{b14m&^!ko1^XX)*+P!aY{3CqLjEhCCpr>sZJcbNPKn9%I8&ehIPOXBf5w{nbh_<5 zqqzQNL$Y?Yb4E{+=~_fM3k-AC)zWry6t90wR5swoe|%(3bca$l19<=Q*`)7`_LT2` zz&Sf7D4A#f=`~e*5kk)j@2T4A2nEv40bKuCHwGRzP@|n)iO#5QL4EsSo)?>wRd0$; zmA=V+5{OO?Gxz_`!)5Am0LciCG*|0M?O;cO$~@H|Og5(LESmHDe@f(ZraD?Wqw3@g zk5OkRyORwl*XQB+0u5Ip3TlEi><`N7H1YajdH=9{CM~!Z$I*62Fat2_-?<==Xic_Z&WO@ON?h`0uBVi%tDQdk#$F zW5#<99yBzb;k5Ul;XVU#`+$+*i6dfrui>d_uRVKz3=5;*|PN4*j1c&HtDp|39qtOtI6zM_hE@W%dZ43Uf+S6KL|fpj5eNWadhzv?5va+!sKiyuk_fi6!*TOGHf$x zFsd=WsC(DmfXkc}d(}+`Yw5e!n#ZROE7YshX|6w|TNHccbU*QpU18@V4EM&(9^$_B zK2H`une*k^gj-(NFeD0HxWQf240-i%v!I5Tgy;C=P&Es{GlPMo=3;&<-W z4m-cJ?fcGX&bGa9QtRB~G>0$upPCp&8brpWZmv{Pe#F^Z@uz%E4l92fTC;HNLhFl5E+4(D zTE6N))$GFcg?D!(ZuNb*UpHV|(6+#Bp-KKp*Q`ySu&Y14_8>f8@OH1X$Gs4{;L^Oq zWodg65&rHwszuSXqCCjH{E$8%_P zl-hD%g93B6wxdHj!xF(Aw{(XL8)~+n%R3tD*(ud&XeE^9{n~-Q#A<375X!ywhhG9A z!HNacj~_4WKr1f8>A(qH=L>6cmn>cL%-Cn%VxOPp&)4yvedJci@z`trJ2uU#-ZO9G z?+@MP<%WF&B^ZgT9S>_%ZThBt^0CHil_T!5-Ir2{8mp?(bv&7);S-ha zwX0O;JIOUKI1&HuN`%7+Zuhg8h(4aqXyh>0y?HAw<+OwuqhM{rY}*F&v+<^HtK$vQ zPH%2Lnbo?#SVM!JI(UnhspjW(GCIO_>`iUQR$9fgiwX7L9u6MJ>6op?aU{Ii_x`Y= zR#?B$8~gVqe|nf~mQH+Yz|tzqOmK-OXM~Zj%5)UJ3%r{cmZ{u4(mZ>Sn_P9@HSeLi z=zwu$hMtJaZg44+OH8RZC$|oagwgnS5-0=qG$E%eR8$;H^zEu~@<@q@^80AgHiApf ztZ?)jK0qBiV7r*x#4d_x`MM#FK6F)0dmy7Lg!gr4qIbnHWzWoyIiG#9pADT z=Hm-Z3l`f;owG)36aB`+ ze$FH0whlO@_egqX6kTc&veIMj>2dGqoxWjIzjYmzUq;ROW+Z$17@ym8BGIST*mR;g zEboBM=uIEipdu%K|HhB+u8b{tap3!jI45q!`85-N<+Udy*0R3`HkuFkGR!<0yTgm5 z^!Q&3zouLneyG(p9I~vfK+fYzcB*ylh21O*k%HTPj^9 zPwrno!qVu8e1i>&Xd8PTWYW^PBFLom`^li@Hdb2Dn`M3a1186Ib-&$g*86AGW)srh zd%a5)C!|b|?6)~_&c+z$uAggE)s)(8y!x8%Gq)X`31$Ot2hy6&lg9*a3wu5eh2-<4 zL_<bOv{f$QOQKZpKHnZ2=6w5I#mDQOd+1V+J^07{B<*kR z3CH}1)XzoNvUTs#Qb#Z1x|>M&q8f zb@o60pze!1zSTNZ$BAG=JFD+-DeLc=^HN44%`x)0L2f{Ho{=aa{`__=V-xBhmVyd$ zYoB>gc1ySN9g1zuN5f{!XrDPdE9kpOIuOF6^G#T8f9J1ZndNuyOQmnbJG)%jY-;IJ zvf13_b{5l3Ub%fXzv$vCvw;iCq*@k87Y2^3m5z4#a`b>>exUOn>SNzq-;ED9ld5!> zX6~8C=hKhU7n2_)wCY{cy}~C51yy)8qzYF zTL;rPHF|=Y-^b}eW}dC?F2g|tUzhg==B~-?HnJhRK-$-0UwhStcFgGyyM`2pMxWg| ze5PfhE+S!6nT=oZFJz<1B67v9h+F#(f?xfdW=D^S%`2+dkT8 zI+d3m^rupPZ&H_}#K4LKoSfUI&h`MQ=#e!2R_nr%b<&ydo=kMQzZtJHQOR;hsn`|7 zgIxvjTA6+exWV%WlQ#G7>G#jG%oOgSKMOU&`Tp(qb-UKU+nV5)2@`XM=lEGoT>iY` z%j3~6DlL*M-_92m(#kwzEq*>-B%sHP-;L9@8BPk+ad2U1(Y;3sQk5LdP2xlnlIj*m zh546t`1-+u=PcQrj@LT&qM^?!B5sU`+c_Lc<#%3D@$Kl`O7#BNc_)VdwbNFQ*SKE9 zuM%kwkjgc@3erbS1!Ydz18E!Sq^P8|{R@>ds1CRNc6-NCVv@`7`~v(z*}sS1J^W5J z_j|m+?Axc8v|;Os*;(JZE`NLF5z|L~VUW%~7Lk}X_BSeCG;cWjH(sUNqmwO0gIgPp zWPPa{qdRydh1tfXHd-iOnIGA~i(>lP4hxu6>TM>4Ne=ph&L)V)2|+O;KBF(BJ5p6J z=t;}=s)=aZF+2;G-t3g^ZZzQCxdy+i$Kk};uNPGn$-A#F)64r3tLz@L_hgL4>%}I{ z=6zC^DEJyj6F$95$fk+P+W0+cD(2%ajkiW~%WaikRuKYqVoXFbEtZLdtKJUT9tl*x zcl+eucvX?xQaGh*d8(TUqKSIxxEQ~QxlaV5u{ga}3mWe$zh!%~QPspN+Qh3Df>DJ+ zoaraEj`&lvUaTzeVdbZ(N|1MdAW%+}tYE9~8)x}l%-Dlh_>G#%Gi4uRE$XLmt;+J+ z=csUcQ9P9N!4xGmF~YGIj(;U5-Sc(HIKXQ4r0bUzL`ez5%e2o8cSupahGSJIcDGfi z+>bKPSmT2C**!r7erKniuuE@+o^UucF30gUuRF58uk22k-?x4EGyDoVzv2rko$kkb z5jlbD!f|92mS)5m-h6JDf3b5S>?Ktr%T4j>`m}PX=su|n?93iDE23#SrLnY(#?ED$ zjs9imYxU-ZA-SohZam$&yK1<@qKcW|GM2?kpi#IV33;4yTiujsUsg(t*>AFU@Kx`H zkxGKkp?+^Uu;7fr7QfdFGageUWY&1=9MUZ#3|}`s*fo0>R{G0DI?g_CO|N#ol=Xhq z58s)7rw2OyVig2f`jH&}%Kb5qJOq^@P1dR!=8@qDW1O@{Od{Ks%CfETdLU=pWoh_r z|BVACpA$zH3A+hGo73ESs-V6ka;#6bYFGdGcw-N4e}5l0@{YjzAt{#1_N1zn$c&8+ z+kOc!EW&+L-JG|#ByEHIahmfvZknO8n~IrLt$1%2f zpL41+uSh7cn(q=*3@im2erZA@swksO$H@gEkyI@~*L94pSjY;g=`f~E)b?s-`HFaS z+EJG_S4L09T|(8|8*KM}2|Op?EhbVgI;CY7t!FcV`=Qf>K2dkpWRMiYJJ|KJ;F9nl z{!zu9Hhj{8j@>1Sbkhu`$vUTN5~T*Tj~2`7?xfHRU*&wwQ)n&))MF;C^dzf%_!?HY% zpD(6r9ZOLzrZy2D8r+N*amtjOR&7>ivC?Uj;fM7(=dQ21zH=~VwDMRBrfz~NwDjHQ zlZ;opaM1fguM6$AbGv6P-e2eaN<$6LjWpqoiP{jt*c0ik^1`7&!(>y{WfaYp#{C(~ zCZQB}klXrLhroDK(KTQ=wUnAST?3;q~qlx_<7R;rx*Yp<0Z1YLn z$7oQo*;aW>x$C~1{P48{zBd=0)!Uqq?)51^en))z;<6g4LfyRF;S>$|f#~y_^}7wB zn!mq4B4N&Js!zC6pF8Ltr181z29KBb)lvlcYn4TaW(Wmm7(M(v>I-e!k(eiggR%Tv z-DrjVCA0#G;q?P@xM#!j3$faNlgv#uOD=LQuac?u9wRi8zB0HU*80VpHXG9gntm+w zYO^Upp;URUeaMOalT@PQ{s?Ik%2x$^rdQ)f^E6Hzbs|pxD=*C>PLNViN?pQG(tBQN zMS3Fj!LI>o9L>C;o_ViJ$NjK$S*dN)3Ylu=EAsd4&%Zy%zjps^8Sd>I$JSG~7A?fx zxY)V*K9&EadTY#)*Pj}0CiH5{{@pL)CR(eUOEqguRvHN&;=eca8~KvZsNGOjR^MhB zimT+7!3*IgWtHG>D(3u7>BMEjmd({)3Ghm&yslAYfOi{zY~_$Xbu@y0P~F>U5HEDR z@Do#*bN5BqQS<(NJcd-#6~10p;l;5zz7o~})qM|s9^Dm~Vfz=yf8~;>m}9c@SQEZ} zy}N#n(MfPmLzxDU<+&8L& zpJ-`SYPAVE^(n3~OE!C*Bb22vtA@3;*ne_;9%gB?GpnL{?zyxt4a+G0f;**`FMnC0 z^aej*WD)hmFth8=`W~qYnW#I~vp9*P>|Uw2TD%?KoC#*A7vCYtD* zuZpbyXr*P7rdM_QWumtuWt~nhZY*qgehIE&t`UQhS$ZPy?qIyCfx{zSKq}8c6g!aE zH;S^4nlu#C;}rku#7X-N)q`DqjVnGDkuTvCq=#n7oAsz$62`)Pjd;CUWq0OEPO_6!s52L z%X%E@z=C{T$Cy@nS`(+J#Erx0alYG_<2b>)G0e#crSw}%E5-PZXj-c5UzMrqTD&W& z#Lq2yJ-$`>-Uz)?d$e5t2KU}3*>AER#tV|Vq!Y$=WNdJ!eAp58a^H9MWhHIP)lyyl zY5T(ZcU%2dI(uT4(Lk>-mh57c=dV#zeD#vyfToGxU`(?4700x;M5}Dt-or%^*D$pXI7DjqovwN~o0)xCrsKDaPsb)cc#KpJJ??wU?DHm777%Xid2qLg zR7Q4haShEg^lPD~ck?s`>5A^d4x@9d+SPZ5spqdad(Z;U|ER`!KS#x@VDrx_dKOm5 zDD86d2*F*_$*y9z+i*d-IDGIyeo7yr_)S@@kC0WCch-^ZaisCxLf3HskFxXP4($vO<}x0%SK|`>U3>% zo`hpshv#=nU0?Dhxt5Ugd|N~MZw`OxIeUcS+VNCs^N2C=cwbuG#>8JY5lX$2q?uQ9 z1*Mvoql*HZvH07}oIiBao{$uGDMa@AzE5`E;8USd{V>2h(!K8Vo$$WyY&Xd*C2=7p zWxw)byHY7y-gX~09g>Uv{+?QhRh>0JC+nA9bbBxDPc6aK-3=k04qv(KjM_GqM5=v? zz^7T7+>l)A5yN0aFpeiQP#VhU+iBJbRi?zt2?`zi42$OEgm;xj3g#JW9>_Xemeb(i z*E!a?I7*_6EBC7Qt5&5Bof-2hd!jm!vrTdc$Nkce>F+(G_o$*)^G?lAK@xxdDzBd1 zxwkJ>aK@gOpA&d1@BJB{hGmpI)p&JjehjBr>F_3kp)RDCm)v*U4^ozbTjPCJ zYc26R8{y~E<`L#(*fY{299@QcV&6UHz`nR|+kE25havUn$eBCB**=?s{9;rnq2w0p zGg1K(rP!hR!FGc672=9Q-2I_BC9`*>FFKVtU>uqFh*onvx#_UXAOL{pRUMZ||GJsH3S9R*b z9WEb!MmndAmsE7GloftBZNFkgsNdMrIL23gW&Bqc1@5zskFGCBB<=d~FRJ!tuk}+; z9=>tLySIp!*k-ugz(!(>_Sd3OiFN{0-uF!s1GjR)sm&wJ6W9Vezi`);fwklP+Z$py zYaDK~2aCBDRcyBKeyZ-+s;Dyy)^51ItaSF}g!#HRmOA}WtJfSQ6Y(&ni0*sSQ*!v^ z>61mN&arU?J9!Qti?;X55-gSF2l!u1yuZEIJT1G}I)K(-;gEkuyUroC_T&NSlbwZ~ z*dCl^`U};92H~bU<31yNvty_qp5<_d-PO*_@U;H+>r!2}!|ij-x{5Y-9ANyx(D$lg z2lH2@7vXu_jxH&^3c|)$BN?6v^Kr%>(w%LsU%=OjmTbN488rdFu9CR6h|CUN^vy+W zmw$gsm2Q=C4qK&Hb&smnsf3=eG?lu|X*tJAV)8KbaswYj9Lra)!Js7ZFV8oBF!nO` zFlNcS%~yLv{95MP9HnK@-8eC9n_EeMxA?=|owgF@c7ola#FcaS z+zmUWcl6#;PK^s5z8IVzbW4V_3he1mXJGbsE~Hy(4rX3hF*!nix2I!UJMBx1^MlIjl#~>6rIh!UF?GB z@a9qT=fj)ie24+Br0WX1dhnnrV&L zIb~a?9@oua?O>cEq{T+xVZ;p@F`uW1N>BM>WVadnOW1|&l%#rhsBGwusxDs;|6Hme zpJiJfW1GCMi6$g8vz?ss;w+-W+>}3Uj#!+%ZDg&-lemukESqe|n$qfTpS;_uR#My8 zJ3{T^U%t5#(9!VjX@87C87W0>@J4fiW+X|QePZy-q1@g=Uw`!lCeHQQZSJ|rYvjMk zwuCKU?=#3T$k;^LJru(io@q`cHVS&14LVlR=;=#7(8GJY;t3%NutKF)pxE?7c?x>TVi7Rc4lZ&tS{VDx238!miyt^x#GM!OQTb4K}hC@!Pf- zH{phU=HBSUY27vC8d(dAeP8!}5jIlOV)U#W_P$-K*>9R3_*wb#0=HK0HAH%ga5%@I zEN$#=^!=rd6u#iQG40`pza_o;+7bxY4Wj}`47a@38)C?r`*o}I&5RCoDa$75E)*7Q z;23KU9=g(6px9Ypz2$F@t=ymig4*CK&&7GOM8y#|cw>7waRbej>2G}v?Y|bj3v9UB z5a_I6moEK2aM{P$k5Mw_`em7T({1?nw(pN~25Y%L3li5aIu~)fvQ;lUPV&PG{E7v4 ze<4}z8A_LYT8g9pa#`h=mE*e$zW(icx5?o1fzjNgqP*Xrz>N+Of!;i z@8FE@P$xPN1``+N%GX^Q%51dMj1zG%Lx~M74+{k!6km;F>-u%7W(Y1E6<5F^9MBk`nGDa6T0Z z@^9A`W7`v%fg(v8Li9Wn>q7&CmNMqEsChjz<+H~p5jmbLapTHWtDJ?l+R z>#r8xcwt|WEP!9+NBa7s-@8TTiNct>|5`8-_r;i7cp#@&yXllJXKcqx){dNB-q(N> zU)q6anP?OHKFaF8ZQr)^skReuoU|U5UVgO|cX^Y8r8YZ-#uMh1O!!QEDl3X%GG%P* ze6Df-;>t*OK1y4roN@K?0`G_dz|xgi;^qjqGM7F3SP!_d28GkP_h{$?H9JA z-Qh|svBkaRA+U1QCPG`-k5LM4&H!)`FCCY(JiBn{VE3|4MXKbZ)yme7bYIDavb`z zPT~fKdB#KJ#;)+$URBK;;BOP2gi1(v%U=H>4a73jJ>ZjOD-ESE)Aik zRxno#8voK5SNt$3xa4Ao%6|0LX7U_grz~*_YR5X zn38Z%R%c%0; z>m^f}{$5J?o=+*X_nO-DsG}aT&a@$a-NGx~)lPvveqRrz1q`%!sMjC!3DCpeNPHCf zjT4qAd{sC!bo*W@W>-G#JLT%cxi%F}Ur_O;*S(|4Tg^`Q2|iC8j>sIVq6$ZA)W~D8 zdYl5O=iHwiw^E9YB9Fv1+;FzG-sHQ#K%w5QEc#UpgIS>CM`#i@uuaIk)I^Hoga`ic z<`i(#4urm93h{^$k|b zN6Sg;gvoc+39Gc5Ig*u4SzpowbxoyhCPc^9cy56qb)u#wo%cF3t!=OOjZ|)PY2Nz2 z=(6JxvL(J18&B)q`7)ey=a&sSfz*k3=LXKbfirVOua>hmN8ws9qE3MiD~6^tH(zMN zwysEDndHdi4KFBP@F~LmLh-4KlKN$|u4w+X?19>L$)`gF?s)@G4Q-n{c71oA{Zkh#&7y@Nk|KV#i;))xbn$~L~qXEB!fyCwHj02j& zy1FF2iM14RahhNv&?2#FB)X6$Xr>)Xi`iO)cP}%uSwg%hxF%|73oE2(^lLp=U)*vh zgjcw1Sbcbn^_6z1xYcojvGfvJ-GgXJ(GAhihun@2q8cIPqY;lVUr6%658iq!(r6i2 zkfyU}P+#s&*e@!k9g!l}n@x3PDcmMXk}aF7GND3ejkF%7bJX;T=4Plwd>STfVinjQ z)XLMiPx%;I=^kk~muh`AggV?wwjZV+=g~|`D7sRjV(N{}-===f~s*| zfllx9241`F^C3^Y(O;Z5H2I7;*V8AblHNQfl;e+MGx9?V<}?IKkTO(i2LtR44>*t< zTJ+N8`sJ)cJBTe9>M+&u?Zh1W0fxPtbuLoYIROl)(TUx5f?b$_uWJ@cZ4(G~TBmP~<6*J`>~_s7mT5e1%Z zQLLU-4!arorg}70vRo+rU(;2>+4PWV`b8=RdOnVG5 z)N6(0#`-^p4C#6k6oo;9MnQXPO?&gP4A0&&=X^m$JV!S%O_Ic{FT9^qu<#rDT{jx@lgP#CXbaVvMQau|_;a{&A`6v6eAVTK@WMSq`dXV) zq_q08b{_WImm9-0Vd6J=GsY711O-dtYCpE5*^kThUrHmEN3DD_{2=ozqgc{Sa&|fK7S=H*XcaWl1+3nP9N*#}=souySfQI-3Oa9TkawQ`&2w%nr#dC_}L zB2Sbns%lV~kZTs0HZ#MO^g1tSg{$1_dFYs)OSTl%-9GlR6`z$bP;@Hu?%JyNxu&mP ztC#DxXNF7bgqy4gSQhqFfl(^y=0Nt_6j>%9HFRP6bppNxTGFlck`gmxc3x?{b*1A% z9ra6ZP17UyKH3G|QX5|0bEj1jh0$`0J*zh?6)g}tV00={MQwRj65n!y((nsQ;fc9J zef+LY$e6&yar{Z4Fjr9}k$86?V^GT`Y21|Uo@c+kH0)fni)lV({J7`%Vlrc&PiXUa z(#2Y%3{MBG!NwR$f?+nZL5a1Ju9BzMyiinF+QO_gIGG}RbvR~-W)WL=-P_ZdeO)2< zC*f&{`+oWAkJ6z4gux$InX=z9l=Q5evb$PG<=}4+yl_pwywTjauK_k}yrv~_k%X+} zcQ0p2)@M?BI!nV)!=kD*GjO60H&&LZD?2axm3~oFdyEH@J7}nFz*DRLNji_-G~BDT zAp6yQ*?C2`@8#h%OZ`1JXH$rrGTfLf1$z;`{LWp>uMsX2eLh(&!ciwS6llNLrJg1V z@f<1eIe4I4E1EY*K4K~Qd^>bGOX(m}xkH8Tyd`|j=(7SpW%rO@H`20RY(A>SGm|L0 z*X|^*#+buv6E@xrq4ZEX@XfE8fmE(v=+^Rh5k2v&B8lqWG!{U`OZ1-+4tIaRso#-W ziO=`J2(OM*cNlS0YDG1Mmj^GAs~h~GE-WE6lQKN}EwdTXVVnE)%tw+}XZP<69(KM@ z=#($e>XmI{#p-OR@b1|AVUSDWct!@WGgLTiTQ`2I%!*uQy|N`ix8T9fgiM!?cWiq0 zSw(y5_qV;$d@lTdMB3z(>0CgL)*Ju|t zwxLXy<;HFeeK168pF`Mj?*a2kWOSeQMDXmI=($0v1E)0TI<8S9xxno=4n#6o-M%mS zNQUeaha2prhWu&6tNOM*+kA1%9-vb7B^@jHj=+Sw_I-F(U zRVDrbdNQ8|Xu6~^!T$aOe1UX|!(gl>Ax z%L}2D={2w^l@;R(tPk_Z<0n;gmH5jdb`AzoQ(vhqKX>4+8$B^mkg)Hga6i7i^9nP# zgXnm80z^{!s7|qXfqK0xA4to5Lak&Q`zhV-4bLf9u z9mDo@=DQcRU11wLuc7!03G&P_Y}e|Wv8DcYynd?sBLQwSI$=34#Ip)V?)_bPr2jfM zC)W3=juQFG(`Y7t^6C@k@twZ-EH-v6O)X!7SWD3mks~H$iL9+JES+1 zA8?_Z9WuhjYjBk^UYfc!^7@7>BzeiXwptnEI~o#pRHVX*K9`gudk@QV;Y)svkQv{gUkJLE62Z%SSEEgVCW+Lrn-ODX|k;#GPR@b zSi2owqFT>V!Y2mb5?i3V$?QgWvt*t1pVYIVItgaU!mvYCWgm-uBMsw74W2nTBL(p1BY}MMp2Rl2w>|k2vqg#@s-EBninMdmV!Vh=y8KrII&boqjp{u6nl2D3 z$QRFjCY5y6O>|+D0N*MzvRLK|$UgL6c8OMDYVOVe1NsPA~Y!gbsHZhOV- z!tt^O#|nGGZx6B)cl4NqRS2ylew7@O?1(k+WCzlOIn5ArE-={0)Mx#apR+cI529xvQJ zZSYf*1pUTmR&NHI*Ms>O<85WB&_g=C@?QQ0YbLLD(?{VYJ^E4p?k(p-Z%f#3;Vc?3 zr6q3h!cZMswT?PW{8@@E(DPd(vzTu!I?x{gkrr3wnC9(g>DPW)PtvEdffX z;YTpbY9qeI3JLGjx+Q<1ckQ6;?hJ)(_I>{HqHGq&w6nn1zj)TA-{FmPcaz_Qzw;yb zS|TefF!#yFhP_Z1E!tpK*hVsy;Xf5c&y9$lo346=*^(EM-6hEJBUF{_(>@_>bBv&Q z-`BHWkr63Qp58nS%_CO_BNJFnUG{*?crq?4FR zbqg~&e)b~g*IjgtM{T!4s6&IBDDJ%jy0Q)SiA8^ghD8m&*qWI>`Yp#g+P7>2cL{w- zm7jJ73U>D0xn!F|I+`pNIT0s((4|%-!Si8~50&^ZO-_xaNkvrDvieTe5I4yzU2T#^>CRrZrHycUCT2Hqz!fahjB4Pb(N5+{n@e{3ao!m|MK?+bt;bgFh04NEB$>m6`dq#H7(xd$|_(za)PpufB1oCw$;*te`Eo zwaPM-?VIDvj%Y2L!{hLhR7|*e)!bo4<2c^ZmHAdAHqZUzxL@nsvGDf1)H=@4YAN5J zamCnbg->k1Ji|N0_)+c`>&05=pSzH$PMN zQP)DY#)BfgaK%L)jf1_{QmmtJX{6jQqbD!rk~vkzbfaOs3tu;_hCH|5uR==jTxiUT zjV^Q<(fc-2;gpO`5(a6S$a#`owAsb;1<}G_a$UuaJ|z*(Dv)f|+A>WQ3k#WPC~O8Foz!(Q*nI&=p1# ze> z;1weuU-uyH6Sc#&?$#^MQi)+)(Z$dBVg*r^&6clO&X3ZmX*)PojsEcV3;*SQ(w|Mk z2Xz~4O`5!K+NYjoF7IRBFO(0f#l|$Mk-YM@x9c2x!QA9+{6MZ-D~0#78ri0oHCK^O zaml0n`7Lr#?LcI@Q_4%cWD>R)$BFj+Brr%gKH;^Kug~8j`$#(ZU|POs-~BF({K^I4 zylv7KbRSgy;d`;cKX#~WPTHDqr7K~cUM_1I+#SeyT`g>-n7-J&wNApemMGiUimvBx zLK^y{bFBv>j#o2u*_kzJn+MWMLt9mJa&p}+=&;>;(=LZ}G0O&vW^E7|>s3|PdnNeg zo8BRoKlIf7``LMNw`Wm|Xtm_}UG2F)TOF*?*j5_YxPbIX7;{UKd$||a)4$un->qLl zlU0Dn!50uiMw72zn@gA{)v>l|(J0%>#ofWq3oIPuf%fP%10=vA$B91OQ2@@+-ICgFEZ!K zuOqC<=z8^L^DB|as*ge}R@={4df`p-4a`k8hwl=xMav9AHZ7sY9m|Tf&U!wY(o9c0 zu!Ywr`$?)dwD?iUQ_e=?#9hPD&TE7i$^58A+X&@)mx-ZEg2>4NU#rnwA$?NL{^gC> ztl&lSaLIhct2w!cV!aA)^p7RJk2Ez7OCknlI}3dsY*N|uO{NQNhRLpM2pb3vDSz};Ma&h6CO`Fjm9NaN+3B6L-S!$f*!j+q{YJW) zJg4b|@5MIh{Mow-2&?-o9}v0u9tjoA(oSyuMGEYQBJ)*mJ$FS5-gpEA*OYRTgv?sc z_gv0|o})#44E5xAK%%l)fq8bIPV48jX4Splm{Bzi#{5~OE7i8H zU+xR+UG~UcBZR9j(dpKDr*2`YognkgV~y;!;6+kBr4j{OPxX+q3NqkzF}qUdeo^bF zbzenoeoOcfSvvc6cda4K*0-!phF(7^%r0dsg@rhsSsGzz%e(t&t(ixE)qHB=^`!np zl0PBqkiPoOy!MwnZ7JDr+~WczPHXu~I9y~I9`H2h;Uy;)u(prR`Dc+-P)hlau zjTOtM{b1?hwxyFBmK;epC3Hkrz1^Q1u&*Ldzc~)*yZA3+mIsv_R&woX(~qn8*U#uC z`hkCh-slhqtb@S=z7n6Xbhpkgluus}f1u;veSzTb`~SY@HMV)%_>pwZ=DRoS-B%0) zSMyF5-1TGXqaNXPaM$LGXTKoU9qA3K|GM+gf#~GP@ve%Jf^D&n%gkpsqt;uhwr&0FnT!oStu9a--W-ly92SK&|eks}ZABmDvn z5baJXcH$cNq%Vjs(Az&AXw&{X0SAJ6+IvzwNZU7t!$Iv@zaIN8^?c(OeoDt(dv~2U z9_))h-zeYbVO3Xc{s!t?qV9A+7j!~5bVOI$4S)J~(bubDt>}jXB;x`xt8GhmD%rh6 zKX-7+l}fHza%_zeo>9K@_h3o%nIjMA**G$N0}KdXi?9*m3H&Ww5=+--tbI>%iZl2x z0RNq!AJ#t2vBON8g*Dq^eCEC#?_lo!eV$vHTpK$NcTybsVa2##P<1=0gpa4qtE)Pz zI~~vkozM*(1^ei)cAaZ~sRJHgs6>CppXC#XXR&$vmuLr9DY3}ZcvJl&laew_oc1?dlVt_sE$@PG7$N0b~@azeG8$5b2rT-Gp0jna1^ga!Tl&Fl<@0rT%wH1s?5P%UDQe4)G=*dUwB@$_f@TBf1Lxd1$1G| zLpSWA_(ynfaOK%f{_?d-jwv~z7&2JoLa4zSChPS1S=Wq4(oUZd7t&#nVozwWtrQx#VZnSo`%g z_WO8Y_mvuZf4kc4kIG*Eym0+Z;k>4BUQ?X;P3`}A9sg0C_norkU#)TDCu*+gjkQ+w zIn}-&Qun=G3A}IV86}?OnVzi-%A!olri{v}%*w6~>Y`5SrjFg#|32bgDp>am2c#D$ zp_}j^_JGagCtLRUhe7Mp5a-Z z8O)VMnUqZ#m30nx^-4V}yX7~df#`>>2z$`|M0QlWGOtA6+S=|Ve1*MAU~)jo!6k6I zT#5czTZP}@YXzQNvfnw*b&YG?!@bam|VO>n}ib^0keHd;J07N{%ZxMB-@TTXP*++xYj+~%RSxO zGd#;PN6eM2<9`0yj#PHbZxb{S{Ymj)jtlzN@PX~+Z-o=uC(L#&fgd|f;Mpbno#R~B zxHee3r+cT3dnO)^m@8i|b8T+>37kBDu6O*o++h8cmMHoKezW9PdTuX4W; zZ_iCRdf96CmfzW|fv#`)-~f{dTTJjG0>kAb=Sg#Y?za@)p1qG&)xf+t?g!b`u_vNc1av~+Fg)KYQr!PhSgImM@e?%?AkdR#8ebx3nIGHO!fzrrq)IxvS<%SfxP3(VAi%yq(;F7>4V$uHF^R zaUYZUHB*KsXPSi8tZ6$1IKvf83@vSnDj^6zx-@ew#t4ze)Ih?8Pb${5VQT>f4-U6% z>6SI={J%Im4;S!Y1h)7%p87vSUWgg%HCN9+P#iO+xjZcA89#;m0_dz_e0bV(_V7;G z!pOjIgMop;*~6Qg14thO;-e5gGl%JWw?` zK>9R5}`jW0Lllca{_z~qy?aC8z9XOwa);_J{2I%hh`ry7V`ik z{TAzZ+Fg{#N(C_#h7+vdPHfk5?Y&~}8#jVGMa8|i@EH^f_PVhw1REAaaUoVvu{?$P zFnW@iG5`DnhdCdoCOJt@Z{O%hyiyxVsh-}xu|)YViD;ic<2)99^g;A@U%wRn&DRe^ zU-a}O6Td0)l2H2tRl$JK|!O-!}W8;MFM6|F6b&ACc->I l8IHpOmg0?DCSD<4C0=uEpX^VO4=A>dZIqif{s3k#$$Nvw, 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