Compare commits

..

1 Commits

Author SHA1 Message Date
Tom 'TAsn' Hacohen 10a69c85b3 Add module interface for elm-clouseau integration. 2013-08-30 16:33:29 +01:00
68 changed files with 5250 additions and 8823 deletions

View File

@ -1,4 +0,0 @@
{
"project_id" : "clouseau",
"conduit_uri" : "https://phab.enlightenment.org/"
}

5
.gitignore vendored
View File

@ -7,10 +7,10 @@
Makefile
Makefile.in
*.so
*~
.*.sw[po]
*.gcov
*.gcno
/README
/aclocal.m4
/autom4te.cache/
/config.cache
@ -41,7 +41,8 @@ coverage
/m4/ltversion.m4
/m4/lt~obsolete.m4
INSTALL
src/bin/client
src/bin/clouseaud
src/scripts/clouseau
src/bin/clouseau_client
src/scripts/clouseau_start
build/

1
AUTHORS Normal file
View File

@ -0,0 +1 @@
Tom Hacohen <tom@stosb.com>

View File

@ -1,27 +0,0 @@
cmake_minimum_required(VERSION 2.8.1)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
project(CLOUSEAU)
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)
set(DEBUG_COMMON_DEFINITIONS -DEFL_EO_API_SUPPORT -DEFL_BETA_API_SUPPORT)
add_definitions(${DEBUG_COMMON_DEFINITIONS})
find_package(Efl REQUIRED)
find_package(Eina REQUIRED)
find_package(Eet REQUIRED)
find_package(Efreet REQUIRED)
find_package(Eolian REQUIRED)
find_package(Eo REQUIRED)
find_package(Elementary REQUIRED)
find_package(Ecore REQUIRED)
find_package(Evas REQUIRED)
find_package(Ffi REQUIRED)
find_package(efl_profiler QUIET)
add_subdirectory(src/bin)
add_subdirectory(src/lib)
add_subdirectory(data)
add_dependencies(clouseau_evlog clouseau_evlog_edj)

25
COPYING Normal file
View File

@ -0,0 +1,25 @@
Copyright notice for Clouseau:
Copyright (C) 2000-2011 Tom Hacohen and various contributors (see AUTHORS)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

1
COPYING.icons Normal file
View File

@ -0,0 +1 @@
The icons in this repository are herefore released into the Public Domain.

0
ChangeLog Normal file
View File

10
Makefile.am Normal file
View File

@ -0,0 +1,10 @@
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \
config.h.in config.sub configure install-sh \
depcomp libtool missing
EXTRA_DIST = README AUTHORS COPYING autogen.sh
SUBDIRS = src data
ACLOCAL_AMFLAGS = -I m4

0
NEWS Normal file
View File

39
README
View File

@ -1,28 +1,19 @@
Clouseau
An UI inspection tool for the EFL. This tool lets you inspect UI elements and get a lot of their properties, e.g position, size and weight.
Clouseau is a UI inspection tool aimed to debug EFL applications.
Clouseau consists of a client (clouseau_client) and launcher (clouseau_server). This design means we can:
1. Run the application we are debugging on one device and the clouseau_client itself on another.
2. Run the application we are debugging with a different environment/theme/etc compared to the clouseau client.
Requirements:
Clouseau provides a wrapper script that automatically launches the application with clouseau support, and launches the client, the script is called "clouseau".
efl (1.20 +)
Usage:
1. Using the wrapper script:
"clouseau elementary_test" or "clouseau elementary_test Entry".
2. Using the split client/server approach (different machines/environments/setups):
"clouseau_start elementary_test" and then "clouseau_client"
As mentioned above, this is done over the network, so it can be run from different machines
Compiling:
1. mkdir build
2. cd build
3. cmake -DCMAKE_INSTALL_PREFIX=/your_install_path ..
4. make
5. (sudo) make install
How to use it?
1. Run efl_debugd on the machine where the program to debug has to run
2. Run your program
3. Run clouseau_client -l / -r [port]
4. Choose the extension you want to use
5. Choose your application
clouseau_client can run in three modes:
- locally: it connects to the local daemon (efl_debugd)
- remotely: you have to establish a connection (SSH...) and to supply the port to use to Clouseau
- offline: this is for the case you want to visualize a snapshot saved earlier
Using the clouseau client:
When the client opens you'll be asked to enter the server's IP address. That's the IP address of where you ran clouseau_start from. When in doubt, just use the default, 127.0.0.1.
Then press "Ok" to connect to the server, and the rest should be fairly straightforward.
TBD

18
TODO Normal file
View File

@ -0,0 +1,18 @@
* Make it possible to hide rects? or show only elm-widgets? or something similar? too much clutter atm.
* Add filter?
* Make it an elm module (or setting an env var without a module?) so I'll be able to remotely connect to elm apps.
* Split UI and actual program code (better to do the previous bullet first).
* Add "grab screenshot" button.
* Add a clipping range rectangle.
* Add special per object info, for example edje part names?
* When items are coloured, show the exact colour using a rect?
* Handle map/proxy
* add a way to filter object with some regexp on the name and also finding a specific object according to name.
* Add general info like hinting/whole interface scale/finger size and etc.
* Things to show per-object
* clipping info.
* callback list?
* Fix has_focus.
* Hook on feed events or something and let us see who gets what?

14
autogen.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
rm -rf autom4te.cache
rm -f aclocal.m4 ltmain.sh
echo "Running aclocal..." ; aclocal -I m4 $ACLOCAL_FLAGS || exit 1
echo "Running autoheader..." ; autoheader || exit 1
echo "Running autoconf..." ; autoconf || exit 1
echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1
echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1
if [ -z "$NOCONFIGURE" ]; then
./configure "$@"
fi

View File

@ -1,40 +0,0 @@
# - Try to find ffi
# Once done this will define
# FFI_FOUND - System has ffi
# FFI_INCLUDE_DIRS - The ffi include directories
# FFI_LIBRARIES - The libraries needed to use ffi
# FFI_LDFLAGS_OTHER - Other LDFLAGS needed te use ffi.
# FFI_DEFINITIONS - Compiler switches required for using ffi
find_package(PkgConfig)
if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER "2.8.1")
# "QUIET" was introduced in 2.8.2
set(_QUIET QUIET)
endif ()
pkg_check_modules(PC_LIBFFI ${_QUIET} libffi)
#set(FFI_DEFINITIONS ${PC_LIBFFI_CFLAGS_OTHER})
#set(FFI_LDFLAGS_OTHER ${PC_LIBFFI_LDFLAGS_OTHER})
# before verison 2.8.11 variable CMAKE_LIBRARY_ARCHITECTURE wasn't automatically added to search path
if ("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_LESS "2.8.11")
set(FIND_PATH_HINTS ${PC_LIBFFI_INCLUDEDIR}/${CMAKE_LIBRARY_ARCHITECTURE})
endif ()
find_path(FFI_INCLUDE_DIR ffi.h
HINTS ${PC_LIBFFI_INCLUDEDIR} ${PC_LIBFFI_INCLUDE_DIRS}
${FIND_PATH_HINTS}
)
find_library(FFI_LIBRARY NAMES ffi libffi
HINTS ${PC_LIBFFI_LIBDIR} ${PC_LIBFFI_LIBRARY_DIRS})
set(FFI_INCLUDE_DIRS ${FFI_INCLUDE_DIR})
set(FFI_LIBRARIES ${FFI_LIBRARY})
#include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set EINA_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(ffi DEFAULT_MSG
FFI_LIBRARY)
mark_as_advanced(FFI_INCLUDE_DIRS FFI_LIBRARY)

94
configure.ac Normal file
View File

@ -0,0 +1,94 @@
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
m4_define([v_maj], [0])
m4_define([v_min], [2])
m4_define([v_mic], [0])
m4_define([v_rev], m4_esyscmd([(svnversion "${SVN_REPO_PATH:-.}" | grep -v '\(export\|Unversioned directory\)' || echo 0) | awk -F : '{printf("%s\n", $1);}' | tr -d ' :MSP\n']))
m4_if(v_rev, [0], [m4_define([v_rev], m4_esyscmd([git log 2> /dev/null | (grep -m1 git-svn-id || echo 0) | sed -e 's/.*@\([0-9]*\).*/\1/' | tr -d '\n']))])
##-- When released, remove the dnl on the below line
dnl m4_undefine([v_rev])
##-- When doing snapshots - change soname. remove dnl on below line
dnl m4_define([relname], [ver-pre-svn-07])
dnl m4_define([v_rel], [-release relname])
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
m4_ifdef([v_rev], [m4_define([v_ver], [v_maj.v_min.v_mic.v_rev])], [m4_define([v_ver], [v_maj.v_min.v_mic])])
m4_define([lt_cur], m4_eval(v_maj + v_min))
m4_define([lt_rev], v_mic)
m4_define([lt_age], v_min)
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
AC_INIT(clouseau, [v_ver], tom@stosb.com)
AC_PREREQ(2.52)
AC_CONFIG_SRCDIR(configure.ac)
AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(1.6 dist-bzip2)
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AM_CONFIG_HEADER(config.h)
AC_GNU_SOURCE
AC_PROG_LIBTOOL
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
m4_ifdef([v_rev], , [m4_define([v_rev], [0])])
m4_ifdef([v_rel], , [m4_define([v_rel], [])])
AC_DEFINE_UNQUOTED(VMAJ, [v_maj], [Major version])
AC_DEFINE_UNQUOTED(VMIN, [v_min], [Minor version])
AC_DEFINE_UNQUOTED(VMIC, [v_mic], [Micro version])
AC_DEFINE_UNQUOTED(VREV, [v_rev], [Revison])
version_info="lt_cur:lt_rev:lt_age"
release_info="v_rel"
AC_SUBST(version_info)
AC_SUBST(release_info)
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
VMAJ=v_maj
AC_SUBST(VMAJ)
PKG_CHECK_MODULES([EFL],
[
eina >= 1.0.0
eet >= 1.0.0
elementary >= 0.7.0
evas >= 1.0.0
ecore >= 1.0.0
ecore-ipc >= 1.0.0
edje >= 1.0.0
]
)
### Checks for linker characteristics
lt_enable_auto_import=""
case "${host_os}" in
mingw*)
lt_enable_auto_import="-Wl,--enable-auto-import"
;;
esac
case "$host_vendor" in
ps3*)
# Escape had already been checked to exist
;;
esac
AC_SUBST([lt_enable_auto_import])
EFL_ATTRIBUTE_UNUSED
AC_CHECK_LIB(dl,dlopen)
AC_CHECK_FUNCS(dlopen dlerror)
AC_CONFIG_FILES([
Makefile
src/Makefile
src/lib/Makefile
src/bin/Makefile
src/scripts/Makefile
data/Makefile
data/images/Makefile
])
AC_OUTPUT

View File

@ -1,22 +0,0 @@
add_custom_command (
OUTPUT clouseau_evlog.edj
COMMAND edje_cc -id ${CMAKE_CURRENT_SOURCE_DIR}/images ${CMAKE_CURRENT_SOURCE_DIR}/evlog.edc clouseau_evlog.edj
DEPENDS evlog.edc
)
add_custom_command (
OUTPUT clouseau_focus_inspector.edj
COMMAND edje_cc -id ${CMAKE_CURRENT_SOURCE_DIR}/images ${CMAKE_CURRENT_SOURCE_DIR}/focus_inspector.edc clouseau_focus_inspector.edj
DEPENDS focus_inspector.edc
)
add_custom_target (
clouseau_evlog_edj
DEPENDS clouseau_evlog.edj evlog.edc
)
add_custom_target(focus_inspector_theme DEPENDS clouseau_focus_inspector.edj)
install (
FILES ${CMAKE_CURRENT_BINARY_DIR}/clouseau_focus_inspector.edj ${CMAKE_CURRENT_BINARY_DIR}/clouseau_evlog.edj images/show-screenshot.png images/take-screenshot.png
DESTINATION share/${PROJECT_NAME_LOWER}
)

2
data/Makefile.am Normal file
View File

@ -0,0 +1,2 @@
MAINTAINERCLEANFILES = Makefile.in
SUBDIRS = images

View File

@ -1,138 +0,0 @@
#define TILED_PATTERN(_WIDTH, _HEIGHT) \
fill { size { relative: 0.0 0.0; offset: _WIDTH _HEIGHT; } }
collections {
images.image: "box_glow.png" COMP;
images.image: "box_outline.png" COMP;
group { name: "range";
parts {
part { name: "bg"; type: RECT;
description { state: "default" 0.0;
rel1.offset: 1 1;
rel2.offset: -2 -2;
color_class: "range";
}
}
part { name: "text"; type: TEXT;
scale: 1;
description { state: "default" 0.0;
rel1.to: "bg";
rel2.to: "bg";
color: 255 255 255 255;
text { font: "Sans"; size: 10;
min: 0 1;
align: 0.0 1.0;
}
}
}
}
}
group { name: "cpufreq";
parts {
part { name: "bg"; type: RECT;
description { state: "default" 0.0;
// rel1.offset: 1 1;
// rel2.offset: -2 -2;
color_class: "range";
}
}
}
}
group { name: "cpuused";
parts {
part { name: "bg"; type: RECT;
description { state: "default" 0.0;
// rel1.offset: 1 1;
// rel2.offset: -2 -2;
color_class: "range";
}
}
}
}
images.image: "diagonal_stripes.png" COMP;
group { name: "state";
parts {
part { name: "bg";
description { state: "default" 0.0;
rel1.offset: 1 1;
rel2.offset: -2 -2;
color_class: "state";
TILED_PATTERN(240, 240)
image.normal: "diagonal_stripes.png";
}
}
part { name: "text"; type: TEXT;
scale: 1;
description { state: "default" 0.0;
rel1.to: "bg";
rel2.to: "bg";
color: 255 255 255 255;
text { font: "Sans"; size: 10;
min: 0 1;
align: 0.0 1.0;
}
}
}
}
}
images.image: "handle_pick_up_right.png" COMP;
group { name: "frame";
parts {
part { name: "base"; type: RECT;
description { state: "default" 0.0;
color: 51 153 255 128;
min: 1 1;
}
}
part { name: "bg";
description { state: "default" 0.0;
image.normal: "handle_pick_up_right.png";
rel1.offset: -12 -11;
rel1.relative: 0.0 1.0;
rel2.offset: -12 -11;
rel2.relative: 0.0 1.0;
align: 0.0 0.0;
min: 42 54;
max: 42 54;
}
}
}
}
group { name: "event";
parts {
part { name: "base"; type: RECT; mouse_events: 0;
description { state: "default" 0.0;
color_class: "event";
min: 1 1;
}
}
part { name: "over"; type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
min: 5 1;
}
}
part { name: "text"; type: TEXT;
scale: 1;
description { state: "default" 0.0;
rel1.relative: 0.0 1.0;
rel2.relative: 1.0 1.0;
align: 0.5 0.0;
color_class: "event";
text { font: "Sans"; size: 10;
min: 1 1;
align: 0.5 0.0;
}
}
}
}
}
}

View File

@ -1,91 +0,0 @@
collections {
images {
image: "focus_inspector_history.svg" COMP;
image: "focus_inspector_logical.svg" COMP;
image: "focus_inspector_regular.svg" COMP;
image: "focus_inspector_redirect.svg" COMP;
}
group { "focus_inspector/regular";
parts {
image { "indicator";
desc { "default";
rel1.to: "widget_name";
rel1.offset: -3px -3px;
rel2.to: "widget_name";
rel2.offset: 3px 3px;
image {
border: 1 1 1 1;
normal: "focus_inspector_regular.svg";
}
}
}
text { "widget_name";
desc { "default";
text {
font: Sans;
text: "<widget-name>";
size: 8;
min: 1 1;
max: 1 1;
}
}
}
}
}
group { "focus_inspector/logical";
inherit: "focus_inspector/regular";
parts {
image { "indicator";
desc { "default";
rel1.to: "widget_name";
rel1.offset: -3px -3px;
rel2.to: "widget_name";
rel2.offset: 3px 3px;
image {
border: 1 1 1 1;
normal: "focus_inspector_logical.svg";
}
}
}
}
}
group { "focus_inspector/history";
inherit: "focus_inspector/regular";
parts {
image { "indicator";
desc { "default";
rel1.to: "widget_name";
rel1.offset: -3px -3px;
rel2.to: "widget_name";
rel2.offset: 3px 3px;
image {
border: 1 1 1 1;
normal: "focus_inspector_history.svg";
}
}
}
}
}
group { "focus_inspector/redirect";
inherit: "focus_inspector/regular";
parts {
image { "indicator";
desc { "default";
rel1.to: "widget_name";
rel1.offset: -3px -3px;
rel2.to: "widget_name";
rel2.offset: 3px 3px;
image {
border: 1 1 1 1;
normal: "focus_inspector_redirect.svg";
}
}
}
}
}
}

12
data/images/Makefile.am Normal file
View File

@ -0,0 +1,12 @@
MAINTAINERCLEANFILES = Makefile.in
filesdir = $(datadir)/clouseau/images
files_DATA = \
clipper.png \
hidden.png \
background.png \
screenshot-missing.png \
show-screenshot.png \
take-screenshot.png
EXTRA_DIST = $(files_DATA)

BIN
data/images/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

BIN
data/images/clipper.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="99.855179mm"
height="28.76149mm"
viewBox="0 0 99.855179 28.76149"
version="1.1"
id="svg8"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="focus_inspector_history.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="-3.7169149"
inkscape:cy="-166.01003"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.58634746,-0.38263321)">
<rect
style="fill:#484e4d;fill-opacity:1;fill-rule:nonzero;stroke:#259700;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4504"
width="98.355179"
height="27.26149"
x="1.3363475"
y="1.1326332"
ry="8.5526237"
rx="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="99.855179mm"
height="28.76149mm"
viewBox="0 0 99.855179 28.76149"
version="1.1"
id="svg8"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="focus_inspector_logical.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="-3.7169149"
inkscape:cy="-166.01003"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.58634746,-0.38263321)">
<rect
style="fill:#484e4d;fill-opacity:1;fill-rule:nonzero;stroke:#787878;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4504"
width="98.355179"
height="27.26149"
x="1.3363475"
y="1.1326332"
ry="8.5526237"
rx="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="99.855179mm"
height="28.76149mm"
viewBox="0 0 99.855179 28.76149"
version="1.1"
id="svg8"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="focus_inspector_redirect.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="-3.7169149"
inkscape:cy="-166.01003"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.58634746,-0.38263321)">
<rect
style="fill:#484e4d;fill-opacity:1;fill-rule:nonzero;stroke:#c0392b;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4504"
width="98.355179"
height="27.26149"
x="1.3363475"
y="1.1326332"
ry="8.5526237"
rx="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="99.855179mm"
height="28.76149mm"
viewBox="0 0 99.855179 28.76149"
version="1.1"
id="svg8"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="focus_inspector_regular.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="-3.7169149"
inkscape:cy="-166.01003"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.58634746,-0.38263321)">
<rect
style="fill:#484e4d;fill-opacity:1;fill-rule:nonzero;stroke:#2288ee;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4504"
width="98.355179"
height="27.26149"
x="1.3363475"
y="1.1326332"
ry="8.5526237"
rx="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

BIN
data/images/hidden.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

0
m4/A Normal file
View File

56
m4/efl_attribute.m4 Normal file
View File

