Clouseau: Changed file naming a bit.
Preload is now in it's own file. Will sort the lib names next. SVN revision: 83514
This commit is contained in:
parent
ca8f724773
commit
74407dec92
|
@ -16,19 +16,9 @@ EXTRA_DIST = \
|
|||
pkgdir = $(libdir)/clouseau
|
||||
pkg_LTLIBRARIES = libclouseau.la libclouseau_client.la
|
||||
|
||||
libclouseau_la_SOURCES = \
|
||||
clouseau_client.c \
|
||||
clouseau_object_information.c \
|
||||
clouseau_data_legacy.c \
|
||||
clouseau_data.c
|
||||
|
||||
libclouseau_la_LDFLAGS = -module -avoid-version -rdynamic
|
||||
libclouseau_la_DEPENDENCIES = $(top_builddir)/config.h
|
||||
libclouseau_la_LIBADD = @EFL_LIBS@
|
||||
libclouseau_la_CFLAGS = @EFL_CFLAGS@
|
||||
|
||||
libclouseau_client_la_SOURCES = clouseau_object_information.c \
|
||||
clouseau_data_legacy.c \
|
||||
clouseau_client.c \
|
||||
clouseau_data.c
|
||||
|
||||
libclouseau_client_la_DEPENDENCIES = $(top_builddir)/config.h
|
||||
|
@ -36,3 +26,14 @@ libclouseau_client_la_LIBADD = @EFL_LIBS@
|
|||
libclouseau_client_la_CFLAGS = @EFL_CFLAGS@
|
||||
libclouseau_client_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
|
||||
|
||||
libclouseau_la_SOURCES = \
|
||||
clouseau_preload.c \
|
||||
clouseau_object_information.c \
|
||||
clouseau_data_legacy.c \
|
||||
clouseau_data.c
|
||||
|
||||
libclouseau_la_LDFLAGS = -module -avoid-version -rdynamic
|
||||
libclouseau_la_DEPENDENCIES = $(top_builddir)/config.h
|
||||
libclouseau_la_LIBADD = $(top_builddir)/src/lib/libclouseau_client.la @EFL_LIBS@
|
||||
libclouseau_la_CFLAGS = @EFL_CFLAGS@
|
||||
|
||||
|
|
|
@ -1,358 +1,146 @@
|
|||
#include "clouseau_private2.h"
|
||||
#include <dlfcn.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
#include <Ecore_Con_Eet.h>
|
||||
#include <Edje.h>
|
||||
#include <Evas.h>
|
||||
#include <Elementary.h>
|
||||
#include <Ecore_X.h>
|
||||
|
||||
#include "clouseau_private.h"
|
||||
|
||||
static Eina_Bool _elm_is_init = EINA_FALSE;
|
||||
static const char *_my_app_name = NULL;
|
||||
|
||||
static void
|
||||
libclouseau_item_add(Evas_Object *o, Clouseau_Tree_Item *parent)
|
||||
{
|
||||
Clouseau_Tree_Item *treeit;
|
||||
Eina_List *children;
|
||||
Evas_Object *child;
|
||||
|
||||
treeit = calloc(1, sizeof(Clouseau_Tree_Item));
|
||||
if (!treeit) return ;
|
||||
|
||||
treeit->ptr = (uintptr_t) o;
|
||||
treeit->is_obj = EINA_TRUE;
|
||||
|
||||
treeit->name = eina_stringshare_add(evas_object_type_get(o));
|
||||
treeit->is_clipper = !!evas_object_clipees_get(o);
|
||||
treeit->is_visible = evas_object_visible_get(o);
|
||||
treeit->info = clouseau_object_information_get(treeit);
|
||||
|
||||
parent->children = eina_list_append(parent->children, treeit);
|
||||
|
||||
/* if (!evas_object_smart_data_get(o)) return ; */
|
||||
|
||||
/* Do this only for smart object */
|
||||
children = evas_object_smart_members_get(o);
|
||||
EINA_LIST_FREE(children, child)
|
||||
libclouseau_item_add(child, treeit);
|
||||
}
|
||||
|
||||
static void *
|
||||
_canvas_bmp_get(Ecore_Evas *ee, Evas_Coord *w_out, Evas_Coord *h_out)
|
||||
{
|
||||
Ecore_X_Image *img;
|
||||
Ecore_X_Window_Attributes att;
|
||||
unsigned char *src;
|
||||
unsigned int *dst;
|
||||
int bpl = 0, rows = 0, bpp = 0;
|
||||
Evas_Coord w, h;
|
||||
|
||||
/* Check that this window still exists */
|
||||
Eina_List *eeitr, *ees = ecore_evas_ecore_evas_list_get();
|
||||
Ecore_Evas *eel;
|
||||
Eina_Bool found_evas = EINA_FALSE;
|
||||
|
||||
EINA_LIST_FOREACH(ees, eeitr, eel)
|
||||
if (eel == ee)
|
||||
{
|
||||
found_evas = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
Ecore_X_Window xwin = (found_evas) ?
|
||||
(Ecore_X_Window) ecore_evas_window_get(ee) : 0;
|
||||
|
||||
if (!xwin)
|
||||
{
|
||||
printf("Can't grab X window.\n");
|
||||
*w_out = *h_out = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Evas *e = ecore_evas_get(ee);
|
||||
evas_output_size_get(e, &w, &h);
|
||||
memset(&att, 0, sizeof(Ecore_X_Window_Attributes));
|
||||
ecore_x_window_attributes_get(xwin, &att);
|
||||
img = ecore_x_image_new(w, h, att.visual, att.depth);
|
||||
ecore_x_image_get(img, xwin, 0, 0, 0, 0, w, h);
|
||||
src = ecore_x_image_data_get(img, &bpl, &rows, &bpp);
|
||||
dst = malloc(w * h * sizeof(int)); /* Will be freed by the user */
|
||||
if (!ecore_x_image_is_argb32_get(img))
|
||||
{ /* Fill dst buffer with image convert */
|
||||
ecore_x_image_to_argb_convert(src, bpp, bpl,
|
||||
att.colormap, att.visual,
|
||||
0, 0, w, h,
|
||||
dst, (w * sizeof(int)), 0, 0);
|
||||
}
|
||||
else
|
||||
{ /* Fill dst buffer by copy */
|
||||
memcpy(dst, src, (w * h * sizeof(int)));
|
||||
}
|
||||
|
||||
/* dst now holds window bitmap */
|
||||
ecore_x_image_free(img);
|
||||
*w_out = w;
|
||||
*h_out = h;
|
||||
return (void *) dst;
|
||||
}
|
||||
|
||||
static Eina_List *
|
||||
_load_list(void)
|
||||
{
|
||||
Eina_List *tree = NULL;
|
||||
Eina_List *ees;
|
||||
Ecore_Evas *ee;
|
||||
|
||||
ees = ecore_evas_ecore_evas_list_get();
|
||||
|
||||
EINA_LIST_FREE(ees, ee)
|
||||
{
|
||||
Eina_List *objs;
|
||||
Evas_Object *obj;
|
||||
Clouseau_Tree_Item *treeit;
|
||||
|
||||
Evas *e;
|
||||
int w, h;
|
||||
|
||||
e = ecore_evas_get(ee);
|
||||
evas_output_size_get(e, &w, &h);
|
||||
|
||||
treeit = calloc(1, sizeof(Clouseau_Tree_Item));
|
||||
if (!treeit) continue ;
|
||||
|
||||
treeit->name = eina_stringshare_add(ecore_evas_title_get(ee));
|
||||
treeit->ptr = (uintptr_t) ee;
|
||||
|
||||
tree = eina_list_append(tree, treeit);
|
||||
|
||||
objs = evas_objects_in_rectangle_get(e, SHRT_MIN, SHRT_MIN,
|
||||
USHRT_MAX, USHRT_MAX, EINA_TRUE, EINA_TRUE);
|
||||
|
||||
EINA_LIST_FREE(objs, obj)
|
||||
libclouseau_item_add(obj, treeit);
|
||||
}
|
||||
|
||||
return tree; /* User has to call clouseau_tree_free() */
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_add(EINA_UNUSED void *data, Ecore_Con_Reply *reply,
|
||||
EINA_UNUSED Ecore_Con_Server *conn)
|
||||
{
|
||||
/* ecore_con_server_data_size_max_set(conn, -1); */
|
||||
connect_st t = { getpid(), _my_app_name };
|
||||
ecore_con_eet_send(reply, CLOUSEAU_APP_CLIENT_CONNECT_STR, &t);
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_del(EINA_UNUSED void *data, EINA_UNUSED Ecore_Con_Reply *reply,
|
||||
Ecore_Con_Server *conn)
|
||||
{
|
||||
if (!conn)
|
||||
{
|
||||
printf("Failed to establish connection to the server.\nExiting.\n");
|
||||
ecore_main_loop_quit();
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
printf("Lost server with ip <%s>\n", ecore_con_server_ip_get(conn));
|
||||
|
||||
ecore_con_server_del(conn);
|
||||
|
||||
ecore_main_loop_quit();
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
void
|
||||
_data_req_cb(EINA_UNUSED void *data, Ecore_Con_Reply *reply,
|
||||
EINA_UNUSED const char *protocol_name, void *value)
|
||||
{ /* data req includes ptr to GUI, to tell which client asking */
|
||||
data_req_st *req = value;
|
||||
tree_data_st t;
|
||||
t.gui = req->gui; /* GUI client requesting data from daemon */
|
||||
t.app = req->app; /* APP client sending data to daemon */
|
||||
t.tree = _load_list();
|
||||
|
||||
if (t.tree)
|
||||
{ /* Reply with tree data to data request */
|
||||
ecore_con_eet_send(reply, CLOUSEAU_TREE_DATA_STR, &t);
|
||||
clouseau_data_tree_free(t.tree);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_highlight_cb(EINA_UNUSED void *data, EINA_UNUSED Ecore_Con_Reply *reply,
|
||||
EINA_UNUSED const char *protocol_name, void *value)
|
||||
{ /* Highlight msg contains PTR of object to highlight */
|
||||
highlight_st *ht = value;
|
||||
Evas_Object *obj = (Evas_Object *) (uintptr_t) ht->object;
|
||||
clouseau_data_object_highlight(obj, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_bmp_req_cb(EINA_UNUSED void *data, EINA_UNUSED Ecore_Con_Reply *reply,
|
||||
EINA_UNUSED const char *protocol_name, void *value)
|
||||
{ /* Bitmap req msg contains PTR of Ecore Evas */
|
||||
bmp_req_st *req = value;
|
||||
Evas_Coord w, h;
|
||||
unsigned int size = 0;
|
||||
void *bmp = _canvas_bmp_get((Ecore_Evas *) (uintptr_t)
|
||||
req->object, &w, &h);
|
||||
|
||||
bmp_info_st t = { req->gui,
|
||||
req->app, req->object , req->ctr, w, h,
|
||||
NULL,NULL, NULL, 1.0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
void *p = clouseau_data_packet_compose(CLOUSEAU_BMP_DATA_STR,
|
||||
&t, &size, bmp, (w * h * sizeof(int)));
|
||||
|
||||
|
||||
if (p)
|
||||
{
|
||||
ecore_con_eet_raw_send(reply, CLOUSEAU_BMP_DATA_STR, "BMP", p, size);
|
||||
free(p);
|
||||
}
|
||||
|
||||
if (bmp)
|
||||
free(bmp);
|
||||
}
|
||||
|
||||
/* Highlight functions. */
|
||||
static Eina_Bool
|
||||
_connect_to_daemon(void)
|
||||
_clouseau_highlight_fade(void *_rect)
|
||||
{
|
||||
Ecore_Con_Server *server;
|
||||
const char *address = LOCALHOST;
|
||||
Ecore_Con_Eet *eet_svr = NULL;
|
||||
Evas_Object *rect = _rect;
|
||||
int r, g, b, a;
|
||||
double na;
|
||||
|
||||
eina_init();
|
||||
ecore_init();
|
||||
ecore_con_init();
|
||||
|
||||
server = ecore_con_server_connect(ECORE_CON_REMOTE_TCP,
|
||||
LOCALHOST, PORT, NULL);
|
||||
|
||||
if (!server)
|
||||
evas_object_color_get(rect, &r, &g, &b, &a);
|
||||
if (a < 20)
|
||||
{
|
||||
printf("could not connect to the server: %s, port %d.\n",
|
||||
address, PORT);
|
||||
return EINA_FALSE;
|
||||
evas_object_del(rect);
|
||||
/* The del callback of the object will destroy the animator */
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
eet_svr = ecore_con_eet_client_new(server);
|
||||
if (!eet_svr)
|
||||
{
|
||||
printf("could not create con_eet client.\n");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
clouseau_register_descs(eet_svr);
|
||||
|
||||
/* Register callbacks for ecore_con_eet */
|
||||
ecore_con_eet_server_connect_callback_add(eet_svr, _add, NULL);
|
||||
ecore_con_eet_server_disconnect_callback_add(eet_svr, _del, NULL);
|
||||
ecore_con_eet_data_callback_add(eet_svr, CLOUSEAU_DATA_REQ_STR,
|
||||
_data_req_cb, NULL);
|
||||
ecore_con_eet_data_callback_add(eet_svr, CLOUSEAU_HIGHLIGHT_STR,
|
||||
_highlight_cb, NULL);
|
||||
ecore_con_eet_data_callback_add(eet_svr, CLOUSEAU_BMP_REQ_STR,
|
||||
_bmp_req_cb, NULL);
|
||||
na = a - 5;
|
||||
r = na / a * r;
|
||||
g = na / a * g;
|
||||
b = na / a * b;
|
||||
evas_object_color_set(rect, r, g, b, na);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/* Hook on the elm_init
|
||||
* We only do something here if we didn't already go into elm_init,
|
||||
* which probably means we are not using elm. */
|
||||
EAPI int
|
||||
elm_init(int argc, char **argv)
|
||||
static Evas_Object *
|
||||
_clouseau_verify_e_children(Evas_Object *obj, Evas_Object *ptr)
|
||||
{
|
||||
int (*_elm_init)(int, char **) = dlsym(RTLD_NEXT, __func__);
|
||||
/* Verify that obj still exists (can be found on evas canvas) */
|
||||
Evas_Object *child;
|
||||
Evas_Object *p = NULL;
|
||||
Eina_List *children;
|
||||
|
||||
if (!_elm_is_init)
|
||||
if (ptr == obj)
|
||||
return ptr;
|
||||
|
||||
children = evas_object_smart_members_get(obj);
|
||||
EINA_LIST_FREE(children, child)
|
||||
{
|
||||
_my_app_name = argv[0];
|
||||
_elm_is_init = EINA_TRUE;
|
||||
p = _clouseau_verify_e_children(child, ptr);
|
||||
if (p) break;
|
||||
}
|
||||
eina_list_free(children);
|
||||
|
||||
return _elm_init(argc, argv);
|
||||
return p;
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_clouseau_verify_e_obj(Evas_Object *obj)
|
||||
{
|
||||
/* Verify that obj still exists (can be found on evas canvas) */
|
||||
Evas_Object *o;
|
||||
Eina_List *ees;
|
||||
Ecore_Evas *ee;
|
||||
Evas_Object *rt = NULL;
|
||||
|
||||
ees = ecore_evas_ecore_evas_list_get();
|
||||
EINA_LIST_FREE(ees, ee)
|
||||
{
|
||||
Evas *e;
|
||||
Eina_List *objs;
|
||||
|
||||
e = ecore_evas_get(ee);
|
||||
objs = evas_objects_in_rectangle_get(e, SHRT_MIN, SHRT_MIN,
|
||||
USHRT_MAX, USHRT_MAX,
|
||||
EINA_TRUE, EINA_TRUE);
|
||||
|
||||
EINA_LIST_FREE(objs, o)
|
||||
{
|
||||
rt = _clouseau_verify_e_children(o, obj);
|
||||
if (rt) break;
|
||||
}
|
||||
eina_list_free(objs);
|
||||
|
||||
if (rt) break;
|
||||
}
|
||||
eina_list_free(ees);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
static void
|
||||
_clouseau_highlight_del(void *data,
|
||||
EINA_UNUSED Evas *e,
|
||||
EINA_UNUSED Evas_Object *obj,
|
||||
EINA_UNUSED void *event_info)
|
||||
{ /* Delete timer for this rect */
|
||||
ecore_animator_del(data);
|
||||
}
|
||||
|
||||
/* Hook on the main loop
|
||||
* We only do something here if we didn't already go into elm_init,
|
||||
* which probably means we are not using elm. */
|
||||
EAPI void
|
||||
ecore_main_loop_begin(void)
|
||||
clouseau_data_object_highlight(Evas_Object *obj, Clouseau_Evas_Props *props, bmp_info_st *view)
|
||||
{
|
||||
void (*_ecore_main_loop_begin)(void) = dlsym(RTLD_NEXT, __func__);
|
||||
|
||||
if (!_elm_is_init)
|
||||
{
|
||||
_my_app_name = "clouseau";
|
||||
}
|
||||
|
||||
clouseau_data_init();
|
||||
|
||||
if(!_connect_to_daemon())
|
||||
{
|
||||
printf("Failed to connect to server.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
_ecore_main_loop_begin();
|
||||
|
||||
clouseau_data_shutdown();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#define EINA_LOCK_DEBUG_BT_NUM 64
|
||||
typedef void (*Eina_Lock_Bt_Func) ();
|
||||
|
||||
EAPI Evas_Object *
|
||||
evas_object_new(Evas *e)
|
||||
{
|
||||
Eina_Lock_Bt_Func lock_bt[EINA_LOCK_DEBUG_BT_NUM];
|
||||
int lock_bt_num;
|
||||
Evas_Object *(*_evas_object_new)(Evas *e) = dlsym(RTLD_NEXT, __func__);
|
||||
Eina_Strbuf *str;
|
||||
Ecore_Animator *t;
|
||||
Evas_Object *r;
|
||||
char **strings;
|
||||
int i;
|
||||
int x, y, wd, ht;
|
||||
Evas *e = NULL;
|
||||
|
||||
r = _evas_object_new(e);
|
||||
if (!r) return NULL;
|
||||
if (props)
|
||||
{
|
||||
/* When working offline grab info from struct */
|
||||
Evas_Coord x_bmp, y_bmp;
|
||||
|
||||
lock_bt_num = backtrace((void **)lock_bt, EINA_LOCK_DEBUG_BT_NUM);
|
||||
strings = backtrace_symbols((void **)lock_bt, lock_bt_num);
|
||||
evas_object_geometry_get(view->o, &x_bmp, &y_bmp, NULL, NULL);
|
||||
x = (view->zoom_val * props->x) + x_bmp;
|
||||
y = (view->zoom_val * props->y) + y_bmp;
|
||||
wd = (view->zoom_val * props->w);
|
||||
ht = (view->zoom_val * props->h);
|
||||
|
||||
str = eina_strbuf_new();
|
||||
e = evas_object_evas_get(view->win);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check validity of object when working online */
|
||||
if (!_clouseau_verify_e_obj(obj))
|
||||
{
|
||||
printf("<%s> Evas Object not found <%p> (probably deleted)\n",
|
||||
__func__, obj);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i < lock_bt_num; ++i)
|
||||
eina_strbuf_append_printf(str, "%s\n", strings[i]);
|
||||
evas_object_geometry_get(obj, &x, &y, &wd, &ht);
|
||||
|
||||
evas_object_data_set(r, ".clouseau.bt", eina_stringshare_add(eina_strbuf_string_get(str)));
|
||||
/* Take evas from object if working online */
|
||||
e = evas_object_evas_get(obj);
|
||||
if (!e) return;
|
||||
}
|
||||
|
||||
free(strings);
|
||||
eina_strbuf_free(str);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_object_free(Evas_Object *obj, int clean_layer)
|
||||
{
|
||||
void (*_evas_object_free)(Evas_Object *obj, int clean_layer) = dlsym(RTLD_NEXT, __func__);
|
||||
const char *tmp;
|
||||
/* Continue and do the Highlight */
|
||||
r = evas_object_rectangle_add(e);
|
||||
evas_object_move(r, x - PADDING, y - PADDING);
|
||||
evas_object_resize(r, wd + (2 * PADDING), ht + (2 * PADDING));
|
||||
evas_object_color_set(r,
|
||||
HIGHLIGHT_R, HIGHLIGHT_G, HIGHLIGHT_B, HIGHLIGHT_A);
|
||||
evas_object_show(r);
|
||||
|
||||
/* Add Timer for fade and a callback to delete timer on obj del */
|
||||
t = ecore_animator_add(_clouseau_highlight_fade, r);
|
||||
evas_object_event_callback_add(r, EVAS_CALLBACK_DEL,
|
||||
_clouseau_highlight_del, t);
|
||||
/* Print backtrace info, saved for future ref
|
||||
tmp = evas_object_data_get(obj, ".clouseau.bt");
|
||||
eina_stringshare_del(tmp);
|
||||
|
||||
_evas_object_free(obj, clean_layer);
|
||||
fprintf(stderr, "Creation backtrace :\n%s*******\n", tmp); */
|
||||
}
|
||||
|
|
|
@ -651,151 +651,6 @@ clouseau_data_packet_info_get(const char *p_type, void *data, size_t size)
|
|||
return st;
|
||||
}
|
||||
|
||||
/* HIGHLIGHT code. */
|
||||
static Eina_Bool
|
||||
_clouseau_highlight_fade(void *_rect)
|
||||
{
|
||||
Evas_Object *rect = _rect;
|
||||
int r, g, b, a;
|
||||
double na;
|
||||
|
||||
evas_object_color_get(rect, &r, &g, &b, &a);
|
||||
if (a < 20)
|
||||
{
|
||||
evas_object_del(rect);
|
||||
/* The del callback of the object will destroy the animator */
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
na = a - 5;
|
||||
r = na / a * r;
|
||||
g = na / a * g;
|
||||
b = na / a * b;
|
||||
evas_object_color_set(rect, r, g, b, na);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_clouseau_verify_e_children(Evas_Object *obj, Evas_Object *ptr)
|
||||
{
|
||||
/* Verify that obj still exists (can be found on evas canvas) */
|
||||
Evas_Object *child;
|
||||
Evas_Object *p = NULL;
|
||||
Eina_List *children;
|
||||
|
||||
if (ptr == obj)
|
||||
return ptr;
|
||||
|
||||
children = evas_object_smart_members_get(obj);
|
||||
EINA_LIST_FREE(children, child)
|
||||
{
|
||||
p = _clouseau_verify_e_children(child, ptr);
|
||||
if (p) break;
|
||||
}
|
||||
eina_list_free(children);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_clouseau_verify_e_obj(Evas_Object *obj)
|
||||
{
|
||||
/* Verify that obj still exists (can be found on evas canvas) */
|
||||
Evas_Object *o;
|
||||
Eina_List *ees;
|
||||
Ecore_Evas *ee;
|
||||
Evas_Object *rt = NULL;
|
||||
|
||||
ees = ecore_evas_ecore_evas_list_get();
|
||||
EINA_LIST_FREE(ees, ee)
|
||||
{
|
||||
Evas *e;
|
||||
Eina_List *objs;
|
||||
|
||||
e = ecore_evas_get(ee);
|
||||
objs = evas_objects_in_rectangle_get(e, SHRT_MIN, SHRT_MIN,
|
||||
USHRT_MAX, USHRT_MAX,
|
||||
EINA_TRUE, EINA_TRUE);
|
||||
|
||||
EINA_LIST_FREE(objs, o)
|
||||
{
|
||||
rt = _clouseau_verify_e_children(o, obj);
|
||||
if (rt) break;
|
||||
}
|
||||
eina_list_free(objs);
|
||||
|
||||
if (rt) break;
|
||||
}
|
||||
eina_list_free(ees);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
static void
|
||||
_clouseau_highlight_del(void *data,
|
||||
EINA_UNUSED Evas *e,
|
||||
EINA_UNUSED Evas_Object *obj,
|
||||
EINA_UNUSED void *event_info)
|
||||
{ /* Delete timer for this rect */
|
||||
ecore_animator_del(data);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
clouseau_data_object_highlight(Evas_Object *obj, Clouseau_Evas_Props *props, bmp_info_st *view)
|
||||
{
|
||||
Ecore_Animator *t;
|
||||
Evas_Object *r;
|
||||
int x, y, wd, ht;
|
||||
Evas *e = NULL;
|
||||
|
||||
if (props)
|
||||
{
|
||||
/* When working offline grab info from struct */
|
||||
Evas_Coord x_bmp, y_bmp;
|
||||
|
||||
evas_object_geometry_get(view->o, &x_bmp, &y_bmp, NULL, NULL);
|
||||
x = (view->zoom_val * props->x) + x_bmp;
|
||||
y = (view->zoom_val * props->y) + y_bmp;
|
||||
wd = (view->zoom_val * props->w);
|
||||
ht = (view->zoom_val * props->h);
|
||||
|
||||
e = evas_object_evas_get(view->win);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check validity of object when working online */
|
||||
if (!_clouseau_verify_e_obj(obj))
|
||||
{
|
||||
printf("<%s> Evas Object not found <%p> (probably deleted)\n",
|
||||
__func__, obj);
|
||||
return;
|
||||
}
|
||||
|
||||
evas_object_geometry_get(obj, &x, &y, &wd, &ht);
|
||||
|
||||
/* Take evas from object if working online */
|
||||
e = evas_object_evas_get(obj);
|
||||
if (!e) return;
|
||||
}
|
||||
|
||||
/* Continue and do the Highlight */
|
||||
r = evas_object_rectangle_add(e);
|
||||
evas_object_move(r, x - PADDING, y - PADDING);
|
||||
evas_object_resize(r, wd + (2 * PADDING), ht + (2 * PADDING));
|
||||
evas_object_color_set(r,
|
||||
HIGHLIGHT_R, HIGHLIGHT_G, HIGHLIGHT_B, HIGHLIGHT_A);
|
||||
evas_object_show(r);
|
||||
|
||||
/* Add Timer for fade and a callback to delete timer on obj del */
|
||||
t = ecore_animator_add(_clouseau_highlight_fade, r);
|
||||
evas_object_event_callback_add(r, EVAS_CALLBACK_DEL,
|
||||
_clouseau_highlight_del, t);
|
||||
/* Print backtrace info, saved for future ref
|
||||
tmp = evas_object_data_get(obj, ".clouseau.bt");
|
||||
fprintf(stderr, "Creation backtrace :\n%s*******\n", tmp); */
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
clouseau_data_eet_info_save(const char *filename,
|
||||
app_info_st *a, tree_data_st *ftd, Eina_List *ck_list)
|
||||
|
|
|
@ -0,0 +1,360 @@
|
|||
#include "clouseau_private2.h"
|
||||
#include <dlfcn.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
#include <Ecore_Con_Eet.h>
|
||||
#include <Edje.h>
|
||||
#include <Evas.h>
|
||||
#include <Elementary.h>
|
||||
#include <Ecore_X.h>
|
||||
|
||||
#include "clouseau_private.h"
|
||||
|
||||
static Eina_Bool _elm_is_init = EINA_FALSE;
|
||||
static const char *_my_app_name = NULL;
|
||||
|
||||
static void
|
||||
libclouseau_item_add(Evas_Object *o, Clouseau_Tree_Item *parent)
|
||||
{
|
||||
Clouseau_Tree_Item *treeit;
|
||||
Eina_List *children;
|
||||
Evas_Object *child;
|
||||
|
||||
treeit = calloc(1, sizeof(Clouseau_Tree_Item));
|
||||
if (!treeit) return ;
|
||||
|
||||
treeit->ptr = (uintptr_t) o;
|
||||
treeit->is_obj = EINA_TRUE;
|
||||
|
||||
treeit->name = eina_stringshare_add(evas_object_type_get(o));
|
||||
treeit->is_clipper = !!evas_object_clipees_get(o);
|
||||
treeit->is_visible = evas_object_visible_get(o);
|
||||
treeit->info = clouseau_object_information_get(treeit);
|
||||
|
||||
parent->children = eina_list_append(parent->children, treeit);
|
||||
|
||||
/* if (!evas_object_smart_data_get(o)) return ; */
|
||||
|
||||
/* Do this only for smart object */
|
||||
children = evas_object_smart_members_get(o);
|
||||
EINA_LIST_FREE(children, child)
|
||||
libclouseau_item_add(child, treeit);
|
||||
}
|
||||
|
||||
static void *
|
||||
_canvas_bmp_get(Ecore_Evas *ee, Evas_Coord *w_out, Evas_Coord *h_out)
|
||||
{
|
||||
Ecore_X_Image *img;
|
||||
Ecore_X_Window_Attributes att;
|
||||
unsigned char *src;
|
||||
unsigned int *dst;
|
||||
int bpl = 0, rows = 0, bpp = 0;
|
||||
Evas_Coord w, h;
|
||||
|
||||
/* Check that this window still exists */
|
||||
Eina_List *eeitr, *ees = ecore_evas_ecore_evas_list_get();
|
||||
Ecore_Evas *eel;
|
||||
Eina_Bool found_evas = EINA_FALSE;
|
||||
|
||||
EINA_LIST_FOREACH(ees, eeitr, eel)
|
||||
if (eel == ee)
|
||||
{
|
||||
found_evas = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
Ecore_X_Window xwin = (found_evas) ?
|
||||
(Ecore_X_Window) ecore_evas_window_get(ee) : 0;
|
||||
|
||||
if (!xwin)
|
||||
{
|
||||
printf("Can't grab X window.\n");
|
||||
*w_out = *h_out = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Evas *e = ecore_evas_get(ee);
|
||||
evas_output_size_get(e, &w, &h);
|
||||
memset(&att, 0, sizeof(Ecore_X_Window_Attributes));
|
||||
ecore_x_window_attributes_get(xwin, &att);
|
||||
img = ecore_x_image_new(w, h, att.visual, att.depth);
|
||||
ecore_x_image_get(img, xwin, 0, 0, 0, 0, w, h);
|
||||
src = ecore_x_image_data_get(img, &bpl, &rows, &bpp);
|
||||
dst = malloc(w * h * sizeof(int)); /* Will be freed by the user */
|
||||
if (!ecore_x_image_is_argb32_get(img))
|
||||
{ /* Fill dst buffer with image convert */
|
||||
ecore_x_image_to_argb_convert(src, bpp, bpl,
|
||||
att.colormap, att.visual,
|
||||
0, 0, w, h,
|
||||
dst, (w * sizeof(int)), 0, 0);
|
||||
}
|
||||
else
|
||||
{ /* Fill dst buffer by copy */
|
||||
memcpy(dst, src, (w * h * sizeof(int)));
|
||||
}
|
||||
|
||||
/* dst now holds window bitmap */
|
||||
ecore_x_image_free(img);
|
||||
*w_out = w;
|
||||
*h_out = h;
|
||||
return (void *) dst;
|
||||
}
|
||||
|
||||
static Eina_List *
|
||||
_load_list(void)
|
||||
{
|
||||
Eina_List *tree = NULL;
|
||||
Eina_List *ees;
|
||||
Ecore_Evas *ee;
|
||||
|
||||
ees = ecore_evas_ecore_evas_list_get();
|
||||
|
||||
EINA_LIST_FREE(ees, ee)
|
||||
{
|
||||
Eina_List *objs;
|
||||
Evas_Object *obj;
|
||||
Clouseau_Tree_Item *treeit;
|
||||
|
||||
Evas *e;
|
||||
int w, h;
|
||||
|
||||
e = ecore_evas_get(ee);
|
||||
evas_output_size_get(e, &w, &h);
|
||||
|
||||
treeit = calloc(1, sizeof(Clouseau_Tree_Item));
|
||||
if (!treeit) continue ;
|
||||
|
||||
treeit->name = eina_stringshare_add(ecore_evas_title_get(ee));
|
||||
treeit->ptr = (uintptr_t) ee;
|
||||
|
||||
tree = eina_list_append(tree, treeit);
|
||||
|
||||
objs = evas_objects_in_rectangle_get(e, SHRT_MIN, SHRT_MIN,
|
||||
USHRT_MAX, USHRT_MAX, EINA_TRUE, EINA_TRUE);
|
||||
|
||||
EINA_LIST_FREE(objs, obj)
|
||||
libclouseau_item_add(obj, treeit);
|
||||
}
|
||||
|
||||
return tree; /* User has to call clouseau_tree_free() */
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_add(EINA_UNUSED void *data, Ecore_Con_Reply *reply,
|
||||
EINA_UNUSED Ecore_Con_Server *conn)
|
||||
{
|
||||
/* ecore_con_server_data_size_max_set(conn, -1); */
|
||||
connect_st t = { getpid(), _my_app_name };
|
||||
ecore_con_eet_send(reply, CLOUSEAU_APP_CLIENT_CONNECT_STR, &t);
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
_del(EINA_UNUSED void *data, EINA_UNUSED Ecore_Con_Reply *reply,
|
||||
Ecore_Con_Server *conn)
|
||||
{
|
||||
if (!conn)
|
||||
{
|
||||
printf("Failed to establish connection to the server.\nExiting.\n");
|
||||
ecore_main_loop_quit();
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
printf("Lost server with ip <%s>\n", ecore_con_server_ip_get(conn));
|
||||
|
||||
ecore_con_server_del(conn);
|
||||
|
||||
ecore_main_loop_quit();
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
void
|
||||
_data_req_cb(EINA_UNUSED void *data, Ecore_Con_Reply *reply,
|
||||
EINA_UNUSED const char *protocol_name, void *value)
|
||||
{ /* data req includes ptr to GUI, to tell which client asking */
|
||||
data_req_st *req = value;
|
||||
tree_data_st t;
|
||||
t.gui = req->gui; /* GUI client requesting data from daemon */
|
||||
t.app = req->app; /* APP client sending data to daemon */
|
||||
t.tree = _load_list();
|
||||
|
||||
if (t.tree)
|
||||
{ /* Reply with tree data to data request */
|
||||
ecore_con_eet_send(reply, CLOUSEAU_TREE_DATA_STR, &t);
|
||||
clouseau_data_tree_free(t.tree);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_highlight_cb(EINA_UNUSED void *data, EINA_UNUSED Ecore_Con_Reply *reply,
|
||||
EINA_UNUSED const char *protocol_name, void *value)
|
||||
{ /* Highlight msg contains PTR of object to highlight */
|
||||
highlight_st *ht = value;
|
||||
Evas_Object *obj = (Evas_Object *) (uintptr_t) ht->object;
|
||||
clouseau_data_object_highlight(obj, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_bmp_req_cb(EINA_UNUSED void *data, EINA_UNUSED Ecore_Con_Reply *reply,
|
||||
EINA_UNUSED const char *protocol_name, void *value)
|
||||
{ /* Bitmap req msg contains PTR of Ecore Evas */
|
||||
bmp_req_st *req = value;
|
||||
Evas_Coord w, h;
|
||||
unsigned int size = 0;
|
||||
void *bmp = _canvas_bmp_get((Ecore_Evas *) (uintptr_t)
|
||||
req->object, &w, &h);
|
||||
|
||||
bmp_info_st t = { req->gui,
|
||||
req->app, req->object , req->ctr, w, h,
|
||||
NULL,NULL, NULL, 1.0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
void *p = clouseau_data_packet_compose(CLOUSEAU_BMP_DATA_STR,
|
||||
&t, &size, bmp, (w * h * sizeof(int)));
|
||||
|
||||
|
||||
if (p)
|
||||
{
|
||||
ecore_con_eet_raw_send(reply, CLOUSEAU_BMP_DATA_STR, "BMP", p, size);
|
||||
free(p);
|
||||
}
|
||||
|
||||
if (bmp)
|
||||
free(bmp);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_connect_to_daemon(void)
|
||||
{
|
||||
Ecore_Con_Server *server;
|
||||
const char *address = LOCALHOST;
|
||||
Ecore_Con_Eet *eet_svr = NULL;
|
||||
|
||||
eina_init();
|
||||
ecore_init();
|
||||
ecore_con_init();
|
||||
|
||||
server = ecore_con_server_connect(ECORE_CON_REMOTE_TCP,
|
||||
LOCALHOST, PORT, NULL);
|
||||
|
||||
if (!server)
|
||||
{
|
||||
printf("could not connect to the server: %s, port %d.\n",
|
||||
address, PORT);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
eet_svr = ecore_con_eet_client_new(server);
|
||||
if (!eet_svr)
|
||||
{
|
||||
printf("could not create con_eet client.\n");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
clouseau_register_descs(eet_svr);
|
||||
|
||||
/* Register callbacks for ecore_con_eet */
|
||||
ecore_con_eet_server_connect_callback_add(eet_svr, _add, NULL);
|
||||
ecore_con_eet_server_disconnect_callback_add(eet_svr, _del, NULL);
|
||||
ecore_con_eet_data_callback_add(eet_svr, CLOUSEAU_DATA_REQ_STR,
|
||||
_data_req_cb, NULL);
|
||||
ecore_con_eet_data_callback_add(eet_svr, CLOUSEAU_HIGHLIGHT_STR,
|
||||
_highlight_cb, NULL);
|
||||
ecore_con_eet_data_callback_add(eet_svr, CLOUSEAU_BMP_REQ_STR,
|
||||
_bmp_req_cb, NULL);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/** PRELOAD functions. */
|
||||
|
||||
/* Hook on the elm_init
|
||||
* We only do something here if we didn't already go into elm_init,
|
||||
* which probably means we are not using elm. */
|
||||
EAPI int
|
||||
elm_init(int argc, char **argv)
|
||||
{
|
||||
int (*_elm_init)(int, char **) = dlsym(RTLD_NEXT, __func__);
|
||||
|
||||
if (!_elm_is_init)
|
||||
{
|
||||
_my_app_name = argv[0];
|
||||
_elm_is_init = EINA_TRUE;
|
||||
}
|
||||
|
||||
return _elm_init(argc, argv);
|
||||
}
|
||||
|
||||
/* Hook on the main loop
|
||||
* We only do something here if we didn't already go into elm_init,
|
||||
* which probably means we are not using elm. */
|
||||
EAPI void
|
||||
ecore_main_loop_begin(void)
|
||||
{
|
||||
void (*_ecore_main_loop_begin)(void) = dlsym(RTLD_NEXT, __func__);
|
||||
|
||||
if (!_elm_is_init)
|
||||
{
|
||||
_my_app_name = "clouseau";
|
||||
}
|
||||
|
||||
clouseau_data_init();
|
||||
|
||||
if(!_connect_to_daemon())
|
||||
{
|
||||
printf("Failed to connect to server.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
_ecore_main_loop_begin();
|
||||
|
||||
clouseau_data_shutdown();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#define EINA_LOCK_DEBUG_BT_NUM 64
|
||||
typedef void (*Eina_Lock_Bt_Func) ();
|
||||
|
||||
EAPI Evas_Object *
|
||||
evas_object_new(Evas *e)
|
||||
{
|
||||
Eina_Lock_Bt_Func lock_bt[EINA_LOCK_DEBUG_BT_NUM];
|
||||
int lock_bt_num;
|
||||
Evas_Object *(*_evas_object_new)(Evas *e) = dlsym(RTLD_NEXT, __func__);
|
||||
Eina_Strbuf *str;
|
||||
Evas_Object *r;
|
||||
char **strings;
|
||||
int i;
|
||||
|
||||
r = _evas_object_new(e);
|
||||
if (!r) return NULL;
|
||||
|
||||
lock_bt_num = backtrace((void **)lock_bt, EINA_LOCK_DEBUG_BT_NUM);
|
||||
strings = backtrace_symbols((void **)lock_bt, lock_bt_num);
|
||||
|
||||
str = eina_strbuf_new();
|
||||
|
||||
for (i = 1; i < lock_bt_num; ++i)
|
||||
eina_strbuf_append_printf(str, "%s\n", strings[i]);
|
||||
|
||||
evas_object_data_set(r, ".clouseau.bt", eina_stringshare_add(eina_strbuf_string_get(str)));
|
||||
|
||||
free(strings);
|
||||
eina_strbuf_free(str);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_object_free(Evas_Object *obj, int clean_layer)
|
||||
{
|
||||
void (*_evas_object_free)(Evas_Object *obj, int clean_layer) = dlsym(RTLD_NEXT, __func__);
|
||||
const char *tmp;
|
||||
|
||||
tmp = evas_object_data_get(obj, ".clouseau.bt");
|
||||
eina_stringshare_del(tmp);
|
||||
|
||||
_evas_object_free(obj, clean_layer);
|
||||
}
|
Loading…
Reference in New Issue