@ -0,0 +1,56 @@
dnl Copyright (C) 2011 Vincent Torri <vtorri at univ-evry dot fr>
dnl That code is public domain and can be freely used or copied.
dnl Macros for checking if the compiler supports some __attribute__ uses
dnl Usage: EFL_ATTRIBUTE_UNUSED
dnl call AC_DEFINE for __UNUSED__ if __attribute__((unused)) is available
AC_DEFUN([EFL_ATTRIBUTE_UNUSED],
[
AC_MSG_CHECKING([for __attribute__ ((unused))])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
void foo(int x __attribute__ ((unused))) {}
]],
[[
]])],
[have_attribute_unused="yes"],
[have_attribute_unused="no"])
AC_MSG_RESULT([${have_attribute_unused}])
if test "x${have_attribute_unused}" = "xyes" ; then
AC_DEFINE([__UNUSED__], [__attribute__ ((unused))], [Macro declaring a function argument to be unused.])
else
AC_DEFINE([__UNUSED__], [], [__attribute__ ((unused)) is not supported.])
fi
])
dnl Usage: EFL_ATTRIBUTE_VECTOR
dnl call AC_DEFINE for HAVE_GCC_ATTRIBUTE_VECTOR if __attribute__((vector)) is available
AC_DEFUN([EFL_ATTRIBUTE_VECTOR],
[
AC_MSG_CHECKING([for __attribute__ ((vector))])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
typedef int v4si __attribute__ ((vector_size (16)));
]],
[[
if (sizeof(v4si) == 16)
return 0;
else
return -1;
]])],
[have_attribute_vector="yes"],
[have_attribute_vector="no"])
AC_MSG_RESULT([${have_attribute_vector}])
if test "x${have_attribute_vector}" = "xyes" ; then
AC_DEFINE([HAVE_GCC_ATTRIBUTE_VECTOR], [1], [Define to 1 if your compiler supports __attribute__ ((vector)).])
fi
])
dnl End of efl_attribute.m4

4
make.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
gcc -Wall -Wextra -fPIC -rdynamic -g3 -O0 -c libclouseau.c `pkg-config --libs --cflags elementary ecore evas`
gcc -g3 -O0 -shared -Wl,-soname,libclouseau.so.1 -o libclouseau.so.1.0.1 libclouseau.o -lc -ldl `pkg-config --libs --cflags elementary`

4
src/Makefile.am Normal file
View File

@ -0,0 +1,4 @@
MAINTAINERCLEANFILES = Makefile.in
SUBDIRS = lib bin scripts

View File

@ -1,39 +0,0 @@
set(CMAKE_BUILD_TYPE Debug)
LIST(APPEND SOURCES clouseau_client.c gui.c)
add_definitions(-DEFL_EO_API_SUPPORT -DGUI_IMAGES_PATH="${CMAKE_INSTALL_PREFIX}/data/images")
add_definitions(-DINSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
link_directories (${PC_LIBELEMENTARY_LIBRARY_DIRS})
include_directories(
${CMAKE_SOURCE_DIR}/src/lib
${ELEMENTARY_INCLUDE_DIRS}
${EINA_INCLUDE_DIRS}
${EET_INCLUDE_DIRS}
${EFREET_INCLUDE_DIRS}
${EO_INCLUDE_DIRS}
${ECORE_INCLUDE_DIRS}
${EVAS_INCLUDE_DIRS}
)
set(EOLIAN_INCLUDE_FLAG -I \"${EOLIAN_EO_DIR}/eo-1\" -I${CMAKE_CURRENT_SOURCE_DIR})
add_executable(clouseau_client ${SOURCES})
target_link_libraries(clouseau_client
pthread
${EFL_LIBRARIES}
${ELEMENTARY_LIBRARIES}
${EINA_LIBRARIES}
${EET_LIBRARIES}
${EFREET_LIBRARIES}
${EO_LIBRARIES}
${ECORE_LIBRARIES}
${EVAS_LIBRARIES}
ecore_file
)
install(TARGETS clouseau_client DESTINATION bin)
install(PROGRAMS clouseau DESTINATION bin)

18
src/bin/Makefile.am Normal file
View File

@ -0,0 +1,18 @@
MAINTAINERCLEANFILES = Makefile.in
bin_PROGRAMS = clouseaud clouseau_client
clouseaud_SOURCES = clouseaud.c
clouseau_client_SOURCES = clouseau.c
AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/include \
-I$(top_builddir)/src/include \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EFL_CFLAGS@
clouseaud_LDADD = $(top_builddir)/src/lib/libclouseau_client.la @EFL_LIBS@
clouseau_client_LDADD = $(top_builddir)/src/lib/libclouseau_client.la @EFL_LIBS@

View File

@ -1,11 +0,0 @@
#!/bin/sh
if [ $# -lt 1 ]
then
echo "Usage: clouseau <executable> [executable parameters]"
else
# Start the local daemon. In case it is already running, it exits directly.
efl_debugd &
# Start the application
$@ &
clouseau_client -l -p $!
fi

1935
src/bin/clouseau.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

475
src/bin/clouseaud.c Normal file
View File

@ -0,0 +1,475 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <fcntl.h>
#include <Ecore_Ipc.h>
#include "clouseau_private.h"
#define RUNNING_DIR "/tmp"
#define LOCK_FILE ".clouseaud.lock"
#define LOG_FILE "clouseaud.log"
static Eina_List *gui = NULL; /* List of app_info_st for gui clients */
static Eina_List *app = NULL; /* List of app_info_st for app clients */
Ecore_Ipc_Server *ipc_svr = NULL;
/* For Debug */
char msg_buf[MAX_LINE+1];
struct _tree_info_st
{
void *app; /* app ptr to identify where the data came from */
void *data; /* Tree data */
};
typedef struct _tree_info_st tree_info_st;
static void
log_message(char *filename, char *mode, char *message)
{
FILE *logfile;
logfile=fopen(filename, mode);
if(!logfile) return;
fprintf(logfile,"%s\n",message);
fclose(logfile);
}
static void
_daemon_cleanup(void)
{ /* Free strings */
app_info_st *p;
sprintf(msg_buf,"Clients connected to this server when exiting: %d\n",
eina_list_count(ecore_ipc_server_clients_get(ipc_svr)));
log_message(LOG_FILE, "a", msg_buf);
EINA_LIST_FREE(gui, p)
{
if(p->file)
free(p->file);
free(p->name);
free(p);
}
EINA_LIST_FREE(app, p)
{
if(p->file)
free(p->file);
free(p->name);
free(p);
}
gui = app = NULL;
ipc_svr = NULL;
clouseau_data_shutdown();
ecore_ipc_shutdown();
ecore_shutdown();
eina_shutdown();
}
void daemonize(void)
{
int i,lfp;
char str[10];
time_t currentTime;
if(getppid()==1) return; /* already a daemon */
i=fork();
if (i<0) exit(1); /* fork error */
if (i>0) exit(0); /* parent exits */
time (&currentTime);
/* child (daemon) continues */
setsid(); /* obtain a new process group */
for (i=getdtablesize();i>=0;--i) close(i); /* close all descriptors */
i=open("/dev/null",O_RDWR);
if (dup(i) == -1) return; /* handle standart I/O */
if (dup(i) == -1) return; /* handle standart I/O */
umask(027); /* set newly created file permissions */
if (chdir(RUNNING_DIR) == -1) return; /* change running directory */
lfp=open(LOCK_FILE,O_RDWR|O_CREAT,0640);
if (lfp<0) exit(1); /* can not open */
if (lockf(lfp,F_TLOCK,0)<0) exit(0); /* can not lock */
/* first instance continues */
sprintf(str,"%d\n",getpid());
if (write(lfp,str,strlen(str)) == -1) return; /* record pid to lockfile */
signal(SIGCHLD,SIG_IGN); /* ignore child */
signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
log_message(LOG_FILE, "w", "Daemon Started");
log_message(LOG_FILE, "a", ctime(&currentTime));
}
/* START - Ecore communication callbacks */
static int
_client_ptr_cmp(const void *d1, const void *d2)
{
return (((app_info_st *) d1)->ptr - ((unsigned long long) (uintptr_t) d2));
}
static Eina_List *
_add_client(Eina_List *clients, connect_st *t, void *client)
{
if(!eina_list_search_unsorted(clients, _client_ptr_cmp, client))
{
app_info_st *st = calloc(1, sizeof(app_info_st));
st->name = strdup(t->name);
st->pid = t->pid;
st->ptr = (unsigned long long) (uintptr_t) client;
return eina_list_append(clients, st);
}
return clients;
}
static Eina_List *
_remove_client(Eina_List *clients, void *client)
{
app_info_st *p = eina_list_search_unsorted(clients, _client_ptr_cmp, client);
if (p)
{
free(p->name);
free(p);
return eina_list_remove(clients, p);
}
return clients;
}
Eina_Bool
_add(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Ipc_Event_Client_Add *ev)
{
ecore_ipc_client_data_size_max_set(ev->client, -1);
sprintf(msg_buf, "<%s> msg from <%p>", __func__, ev->client);
log_message(LOG_FILE, "a", msg_buf);
return ECORE_CALLBACK_RENEW;
}
Eina_Bool
_del(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Ipc_Event_Client_Del *ev)
{
if (!ev->client)
return ECORE_CALLBACK_RENEW;
sprintf(msg_buf, "<%s> msg from <%p>", __func__, ev->client);
log_message(LOG_FILE, "a", msg_buf);
/* Now we need to find if its an APP or GUI client */
app_info_st *i = eina_list_search_unsorted(gui, _client_ptr_cmp, ev->client);
if (i) /* Only need to remove GUI client from list */
gui = _remove_client(gui, ev->client);
i = eina_list_search_unsorted(app, _client_ptr_cmp, ev->client);
if (i)
{ /* Notify all GUI clients to remove this APP */
app_closed_st t = { (unsigned long long) (uintptr_t) ev->client };
Eina_List *l;
int size;
void *p = clouseau_data_packet_compose(CLOUSEAU_APP_CLOSED,
&t, sizeof(t), &size, NULL, 0);
if (p)
{
EINA_LIST_FOREACH(gui, l, i)
{
ecore_ipc_client_send((void *) (uintptr_t) i->ptr,
0,0,0,0,EINA_FALSE, p, size);
ecore_ipc_client_flush((void *) (uintptr_t) i->ptr);
}
free(p);
}
app = _remove_client(app, ev->client);
}
ecore_ipc_client_del(ev->client);
if (!eina_list_count(ecore_ipc_server_clients_get(ipc_svr)))
{ /* Trigger cleanup and exit when all clients disconneced */
ecore_main_loop_quit();
}
return ECORE_CALLBACK_RENEW;
}
Eina_Bool
_data(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Ipc_Event_Client_Data *ev)
{
void *p;
int size = 0;
sprintf(msg_buf, "<%s> msg from <%p>", __func__, ev->client);
log_message(LOG_FILE, "a", msg_buf);
Variant_st *v = clouseau_data_packet_info_get(ev->data, ev->size);
/* This is where daemon impl communication protocol.
* In order to simplify, all messages also contains recipient ptr
* as saved by daemon.
* Thus we only need to peek this info then FWD, reply to this recipient */
if (!v)
{
log_message(LOG_FILE, "a", "Failed to decode data.");
return ECORE_CALLBACK_RENEW;
}
switch(clouseau_data_packet_mapping_type_get(v->type))
{
case CLOUSEAU_APP_CLIENT_CONNECT:
{ /* Register APP then notify GUI about it */
app_info_st *st;
Eina_List *l;
connect_st *t = v->data;
app_info_st m = { t->pid, (char *) t->name, NULL,
(unsigned long long) (uintptr_t) ev->client, NULL, 0 };
app = _add_client(app, t, ev->client);
p = clouseau_data_packet_compose(CLOUSEAU_APP_ADD,
&m, sizeof(m), &size, NULL, 0);
if (p)
{
EINA_LIST_FOREACH(gui, l, st)
{ /* Notify all GUI clients to add APP */
ecore_ipc_client_send(
(void *) (uintptr_t) st->ptr,
0,0,0,0,EINA_FALSE, p, size);
ecore_ipc_client_flush(
(void *) (uintptr_t) st->ptr);
}
free(p);
}
}
break;
case CLOUSEAU_GUI_CLIENT_CONNECT:
{ /* Register GUI, then notify about all APP */
app_info_st *st;
Eina_List *l;
connect_st *t = v->data;
gui = _add_client(gui, t, ev->client);
EINA_LIST_FOREACH(app, l, st)
{ /* Add all registered apps to newly open GUI */
p = clouseau_data_packet_compose(CLOUSEAU_APP_ADD,
st, sizeof(*st), &size, NULL, 0);
if (p)
{
ecore_ipc_client_send(ev->client,
0,0,0,0,EINA_FALSE, p, size);
ecore_ipc_client_flush(ev->client);
free(p);
}
}
}
break;
case CLOUSEAU_DATA_REQ:
{ /* msg coming from GUI, FWD this to app specified in req */
data_req_st *req = v->data;
if (req->app)
{ /* Requesting specific app data */
if(eina_list_search_unsorted(app,
_client_ptr_cmp,
(void *) (uintptr_t) req->app))
{ /* Do the req only of APP connected to daemon */
data_req_st t = {
(unsigned long long) (uintptr_t) ev->client,
(unsigned long long) (uintptr_t) req->app };
p = clouseau_data_packet_compose(CLOUSEAU_DATA_REQ,
&t, sizeof(t), &size, NULL, 0);
if (p)
{
ecore_ipc_client_send(
(void *) (uintptr_t) req->app,
0,0,0,0, EINA_FALSE, p, size);
ecore_ipc_client_flush(
(void *) (uintptr_t) req->app);
free(p);
}
}
}
else
{ /* requesting ALL apps data */
Eina_List *l;
app_info_st *st;
data_req_st t = {
(unsigned long long) (uintptr_t) ev->client,
(unsigned long long) (uintptr_t) NULL };
EINA_LIST_FOREACH(app, l, st)
{
t.app = (unsigned long long) (uintptr_t) st->ptr;
p = clouseau_data_packet_compose(CLOUSEAU_DATA_REQ,
&t, sizeof(t), &size, NULL, 0);
if (p)
{
ecore_ipc_client_send(
(void *) (uintptr_t) st->ptr,
0,0,0,0, EINA_FALSE, p, size);
ecore_ipc_client_flush(
(void *) (uintptr_t) st->ptr);
free(p);
}
}
}
}
break;
case CLOUSEAU_TREE_DATA:
{ /* Tree Data comes from APP, GUI client specified in msg */
tree_data_st *td = v->data;
if (td->gui)
{ /* Sending tree data to specific GUI client */
if(eina_list_search_unsorted(gui,
_client_ptr_cmp,
(void *) (uintptr_t) td->gui))
{ /* Do the req only of GUI connected to daemon */
ecore_ipc_client_send(
(void *) (uintptr_t) td->gui, 0,0,0,0,
EINA_FALSE, ev->data, ev->size);
ecore_ipc_client_flush(
(void *) (uintptr_t) td->gui);
}
}
else
{ /* Sending tree data to all GUI clients */
Eina_List *l;
app_info_st *info;
EINA_LIST_FOREACH(gui, l, info)
{
ecore_ipc_client_send(
(void *) (uintptr_t) info->ptr, 0,0,0,0,
EINA_FALSE, ev->data, ev->size);
ecore_ipc_client_flush(
(void *) (uintptr_t) info->ptr);
}
}
clouseau_data_tree_free(td->tree);
}
break;
case CLOUSEAU_HIGHLIGHT:
{ /* FWD this message to app */
highlight_st *ht = v->data;
if(eina_list_search_unsorted(app,
_client_ptr_cmp, (void *) (uintptr_t) ht->app))
{ /* Do the req only of APP connected to daemon */
ecore_ipc_client_send((void *)
(uintptr_t) ht->app, 0,0,0,0,
EINA_FALSE, ev->data, ev->size);
ecore_ipc_client_flush((void *) (uintptr_t) ht->app);
}
}
break;
case CLOUSEAU_BMP_REQ:
{
bmp_req_st *req = v->data;
if(eina_list_search_unsorted(app,
_client_ptr_cmp, (void *) (uintptr_t) req->app))
{ /* Do the req only of APP connected to daemon */
bmp_req_st t = {
(unsigned long long) (uintptr_t) ev->client,
req->app, req->object, req->ctr };
p = clouseau_data_packet_compose(CLOUSEAU_BMP_REQ,
&t, sizeof(t), &size, NULL, 0);
if (p)
{ /* FWD req to app with client data */
ecore_ipc_client_send(
(void *) (uintptr_t) req->app,
0,0,0,0, EINA_FALSE, p, size);
ecore_ipc_client_flush(
(void *) (uintptr_t) req->app);
free(p);
}
}
}
break;
case CLOUSEAU_BMP_DATA:
{ /* Bmp Data comes from APP, GUI client specified in msg */
bmp_info_st *st = v->data;
if (st->gui)
{ /* Sending BMP data to specific GUI client */
if(eina_list_search_unsorted(gui,
_client_ptr_cmp,
(void *) (uintptr_t) st->gui))
{ /* Do the req only of GUI connected to daemon */
ecore_ipc_client_send(
(void *) (uintptr_t) st->gui, 0,0,0,0,
EINA_FALSE, ev->data, ev->size);
ecore_ipc_client_flush(
(void *) (uintptr_t) st->gui);
}
}
else
{ /* Sending BMP data to all GUI clients */
Eina_List *l;
app_info_st *info;
EINA_LIST_FOREACH(gui, l, info)
{
ecore_ipc_client_send(
(void *) (uintptr_t) info->ptr, 0,0,0,0,
EINA_FALSE, ev->data, ev->size);
ecore_ipc_client_flush(
(void *) (uintptr_t) info->ptr);
}
}
if (st->bmp)
free(st->bmp);
}
break;
default:
break;
}
clouseau_data_variant_free(v);
log_message(LOG_FILE, "a", "_data() finished");
return ECORE_CALLBACK_RENEW;
}
/* END - Ecore communication callbacks */
int main(void)
{
daemonize();
eina_init();
ecore_init();
ecore_ipc_init();
clouseau_data_init();
if (!(ipc_svr = ecore_ipc_server_add(ECORE_IPC_REMOTE_SYSTEM,
LISTEN_IP, PORT, NULL)))
exit(1);
ecore_ipc_server_data_size_max_set(ipc_svr, -1);
ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, (Ecore_Event_Handler_Cb)_add, NULL);
ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, (Ecore_Event_Handler_Cb)_del, NULL);
ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, (Ecore_Event_Handler_Cb)_data, NULL);
ecore_main_loop_begin();
_daemon_cleanup();
return 0;
}

View File

@ -1,595 +0,0 @@
{
"JSON_Version":"1",
"Settings":
{
"project":"gui",
"start_points":["main_win"]
},
"Resources":
{
"Images":
{
"SCREENSHOT_ICON":"../../data/images/show-screenshot.png"
},
"Eo_Callbacks":
{
"profile_close":"_profile_win_close_cb",
"new_profile_save":"_new_profile_save_cb",
"new_profile_cancel":"_new_profile_cancel_cb",
"profile_del":"_profile_del_cb",
"screenshot_request":"screenshot_req_cb"
}
},
"Widgets":
{
"main_win":
{
"Desc":
{
"parent":null,
"class":"Elm.Win",
"public":true
},
"Properties":
{
"Elm.Win.type":["ELM_WIN_BASIC"],
"Elm.Widget.part_text":[null, "Window"],
"Elm.Win.autodel":[true],
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[478, 484]
},
"Contains":["elm_bg1", "elm_box1"]
},
"elm_bg1":
{
"Desc":
{
"parent":"main_win",
"class":"Elm.Bg"
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.position":[0, 0]
}
},
"elm_box1":
{
"Desc":
{
"parent":"main_win",
"class":"Elm.Box"
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[643, 598],
"Efl.Gfx.Base.position":[-7, -2],
"Elm.Box.padding":[0, 0],
"Elm.Box.align":[0, 0]
},
"Contains":["apps_selector", "elm_panes1"]
},
"apps_selector":
{
"Desc":
{
"parent":"elm_box1",
"class":"Elm.Hoversel",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 0],
"Evas.Object.size_hint_align":[0.50, 0],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[1174, 643],
"Efl.Gfx.Base.position":[-8, -2],
"Elm.Widget.part_text":[null, "Select App"]
}
},
"elm_panes1":
{
"Desc":
{
"parent":"elm_box1",
"class":"Elm.Panes"
},
"Properties":
{
"Elm.Panes.content_right_size":[0.60],
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.size":[75, 75],
"Efl.Gfx.Base.visible":[true],
"Evas.Object.size_hint_weight":[1, 1],
"Evas.Object.size_hint_align":[-1, -1]
},
"Contains":
{
"objects_list":["left"],
"object_infos_list":["right"]
}
},
"object_infos_list":
{
"Desc":
{
"parent":"elm_panes1",
"class":"Elm.Genlist",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true]
}
},
"objects_list":
{
"Desc":
{
"parent":"elm_panes1",
"class":"Elm.Genlist",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true]
}
},
"profiles_win":
{
"Desc":
{
"parent":null,
"class":"Elm.Win",
"public":true
},
"Properties":
{
"Elm.Win.name":["Win"],
"Elm.Win.type":["ELM_WIN_BASIC"],
"Elm.Win.autodel":[true],
"Elm.Widget.part_text":[null, "Window"],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[347, 362],
"Evas.Object.size_hint_weight":[1, 1],
"Evas.Object.freeze_events":[false],
"Evas.Object.repeat_events":[false],
"Elm.Win.title":["Profiles"]
},
"Contains":["elm_bg2", "elm_box2"]
},
"elm_bg2":
{
"Desc":
{
"parent":"profiles_win",
"class":"Elm.Bg"
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true]
}
},
"elm_box2":
{
"Desc":
{
"parent":"profiles_win",
"class":"Elm.Box"
},
"Properties":
{
"Elm.Box.padding":[7, 0],
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.size":[200, 200],
"Efl.Gfx.Base.visible":[true]
},
"Contains":["profiles_list", "elm_box3"]
},
"elm_box3":
{
"Desc":
{
"parent":"elm_box2",
"class":"Elm.Box"
},
"Properties":
{
"Elm.Box.padding":[7, 0],
"Evas.Object.size_hint_align":[-1, -1],
"Efl.Gfx.Base.visible":[true],
"Elm.Box.horizontal":[true],
"Efl.Gfx.Base.size":[200, 139],
"Efl.Gfx.Base.position":[289, 742],
"Evas.Object.size_hint_weight":[1, 0.20]
},
"Contains":["profile_ok_button", "profile_cancel_button", "profile_new_button", "profile_delete_button"]
},
"profile_delete_button":
{
"Desc":
{
"parent":"elm_box3",
"class":"Elm.Button",
"public":true
},
"Properties":
{
"Efl.Gfx.Base.visible":[true],
"Elm.Widget.disabled":[true],
"Elm.Widget.part_text":[null, "Delete profile"],
"Efl.Gfx.Base.size":[115, 30],
"Efl.Gfx.Base.position":[-42, 0],
"Evas.Object.size_hint_align":[0.50, 0.50],
"Evas.Object.size_hint_weight":[1, 1]
},
"Callbacks":
{
"clicked":["Invoke", "profile_del", null]
}
},
"profile_ok_button":
{
"Desc":
{
"parent":"elm_box3",
"class":"Elm.Button",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[73, 30],
"Elm.Widget.part_text":[null, "Ok"],
"Elm.Widget.disabled":[true]
},
"Callbacks":
{
"clicked":["Invoke", "profile_close", null]
}
},
"profile_cancel_button":
{
"Desc":
{
"parent":"elm_box3",
"class":"Elm.Button",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[73, 30],
"Elm.Widget.part_text":[null, "Cancel"]
}
},
"profile_new_button":
{
"Desc":
{
"parent":"elm_box3",
"class":"Elm.Button"
},
"Properties":
{
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[73, 30],
"Elm.Widget.part_text":[null, "New profile"],
"Evas.Object.size_hint_weight":[1, 1],
"Evas.Object.size_hint_align":[0.50, 0.50]
},
"Callbacks":
{
"clicked":["Create", "new_profile_win", null]
}
},
"profiles_list":
{
"Desc":
{
"parent":"elm_box2",
"class":"Elm.Genlist",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Evas.Object.size_hint_align":[-1, -1]
}
},
"new_profile_win":
{
"Desc":
{
"parent":null,
"class":"Elm.Win",
"public":true
},
"Properties":
{
"Elm.Win.type":["ELM_WIN_BASIC"],
"Elm.Win.autodel":[true],
"Elm.Widget.part_text":[null, "Window"],
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[689, 390],
"Elm.Win.title":["New profile..."],
"Elm.Win.modal":[true]
},
"Contains":["elm_bg4", "elm_box5"]
},
"elm_bg4":
{
"Desc":
{
"parent":"new_profile_win",
"class":"Elm.Bg"
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true]
}
},
"elm_box5":
{
"Desc":
{
"parent":"new_profile_win",
"class":"Elm.Box"
},
"Properties":
{
"Elm.Box.padding":[7, 0],
"Evas.Object.size_hint_weight":[1, 1],
"Evas.Object.size_hint_align":[-1, -1],
"Efl.Gfx.Base.size":[200, 200],
"Efl.Gfx.Base.visible":[true]
},
"Contains":["elm_box6", "elm_label1", "new_profile_command", "elm_label2", "new_profile_script", "elm_box4"]
},
"elm_box4":
{
"Desc":
{
"parent":"elm_box5",
"class":"Elm.Box"
},
"Properties":
{
"Elm.Box.padding":[7, 0],
"Evas.Object.size_hint_weight":[1, 1],
"Evas.Object.size_hint_align":[-1, -1],
"Efl.Gfx.Base.size":[200, 200],
"Efl.Gfx.Base.visible":[true],
"Elm.Box.horizontal":[true]
},
"Contains":["new_profile_save_button", "new_profile_cancel_button"]
},
"new_profile_cancel_button":
{
"Desc":
{
"parent":"elm_box4",
"class":"Elm.Button",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[73, 30],
"Elm.Widget.part_text":[null, "Cancel"]
}
},
"new_profile_save_button":
{
"Desc":
{
"parent":"elm_box4",
"class":"Elm.Button",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[73, 30],
"Elm.Widget.part_text":[null, "Save"]
},
"Callbacks":
{
"clicked":["Invoke", "new_profile_save", null]
}
},
"elm_box6":
{
"Desc":
{
"parent":"elm_box5",
"class":"Elm.Box"
},
"Properties":
{
"Elm.Box.padding":[7, 0],
"Evas.Object.size_hint_weight":[1, 1],
"Evas.Object.size_hint_align":[-1, -1],
"Efl.Gfx.Base.size":[200, 200],
"Efl.Gfx.Base.visible":[true],
"Elm.Box.horizontal":[true]
},
"Contains":["new_profile_type_selector", "elm_label3", "new_profile_name"]
},
"new_profile_type_selector":
{
"Desc":
{
"parent":"elm_box6",
"class":"Elm.Hoversel",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[60, 40],
"Evas.Object.size_hint_align":[0, 0.50],
"Elm.Widget.part_text":[null, "Choose the profile type"]
}
},
"elm_label3":
{
"Desc":
{
"parent":"elm_box6",
"class":"Elm.Label"
},
"Properties":
{
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[60, 30],
"Evas.Object.size_hint_align":[1, -1],
"Elm.Widget.part_text":[null, "Name: "],
"Evas.Object.size_hint_weight":[0, 1]
}
},
"new_profile_name":
{
"Desc":
{
"parent":"elm_box6",
"class":"Elm.Entry",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_align":[-1, -1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[65, 35],
"Elm.Entry.scrollable":[true],
"Elm.Entry.single_line":[true],
"Evas.Object.size_hint_weight":[4, 1],
"Elm.Entry.editable":[true],
"Elm.Widget.part_text":[null, ""]
}
},
"elm_label1":
{
"Desc":
{
"parent":"elm_box5",
"class":"Elm.Label"
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[115, 30],
"Efl.Gfx.Base.position":[847, 0],
"Elm.Widget.part_text":[null, "Command: "],
"Evas.Object.size_hint_align":[0, 2]
}
},
"new_profile_command":
{
"Desc":
{
"parent":"elm_box5",
"class":"Elm.Entry",
"public":true
},
"Properties":
{
"Elm.Entry.scrollable":[true],
"Evas.Object.size_hint_align":[-1, -1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[65, 35],
"Elm.Entry.single_line":[true],
"Evas.Object.size_hint_weight":[1, 2],
"Elm.Widget.disabled":[true]
}
},
"elm_label2":
{
"Desc":
{
"parent":"elm_box5",
"class":"Elm.Label"
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[60, 30],
"Evas.Object.size_hint_align":[0, 1],
"Elm.Widget.part_text":[null, "Script: "]
}
},
"new_profile_script":
{
"Desc":
{
"parent":"elm_box5",
"class":"Elm.Entry",
"public":true
},
"Properties":
{
"Elm.Entry.scrollable":[true],
"Evas.Object.size_hint_align":[-1, -1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[65, 35],
"Evas.Object.size_hint_weight":[1, 8],
"Elm.Widget.disabled":[true]
}
},
"screenshot_button":
{
"Desc":
{
"parent":null,
"class":"Elm.Button",
"public":true
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[73, 30]
},
"Callbacks":
{
"clicked":["Invoke", "screenshot_request", null]
},
"Contains":
{
"elm_icon1":["icon"]
}
},
"elm_icon1":
{
"Desc":
{
"parent":"screenshot_button",
"class":"Elm.Icon"
},
"Properties":
{
"Evas.Object.size_hint_weight":[1, 1],
"Efl.Gfx.Base.visible":[true],
"Efl.Gfx.Base.size":[40, 40],
"Efl.File.file":["SCREENSHOT_ICON", null]
}
}
}
}

View File

@ -1,139 +0,0 @@
#ifndef EFL_BETA_API_SUPPORT
#define EFL_BETA_API_SUPPORT
#endif
#ifndef EFL_EO_API_SUPPORT
#define EFL_EO_API_SUPPORT
#endif
#ifndef ELM_INTERNAL_API_ARGESFSDFEFC
#define ELM_INTERNAL_API_ARGESFSDFEFC
#endif
#include <Elementary.h>
#include "gui.h"
extern void
conn_menu_show(void *data, Evas_Object *obj, void *event_info);
extern void
save_load_perform(void *data, Evas_Object *obj, void *event_info);
extern void
remote_port_entry_changed(void *data, Evas_Object *obj, void *event_info);
static void
_pubs_free_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
free(data);
}
Gui_Main_Win_Widgets *
gui_main_win_create(Eo *__main_parent)
{
Gui_Main_Win_Widgets *pub_widgets = calloc(1, sizeof(*pub_widgets));
Eo *main_win;
Eo *bg;
Eo *main_box, *ext_box;
Eo *tb;
Eo *ext_selector;
Eo *freeze_pulse;
Eo *freeze_inwin;
main_win = elm_win_add(__main_parent, "Window", ELM_WIN_BASIC);
pub_widgets->main_win = main_win;
elm_win_autodel_set(main_win, EINA_TRUE);
elm_win_title_set(main_win, "Clouseau");
efl_gfx_entity_size_set(main_win, EINA_SIZE2D(478, 484));
bg = elm_bg_add(main_win);
evas_object_size_hint_weight_set(bg, 1.000000, 1.000000);
efl_gfx_entity_visible_set(bg, EINA_TRUE);
efl_gfx_entity_position_set(bg, EINA_POSITION2D(0, 0));
elm_win_resize_object_add(main_win, bg);
main_box = elm_box_add(main_win);
evas_object_size_hint_weight_set(main_box, 1.000000, 1.000000);
efl_gfx_entity_visible_set(main_box, EINA_TRUE);
elm_win_resize_object_add(main_win, main_box);
tb = elm_toolbar_add(main_win);
elm_toolbar_shrink_mode_set(tb, ELM_TOOLBAR_SHRINK_MENU);
evas_object_size_hint_weight_set(tb, 0, 0);
evas_object_size_hint_align_set(tb, -1, 0);
elm_toolbar_menu_parent_set(tb, main_win);
pub_widgets->conn_selector = elm_toolbar_item_append(tb, "call-start", "Connection", NULL, NULL);
elm_toolbar_item_menu_set(pub_widgets->conn_selector, EINA_TRUE);
pub_widgets->conn_selector_menu = elm_toolbar_item_menu_get(pub_widgets->conn_selector);
pub_widgets->apps_selector = elm_toolbar_item_append(tb, "view-list-details", "Select App", NULL, NULL);
elm_toolbar_item_menu_set(pub_widgets->apps_selector, EINA_TRUE);
pub_widgets->apps_selector_menu = elm_toolbar_item_menu_get(pub_widgets->apps_selector);
pub_widgets->save_load_bt = elm_toolbar_item_append(tb, "document-export", "Save", save_load_perform, NULL);
ext_selector = elm_toolbar_item_append(tb, "system-reboot", "Extensions", NULL, NULL);
elm_toolbar_item_menu_set(ext_selector, EINA_TRUE);
pub_widgets->ext_selector_menu = elm_toolbar_item_menu_get(ext_selector);
/*
Eo *settings_it = elm_toolbar_item_append(tb, "system-run", "Settings", NULL, NULL);
elm_toolbar_item_menu_set(settings_it, EINA_TRUE);
*/
elm_box_pack_end(main_box, tb);
efl_gfx_entity_visible_set(tb, EINA_TRUE);
freeze_pulse = elm_progressbar_add(main_win);
pub_widgets->freeze_pulse = freeze_pulse;
elm_object_style_set(freeze_pulse, "wheel");
elm_object_text_set(freeze_pulse, "Style: wheel");
elm_progressbar_pulse_set(freeze_pulse, EINA_TRUE);
elm_progressbar_pulse(freeze_pulse, EINA_FALSE);
evas_object_size_hint_align_set(freeze_pulse, 0.5, 0.0);
evas_object_size_hint_weight_set(freeze_pulse, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(main_win, freeze_pulse);
ext_box = elm_box_add(main_box);
pub_widgets->ext_box = ext_box;
evas_object_size_hint_weight_set(ext_box, 1.000000, 1.000000);
evas_object_size_hint_align_set(ext_box, -1.000000, -1.000000);
efl_gfx_entity_visible_set(ext_box, EINA_TRUE);
elm_box_pack_end(main_box, ext_box);
freeze_inwin = elm_win_inwin_add(main_win);
pub_widgets->freeze_inwin = freeze_inwin;
elm_object_style_set(freeze_inwin, "minimal");
efl_gfx_entity_visible_set(main_win, EINA_TRUE);
efl_event_callback_add(main_win, EFL_EVENT_DEL, _pubs_free_cb, pub_widgets);
return pub_widgets;
}
Gui_Remote_Port_Win_Widgets *
gui_remote_port_win_create(Eo *__main_parent)
{
Gui_Remote_Port_Win_Widgets *pub_widgets = calloc(1, sizeof(*pub_widgets));
Eo *inwin;
Eo *entry;
inwin = elm_win_inwin_add(__main_parent);
pub_widgets->inwin = inwin;
entry = elm_entry_add(inwin);
elm_entry_scrollable_set(entry, EINA_TRUE);
elm_entry_single_line_set(entry, EINA_TRUE);
elm_object_part_text_set(entry, "guide", "Port to connect to remote device");
evas_object_smart_callback_add(entry, "activated", remote_port_entry_changed, inwin);
evas_object_show(entry);
elm_win_inwin_content_set(inwin, entry);
elm_win_inwin_activate(inwin);
efl_event_callback_add(inwin, EFL_EVENT_DEL, _pubs_free_cb, pub_widgets);
return pub_widgets;
}

View File

@ -1,33 +0,0 @@
#ifndef _gui_h_
#define _gui_h_
#include <Eo.h>
#include <Elementary.h>
typedef struct
{
Eo *main_win;
Eo *ext_box;
Eo *conn_selector;
Eo *conn_selector_menu;
Eo *apps_selector;
Eo *apps_selector_menu;
Eo *save_load_bt;
Eo *ext_selector_menu;
Eo *freeze_pulse;
Eo *freeze_inwin;
} Gui_Main_Win_Widgets;
typedef struct
{
Eo *inwin;
Eo *cancel_button;
Eo *save_button;
Eo *name_entry;
Eo *port_entry;
} Gui_Remote_Port_Win_Widgets;
Gui_Main_Win_Widgets *gui_main_win_create(Eo *parent);
Gui_Remote_Port_Win_Widgets *gui_remote_port_win_create(Eo *parent);
#endif

View File

@ -1,28 +0,0 @@
set(CMAKE_BUILD_TYPE Debug)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${EINA_INCLUDE_DIRS}
${EOLIAN_INCLUDE_DIRS}
${EO_INCLUDE_DIRS}
${FFI_INCLUDE_DIRS}
${EVAS_INCLUDE_DIRS}
${ELEMENTARY_INCLUDE_DIRS}
)
add_library(clouseau_debug SHARED clouseau_debug.c)
target_link_libraries(clouseau_debug
${EINA_LIBRARIES}
${EO_LIBRARIES}
${EOLIAN_LIBRARIES}
${EVAS_LIBRARIES}
${ELEMENTARY_LIBRARIES}
${FFI_LIBRARIES}
)
INSTALL(FILES Clouseau.h DESTINATION include)
INSTALL(TARGETS clouseau_debug LIBRARY DESTINATION lib)
add_subdirectory(extensions)

View File

@ -1,61 +1,160 @@
#ifndef _CLOUSEAU_H
#define _CLOUSEAU_H
#ifndef _LIBCLOUSEAU_H
#define _LIBCLOUSEAU_H
#ifdef EAPI
# undef EAPI
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
# ifdef DEBUG_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! DEBUG_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
#include <Elementary.h>
#include <Eina.h>
#define ELM_INTERNAL_API_ARGESFSDFEFC
#include <elm_widget.h>
typedef struct _Extension_Config Extension_Config;
typedef struct _Clouseau_Extension Clouseau_Extension;
typedef struct _Clouseau_Evas_Props Clouseau_Evas_Props;
typedef struct _Clouseau_Evas_Text_Props Clouseau_Evas_Text_Props;
typedef struct _Clouseau_Evas_Image_Props Clouseau_Evas_Image_Props;
typedef struct _Clouseau_Elm_Props Clouseau_Elm_Props;
typedef struct _Clouseau_Edje_Props Clouseau_Edje_Props;
typedef struct _Clouseau_Evas_Map_Point_Props Clouseau_Evas_Map_Point_Props;
typedef Eo *(*Ui_Get_Cb)(Clouseau_Extension *ext, Eo *parent);
typedef void (*Session_Changed_Cb)(Clouseau_Extension *ext);
typedef void (*App_Changed_Cb)(Clouseau_Extension *ext);
typedef void (*Import_Data_Cb)(Clouseau_Extension *ext, void *buffer, int size, int version);
typedef void *(*Export_Data_Cb)(Clouseau_Extension *ext, int *size, int *version);
typedef struct _Clouseau_Extra_Props Clouseau_Extra_Props;
typedef struct _Clouseau_Object Clouseau_Object;
typedef struct _Clouseau_Bitmap Clouseau_Bitmap;
typedef Eo *(*Inwin_Create_Cb)();
typedef void (*Ui_Freeze_Cb)(Clouseau_Extension *ext, Eina_Bool freeze);
typedef struct _Clouseau_Tree_Item Clouseau_Tree_Item;
struct _Clouseau_Extension
{
const char *name; /* Name filled by the extension */
Eina_Debug_Session *session; /* Current session */
int app_id; /* Current application */
Eina_Stringshare *path_to_config; /* Path to configuration directory */
Eo *ui_object; /* Main object of the UI extension */
Session_Changed_Cb session_changed_cb; /* Function called when the session changed */
App_Changed_Cb app_changed_cb; /* Function called when the app changed */
Import_Data_Cb import_data_cb; /* Function called when data has to be imported */
Export_Data_Cb export_data_cb; /* Function called when data has to be exported */
Inwin_Create_Cb inwin_create_cb; /* Function to call to create a Inwin */
Ui_Freeze_Cb ui_freeze_cb; /* Function to call to freeze/thaw the UI */
void *data; /* Data allocated and managed by the extension */
Extension_Config *ext_cfg; /* Extention configuration - used by Clouseau */
/* The color of the highlight */
enum {
HIGHLIGHT_R = 255,
HIGHLIGHT_G = 128,
HIGHLIGHT_B = 128,
HIGHLIGHT_A = 255,
/* How much padding around the highlight box.
* Currently we don't want any. */
PADDING = 0,
};
typedef enum
{
CLOUSEAU_OBJ_TYPE_UNKNOWN,
CLOUSEAU_OBJ_TYPE_OTHER,
CLOUSEAU_OBJ_TYPE_ELM,
CLOUSEAU_OBJ_TYPE_TEXT,
CLOUSEAU_OBJ_TYPE_IMAGE,
CLOUSEAU_OBJ_TYPE_EDJE,
CLOUSEAU_OBJ_TYPE_TEXTBLOCK
} Clouseau_Object_Type;
struct _Clouseau_Evas_Map_Point_Props
{
Evas_Coord x, y, z;
};
struct _Clouseau_Evas_Props
{
const char *name;
const char *bt;
short layer;
Evas_Coord x, y, w, h;
double scale;
Evas_Coord min_w, min_h, max_w, max_h, req_w, req_h;
double align_x, align_y;
double weight_x, weight_y;
int r, g, b, a;
Eina_Bool pass_events;
Eina_Bool repeat_events;
Eina_Bool propagate_events;
Eina_Bool has_focus;
Eina_Bool is_clipper;
Eina_Bool is_visible;
Evas_Object_Pointer_Mode mode;
Clouseau_Evas_Map_Point_Props *points;
int points_count;
unsigned long long clipper;
};
struct _Clouseau_Evas_Text_Props
{
const char *font;
int size;
const char *source;
const char *text;
};
struct _Clouseau_Evas_Image_Props
{
const char *file, *key;
void *source;
const char *load_err;
};
struct _Clouseau_Evas_Textblock_Props
{
const char *style;
const char *text;
};
typedef struct _Clouseau_Evas_Textblock_Props Clouseau_Evas_Textblock_Props;
struct _Clouseau_Edje_Props
{
const char *file, *group;
const char *load_err;
};
struct _Clouseau_Elm_Props
{
const char *type;
const char *style;
double scale;
Eina_Bool has_focus;
Eina_Bool is_disabled;
Eina_Bool is_mirrored;
Eina_Bool is_mirrored_automatic;
};
struct _Clouseau_Extra_Props
{ /* as Example_Union */
Clouseau_Object_Type type;
union {
Clouseau_Elm_Props elm;
Clouseau_Evas_Text_Props text;
Clouseau_Evas_Image_Props image;
Clouseau_Edje_Props edje;
Clouseau_Evas_Textblock_Props textblock;
} u;
};
struct _Clouseau_Object
{
Clouseau_Evas_Props evas_props;
Clouseau_Extra_Props extra_props;
};
struct _Clouseau_Bitmap
{
unsigned char *bmp;
int bmp_count; /* is (w * h), for EET_DATA_DESCRIPTOR_ADD_BASIC_VAR_ARRAY */
Evas_Coord w;
Evas_Coord h;
};
struct _Clouseau_Tree_Item
{
Eina_List *children;
const char *name;
unsigned long long ptr; /* Just a ptr, we keep the value but not accessing mem */
Clouseau_Object *info;
Eina_Bool is_obj;
Eina_Bool is_clipper;
Eina_Bool is_visible;
};
Eet_Data_Descriptor *clouseau_object_desc_make(void);
void clouseau_object_desc_shutdown(void);
void clouseau_object_information_list_clear(void);
/* Public */
EAPI Evas_Object *clouseau_object_information_list_add(Evas_Object *parent);
EAPI void clouseau_object_information_list_populate(Clouseau_Tree_Item *treeit, Evas_Object *lb);
#endif

View File

@ -1,178 +0,0 @@
#ifndef _CLOUSEAU_DEBUG_H
#define _CLOUSEAU_DEBUG_H
#ifdef EAPI
# undef EAPI
#endif
#ifdef _WIN32
# ifdef DEBUG_BUILD
# ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif /* ! DLL_EXPORT */
# else
# define EAPI __declspec(dllimport)
# endif /* ! DEBUG_BUILD */
#else
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
#endif /* ! _WIN32 */
#define EOLIAN_DEBUG_MAXARGS 15
#include <Eo.h>
#include <Eolian.h>
#include <Elementary.h>
typedef void (*Eo_Debug_Class_Extract_Cb)(void *data, uint64_t kl, char *kl_name);
typedef void (*Eo_Debug_Object_Extract_Cb)(void *data, uint64_t obj, uint64_t kl, uint64_t parent);
typedef enum
{
EOLIAN_DEBUG_INVALID_TYPE = 0,
EOLIAN_DEBUG_POINTER,
EOLIAN_DEBUG_STRING,
EOLIAN_DEBUG_CHAR,
EOLIAN_DEBUG_INT,
EOLIAN_DEBUG_SHORT,
EOLIAN_DEBUG_DOUBLE,
EOLIAN_DEBUG_BOOLEAN,
EOLIAN_DEBUG_LONG,
EOLIAN_DEBUG_UINT,
EOLIAN_DEBUG_LIST,
EOLIAN_DEBUG_OBJECT,
EOLIAN_DEBUG_VOID,
EOLIAN_DEBUG_STRUCT
} Eolian_Debug_Basic_Type;
typedef struct
{
Eolian_Debug_Basic_Type type;
uint64_t value;
Eina_List *complex_type_values;
} Eolian_Debug_Value;
typedef struct
{
Eolian_Debug_Value value;
const Eolian_Function_Parameter *eparam;
} Eolian_Debug_Parameter;
typedef struct
{
Eolian_Debug_Value value;
const Eolian_Type *etype;
} Eolian_Debug_Return;
typedef struct
{
const Eolian_Function *efunc;
Eolian_Debug_Return ret;
Eina_List *params; /* List of Eolian_Debug_Parameter * */
} Eolian_Debug_Function;
typedef struct
{
const Eolian_Unit *unit;
const Eolian_Class *ekl;
Eina_List *functions; /* List of Eolian_Debug_Function * */
} Eolian_Debug_Class;
typedef struct
{
uint64_t obj; /* Eo * */
Eina_List *classes; /* List of Eolian_Debug_Class * */
} Eolian_Debug_Object_Information;
typedef struct
{
uint64_t obj;
int w;
int h;
char *img;
int img_size;
int tm_sec;
int tm_min;
int tm_hour;
} Evas_Debug_Screenshot;
typedef struct {
Eo *redirect_manager;
Eo *focused;
const char *class_name;
Eina_List *relations;
} Clouseau_Focus_Manager_Data;
typedef struct {
Efl_Ui_Focus_Relations relation;
const char *class_name;
Evas_Object *vis;
} Clouseau_Focus_Relation;
typedef struct {
uintptr_t ptr;
const char *helper_name;
} Clouseau_Focus_List_Item;
typedef struct {
Eina_List *managers;
} Clouseau_Focus_Managers;
EAPI void *eo_debug_eoids_request_prepare(int *size, ...);
EAPI void eo_debug_klids_extract(void *buffer, int size, Eo_Debug_Class_Extract_Cb cb, void *data);
EAPI void eo_debug_eoids_extract(void *buffer, int size, Eo_Debug_Object_Extract_Cb cb, void *data);
EAPI void eolian_debug_object_information_free(Eolian_Debug_Object_Information *main);
EAPI Eolian_Debug_Object_Information *
eolian_debug_object_information_decode(char *buffer, unsigned int size);
EAPI Evas_Debug_Screenshot *
evas_debug_screenshot_decode(char *buffer, unsigned int size);
typedef struct
{
Eina_Debug_Session *session;
int srcid;
void *buffer;
unsigned int size;
} Main_Loop_Info;
#define WRAPPER_TO_XFER_MAIN_LOOP(foo) \
static void \
_intern_main_loop ## foo(void *data) \
{ \
Main_Loop_Info *info = data; \
_main_loop ## foo(info->session, info->srcid, info->buffer, info->size); \
free(info->buffer); \
free(info); \
} \
static Eina_Bool \
foo(Eina_Debug_Session *session, int srcid, void *buffer, int size) \
{ \
Main_Loop_Info *info = calloc(1, sizeof(*info)); \
info->session = session; \
info->srcid = srcid; \
info->size = size; \
if (info->size) \
{ \
info->buffer = malloc(info->size); \
memcpy(info->buffer, buffer, info->size); \
} \
ecore_main_loop_thread_safe_call_async(_intern_main_loop ## foo, info); \
return EINA_TRUE; \
}
#endif

35
src/lib/Makefile.am Normal file
View File

@ -0,0 +1,35 @@
MAINTAINERCLEANFILES = Makefile.in
AM_CPPFLAGS = \
-I$(top_srcdir)/src/include \
-I$(top_builddir)/src/include \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EFL_CFLAGS@
EXTRA_DIST = \
Clouseau.h \
clouseau_private.h
pkgdir = $(libdir)/clouseau
pkg_LTLIBRARIES = libclouseau.la libclouseau_client.la
libclouseau_la_SOURCES = \
clouseau_client.c \
clouseau_object_information.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.c
libclouseau_client_la_DEPENDENCIES = $(top_builddir)/config.h
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@

447
src/lib/clouseau_client.c Normal file
View File

@ -0,0 +1,447 @@
#include "Clouseau.h"
#include <dlfcn.h>
#include <execinfo.h>
#include <Ecore_Ipc.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 int _connect_to_daemon(void);
/**************************************************************************/
/* This is an attempt to somehow replicate what's available in new versions
* of clouseau. I.e the module interface. */
static int _clouseau_init_count = 0;
static char *_module_my_app_name = NULL;
EAPI Eina_Bool
clouseau_app_connect(const char *appname)
{
_my_app_name = _module_my_app_name = strdup(appname);
if(!_connect_to_daemon())
{
printf("Failed to connect to server.\n");
return EINA_FALSE;
}
return EINA_TRUE;
}
EAPI int
clouseau_init(void)
{
if (++_clouseau_init_count == 1)
{
eina_init();
ecore_init();
ecore_con_init();
clouseau_data_init();
}
return _clouseau_init_count;
}
EAPI int
clouseau_shutdown(void)
{
if (--_clouseau_init_count == 0)
{
clouseau_data_shutdown();
ecore_con_shutdown();
ecore_shutdown();
eina_shutdown();
free(_module_my_app_name);
_my_app_name = _module_my_app_name = NULL;
}
else if (_clouseau_init_count < 0)
{
_clouseau_init_count = 0;
printf("Tried to shutdown although not initiated.\n");
}
return _clouseau_init_count;
}
/***************************** END OF EINA MODULE *************************/
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() */
}
static Eina_Bool
_add(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Ipc_Event_Server_Add *ev)
{
void *p;
int size = 0;
ecore_ipc_server_data_size_max_set(ev->server, -1);
connect_st t = { getpid(), _my_app_name };
p = clouseau_data_packet_compose(CLOUSEAU_APP_CLIENT_CONNECT,
&t, sizeof(t), &size, NULL, 0);
if (p)
{
ecore_ipc_server_send(ev->server, 0,0,0,0,EINA_FALSE, p, size);
ecore_ipc_server_flush(ev->server);
free(p);
}
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_del(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Ipc_Event_Server_Del *ev)
{
if (!ev->server)
{
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_ipc_server_ip_get(ev->server));
ecore_ipc_server_del(ev->server);
ecore_main_loop_quit();
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_data(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Ipc_Event_Server_Data *ev)
{
Variant_st *v;
v = clouseau_data_packet_info_get(ev->data, ev->size);
switch (clouseau_data_packet_mapping_type_get(v->type))
{
case CLOUSEAU_DATA_REQ:
{ /* data req includes ptr to GUI, to tell which client asking */
int size = 0;
data_req_st *req = v->data;
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 */
void *p = clouseau_data_packet_compose(CLOUSEAU_TREE_DATA,
&t, sizeof(t), &size, NULL, 0);
if (p)
{
ecore_ipc_server_send(ev->server, 0,0,0,0,
EINA_FALSE, p, size);
ecore_ipc_server_flush(ev->server);
free(p);
}
clouseau_data_tree_free(t.tree);
}
}
break;
case CLOUSEAU_HIGHLIGHT:
{ /* Highlight msg contains PTR of object to highlight */
highlight_st *ht = v->data;
Evas_Object *obj = (Evas_Object *) (uintptr_t) ht->object;
clouseau_data_object_highlight(obj, NULL, NULL);
}
break;
case CLOUSEAU_BMP_REQ:
{ /* Bitmap req msg contains PTR of Ecore Evas */
bmp_req_st *req = v->data;
Evas_Coord w, h;
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,
&t, sizeof(t), &size, bmp, (w * h * sizeof(int)));
if (p)
{
ecore_ipc_server_send(ev->server, 0,0,0,0,
EINA_FALSE, p, size);
ecore_ipc_server_flush(ev->server);
free(p);
}
if (bmp)
free(bmp);
}
break;
default:
break;
}
clouseau_data_variant_free(v);
return ECORE_CALLBACK_RENEW;
}
static int
_connect_to_daemon(void)
{
Ecore_Ipc_Server *svr;
const char *address = LOCALHOST;
eina_init();
ecore_init();
ecore_ipc_init();
svr = ecore_ipc_server_connect(ECORE_IPC_REMOTE_SYSTEM,
LOCALHOST, PORT, NULL);
if (!svr)
{
printf("could not connect to the server: %s, port %d.\n",
address, PORT);
return EINA_FALSE;
}
ecore_ipc_server_data_size_max_set(svr, -1);
/* set event handler for server connect */
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD,
(Ecore_Event_Handler_Cb)_add, NULL);
/* set event handler for server disconnect */
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL,
(Ecore_Event_Handler_Cb)_del, NULL);
/* set event handler for receiving server data */
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA,
(Ecore_Event_Handler_Cb)_data, NULL);
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)
{
int (*_elm_init)(int, char **) = dlsym(RTLD_NEXT, __func__);
setenv("ELM_CLOUSEAU", "0", 1);
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_init();
if (!clouseau_app_connect(_my_app_name))
{
printf("Failed to connect to server.\n");
return;
}
_ecore_main_loop_begin();
clouseau_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);
}

1077
src/lib/clouseau_data.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,69 +0,0 @@
static void
_init_manager_details_descriptors(void)
{
Eet_Data_Descriptor_Class klass;
Eet_Data_Descriptor *relations_eed;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&klass, Clouseau_Focus_Relation);
relations_eed = eet_data_descriptor_file_new(&klass);
#define BASIC(field, type) EET_DATA_DESCRIPTOR_ADD_BASIC(relations_eed, Clouseau_Focus_Relation, #field , field, type)
BASIC(class_name, EET_T_STRING);
BASIC(relation.next, EET_T_LONG_LONG);
BASIC(relation.prev, EET_T_LONG_LONG);
BASIC(relation.logical, EET_T_CHAR);
BASIC(relation.parent, EET_T_LONG_LONG);
BASIC(relation.redirect, EET_T_LONG_LONG);
BASIC(relation.node, EET_T_LONG_LONG);
BASIC(relation.position_in_history, EET_T_INT);
#undef BASIC
#define LIST(field, type) EET_DATA_DESCRIPTOR_ADD_LIST(relations_eed, Clouseau_Focus_Relation, #field , field, type)
/*LIST(relation.right, EET_T_UINT);
LIST(relation.left, EET_T_UINT);
LIST(relation.top, EET_T_UINT);
LIST(relation.down, EET_T_UINT);*/
#undef LIST
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&klass, Clouseau_Focus_Manager_Data);
manager_details = eet_data_descriptor_file_new(&klass);
EET_DATA_DESCRIPTOR_ADD_BASIC(manager_details, Clouseau_Focus_Manager_Data, "redirect_manager", redirect_manager, EET_T_LONG_LONG);
EET_DATA_DESCRIPTOR_ADD_BASIC(manager_details, Clouseau_Focus_Manager_Data, "focused", focused, EET_T_LONG_LONG);
EET_DATA_DESCRIPTOR_ADD_BASIC(manager_details, Clouseau_Focus_Manager_Data, "class_name", class_name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_LIST(manager_details, Clouseau_Focus_Manager_Data, "relations", relations, relations_eed);
}
static void
_init_manager_list_descriptors(void)
{
Eet_Data_Descriptor_Class klass;
Eet_Data_Descriptor *detail_eed;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&klass, Clouseau_Focus_List_Item);
detail_eed = eet_data_descriptor_file_new(&klass);
#define BASIC(field, type) EET_DATA_DESCRIPTOR_ADD_BASIC(detail_eed, Clouseau_Focus_List_Item, #field , field, type)
BASIC(helper_name, EET_T_STRING);
BASIC(ptr, EET_T_LONG_LONG);
#undef BASIC
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&klass, Clouseau_Focus_Managers);
manager_list = eet_data_descriptor_file_new(&klass);
EET_DATA_DESCRIPTOR_ADD_LIST(manager_list, Clouseau_Focus_Managers, "managers", managers, detail_eed);
}
static void
_init_data_descriptors(void)
{
_init_manager_list_descriptors();
_init_manager_details_descriptors();
}

View File

@ -0,0 +1,643 @@
#include "Clouseau.h"
typedef struct _Inf_Clouseau_Tree_Item Inf_Clouseau_Tree_Item;
struct _Inf_Clouseau_Tree_Item
{
Eina_List *children;
Evas_Object *icon;
const char *string;
};
static Eina_List *information_tree = NULL;
static Evas_Object *prop_list = NULL;
static Elm_Genlist_Item_Class itc;
static void
_gl_selected(void *data EINA_UNUSED, Evas_Object *pobj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
/* Currently do nothing */
return;
}
static void
gl_exp(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Elm_Object_Item *glit = event_info;
Inf_Clouseau_Tree_Item *parent = elm_object_item_data_get(glit);
Inf_Clouseau_Tree_Item *tit;
Eina_List *itr;
EINA_LIST_FOREACH(parent->children, itr, tit)
{
Elm_Genlist_Item_Type iflag = (tit->children) ?
ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE;
elm_genlist_item_append(prop_list, &itc, tit, glit,
iflag, _gl_selected, NULL);
}
}
static void
gl_con(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Elm_Object_Item *glit = event_info;
elm_genlist_item_subitems_clear(glit);
}
static void
gl_exp_req(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Elm_Object_Item *glit = event_info;
elm_genlist_item_expanded_set(glit, EINA_TRUE);
}
static void
gl_con_req(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Elm_Object_Item *glit = event_info;
elm_genlist_item_expanded_set(glit, EINA_FALSE);
}
static Evas_Object *
item_icon_get(void *data EINA_UNUSED, Evas_Object *parent EINA_UNUSED,
const char *part EINA_UNUSED)
{
return NULL;
}
static char *
item_text_get(void *data, Evas_Object *obj EINA_UNUSED,
const char *part EINA_UNUSED)
{
Inf_Clouseau_Tree_Item *tit = data;
return strdup(tit->string);
}
EAPI Evas_Object *
clouseau_object_information_list_add(Evas_Object *parent)
{
prop_list = elm_genlist_add(parent);
itc.item_style = "default";
itc.func.text_get = item_text_get;
itc.func.content_get = item_icon_get;
itc.func.state_get = NULL;
itc.func.del = NULL;
evas_object_smart_callback_add(prop_list, "expand,request", gl_exp_req,
prop_list);
evas_object_smart_callback_add(prop_list, "contract,request", gl_con_req,
prop_list);
evas_object_smart_callback_add(prop_list, "expanded", gl_exp, prop_list);
evas_object_smart_callback_add(prop_list, "contracted", gl_con, prop_list);
evas_object_smart_callback_add(prop_list, "selected", _gl_selected, NULL);
return prop_list;
}
static void
_clouseau_item_tree_item_free(Inf_Clouseau_Tree_Item *parent)
{
Inf_Clouseau_Tree_Item *treeit;
EINA_LIST_FREE(parent->children, treeit)
{
_clouseau_item_tree_item_free(treeit);
}
eina_stringshare_del(parent->string);
free(parent);
}
static void
_clouseau_item_tree_free(void)
{
Inf_Clouseau_Tree_Item *treeit;
EINA_LIST_FREE(information_tree, treeit)
{
_clouseau_item_tree_item_free(treeit);
}
}
EAPI void
clouseau_object_information_free(Clouseau_Object *oinfo)
{
if (!oinfo)
return;
eina_stringshare_del(oinfo->evas_props.name);
eina_stringshare_del(oinfo->evas_props.bt);
if (oinfo->evas_props.points)
free(oinfo->evas_props.points);
switch (oinfo->extra_props.type)
{
case CLOUSEAU_OBJ_TYPE_ELM:
eina_stringshare_del(oinfo->extra_props.u.elm.type);
eina_stringshare_del(oinfo->extra_props.u.elm.style);
break;
case CLOUSEAU_OBJ_TYPE_TEXT:
eina_stringshare_del(oinfo->extra_props.u.text.font);
eina_stringshare_del(oinfo->extra_props.u.text.source);
eina_stringshare_del(oinfo->extra_props.u.text.text);
break;
case CLOUSEAU_OBJ_TYPE_IMAGE:
eina_stringshare_del(oinfo->extra_props.u.image.file);
eina_stringshare_del(oinfo->extra_props.u.image.key);
eina_stringshare_del(oinfo->extra_props.u.image.load_err);
break;
case CLOUSEAU_OBJ_TYPE_EDJE:
eina_stringshare_del(oinfo->extra_props.u.edje.file);
eina_stringshare_del(oinfo->extra_props.u.edje.group);
eina_stringshare_del(oinfo->extra_props.u.edje.load_err);
break;
case CLOUSEAU_OBJ_TYPE_TEXTBLOCK:
eina_stringshare_del(oinfo->extra_props.u.textblock.style);
eina_stringshare_del(oinfo->extra_props.u.textblock.text);
break;
case CLOUSEAU_OBJ_TYPE_UNKNOWN:
case CLOUSEAU_OBJ_TYPE_OTHER:
break;
}
free(oinfo);
}
EAPI Clouseau_Object *
clouseau_object_information_get(Clouseau_Tree_Item *treeit)
{
Clouseau_Object *oinfo;
Evas_Object *obj = (void*) (uintptr_t) treeit->ptr;
const Evas_Map *map = NULL;
if (!treeit->is_obj)
return NULL;
oinfo = calloc(1, sizeof(Clouseau_Object));
oinfo->evas_props.pass_events = evas_object_pass_events_get(obj);
oinfo->evas_props.repeat_events = evas_object_repeat_events_get(obj);
oinfo->evas_props.propagate_events = evas_object_propagate_events_get(obj);
oinfo->evas_props.has_focus = evas_object_focus_get(obj);
oinfo->evas_props.is_visible = evas_object_visible_get(obj);
oinfo->evas_props.name = eina_stringshare_add(evas_object_name_get(obj));
oinfo->evas_props.layer = evas_object_layer_get(obj);
evas_object_geometry_get(obj, &oinfo->evas_props.x, &oinfo->evas_props.y,
&oinfo->evas_props.w, &oinfo->evas_props.h);
oinfo->evas_props.scale = evas_object_scale_get(obj);
evas_object_size_hint_min_get(obj, &oinfo->evas_props.min_w,
&oinfo->evas_props.min_h);
evas_object_size_hint_max_get(obj, &oinfo->evas_props.max_w,
&oinfo->evas_props.max_h);
evas_object_size_hint_request_get(obj, &oinfo->evas_props.req_w,
&oinfo->evas_props.req_h);
evas_object_size_hint_align_get(obj, &oinfo->evas_props.align_x,
&oinfo->evas_props.align_y);
evas_object_size_hint_weight_get(obj, &oinfo->evas_props.weight_x,
&oinfo->evas_props.weight_y);
evas_object_color_get(obj, &oinfo->evas_props.r, &oinfo->evas_props.g,
&oinfo->evas_props.b, &oinfo->evas_props.a);
oinfo->evas_props.mode = evas_object_pointer_mode_get(obj);
oinfo->evas_props.is_clipper = !!evas_object_clipees_get(obj);
oinfo->evas_props.clipper = (uintptr_t) evas_object_clip_get(obj);
oinfo->evas_props.bt = eina_stringshare_ref(evas_object_data_get(obj, ".clouseau.bt"));
map = evas_object_map_get(obj);
if (map)
{ /* Save map coords count info if object has map */
oinfo->evas_props.points_count = evas_map_count_get(map);
if (oinfo->evas_props.points_count)
{
int i;
Clouseau_Evas_Map_Point_Props *p;
oinfo->evas_props.points = calloc(oinfo->evas_props.points_count,
sizeof(Clouseau_Evas_Map_Point_Props));
for(i = 0 ; i < oinfo->evas_props.points_count; i++)
{
p = &oinfo->evas_props.points[i];
evas_map_point_coord_get(map, i, &p->x, &p->y, &p->z);
}
}
}
if (elm_widget_is(obj))
{
oinfo->extra_props.type = CLOUSEAU_OBJ_TYPE_ELM;
oinfo->extra_props.u.elm.type =
eina_stringshare_add(elm_widget_type_get(obj));
oinfo->extra_props.u.elm.style =
eina_stringshare_add(elm_widget_style_get(obj));
oinfo->extra_props.u.elm.scale = elm_widget_scale_get(obj);
oinfo->extra_props.u.elm.has_focus = elm_object_focus_get(obj);
oinfo->extra_props.u.elm.is_disabled = elm_widget_disabled_get(obj);
oinfo->extra_props.u.elm.is_mirrored = elm_widget_mirrored_get(obj);
oinfo->extra_props.u.elm.is_mirrored_automatic =
elm_widget_mirrored_automatic_get(obj);
}
else if (!strcmp("text", evas_object_type_get(obj)))
{
const char *font;
int size;
oinfo->extra_props.type = CLOUSEAU_OBJ_TYPE_TEXT;
evas_object_text_font_get(obj, &font, &size);
oinfo->extra_props.u.text.font = eina_stringshare_add(font);
oinfo->extra_props.u.text.size = size;
oinfo->extra_props.u.text.source =
eina_stringshare_add(evas_object_text_font_source_get(obj));
oinfo->extra_props.u.text.text = eina_stringshare_add(evas_object_text_text_get(obj));
}
else if (!strcmp("image", evas_object_type_get(obj)))
{
const char *file, *key;
oinfo->extra_props.type = CLOUSEAU_OBJ_TYPE_IMAGE;
evas_object_image_file_get(obj, &file, &key);
oinfo->extra_props.u.image.file = eina_stringshare_add(file);
oinfo->extra_props.u.image.key = eina_stringshare_add(key);
oinfo->extra_props.u.image.source = evas_object_image_source_get(obj);
if (evas_object_image_load_error_get(obj) != EVAS_LOAD_ERROR_NONE)
{
oinfo->extra_props.u.image.load_err = eina_stringshare_add(
evas_load_error_str(evas_object_image_load_error_get(obj)));
}
}
else if (!strcmp("edje", evas_object_type_get(obj)))
{
const char *file, *group;
oinfo->extra_props.type = CLOUSEAU_OBJ_TYPE_EDJE;
edje_object_file_get(obj, &file, &group);
oinfo->extra_props.u.edje.file = eina_stringshare_add(file);
oinfo->extra_props.u.edje.group = eina_stringshare_add(group);
if (edje_object_load_error_get(obj) != EDJE_LOAD_ERROR_NONE)
{
oinfo->extra_props.u.edje.load_err = eina_stringshare_add(
edje_load_error_str(edje_object_load_error_get(obj)));
}
}
else if (!strcmp("textblock", evas_object_type_get(obj)))
{
const char *style;
const char *text;
char shorttext[48];
const Evas_Textblock_Style *ts;
oinfo->extra_props.type = CLOUSEAU_OBJ_TYPE_TEXTBLOCK;
ts = evas_object_textblock_style_get(obj);
style = evas_textblock_style_get(ts);
text = evas_object_textblock_text_markup_get(obj);
strncpy(shorttext, text, 38);
if (shorttext[37])
strcpy(shorttext + 37, "\xe2\x80\xa6"); /* HORIZONTAL ELLIPSIS */
oinfo->extra_props.u.textblock.style = eina_stringshare_add(style);
oinfo->extra_props.u.textblock.text = eina_stringshare_add(shorttext);
}
else
{
oinfo->extra_props.type = CLOUSEAU_OBJ_TYPE_OTHER;
}
return oinfo;
}
static const struct {
const char *text;
Evas_Object_Pointer_Mode mode;
} pointer_mode[3] = {
# define POINTER_MODE(Value) { #Value, Value }
POINTER_MODE(EVAS_OBJECT_POINTER_MODE_AUTOGRAB),
POINTER_MODE(EVAS_OBJECT_POINTER_MODE_NOGRAB),
POINTER_MODE(EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)
# undef POINTER_MODE
};
static void
_clouseau_information_buffer_to_tree(Inf_Clouseau_Tree_Item *parent, const char *buffer)
{
Inf_Clouseau_Tree_Item *item;
item = calloc(1, sizeof (Inf_Clouseau_Tree_Item));
if (!item) return ;
item->string = eina_stringshare_add(buffer);
parent->children = eina_list_append(parent->children, item);
}
static void
_clouseau_information_string_to_tree(Inf_Clouseau_Tree_Item *parent, const char *name, const char *value)
{
char *buffer;
int length;
if (!value) return ;
length = strlen(name) + 5;
length += strlen(value);
buffer = alloca(length);
snprintf(buffer, length, "%s: '%s'", name, value);
_clouseau_information_buffer_to_tree(parent, buffer);
}
static void
_clouseau_information_geometry_to_tree(Inf_Clouseau_Tree_Item *parent, const char *name, int xw, int yh)
{
char *buffer;
int length;
length = strlen(name) + 4 + 20;
buffer = alloca(length);
snprintf(buffer, length, "%s: %d %d", name, xw, yh);
_clouseau_information_buffer_to_tree(parent, buffer);
}
static void
_clouseau_information_bool_to_tree(Inf_Clouseau_Tree_Item *parent, const char *name, Eina_Bool value)
{
_clouseau_information_string_to_tree(parent, name, value ? "EINA_TRUE" : "EINA_FALSE");
}
static void
_clouseau_information_double_to_tree(Inf_Clouseau_Tree_Item *parent, const char *name, double d)
{
char *buffer;
int length;
length = strlen(name) + 3 + 64;
buffer = alloca(length);
snprintf(buffer, length, "%s: %.6lg", name, d);
_clouseau_information_buffer_to_tree(parent, buffer);
}
static void
_clouseau_information_hint_to_tree(Inf_Clouseau_Tree_Item *parent, const char *name, double xw, double yh)
{
char *buffer;
int length;
length = strlen(name) + 3 + 128;
buffer = alloca(length);
snprintf(buffer, length, "%s: %.6lg %.61g", name, xw, yh);
_clouseau_information_buffer_to_tree(parent, buffer);
}
static const struct {
Clouseau_Object_Type type;
const char *name;
} _clouseau_types[] = {
{ CLOUSEAU_OBJ_TYPE_ELM, "Elementary" },
{ CLOUSEAU_OBJ_TYPE_TEXT, "Text" },
{ CLOUSEAU_OBJ_TYPE_IMAGE, "Image" },
{ CLOUSEAU_OBJ_TYPE_EDJE, "Edje" },
{ CLOUSEAU_OBJ_TYPE_TEXTBLOCK, "Textblock" }
};
static const char *
_clouseau_type_to_string(Clouseau_Object_Type type)
{
unsigned int i;
for (i = 0; i < sizeof (_clouseau_types) / sizeof (_clouseau_types[0]); ++i)
if (_clouseau_types[i].type == type)
return eina_stringshare_add(_clouseau_types[i].name);
return NULL;
}
static Inf_Clouseau_Tree_Item *
_clouseau_type_to_parent(Eina_List **main, const char *name)
{
Inf_Clouseau_Tree_Item *item;
if (!name) return NULL;
item = calloc(1, sizeof(Inf_Clouseau_Tree_Item));
item->string = eina_stringshare_add(name);
*main = eina_list_append(*main, item);
return item;
}
EAPI void
clouseau_object_information_list_populate(Clouseau_Tree_Item *treeit, Evas_Object *lb)
{
Inf_Clouseau_Tree_Item *main_tit;
Clouseau_Object *oinfo;
char buf[1024];
unsigned int i;
clouseau_object_information_list_clear();
if (!treeit->is_obj)
return;
oinfo = treeit->info;
/* Populate evas properties list */
main_tit = _clouseau_type_to_parent(&information_tree, "Evas");
_clouseau_information_bool_to_tree(main_tit, "Visibility",
oinfo->evas_props.is_visible);
_clouseau_information_string_to_tree(main_tit, "Name", oinfo->evas_props.name);
snprintf(buf, sizeof(buf), "Layer: %hd", oinfo->evas_props.layer);
_clouseau_information_buffer_to_tree(main_tit, buf);
_clouseau_information_geometry_to_tree(main_tit, "Position",
oinfo->evas_props.x,
oinfo->evas_props.y);
_clouseau_information_geometry_to_tree(main_tit, "Size",
oinfo->evas_props.w,
oinfo->evas_props.h);
_clouseau_information_double_to_tree(main_tit, "Scale", oinfo->evas_props.scale);
#if 0
if (evas_object_clip_get(obj))
{
evas_object_geometry_get(evas_object_clip_get(obj), &x, &y, &w, &h);
_clouseau_information_geometry_to_tree(main_tit, "Clipper position", x, y);
_clouseau_information_geometry_to_tree(main_tit, "Clipper size", w, h);
}
#endif
_clouseau_information_geometry_to_tree(main_tit, "Min size",
oinfo->evas_props.min_w,
oinfo->evas_props.min_h);
_clouseau_information_geometry_to_tree(main_tit, "Max size",
oinfo->evas_props.max_w,
oinfo->evas_props.max_h);
_clouseau_information_geometry_to_tree(main_tit, "Request size",
oinfo->evas_props.req_w,
oinfo->evas_props.req_h);
_clouseau_information_hint_to_tree(main_tit, "Align",
oinfo->evas_props.align_x,
oinfo->evas_props.align_y);
_clouseau_information_hint_to_tree(main_tit, "Weight",
oinfo->evas_props.weight_x,
oinfo->evas_props.weight_y);
#if 0
evas_object_size_hint_aspect_get(obj, &w, &h);
_clouseau_information_geometry_to_tree(main_tit, "Aspect", w, h);
#endif
snprintf(buf, sizeof(buf), "Color: %d %d %d %d",
oinfo->evas_props.r, oinfo->evas_props.g, oinfo->evas_props.b,
oinfo->evas_props.a);
_clouseau_information_buffer_to_tree(main_tit, buf);
_clouseau_information_bool_to_tree(main_tit, "Has focus",
oinfo->evas_props.has_focus);
for (i = 0; i < sizeof (pointer_mode) / sizeof (pointer_mode[0]); ++i)
if (pointer_mode[i].mode == oinfo->evas_props.mode)
{
_clouseau_information_string_to_tree(main_tit, "Pointer mode",
pointer_mode[i].text);
break;
}
_clouseau_information_bool_to_tree(main_tit, "Pass events",
oinfo->evas_props.pass_events);
_clouseau_information_bool_to_tree(main_tit, "Repeat events",
oinfo->evas_props.repeat_events);
_clouseau_information_bool_to_tree(main_tit, "Propagate events",
oinfo->evas_props.propagate_events);
_clouseau_information_bool_to_tree(main_tit, "Has clipees",
oinfo->evas_props.is_clipper);
if (oinfo->evas_props.clipper)
{
snprintf(buf, sizeof(buf), "%llx", oinfo->evas_props.clipper);
_clouseau_information_string_to_tree(main_tit, "Clipper", buf);
}
if (oinfo->evas_props.points_count)
{
main_tit = _clouseau_type_to_parent(&main_tit->children, "Evas Map");
Clouseau_Evas_Map_Point_Props *p;
for(i = 0 ; (int) i < oinfo->evas_props.points_count; i++)
{
p = &oinfo->evas_props.points[i];
snprintf(buf, sizeof(buf), "Coords: %d %d %d", p->x, p->y, p->z);
_clouseau_information_buffer_to_tree(main_tit, buf);
}
}
main_tit = _clouseau_type_to_parent(&information_tree,
_clouseau_type_to_string(oinfo->extra_props.type));
if (main_tit)
{
if (oinfo->extra_props.type == CLOUSEAU_OBJ_TYPE_ELM)
{
_clouseau_information_string_to_tree(main_tit, "Wid-Type", oinfo->extra_props.u.elm.type);
#if 0
/* Extract actual data from theme? */
_clouseau_information_string_to_tree(main_tit, "Theme", elm_widget_theme_get(obj));
#endif
_clouseau_information_string_to_tree(main_tit, "Style", oinfo->extra_props.u.elm.style);
_clouseau_information_double_to_tree(main_tit, "Scale",
oinfo->extra_props.u.elm.scale);
_clouseau_information_bool_to_tree(main_tit, "Disabled",
oinfo->extra_props.u.elm.is_disabled);
_clouseau_information_bool_to_tree(main_tit, "Has focus",
oinfo->extra_props.u.elm.has_focus);
_clouseau_information_bool_to_tree(main_tit, "Mirrored",
oinfo->extra_props.u.elm.is_mirrored);
_clouseau_information_bool_to_tree(main_tit, "Automatic mirroring",
oinfo->extra_props.u.elm.is_mirrored_automatic);
}
else if (oinfo->extra_props.type == CLOUSEAU_OBJ_TYPE_TEXT)
{
_clouseau_information_string_to_tree(main_tit, "Font", oinfo->extra_props.u.text.font);
snprintf(buf, sizeof(buf), "Size: %d", oinfo->extra_props.u.text.size);
_clouseau_information_buffer_to_tree(main_tit, buf);
_clouseau_information_string_to_tree(main_tit, "Source", oinfo->extra_props.u.text.source);
_clouseau_information_string_to_tree(main_tit, "Text", oinfo->extra_props.u.text.text);
}
else if (oinfo->extra_props.type == CLOUSEAU_OBJ_TYPE_IMAGE)
{
_clouseau_information_string_to_tree(main_tit, "Filename", oinfo->extra_props.u.image.file);
_clouseau_information_string_to_tree(main_tit, "File key", oinfo->extra_props.u.image.key);
snprintf(buf, sizeof(buf), "Source: %p", oinfo->extra_props.u.image.source);
_clouseau_information_buffer_to_tree(main_tit, buf);
_clouseau_information_string_to_tree(main_tit, "Load error", oinfo->extra_props.u.image.load_err);
}
else if (oinfo->extra_props.type == CLOUSEAU_OBJ_TYPE_EDJE)
{
_clouseau_information_string_to_tree(main_tit, "File", oinfo->extra_props.u.edje.file);
_clouseau_information_string_to_tree(main_tit, "Group", oinfo->extra_props.u.edje.group);
_clouseau_information_string_to_tree(main_tit, "Load error", oinfo->extra_props.u.edje.load_err);
}
else if (oinfo->extra_props.type == CLOUSEAU_OBJ_TYPE_TEXTBLOCK)
{
_clouseau_information_string_to_tree(main_tit, "Style", oinfo->extra_props.u.textblock.style);
_clouseau_information_string_to_tree(main_tit, "Text", oinfo->extra_props.u.textblock.text);
}
}
/* Update backtrace text */
if (oinfo->evas_props.bt)
{ /* Build backtrace label */
char *k = malloc(strlen("Creation backtrace:\n\n") +
strlen(oinfo->evas_props.bt) + 1);
sprintf(k, "Creation backtrace:\n\n%s", oinfo->evas_props.bt);
char *p = elm_entry_utf8_to_markup(k);
elm_object_text_set(lb, p);
free(p);
free(k);
}
else
elm_object_text_set(lb, NULL);
/* Actually populate the genlist */
{
Eina_List *itr, *expand_list = NULL, *l, *l_prev;
Inf_Clouseau_Tree_Item *tit;
Elm_Object_Item *expand_it = NULL;
EINA_LIST_FOREACH(information_tree, itr, tit)
{
Elm_Object_Item *git;
git = elm_genlist_item_append(prop_list, &itc, tit, NULL,
ELM_GENLIST_ITEM_TREE, _gl_selected, NULL);
expand_list = eina_list_append(expand_list, git);
}
EINA_LIST_REVERSE_FOREACH_SAFE(expand_list, l, l_prev, expand_it)
{
elm_genlist_item_expanded_set(expand_it, EINA_TRUE);
expand_list = eina_list_remove_list(expand_list, l);
}
}
}
EAPI void
clouseau_object_information_list_clear(void)
{
_clouseau_item_tree_free();
elm_genlist_clear(prop_list);
}

169
src/lib/clouseau_private.h Normal file
View File

@ -0,0 +1,169 @@
#ifndef EET_DATA_H
#define EET_DATA_H
#include "Clouseau.h"
/* Global constants */
#define BMP_FIELD "bmp"
#define PORT (22522)
#define MAX_LINE (1023)
#define LOCALHOST "127.0.0.1"
#define LISTEN_IP "0.0.0.0" /* Avail all, no mask */
/* Define packet types, used by packet encode / decode */
#define VARIANT_PACKET 0
#define BMP_RAW_DATA 1
enum _Clouseau_Message_Type
{ /* Add any supported types of packets here */
CLOUSEAU_UNKNOWN = 0,
CLOUSEAU_GUI_CLIENT_CONNECT = 1, /* client PID, name */
CLOUSEAU_APP_CLIENT_CONNECT = 2, /* client PID, name */
CLOUSEAU_APP_ADD = 3, /* client PTR, name, PID fwd to GUI client */
CLOUSEAU_DATA_REQ = 4, /* GUI client PTR (NULL for all),APP client PTR (NULL for all) */
CLOUSEAU_TREE_DATA = 5, /* GUI client PTR (NULL for all),APP client PTR, Tree Data */
CLOUSEAU_APP_CLOSED = 6,/* APP client PTR from DAEMON to GUI */
CLOUSEAU_HIGHLIGHT = 7, /* APP client PTR, object PTR */
CLOUSEAU_BMP_REQ = 8, /* APP client PTR, object PTR */
CLOUSEAU_BMP_DATA = 9 /* bmp_info_st header + BMP raw data */
};
typedef enum _Clouseau_Message_Type Clouseau_Message_Type;
/* This is used for composing message and encoding/decoding with EET */
struct _Variant_st
{
const char *type;
void *data;
};
typedef struct _Variant_st Variant_st;
struct _connect_st
{ /* This will be used for APP, GUI client connect */
unsigned int pid;
const char *name;
};
typedef struct _connect_st connect_st;
struct _app_info_st
{ /* This will be used to register new APP in GUI client */
unsigned int pid;
char *name;
char *file; /* Valid only if was read from file in offline mode */
unsigned long long ptr; /* (void *) client ptr of app as saved by daemon */
Eina_List *view; /* Screen views view->data is (bmp_info_st *) ptr */
unsigned int refresh_ctr; /* Counter of how many times down refresh */
};
typedef struct _app_info_st app_info_st;
struct _data_req_st
{ /* This will be used to ask for tree data by DAEMON or GUI */
unsigned long long gui; /* (void *) client ptr of GUI */
unsigned long long app; /* (void *) client ptr APP */
};
typedef struct _data_req_st data_req_st;
struct _tree_data_st
{ /* This will be used to send tree data to/from APP/DAEMON */
unsigned long long gui; /* (void *) client ptr of GUI */
unsigned long long app; /* (void *) client ptr APP */
Eina_List *tree; /* The actual (Tree_Item *) list */
};
typedef struct _tree_data_st tree_data_st;
struct _app_closed_st
{ /* This will be used to notify GUI of app closed */
unsigned long long ptr; /* (void *) client ptr APP */
};
typedef struct _app_closed_st app_closed_st;
struct _highlight_st
{ /* This will be used to highlight object in APP */
unsigned long long app; /* (void *) client ptr of APP */
unsigned long long object; /* (void *) object ptr of object to highlight */
};
typedef struct _highlight_st highlight_st;
struct _bmp_req_st
{ /* This will be used to send tree data to/from APP/DAEMON */
unsigned long long gui; /* (void *) client ptr of GUI */
unsigned long long app; /* (void *) client ptr APP */
unsigned long long object; /* (void *) object ptr of Evas */
unsigned int ctr; /* Reload counter to match */
};
typedef struct _bmp_req_st bmp_req_st;
struct _bmp_info_st
{ /* This will be used to send app window Bitmap */
/* We are using ULONGLONG because we send this as RAW data */
/* win, bt are NOT transferred. */
unsigned long long gui; /* (void *) client ptr of GUI */
unsigned long long app; /* (void *) client ptr of APP */
unsigned long long object; /* (void *) object ptr of evas */
unsigned long long ctr; /* Reload counter to match */
unsigned long long w; /* BMP width, make Evas_Coord */
unsigned long long h; /* BMP hight, make Evas_Coord */
/* All the following fields are NOT transferred in EET msg */
Evas_Object *win; /* Window of view if open */
Evas_Object *scr; /* Scroller holds view */
Evas_Object *o; /* Actuall object displays BMP */
double zoom_val; /* Current zoom value */
Evas_Object *lb_mouse; /* Label contains mouse cords */
Evas_Object *lb_rgba; /* Current mouse pos rgba val */
Evas_Object *bt; /* Button opening win */
Evas_Object *lx; /* Line on X axis */
Evas_Object *ly; /* Line on Y axis */
void *bmp; /* Bitmap BLOB, size (w * h * sizeof(int)) */
};
typedef struct _bmp_info_st bmp_info_st;
struct _shot_list_st
{ /* This will be used to write a shot list to eet file */
Eina_List *view; /* Screen views eahc is (bmp_info_st *) ptr */
};
typedef struct _shot_list_st shot_list_st;
struct _data_desc
{
Eet_Data_Descriptor *bmp_data;
Eet_Data_Descriptor *bmp_req;
Eet_Data_Descriptor *bmp_info;
Eet_Data_Descriptor *shot_list;
Eet_Data_Descriptor *connect;
Eet_Data_Descriptor *app_add;
Eet_Data_Descriptor *data_req;
Eet_Data_Descriptor *tree_data;
Eet_Data_Descriptor *app_closed;
Eet_Data_Descriptor *highlight;
Eet_Data_Descriptor *tree;
Eet_Data_Descriptor *obj_info;
Eet_Data_Descriptor *_variant_descriptor;
Eet_Data_Descriptor *_variant_unified_descriptor;
};
typedef struct _data_desc data_desc;
/* Private function */
#define CLOUSEAU_APP_ADD_ENTRY "clouseau/app"
#define CLOUSEAU_TREE_DATA_ENTRY "clouseau/app/tree"
#define CLOUSEAU_BMP_LIST_ENTRY "clouseau/app/shot_list"
#define CLOUSEAU_BMP_DATA_ENTRY "clouseau/app/screenshot"
/* Exported From Object information */
EAPI void clouseau_object_information_free(Clouseau_Object *oinfo);
EAPI Clouseau_Object * clouseau_object_information_get(Clouseau_Tree_Item *treeit);
/* Exported function */
EAPI void clouseau_data_tree_free(Eina_List *tree);
EAPI Clouseau_Message_Type clouseau_data_packet_mapping_type_get(const char *name);
EAPI void clouseau_data_variant_free(Variant_st *v);
EAPI Variant_st *clouseau_data_variant_alloc(Clouseau_Message_Type t, size_t size, void *info);
EAPI void * clouseau_data_packet_compose(Clouseau_Message_Type t, void *data, int data_size, int *size, void *blob, int blob_size);
EAPI Variant_st *
clouseau_data_packet_info_get(void *data, int size);
EAPI void clouseau_data_object_highlight(Evas_Object *obj, Clouseau_Evas_Props *props, bmp_info_st *view);
EAPI Eina_Bool clouseau_data_eet_info_save(const char *filename, app_info_st *a, tree_data_st *ftd, Eina_List *ck_list);
EAPI Eina_Bool clouseau_data_eet_info_read(const char *filename, app_info_st **a, tree_data_st **ftd);
EAPI int clouseau_data_init(void);
EAPI int clouseau_data_shutdown(void);
#endif /* EET_DATA_H */

View File

@ -1,7 +0,0 @@
add_subdirectory(objects_introspection)
add_subdirectory(evlog)
add_subdirectory(focus_inspector)
if (${EFL_PROFILER_FOUND})
add_subdirectory(profiling_viewer)
endif (${EFL_PROFILER_FOUND})

View File

@ -1,29 +0,0 @@
set(CMAKE_BUILD_TYPE Debug)
add_definitions(-DEFL_EO_API_SUPPORT -DEVLOG_EDJ="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME_LOWER}/clouseau_evlog.edj")
set(EOLIAN_INCLUDE_FLAG -I \"${EOLIAN_EO_DIR}/eo-1\" -I${CMAKE_CURRENT_SOURCE_DIR})
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${ELEMENTARY_INCLUDE_DIRS}
${EVAS_INCLUDE_DIRS}
${EO_INCLUDE_DIRS}
${EINA_INCLUDE_DIRS}
${EET_INCLUDE_DIRS}
)
link_directories (${PC_LIBELEMENTARY_LIBRARY_DIRS})
add_library(clouseau_evlog SHARED main.c)
target_link_libraries(clouseau_evlog
${ELEMENTARY_LIBRARIES}
${EVAS_LIBRARIES}
${EO_LIBRARIES}
${EINA_LIBRARIES}
${EET_LIBRARIES}
)
INSTALL(TARGETS clouseau_evlog LIBRARY DESTINATION lib)

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +0,0 @@
set(CMAKE_BUILD_TYPE Debug)
add_definitions(${CLI_COMMON_DEFINITIONS} -DEFL_EO_API_SUPPORT
-DFOCUS_EDJ="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME_LOWER}/clouseau_focus_inspector.edj")
add_definitions(-DEFL_EO_API_SUPPORT -DGUI_IMAGES_PATH="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME_LOWER}")
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${ELEMENTARY_INCLUDE_DIRS}
${EVAS_INCLUDE_DIRS}
${EO_INCLUDE_DIRS}
${EINA_INCLUDE_DIRS}
${EET_INCLUDE_DIRS}
${EOLIAN_INCLUDE_DIRS}
)
link_directories (${PC_LIBELEMENTARY_LIBRARY_DIRS})
add_library(clouseau_focus_inspector SHARED main.c gui.c tree_view.c)
target_link_libraries(clouseau_focus_inspector
${ELEMENTARY_LIBRARIES}
${EVAS_LIBRARIES}
${EO_LIBRARIES}
${EINA_LIBRARIES}
${EET_LIBRARIES}
${EOLIAN_LIBRARIES}
clouseau_debug
)
add_dependencies(clouseau_focus_inspector focus_inspector_theme)
INSTALL(TARGETS clouseau_focus_inspector LIBRARY DESTINATION lib)

View File

@ -1,191 +0,0 @@
#include <Elementary.h>
#include "../../Clouseau_Debug.h"
#include "gui.h"
static Evas_Object *table, *managers, *redirect, *history, *scroller;
static Elm_Genlist_Item_Class *itc;
static Clouseau_Focus_List_Item *selected_manager = NULL;
static char*
_text_get(void *data, Elm_Genlist *list EINA_UNUSED, const char *part EINA_UNUSED)
{
Clouseau_Focus_List_Item *it = data;
Eina_Strbuf *res = eina_strbuf_new();
eina_strbuf_append_printf(res, "%s - %p", it->helper_name, (void*)it->ptr);
return eina_strbuf_release(res);
}
static void
_sel_relation_func(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Instance *inst = evas_object_data_get(obj, "__instance");
tree_view_relation_display(inst, elm_radio_state_value_get(obj));
elm_radio_value_set(obj, elm_radio_state_value_get(obj));
}
static void
_reload(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
if (selected_manager)
com_defailt_manager(data, (void*)selected_manager->ptr);
}
EAPI Evas_Object*
ui_create(Instance *inst, Evas_Object *obj)
{
Evas_Object *o, *ic, *table2, *group = NULL;
o = table = elm_table_add(obj);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(o);
ic = elm_icon_add(obj);
elm_icon_standard_set(ic, "edit-redo");
evas_object_show(ic);
o = elm_button_add(obj);
elm_object_part_content_set(o, "icon", ic);
evas_object_show(o);
elm_table_pack(table, o, 0, 0, 1, 1);
evas_object_smart_callback_add(o, "clicked", _reload, inst);
o = managers = elm_combobox_add(obj);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_part_text_set(o, "guide", "Manager to inspect");
evas_object_show(o);
elm_table_pack(table, o, 1, 0, 1, 1);
itc = elm_genlist_item_class_new();
itc->func.text_get = _text_get;
o = elm_label_add(obj);
elm_object_text_set(o, "Redirect:");
evas_object_show(o);
elm_table_pack(table, o, 2, 0, 1, 1);
o = redirect = elm_label_add(obj);
evas_object_show(o);
elm_table_pack(table, o, 3, 0, 1, 1);
o = history = elm_hoversel_add(obj);
elm_object_text_set(o, "History");
evas_object_show(o);
elm_table_pack(table, o, 4, 0, 1, 1);
o = scroller = elm_scroller_add(table);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(o);
elm_table_pack(table, o, 0, 1, 5, 1);
o = table2 = elm_table_add(obj);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(o);
char *text[] = {"Tree","Next","Prev","None"};
for (int i = 0; i <= RELATION_NONE; ++i)
{
o = elm_radio_add(table);
evas_object_data_set(o, "__instance", inst);
evas_object_smart_callback_add(o, "changed", _sel_relation_func, NULL);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, text[i]);
evas_object_show(o);
elm_table_pack(table2, o, i % 5, i/5, 1, 1);
if (!group)
group = o;
else
elm_radio_group_add(o, group);
elm_radio_state_value_set(o, i);
}
elm_radio_value_set(group, RELATION_NONE);
elm_table_pack(table, table2, 0, 2, 5, 1);
return table;
}
static void
_sel(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Clouseau_Focus_List_Item *it = elm_object_item_data_get(event_info);
com_defailt_manager(data, (void*)it->ptr);
selected_manager = it;
}
EAPI void
ui_managers_add(Instance *inst, Clouseau_Focus_Managers *clouseau_managers)
{
Clouseau_Focus_List_Item *it;
Eina_List *n;
elm_genlist_clear(managers);
selected_manager = NULL;
if (!clouseau_managers) return;
EINA_LIST_FOREACH(clouseau_managers->managers, n, it)
{
elm_genlist_item_append(managers, itc, it, NULL, 0, _sel, inst);
}
free(clouseau_managers);
}
static int
_sort(const void *a_raw, const void *b_raw)
{
const Clouseau_Focus_Relation *a = a_raw;
const Clouseau_Focus_Relation *b = b_raw;
int val_a, val_b;
if (a) val_a = a->relation.position_in_history;
if (b) val_b = b->relation.position_in_history;
return val_a - val_b;
}
EAPI void
ui_manager_data_arrived(Instance *inst, Clouseau_Focus_Manager_Data *data)
{
Clouseau_Focus_Relation *rel;
Evas_Object *o;
Eina_List *n, *sorted = NULL;
EINA_LIST_FREE(inst->realized.objects, o)
evas_object_del(o);
inst->realized.focusable_to_cfr = eina_hash_pointer_new(NULL);
if (inst->realized.data)
free(inst->realized.data);
inst->realized.data = data;
elm_hoversel_clear(history);
if (!inst->realized.data) return;
EINA_LIST_FOREACH(data->relations, n, rel)
{
if (rel->relation.position_in_history != -1)
sorted = eina_list_sorted_insert(sorted, _sort, rel);
eina_hash_add(inst->realized.focusable_to_cfr, &rel->relation.node, rel);
}
EINA_LIST_FOREACH(sorted, n, rel)
{
elm_hoversel_item_add(history, rel->class_name, NULL, 0, NULL, NULL);
}
tree_view_update(inst, scroller);
}

View File

@ -1,34 +0,0 @@
#ifndef GUI_H
#define GUI_H
#include "../../Clouseau.h"
#include "../../Clouseau_Debug.h"
typedef struct {
Clouseau_Extension *ext;
struct {
Eina_Hash *focusable_to_cfr;
Eina_List *objects, *relation_objects;
Clouseau_Focus_Manager_Data *data;
} realized;
} Instance;
typedef enum {
RELATION_TREE = 0,
RELATION_NEXT = 1,
RELATION_PREV = 2,
RELATION_NONE = 3
} Relations;
#define PUSH_CLEANUP(inst, o) inst->realized.objects = eina_list_append(inst->realized.objects, o)
#define PUSH_RELAION_CLEANUP(inst, o) inst->realized.relation_objects = eina_list_append(inst->realized.relation_objects, o)
EAPI void tree_view_update(Instance *inst, Evas_Object *scroller);
EAPI void tree_view_relation_display(Instance *inst, Relations rel);
EAPI void ui_managers_add(Instance *inst, Clouseau_Focus_Managers *clouseau_managers);
EAPI void ui_manager_data_arrived(Instance *inst, Clouseau_Focus_Manager_Data *data);
EAPI Evas_Object* ui_create(Instance *inst, Evas_Object *obj);
EAPI void com_refresh_managers(Instance *inst);
EAPI void com_defailt_manager(Instance *inst, Efl_Ui_Focus_Manager *manager);
#endif

View File

@ -1,126 +0,0 @@
#include <Eina.h>
#include <Elementary.h>
#include "../../Clouseau.h"
#include "../../Clouseau_Debug.h"
#include "gui.h"
static Instance inst;
static int _focus_manager_list_op = EINA_DEBUG_OPCODE_INVALID;
static int _focus_manager_detail_op = EINA_DEBUG_OPCODE_INVALID;
static Eet_Data_Descriptor *manager_details = NULL, *manager_list = NULL;
#include "../../clouseau_focus_serialization.x"
static Eina_Bool
_main_loop_focus_manager_list_cb(Eina_Debug_Session *session, int src EINA_UNUSED, void *buffer, int size)
{
Clouseau_Extension *ext = eina_debug_session_data_get(session);
Clouseau_Focus_Managers *managers;
if (!manager_list) _init_manager_list_descriptors();
managers = eet_data_descriptor_decode(manager_list, buffer, size);
ui_managers_add(ext->data, managers);
return EINA_TRUE;
}
WRAPPER_TO_XFER_MAIN_LOOP(_focus_manager_list_cb)
static Eina_Bool
_main_loop_focus_manager_detail_cb(Eina_Debug_Session *session, int src EINA_UNUSED, void *buffer, int size)
{
Clouseau_Extension *ext = eina_debug_session_data_get(session);
Clouseau_Focus_Manager_Data *pd;
if (!manager_details) _init_data_descriptors();
pd = eet_data_descriptor_decode(manager_details, buffer, size);
ui_manager_data_arrived(ext->data, pd);
return EINA_TRUE;
}
WRAPPER_TO_XFER_MAIN_LOOP(_focus_manager_detail_cb)
EINA_DEBUG_OPCODES_ARRAY_DEFINE(_ops,
{"Clouseau/Elementary_Focus/list", &_focus_manager_list_op, &_focus_manager_list_cb},
{"Clouseau/Elementary_Focus/detail", &_focus_manager_detail_op, &_focus_manager_detail_cb},
{NULL, NULL, NULL}
);
static void
_session_changed(Clouseau_Extension *ext)
{
int i = 0;
Eina_Debug_Opcode *ops = _ops();
while (ops[i].opcode_name)
{
if (ops[i].opcode_id) *(ops[i].opcode_id) = EINA_DEBUG_OPCODE_INVALID;
i++;
}
if (ext->session)
{
eina_debug_session_data_set(ext->session, ext);
eina_debug_opcodes_register(ext->session, ops, NULL, ext);
}
ui_managers_add(ext->data, NULL);
ui_manager_data_arrived(ext->data, NULL);
}
static void
_app_changed(Clouseau_Extension *ext)
{
ui_managers_add(ext->data, NULL);
ui_manager_data_arrived(ext->data, NULL);
com_refresh_managers(ext->data);
}
EAPI void
com_refresh_managers(Instance *ext_inst)
{
eina_debug_session_send(ext_inst->ext->session, ext_inst->ext->app_id, _focus_manager_list_op, NULL, 0);
}
EAPI void
com_defailt_manager(Instance *ext_inst, Efl_Ui_Focus_Manager *manager)
{
void *tmp[1];
tmp[0] = manager;
eina_debug_session_send(ext_inst->ext->session, ext_inst->ext->app_id, _focus_manager_detail_op, tmp, sizeof(void*));
}
EAPI const char *
extension_name_get()
{
return "Focus Inspector";
}
EAPI Eina_Bool
extension_start(Clouseau_Extension *ext, Eo *parent)
{
eina_init();
inst.ext = ext;
ext->data = &inst;
ext->ui_object = ui_create(ext->data, parent);
ext->session_changed_cb = _session_changed;
ext->app_changed_cb = _app_changed;
return !!ext->ui_object;
}
EAPI Eina_Bool
extension_stop(Clouseau_Extension *ext)
{
efl_del(ext->ui_object);
eina_shutdown();
return EINA_TRUE;
}

View File

@ -1,313 +0,0 @@
#include <Elementary.h>
#include "../../Clouseau_Debug.h"
#include "gui.h"
static void
find(Instance *pd, void *parent, void (*found)(void *data, Instance *pd, Clouseau_Focus_Relation *relation), void *data)
{
for (unsigned int i = 0; pd->realized.data->relations && i < eina_list_count(pd->realized.data->relations); ++i)
{
Clouseau_Focus_Relation *rel;
rel = eina_list_nth(pd->realized.data->relations, i);
if (rel->relation.parent == parent)
found(data, pd, rel);
}
}
void
tree_level(void *data, Instance *inst, Clouseau_Focus_Relation *relation)
{
Evas_Object *box, *childbox, *vis;
int maxw, maxh, minw, minh;
Eina_Strbuf *buf;
char group[PATH_MAX];
box = evas_object_box_add(evas_object_evas_get(data));
evas_object_box_padding_set(box, 20, 20);
evas_object_show(box);
PUSH_CLEANUP(inst, box);
buf = eina_strbuf_new();
eina_strbuf_append_printf(buf, "%p", relation->relation.node);
vis = edje_object_add(evas_object_evas_get(data));
evas_object_size_hint_weight_set(vis, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(vis, 0.0, EVAS_HINT_FILL);
if (relation->relation.position_in_history != -1 )
snprintf(group, sizeof(group), "focus_inspector/history");
else if (relation->relation.redirect)
snprintf(group, sizeof(group), "focus_inspector/redirect");
else if (relation->relation.logical)
snprintf(group, sizeof(group), "focus_inspector/logical");
else
snprintf(group, sizeof(group), "focus_inspector/regular");
edje_object_file_set(vis, FOCUS_EDJ, group);
edje_object_part_text_set(vis, "widget_name", relation->class_name);
evas_object_show(vis);
evas_object_box_append(box, vis);
edje_object_size_max_get(vis, &maxw, &maxh);
edje_object_size_min_get(vis, &minw, &minh);
if ((minw <= 0) && (minh <= 0))
edje_object_size_min_calc(vis, &minw, &minh);
evas_object_size_hint_max_set(vis, maxw, maxh);
evas_object_size_hint_min_set(vis, minw, minh);
relation->vis = vis;
PUSH_CLEANUP(inst, vis);
childbox = evas_object_box_add(evas_object_evas_get(data));
evas_object_box_padding_set(childbox, 20, 20);
evas_object_box_layout_set(childbox, evas_object_box_layout_vertical, NULL, NULL);
evas_object_box_append(box, childbox);
evas_object_show(childbox);
PUSH_CLEANUP(inst, childbox);
find(inst, relation->relation.node, tree_level, childbox);
evas_object_box_append(data, box);
}
EAPI void
tree_view_update(Instance *inst, Evas_Object *scroller)
{
Evas_Object *box;
box = evas_object_box_add(evas_object_evas_get(scroller));
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_box_layout_set(box, evas_object_box_layout_vertical, NULL, NULL);
evas_object_show(box);
PUSH_CLEANUP(inst, box);
if (inst->realized.data)
find(inst, NULL, tree_level, box);
elm_object_content_set(scroller, box);
tree_view_relation_display(inst, RELATION_NONE);
}
static Evas_Object*
_create_arrow(Evas *e)
{
Evas_Object *vg;
Efl_VG *cont, *tail, *front;
vg = evas_object_vg_add(e);
cont = evas_vg_container_add(vg);
tail = evas_vg_shape_add(cont);
evas_vg_node_color_set(tail, 0, 0, 0, 255);
evas_vg_shape_stroke_color_set(tail, 128, 10,10, 128);
evas_vg_shape_stroke_width_set(tail, 2.0);
evas_vg_shape_stroke_join_set(tail, EFL_GFX_JOIN_MITER);
evas_vg_shape_append_move_to(tail, 0, 0);
evas_vg_shape_append_line_to(tail, -100, 0);
efl_name_set(tail, "tail");
front = evas_vg_shape_add(cont);
evas_vg_node_color_set(front, 0, 0, 0, 255);
evas_vg_shape_stroke_color_set(front, 128, 10,10, 128);
evas_vg_shape_stroke_width_set(front, 2.0);
evas_vg_shape_stroke_join_set(front, EFL_GFX_JOIN_MITER);
evas_vg_shape_append_move_to(front, -6, -6);
evas_vg_shape_append_line_to(front, 0, 0);
evas_vg_shape_append_line_to(front, -6, 6);
evas_vg_shape_append_line_to(front, -6, -6);
efl_name_set(front, "front");
evas_object_vg_root_node_set(vg, cont);
return vg;
}
static void
_arrow_from_to(Evas_Object *vg, Eina_Position2D from, Eina_Position2D to)
{
Eina_Rect pos;
Eina_Matrix3 tmp, root_m;
Efl_VG *shape;
double distance, deg;
shape = evas_object_vg_root_node_get(vg);
EINA_SAFETY_ON_NULL_RETURN(shape);
pos.x = MIN(from.x, to.x);
pos.y = MIN(from.y, to.y);
pos.w = MAX(from.x, to.x) - pos.x;
pos.h = MAX(from.y, to.y) - pos.y;
distance = sqrt(pow(pos.w, 2)+pow(pos.h, 2));
eina_matrix3_identity(&tmp);
eina_matrix3_scale(&tmp, distance/100, 1.0);
evas_vg_node_transformation_set(evas_vg_container_child_get(shape, "tail"), &tmp);
Eina_Size2D size = EINA_SIZE2D((from.x - to.x), (from.y - to.y));
if (from.y - to.y == 0)
{
deg = 0;
}
else if (from.x - to.x == 0)
{
if (from.y > to.y)
deg = M_PI_2;
else
deg = M_PI + M_PI_2;
}
else
{
double di = ((double)(double)from.y - to.y) / ((double)from.x - to.x);
deg = atan(di);
}
if (from.x >= to.x)
{
size.w = 0;
deg += M_PI;
}
if (to.y <= from.y)
{
size.h = 0;
}
size.h = MAX(abs(size.h), 0) + 10;
size.w = MAX(abs(size.w), 0) + 10;
eina_matrix3_identity(&root_m);
eina_matrix3_identity(&tmp);
eina_matrix3_translate(&tmp, size.w, size.h);
eina_matrix3_multiply_copy(&root_m, &root_m, &tmp);
eina_matrix3_identity(&tmp);
eina_matrix3_rotate(&tmp, deg);
eina_matrix3_multiply_copy(&root_m, &root_m, &tmp);
evas_vg_node_transformation_set(shape, &root_m);
evas_object_geometry_set(vg, pos.x - 10, pos.y - 10, pos.w + 20, pos.h + 20);
}
static void
_geom_change(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eina_Rectangle pos1, pos2;
Eina_Position2D from, to;
Evas_Object *line, *vis1, *vis2;
line = data;
vis1 = evas_object_data_get(line, "__from");
vis2 = evas_object_data_get(line, "__to");
evas_object_geometry_get(vis1, &pos1.x, &pos1.y, &pos1.w, &pos1.h);
evas_object_geometry_get(vis2, &pos2.x, &pos2.y, &pos2.w, &pos2.h);
from.x = pos1.x + pos1.w / 2;
from.y = pos1.y + pos1.h / 2;
to.x = pos2.x + pos2.w / 2;
to.y = pos2.y + pos2.h / 2;
_arrow_from_to(line, from, to);
}
static void
_relation_display(Instance *inst, Evas_Object *vis1, Evas_Object *vis2)
{
Evas_Object *line;
Evas_Object *smart;
line = _create_arrow(evas_object_evas_get(vis1));
//evas_object_anti_alias_set(line, EINA_FALSE);
evas_object_pass_events_set(line, EINA_TRUE);
evas_object_data_set(line, "__from", vis1);
evas_object_data_set(line, "__to", vis2);
evas_object_show(line);
smart = evas_object_smart_parent_get(vis1);
evas_object_smart_member_add(line, smart);
_geom_change(line, evas_object_evas_get(vis1), vis1, NULL);
PUSH_RELAION_CLEANUP(inst, line);
evas_object_event_callback_add(vis1, EVAS_CALLBACK_MOVE, _geom_change, line);
evas_object_event_callback_add(vis1, EVAS_CALLBACK_RESIZE, _geom_change, line);
evas_object_event_callback_add(vis2, EVAS_CALLBACK_MOVE, _geom_change, line);
evas_object_event_callback_add(vis2, EVAS_CALLBACK_RESIZE, _geom_change, line);
}
EAPI void
tree_view_relation_display(Instance *inst, Relations rel_type)
{
Evas_Object *o;
EINA_LIST_FREE(inst->realized.relation_objects, o)
{
Evas_Object *vis1, *vis2;
vis1 = evas_object_data_get(o, "__from");
vis2 = evas_object_data_get(o, "__to");
evas_object_event_callback_del_full(vis1, EVAS_CALLBACK_MOVE, _geom_change, o);
evas_object_event_callback_del_full(vis1, EVAS_CALLBACK_RESIZE, _geom_change, o);
evas_object_event_callback_del_full(vis2, EVAS_CALLBACK_MOVE, _geom_change, o);
evas_object_event_callback_del_full(vis2, EVAS_CALLBACK_RESIZE, _geom_change, o);
evas_object_del(o);
}
if (rel_type == RELATION_NONE) return;
if (!inst->realized.data) return;
Clouseau_Focus_Relation *rel;
Eina_List *n;
EINA_LIST_FOREACH(inst->realized.data->relations, n, rel)
{
Eo *from;
Eo *to;
if (rel_type == RELATION_TREE)
{
if (!rel->relation.parent) continue;
from = rel->relation.parent;
to = rel->relation.node;
}
else if (rel_type == RELATION_NEXT)
{
if (!rel->relation.next) continue;
to = rel->relation.next;
from = rel->relation.node;
}
else if (rel_type == RELATION_PREV)
{
if (!rel->relation.prev) continue;
to = rel->relation.prev;
from = rel->relation.node;
}
Clouseau_Focus_Relation *c_from, *c_to;
c_from = eina_hash_find(inst->realized.focusable_to_cfr, &from);
c_to = eina_hash_find(inst->realized.focusable_to_cfr, &to);
EINA_SAFETY_ON_NULL_GOTO(c_from, next);
EINA_SAFETY_ON_NULL_GOTO(c_to, next);
_relation_display(inst, c_from->vis, c_to->vis);
next:
(void) n;
}
}

View File

@ -1,31 +0,0 @@
set(CMAKE_BUILD_TYPE Debug)
add_definitions(${CLI_COMMON_DEFINITIONS} -DEFL_EO_API_SUPPORT)
add_definitions(-DEFL_EO_API_SUPPORT -DGUI_IMAGES_PATH="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME_LOWER}")
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${ELEMENTARY_INCLUDE_DIRS}
${EVAS_INCLUDE_DIRS}
${EO_INCLUDE_DIRS}
${EINA_INCLUDE_DIRS}
${EET_INCLUDE_DIRS}
${EOLIAN_INCLUDE_DIRS}
)
link_directories (${PC_LIBELEMENTARY_LIBRARY_DIRS})
add_library(clouseau_objects_introspection SHARED main.c gui.c)
target_link_libraries(clouseau_objects_introspection
${ELEMENTARY_LIBRARIES}
${EVAS_LIBRARIES}
${EO_LIBRARIES}
${EINA_LIBRARIES}
${EET_LIBRARIES}
${EOLIAN_LIBRARIES}
clouseau_debug
)
INSTALL(TARGETS clouseau_objects_introspection LIBRARY DESTINATION lib)

View File

@ -1,203 +0,0 @@
#ifndef EFL_BETA_API_SUPPORT
#define EFL_BETA_API_SUPPORT
#endif
#ifndef EFL_EO_API_SUPPORT
#define EFL_EO_API_SUPPORT
#endif
#ifndef ELM_INTERNAL_API_ARGESFSDFEFC
#define ELM_INTERNAL_API_ARGESFSDFEFC
#endif
#include <Efl_Ui.h>
#include <Elementary.h>
#include "gui.h"
static const char* objs_types_strings[] =
{
"Show all canvas objects",
"Only show Elementary widgets",
NULL
};
#ifdef GUI_IMAGES_PATH
const char *SHOW_SCREENSHOT_ICON = GUI_IMAGES_PATH"/show-screenshot.png";
const char *TAKE_SCREENSHOT_ICON = GUI_IMAGES_PATH"/take-screenshot.png";
#else
#error "Please define GUI_IMAGES_PATH"
#endif
extern void
screenshot_req_cb(void *data, const Efl_Event *event);
extern void
reload_perform(void *data, Evas_Object *obj, void *event_info);
extern void
take_screenshot_button_clicked(void *data, const Efl_Event *event);
extern void
show_screenshot_button_clicked(void *data, const Efl_Event *event);
extern void
snapshot_do(void *data, Evas_Object *fs, void *event_info);
extern void
objs_type_changed(void *data, Evas_Object *obj, void *event_info);
extern void
highlight_changed(void *data, Evas_Object *obj, void *event_info);
extern void
jump_to_ptr_inwin_show(void *data, Evas_Object *obj, void *event_info);
static void
_pubs_free_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
free(data);
}
Gui_Win_Widgets *
gui_win_create(Eo *__main_parent)
{
Gui_Win_Widgets *pub_widgets = calloc(1, sizeof(*pub_widgets));
Eo *box, *tb;
Eo *panes;
Eo *object_infos_list;
Eo *objects_list;
box = elm_box_add(__main_parent);
pub_widgets->main = box;
evas_object_size_hint_weight_set(box, 1, 1);
evas_object_size_hint_align_set(box, -1, -1);
efl_gfx_entity_visible_set(box, EINA_TRUE);
efl_event_callback_add(box, EFL_EVENT_DEL, _pubs_free_cb, pub_widgets);
tb = elm_toolbar_add(__main_parent);
pub_widgets->tb = tb;
elm_toolbar_shrink_mode_set(tb, ELM_TOOLBAR_SHRINK_MENU);
elm_toolbar_menu_parent_set(tb, __main_parent);
evas_object_size_hint_weight_set(tb, 0, 0);
evas_object_size_hint_align_set(tb, -1, 0);
efl_gfx_entity_visible_set(tb, EINA_TRUE);
pub_widgets->reload_button = elm_toolbar_item_append(tb, "view-refresh", "Reload", reload_perform, NULL);
elm_toolbar_item_append(tb, "edit-find", "Jump To Pointer", jump_to_ptr_inwin_show, NULL);
{
int i = 0;
Eo *settings_it = elm_toolbar_item_append(tb, "system-run", "Settings", NULL, NULL);
elm_toolbar_item_menu_set(settings_it, EINA_TRUE);
Eo *settings_menu = elm_toolbar_item_menu_get(settings_it);
pub_widgets->settings_menu = settings_menu;
Eo *objs_type_it = elm_menu_item_add(settings_menu, NULL, NULL,
"Objects types display", NULL, NULL);
while (objs_types_strings[i])
{
Eo *it = elm_menu_item_add(settings_menu, objs_type_it, NULL,
objs_types_strings[i], objs_type_changed, (void *)(uintptr_t)i);
Eo *rd = elm_radio_add(settings_menu);
elm_radio_state_value_set(rd, i);
if (!i) pub_widgets->objs_type_radio = rd;
else elm_radio_group_add(rd, pub_widgets->objs_type_radio);
elm_object_item_content_set(it, rd);
i++;
}
Eo *highlight_it = elm_menu_item_add(settings_menu, NULL, NULL,
"Hightlight", highlight_changed, NULL);
Eo *ck = elm_check_add(settings_menu);
elm_object_item_content_set(highlight_it, ck);
pub_widgets->highlight_ck = ck;
}
panes = efl_add(EFL_UI_PANES_CLASS, box);
elm_panes_content_right_size_set(panes, 0.600000);
evas_object_size_hint_weight_set(panes, 1.000000, 1.000000);
efl_gfx_entity_size_set(panes, EINA_SIZE2D(75, 75));
efl_gfx_entity_visible_set(panes, EINA_TRUE);
evas_object_size_hint_weight_set(panes, 1.000000, 1.000000);
evas_object_size_hint_align_set(panes, -1.000000, -1.000000);
elm_box_pack_end(box, tb);
elm_box_pack_end(box, panes);
object_infos_list = elm_genlist_add(panes);
pub_widgets->object_infos_list = object_infos_list;
evas_object_size_hint_weight_set(object_infos_list, 1.000000, 1.000000);
efl_gfx_entity_visible_set(object_infos_list, EINA_TRUE);
objects_list = elm_genlist_add(panes);
pub_widgets->objects_list = objects_list;
evas_object_size_hint_weight_set(objects_list, 1.000000, 1.000000);
efl_gfx_entity_visible_set(objects_list, EINA_TRUE);
elm_object_part_content_set(panes, "left", objects_list);
elm_object_part_content_set(panes, "right", object_infos_list);
return pub_widgets;
}
Gui_Take_Screenshot_Button_Widgets *
gui_take_screenshot_button_create(Eo *__main_parent)
{
Gui_Take_Screenshot_Button_Widgets *pub_widgets = calloc(1, sizeof(*pub_widgets));
Eo *bt;
Eo *elm_icon1;
bt = elm_button_add(__main_parent);
pub_widgets->bt = bt;
evas_object_size_hint_weight_set(bt, 1.000000, 1.000000);
evas_object_show(bt);
efl_event_callback_add(bt, EFL_INPUT_EVENT_CLICKED, take_screenshot_button_clicked, NULL);
elm_icon1 = elm_icon_add(bt);
evas_object_size_hint_weight_set(elm_icon1, 1.000000, 1.000000);
efl_gfx_entity_visible_set(elm_icon1, EINA_TRUE);
efl_file_set(elm_icon1, TAKE_SCREENSHOT_ICON);
elm_object_part_content_set(bt, "icon", elm_icon1);
efl_event_callback_add(bt, EFL_EVENT_DEL, _pubs_free_cb, pub_widgets);
return pub_widgets;
}
Gui_Show_Screenshot_Button_Widgets *
gui_show_screenshot_button_create(Eo *__main_parent)
{
Gui_Show_Screenshot_Button_Widgets *pub_widgets = calloc(1, sizeof(*pub_widgets));
Eo *bt;
Eo *elm_icon1;
bt = elm_button_add(__main_parent);
pub_widgets->bt = bt;
evas_object_size_hint_weight_set(bt, 1.000000, 1.000000);
evas_object_show(bt);
evas_object_resize(bt, 73, 30);
efl_event_callback_add(bt, EFL_INPUT_EVENT_CLICKED, show_screenshot_button_clicked, NULL);
elm_icon1 = elm_icon_add(bt);
evas_object_size_hint_weight_set(elm_icon1, 1.000000, 1.000000);
efl_gfx_entity_visible_set(elm_icon1, EINA_TRUE);
efl_gfx_entity_size_set(elm_icon1, EINA_SIZE2D(40, 40));
efl_file_set(elm_icon1, SHOW_SCREENSHOT_ICON);
elm_object_part_content_set(bt, "icon", elm_icon1);
efl_event_callback_add(bt, EFL_EVENT_DEL, _pubs_free_cb, pub_widgets);
return pub_widgets;
}
Gui_Show_Screenshot_Win_Widgets *
gui_show_screenshot_win_create(Eo *__main_parent)
{
Gui_Show_Screenshot_Win_Widgets *pub_widgets = calloc(1, sizeof(*pub_widgets));
Eo *win;
Eo *bg;
win = elm_win_add(__main_parent, "Screenshot", ELM_WIN_BASIC);
pub_widgets->win = win;
elm_win_autodel_set(win, EINA_TRUE);
efl_gfx_entity_size_set(win, EINA_SIZE2D(300, 300));
evas_object_size_hint_weight_set(win, 1.000000, 1.000000);
elm_win_title_set(win, "Screenshot");
bg = elm_bg_add(win);
pub_widgets->bg = bg;
evas_object_size_hint_weight_set(bg, 1.000000, 1.000000);
efl_gfx_entity_visible_set(bg, EINA_TRUE);
elm_win_resize_object_add(win, bg);
efl_gfx_entity_visible_set(win, EINA_TRUE);
efl_event_callback_add(win, EFL_EVENT_DEL, _pubs_free_cb, pub_widgets);
return pub_widgets;
}

View File

@ -1,41 +0,0 @@
#ifndef _gui_h_
#define _gui_h_
#include <Eo.h>
#include <Elementary.h>
typedef struct
{
Eo *main;
Eo *tb;
Eo *settings_menu;
Eo *reload_button;
Eo *objs_type_radio;
Eo *highlight_ck;
Eo *object_infos_list;
Eo *objects_list;
} Gui_Win_Widgets;
typedef struct
{
Eo *bt;
} Gui_Take_Screenshot_Button_Widgets;
typedef struct
{
Eo *bt;
} Gui_Show_Screenshot_Button_Widgets;
typedef struct
{
Eo *win;
Eo *bg;
} Gui_Show_Screenshot_Win_Widgets;
Gui_Win_Widgets *gui_win_create(Eo *parent);
Gui_Take_Screenshot_Button_Widgets *gui_take_screenshot_button_create(Eo *parent);
Gui_Show_Screenshot_Button_Widgets *gui_show_screenshot_button_create(Eo *parent);
Gui_Show_Screenshot_Win_Widgets *gui_show_screenshot_win_create(Eo *parent);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +0,0 @@
set(CMAKE_BUILD_TYPE Debug)
STRING(REGEX REPLACE "\n" "" EOLIAN_EO_DIR "${EOLIAN_EO_DIR}")
STRING(REGEX REPLACE " " "" EOLIAN_EO_DIR "${EOLIAN_EO_DIR}")
add_definitions(${CLI_COMMON_DEFINITIONS} -DEFL_EO_API_SUPPORT
-DEOLIAN_EO_DIR="${EOLIAN_EO_DIR}")
add_definitions(-DEFL_EO_API_SUPPORT -DGUI_IMAGES_PATH="${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME_LOWER}")
set(EOLIAN_INCLUDE_FLAG -I \"${EOLIAN_EO_DIR}/eo-1\" -I${CMAKE_CURRENT_SOURCE_DIR})
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${EFL_PROFILER_INCLUDE_DIRS}
${ELEMENTARY_INCLUDE_DIRS}
${EVAS_INCLUDE_DIRS}
${EO_INCLUDE_DIRS}
${EINA_INCLUDE_DIRS}
${EET_INCLUDE_DIRS}
${EOLIAN_INCLUDE_DIRS}
)
link_directories (${PC_LIBELEMENTARY_LIBRARY_DIRS})
add_library(clouseau_profiling_viewer SHARED main.c)
target_link_libraries(clouseau_profiling_viewer
efl_profiler
${ELEMENTARY_LIBRARIES}
${EVAS_LIBRARIES}
${EO_LIBRARIES}
${EINA_LIBRARIES}
${EET_LIBRARIES}
${EOLIAN_LIBRARIES}
)
INSTALL(TARGETS clouseau_profiling_viewer LIBRARY DESTINATION lib)

View File

@ -1,410 +0,0 @@
#include <Eina.h>
#include <Elementary.h>
#include <Efl_Profiler.h>
#include "../../Clouseau.h"
#define _EET_ENTRY "config"
typedef enum {
STREAM_PAUSED = 0,
STREAM_PROCESSING
} CLOUSEAU_PROFILER_STATUS;
typedef struct {
Evas_Object *profiler;
Ecore_Timer *record_get_timer;
CLOUSEAU_PROFILER_STATUS status; /*<< 0 - stopped, 1 - processing, 2 - paused */
struct {
Evas_Object *obj;
Evas_Object *status_btn;
Evas_Object *follow_btn;
Evas_Object *filters_btn;
Evas_Object *find_btn;
Evas_Object *time_range_btn;
Evas_Object *setting_btn;
} toolbar;
Eina_Bool follow;
Eina_Bool block_processed;
} Inf;
static int _clouseau_profiling_extension_log_dom = 0;
static int _record_on_op = EINA_DEBUG_OPCODE_INVALID;
static int _record_off_op = EINA_DEBUG_OPCODE_INVALID;
static int _record_get_op = EINA_DEBUG_OPCODE_INVALID;
static Eina_Bool _record_get_cb(Eina_Debug_Session *, int, void *, int);
static void _follow_interval_status_change_cb(void *data, Evas_Object *obj, void *event_info);
EINA_DEBUG_OPCODES_ARRAY_DEFINE(_ops,
{"CPU/Freq/on", &_record_on_op, NULL},
{"CPU/Freq/off", &_record_off_op, NULL},
{"EvLog/get", &_record_get_op, &_record_get_cb},
{NULL, NULL, NULL}
);
EAPI const char *
extension_name_get()
{
return "Profiling viewer";
}
static Eina_Bool
_record_request_cb(void *data)
{
Clouseau_Extension *ext = data;
eina_debug_session_send(ext->session, ext->app_id, _record_get_op, NULL, 0);
return EINA_TRUE;
}
static void
_stream_processing_resume_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Clouseau_Extension *ext = data;
Inf *inf = ext->data;
eina_debug_session_send(ext->session, ext->app_id, _record_on_op, NULL, 0);
if (!inf->record_get_timer)
inf->record_get_timer = ecore_timer_add(0.2, _record_request_cb, ext);
}
static void
_session_changed(Clouseau_Extension *ext)
{
int i = 0;
Eina_Debug_Opcode *ops = _ops();
Inf *inf = ext->data;
EINA_LOG_DOM_DBG(_clouseau_profiling_extension_log_dom, "Session changed");
while (ops[i].opcode_name)
{
if (ops[i].opcode_id) *(ops[i].opcode_id) = EINA_DEBUG_OPCODE_INVALID;
i++;
}
if (ext->session)
{
eina_debug_session_data_set(ext->session, ext);
eina_debug_opcodes_register(ext->session, ops, NULL, NULL);
}
/*disable controls on toolbar */
elm_object_disabled_set(inf->toolbar.status_btn, EINA_TRUE);
elm_object_disabled_set(inf->toolbar.follow_btn, EINA_TRUE);
if (!inf->block_processed)
{
elm_object_disabled_set(inf->toolbar.filters_btn, EINA_TRUE);
elm_object_disabled_set(inf->toolbar.time_range_btn, EINA_TRUE);
elm_object_disabled_set(inf->toolbar.find_btn, EINA_TRUE);
}
return;
}
static void
_app_changed(Clouseau_Extension *ext)
{
Inf *inf = ext->data;
evas_object_smart_callback_call(inf->profiler, "stream,app,changed", &ext->app_id);
EINA_LOG_DOM_DBG(_clouseau_profiling_extension_log_dom, "Application changed");
/*enable controls on toolbar */
elm_object_disabled_set(inf->toolbar.status_btn, EINA_FALSE);
elm_object_disabled_set(inf->toolbar.follow_btn, EINA_FALSE);
elm_object_disabled_set(inf->toolbar.filters_btn, EINA_TRUE);
elm_object_disabled_set(inf->toolbar.time_range_btn, EINA_TRUE);
elm_object_disabled_set(inf->toolbar.find_btn, EINA_TRUE);
_follow_interval_status_change_cb(ext, inf->toolbar.follow_btn, NULL);
inf->block_processed = EINA_FALSE;
return;
}
static void
_profiling_import(Clouseau_Extension *ext,
void *buffer, int size,
int version EINA_UNUSED)
{
EINA_LOG_DOM_DBG(_clouseau_profiling_extension_log_dom, "Data imported");
Inf *inf = ext->data;
Stream_Block_Data block_data = { .size = size, .data = buffer };
evas_object_smart_callback_call(inf->profiler, "stream,block,process", &block_data);
inf->block_processed = EINA_TRUE;
_stream_processing_resume_cb(ext,NULL, NULL);
if (inf->block_processed)
{
elm_object_disabled_set(inf->toolbar.filters_btn, EINA_FALSE);
elm_object_disabled_set(inf->toolbar.time_range_btn, EINA_FALSE);
elm_object_disabled_set(inf->toolbar.find_btn, EINA_FALSE);
}
return;
}
static Eina_Bool
_record_get_cb(Eina_Debug_Session *session, int cid EINA_UNUSED, void *buffer, int size)
{
Clouseau_Extension *ext = eina_debug_session_data_get(session);
_profiling_import(ext, buffer, size, -1);
return EINA_TRUE;
}
static void
_find_dialog_show_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Clouseau_Extension *ext = (Clouseau_Extension *)data;
Inf *inf = ext->data;
evas_object_smart_callback_call(inf->profiler, "find,show", NULL);
}
static void
_time_range_dialog_show_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Clouseau_Extension *ext = (Clouseau_Extension *)data;
Inf *inf = ext->data;
evas_object_smart_callback_call(inf->profiler, "time,interval,win", NULL);
}
static void
_filters_dialog_show_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Clouseau_Extension *ext = (Clouseau_Extension *)data;
Inf *inf = ext->data;
evas_object_smart_callback_call(inf->profiler, "filters,show", NULL);
}
static void
_unfollow_interval_cb(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Clouseau_Extension *ext = (Clouseau_Extension *)data;
Inf *inf = ext->data;
Evas_Object *icon = NULL;
evas_object_smart_callback_call(inf->profiler, "unfollow,processed,data", NULL);
inf->follow = EINA_FALSE;
icon = elm_object_part_content_get(inf->toolbar.follow_btn, "icon");
elm_icon_standard_set(icon, "go-last");
}
static void
_follow_interval_status_change_cb(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Clouseau_Extension *ext = (Clouseau_Extension *)data;
Inf *inf = ext->data;
char *icon_name = NULL;
Evas_Object *icon = NULL;
if (inf->follow)
{
evas_object_smart_callback_call(inf->profiler, "unfollow,processed,data", NULL);
inf->follow = EINA_FALSE;
icon_name = "go-last";
}
else
{
evas_object_smart_callback_call(inf->profiler, "follow,processed,data", NULL);
inf->follow = EINA_TRUE;
icon_name = "go-bottom";
}
icon = elm_object_part_content_get(obj, "icon");
elm_icon_standard_set(icon, icon_name);
}
static void
_profiling_status_change_cb(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Clouseau_Extension *ext = (Clouseau_Extension *)data;
Inf *inf = ext->data;
char *icon_name = NULL;
Evas_Object *icon = NULL;
switch (inf->status)
{
case STREAM_PROCESSING:
{
eina_debug_session_send(ext->session, ext->app_id, _record_off_op, NULL, 0);
ecore_timer_del(inf->record_get_timer);
inf->status = STREAM_PAUSED;
icon_name = "media-playback-start";
break;
}
case STREAM_PAUSED:
{
eina_debug_session_send(ext->session, ext->app_id, _record_on_op, NULL, 0);
inf->record_get_timer = NULL;
_stream_processing_resume_cb(ext,NULL, NULL);
inf->status = STREAM_PROCESSING;
icon_name = "media-playback-pause";
break;
}
}
icon = elm_object_part_content_get(obj, "icon");
elm_icon_standard_set(icon, icon_name);
}
static Eo *
_ui_get(Clouseau_Extension *ext, Eo *parent)
{
Inf *inf = ext->data;
Evas_Object *toolbar = NULL;
Evas_Object *box = NULL;
Evas_Object *button = NULL, *icon = NULL;
Elm_Object_Item *item = NULL;
box = elm_box_add(parent);
evas_object_size_hint_weight_set(box, 1, 1);
evas_object_size_hint_align_set(box, -1, -1);
evas_object_show(box);
toolbar = elm_toolbar_add(parent);
inf->toolbar.obj = toolbar;
elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_SCROLL);
elm_toolbar_select_mode_set(toolbar, ELM_OBJECT_SELECT_MODE_NONE);
elm_toolbar_homogeneous_set(toolbar, EINA_TRUE);
elm_object_style_set(toolbar, "transparent");
elm_toolbar_menu_parent_set(toolbar, parent);
evas_object_size_hint_weight_set(toolbar, 0, 0);
evas_object_size_hint_align_set(toolbar, -1, 0);
evas_object_show(toolbar);
item = elm_toolbar_item_append(toolbar, NULL, NULL, NULL, NULL);
button = elm_button_add(toolbar);
elm_object_item_part_content_set(item, "object", button);
evas_object_smart_callback_add(button, "clicked", _profiling_status_change_cb, ext);
icon = elm_icon_add(button);
elm_image_resizable_set(icon, EINA_FALSE, EINA_FALSE);
elm_icon_standard_set(icon, "media-playback-start");
elm_object_part_content_set(button, "icon", icon);
inf->toolbar.status_btn = button;
evas_object_show(button);
elm_object_disabled_set(button, EINA_TRUE);
item = elm_toolbar_item_append(toolbar, NULL, NULL, NULL, NULL);
button = elm_button_add(toolbar);
elm_object_item_part_content_set(item, "object", button);
evas_object_smart_callback_add(button, "clicked", _follow_interval_status_change_cb, ext);
icon = elm_icon_add(button);
elm_icon_standard_set(icon, "go-last");
elm_object_part_content_set(button, "icon", icon);
evas_object_show(button);
inf->toolbar.follow_btn = button;
elm_object_disabled_set(button, EINA_TRUE);
item = elm_toolbar_item_append(toolbar, NULL, NULL, NULL, NULL);
button = elm_button_add(toolbar);
elm_object_item_part_content_set(item, "object", button);
evas_object_smart_callback_add(button, "clicked", _filters_dialog_show_cb, ext);
icon = elm_icon_add(button);
elm_icon_standard_set(icon, "view-list-details");
elm_object_part_content_set(button, "icon", icon);
evas_object_show(button);
inf->toolbar.filters_btn = button;
elm_object_disabled_set(button, EINA_TRUE);
item = elm_toolbar_item_append(toolbar, NULL, NULL, NULL, NULL);
button = elm_button_add(toolbar);
elm_object_item_part_content_set(item, "object", button);
evas_object_smart_callback_add(button, "clicked", _find_dialog_show_cb, ext);
icon = elm_icon_add(button);
elm_icon_standard_set(icon, "system-search");
elm_object_part_content_set(button, "icon", icon);
evas_object_show(button);
inf->toolbar.find_btn = button;
item = elm_toolbar_item_append(toolbar, NULL, NULL, NULL, NULL);
button = elm_button_add(toolbar);
elm_object_item_part_content_set(item, "object", button);
evas_object_smart_callback_add(button, "clicked", _time_range_dialog_show_cb, ext);
icon = elm_icon_add(button);
elm_icon_standard_set(icon, "clock");
elm_object_part_content_set(button, "icon", icon);
evas_object_show(button);
inf->toolbar.time_range_btn = button;
elm_object_disabled_set(button, EINA_TRUE);
item = elm_toolbar_item_append(toolbar, NULL, NULL, NULL, NULL);
button = elm_button_add(toolbar);
elm_object_item_part_content_set(item, "object", button);
icon = elm_icon_add(button);
elm_icon_standard_set(icon, "preferences-other");
elm_object_part_content_set(button, "icon", icon);
evas_object_show(button);
inf->toolbar.setting_btn= button;
elm_object_disabled_set(button, EINA_TRUE);
inf->profiler = efl_profiling_viewer_init(parent);
evas_object_size_hint_weight_set(inf->profiler, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(inf->profiler, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_smart_callback_add(inf->profiler, "unfollow", _unfollow_interval_cb, ext);
elm_box_pack_end(box, toolbar);
elm_box_pack_end(box, inf->profiler);
return box;
}
EAPI Eina_Bool
extension_start(Clouseau_Extension *ext, Eo *parent)
{
Inf *inf;
eina_init();
const char *log_dom = "clouseau_profiling_extension";
_clouseau_profiling_extension_log_dom = eina_log_domain_register(log_dom, EINA_COLOR_ORANGE);
if (_clouseau_profiling_extension_log_dom < 0)
{
EINA_LOG_ERR("Could not register log domain: %s", log_dom);
return EINA_FALSE;
}
EINA_LOG_DOM_DBG(_clouseau_profiling_extension_log_dom, "Extension started");
inf = calloc(1, sizeof(Inf));
ext->data = inf;
ext->session_changed_cb = _session_changed;
ext->app_changed_cb = _app_changed;
ext->import_data_cb = _profiling_import;
ext->ui_object = _ui_get(ext, parent);
return !!ext->ui_object;
}
EAPI Eina_Bool
extension_stop(Clouseau_Extension *ext)
{
Inf *inf = ext->data;
evas_object_smart_callback_call(inf->profiler, "log,close", NULL);
efl_profiling_viewer_shutdown(inf->profiler);
free(inf);
efl_del(ext->ui_object);
EINA_LOG_DOM_DBG(_clouseau_profiling_extension_log_dom, "Extension stopped");
eina_log_domain_unregister(_clouseau_profiling_extension_log_dom);
eina_shutdown();
return EINA_TRUE;
}

16
src/scripts/Makefile.am Normal file
View File

@ -0,0 +1,16 @@
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = gen_script.sh
uninstall-local:
rm $(DESTDIR)$(bindir)/clouseau
rm $(DESTDIR)$(bindir)/clouseau_start
clean-local:
rm clouseau
rm clouseau_start
install-exec-local:
$(srcdir)/gen_script.sh $(libdir)/clouseau
$(INSTALL) clouseau_start $(DESTDIR)$(bindir)
$(INSTALL) clouseau $(DESTDIR)$(bindir)

27
src/scripts/gen_script.sh Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh
cat <<-ENDOFMESSAGE>clouseau_start
#!/bin/sh
if [ \$# -lt 1 ]
then
echo "Usage: clouseau_start <executable> [executable parameters]"
else
# Start clouseau daemon (will start single instance), then run app
clouseaud
#Set the ELM_CLOUSEAU in case preload is disabled.
ELM_CLOUSEAU=1 LD_PRELOAD="$1/libclouseau.so" "\$@"
fi
ENDOFMESSAGE
cat <<-ENDOFMESSAGE>clouseau
#!/bin/sh
if [ \$# -gt 0 ]
then
# Start clouseau daemon (will start single instance), then run app
clouseau_start "\$@" &
fi
clouseau_client
ENDOFMESSAGE
chmod +x clouseau
chmod +x clouseau_start