From ea6dce6adae4a1a89933ba7c6596fe29cb49d8a9 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Thu, 8 Jan 2015 19:52:19 +0900 Subject: [PATCH] Add init code Change-Id: I8a5cf2c1c14b16f7ec75ffe36b725997554bec7c Signed-off-by: Changyeon Lee --- AUTHORS | 1 + COPYING | 20 + ChangeLog | 0 INSTALL | 0 Makefile.am | 3 + NEWS | 0 README | 0 autogen.sh | 13 + configure.ac | 21 + packaging/xinfo.spec | 40 ++ src/Makefile.am | 10 + src/wininfo.c | 1046 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/xinfo.c | 325 ++++++++++++++++ src/xinfo.h | 59 +++ xinfo.manifest | 8 + 15 files changed, 1546 insertions(+) create mode 100755 AUTHORS create mode 100755 COPYING create mode 100755 ChangeLog create mode 100644 INSTALL create mode 100755 Makefile.am create mode 100755 NEWS create mode 100755 README create mode 100755 autogen.sh create mode 100755 configure.ac create mode 100755 packaging/xinfo.spec create mode 100755 src/Makefile.am create mode 100755 src/wininfo.c create mode 100755 src/xinfo.c create mode 100755 src/xinfo.h create mode 100755 xinfo.manifest diff --git a/AUTHORS b/AUTHORS new file mode 100755 index 0000000..8c2ea89 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +SooChan Lim diff --git a/COPYING b/COPYING new file mode 100755 index 0000000..b431e74 --- /dev/null +++ b/COPYING @@ -0,0 +1,20 @@ +Copyright (c) 2010 - 2014 Samsung Electronics Co., Ltd. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/ChangeLog b/ChangeLog new file mode 100755 index 0000000..e69de29 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/Makefile.am b/Makefile.am new file mode 100755 index 0000000..e0dde26 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + + diff --git a/NEWS b/NEWS new file mode 100755 index 0000000..e69de29 diff --git a/README b/README new file mode 100755 index 0000000..e69de29 diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..e81f989 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,13 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" + diff --git a/configure.ac b/configure.ac new file mode 100755 index 0000000..9eca04d --- /dev/null +++ b/configure.ac @@ -0,0 +1,21 @@ + +AC_PREREQ([2.57]) +AC_INIT(xinfo,[0.0.1], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],xinfo) +AM_INIT_AUTOMAKE([dist-bzip2]) +AM_MAINTAINER_MODE + +AM_CONFIG_HEADER(config.h) + +AC_PROG_CC +AC_PROG_INSTALL + +# Checks for pkg-config packages +PKG_CHECK_MODULES(XINFO, x11) +AC_SUBST(XINFO_CFLAGS) +AC_SUBST(XINFO_LIBS) + +XORG_MANPAGE_SECTIONS +XORG_RELEASE_VERSION + +AC_OUTPUT([src/Makefile + Makefile]) diff --git a/packaging/xinfo.spec b/packaging/xinfo.spec new file mode 100755 index 0000000..81873c6 --- /dev/null +++ b/packaging/xinfo.spec @@ -0,0 +1,40 @@ +Name: xinfo +Summary: Window system debug utility. +Version: 0.0.1 +Release: 1 +Group: TO_BE/FILLED_IN +License: TO BE FILLED IN +Source0: %{name}-%{version}.tar.gz +BuildRequires: pkgconfig(x11) + +# some file to be intalled can be ignored when rpm generates packages +#%define _unpackaged_files_terminate_build 0 + +%description +Description: Window system debug utility. + +%prep +%setup -q + +%build + +%reconfigure --prefix=%{_prefix} \ + CFLAGS="${CFLAGS} -Wall -Werror" + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} + +%make_install + +mkdir -p %{_bindir} + +%remove_docs + + +%files +%manifest xinfo.manifest +%defattr(-,root,root,-) +%{_bindir}/xinfo + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100755 index 0000000..ad2b7cb --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,10 @@ + +bin_PROGRAMS = xinfo + +xinfo_CFLAGS = $(XINFO_CFLAGS) +xinfo_LDADD = $(XINFO_LIBS) + +xinfo_SOURCES = \ + wininfo.c \ + xinfo.c + diff --git a/src/wininfo.c b/src/wininfo.c new file mode 100755 index 0000000..7ec70f0 --- /dev/null +++ b/src/wininfo.c @@ -0,0 +1,1046 @@ +/************************************************************************** + xinfo + + Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + + Contact: SooChan Lim + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sub license, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **************************************************************************/ + +#include +#include +#include +#include +#ifndef NO_I18N +#include +#endif +#include +#include +#include +#include +#include +#include + + +static void Display_Window_Id(FILE* fd, Window window, Bool newline_wanted); +static void Display_Pointed_Window_Info(FILE* fd); +static void Display_Focused_Window_Info(FILE* fd); + +Display *dpy; +Atom prop_pid; +Atom prop_c_pid; +Atom prop_class; +Atom prop_command; + +int screen = 0; +static const char *window_id_format = "0x%lx"; +static int win_cnt = 0; + + +typedef struct { + long code; + const char *name; +} binding; + +static const binding _map_states[] = { + { IsUnmapped, "IsUnMapped" }, + { IsUnviewable, "IsUnviewable" }, + { IsViewable, "IsViewable" }, + { 0, 0 } }; + +typedef struct _Wininfo { + struct _Wininfo *prev, *next; + int idx; + /*" PID WinID w h Rel_x Rel_y Abs_x Abs_y Depth WinName App_Name*/ + long pid; + Window winid; + Window BDid; + int w; + int h; + int rel_x; + int rel_y; + int abs_x; + int abs_y; + unsigned int depth; + char *winname; + char *appname; + char *appname_brief; + char *map_state; + char *ping_result; +} Wininfo, *WininfoPtr; + +/* + * Standard fatal error routine - call like printf + * Does not require dpy or screen defined. + */ +void Fatal_Error(const char *msg, ...) +{ + va_list args; + fflush(stdout); + fflush(stderr); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); + fprintf(stderr, "\n"); + exit(0); +} + + static void +Display_Pointed_Window_Info(FILE* fd) +{ + int rel_x, rel_y, abs_x, abs_y; + Window root_win, pointed_win; + unsigned int mask; + + XQueryPointer(dpy, RootWindow(dpy, 0), &root_win, &pointed_win, &abs_x, + &abs_y, &rel_x, &rel_y, &mask); + + if(pointed_win) + { + Display_Window_Id(fd, pointed_win, True); + } + else + { + fprintf(fd, "no pointed window\n"); + } + + +} + + static void +Display_Focused_Window_Info(FILE* fd) +{ + int revert_to; + Window focus_win; + + XGetInputFocus( dpy, &focus_win, &revert_to); + + if(focus_win) + { + Display_Window_Id(fd, focus_win, True); + } + +} + + static void +Display_Window_Id(FILE* fd, Window window, Bool newline_wanted) +{ +#ifdef NO_I18N + char *win_name; +#else + XTextProperty tp; +#endif + fprintf(fd, "[winID:"); + fprintf(fd, window_id_format, window); /* print id # in hex/dec */ + fprintf(fd, "]"); + if (!window) { + fprintf(fd, " (none)"); + } else { + if (window == RootWindow(dpy, screen)) { + fprintf(fd, " (the root window)"); + } +#ifdef NO_I18N + if (!XFetchName(dpy, window, &win_name)) { /* Get window name if any */ + fprintf(fd, " (has no name)"); + } else if (win_name) { + fprintf(fd, " \"%s\"", win_name); + XFree(win_name); + } +#else + if (!XGetWMName(dpy, window, &tp)) { /* Get window name if any */ + fprintf(fd, " (has no name)"); + } else if (tp.nitems > 0) { + fprintf(fd, " \""); + { + int count = 0, i, ret; + char **list = NULL; + ret = XmbTextPropertyToTextList(dpy, &tp, &list, &count); + if((ret == Success || ret > 0) && list != NULL){ + for(i=0; iidx = win_cnt++; + wininfo->next = NULL; + wininfo->prev = NULL; + return wininfo; +} + + static void +free_wininfo(WininfoPtr wininfo) +{ + WininfoPtr w; + /* TODO : free winname and appname map_state*/ + w = wininfo; + while(1) + { + + if(w && w->next) + w = w->next; + else + break; + + } + + while(1) + { + if(w && w->prev) + { + w = w->prev; + if(w && w->next) + free(w->next); + } + else + { + if(w) + free(w); + break; + } + } +} + + + + static void +get_winname(Window window, char* str) +{ + XTextProperty tp; + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + char *class_name = NULL; + + + if (window) + { + if (window == RootWindow(dpy, screen)) + { + printf(" (the root window)"); + } + + if (XGetWMName(dpy, window, &tp)) + { + if (tp.nitems > 0) + { + int count = 0, i, ret; + char **list = NULL; + ret = XmbTextPropertyToTextList(dpy, &tp, &list, &count); + if((ret == Success || ret > 0) && list != NULL) + { + for(i=0; iname) { + if (table->code == code) { + name = table->name; + break; + } + table++; + } + + return(name); +} + + static const char * +Lookup(int code, const binding *table) +{ + return LookupL((long)code, table); +} + + static int +get_map_status(Window window) +{ + XWindowAttributes win_attributes; + + if (!XGetWindowAttributes(dpy, window, &win_attributes)) + printf("Can't get window attributes."); + + if( win_attributes.map_state == 0 ) + return 0; + else + return win_attributes.map_state; +} + +static int Ping_Event_Loop() +{ + XEvent e; + + while (XPending (dpy)) { + XFlush( dpy ); + XNextEvent(dpy, &e); + /* draw or redraw the window */ + if (e.type == Expose) { + fprintf(stderr," Expose \n"); + } + /* exit on key press */ + if (e.type == KeyPress) { + fprintf(stderr," KeyPress \n"); + break; + } + if (e.type == ClientMessage ) { + return 1; + } + } + return 0; +} + + static void +Send_Ping_to_Window(Window window) +{ + XClientMessageEvent xclient; + Display* display = dpy; + + memset (&xclient, 0, sizeof (xclient)); + xclient.type = ClientMessage; + xclient.window = window; + + xclient.message_type = XInternAtom (display, "WM_PROTOCOLS",0); + + xclient.format = 32; + + xclient.data.l[0] = XInternAtom (display, "_NET_WM_PING",0); + xclient.data.l[1] = 0; + // fprintf(stderr,"<0x%x>\n", window); + XSendEvent (display, window, 0, + None, + (XEvent *)&xclient); + XFlush( dpy ); + +} + + + +void print_default(FILE* fd, Window root_win, int num_children) +{ + fprintf(fd, " \n"); + fprintf(fd, " Root window id :"); + Display_Window_Id(fd, root_win, True); + fprintf(fd, " Pointed window :"); + Display_Pointed_Window_Info(fd); + fprintf(fd, " Input Focused window :"); + Display_Focused_Window_Info(fd); + fprintf(fd, "\n"); + fprintf(fd, "%d Top level windows\n", num_children); +} + +void gen_output(XinfoPtr pXinfo, WininfoPtr pWininfo) +{ + int i; + FILE* fd; + pid_t pid; + + int val = pXinfo->xinfo_val; + WininfoPtr w = pWininfo; + char* name = pXinfo->xinfovalname; + char* path = pXinfo->pathname; + char* file = pXinfo->filename; + char *argument[6]; + char *argument_props_root[3]; + char *argument_props_id[4]; + int child_status=0; + + Window root_win = RootWindow(dpy, screen); + int num_children = win_cnt; + + argument[2] = (char *)malloc(sizeof(char)*15); + argument[4] = (char *)malloc(sizeof(char)*255); + + argument[0] = strdup("xwd"); + argument[1] = strdup("-id"); + argument[3] = strdup("-out"); + argument[5] = NULL; + + fd = pXinfo->output_fd; + fprintf(stderr, "[%s] Start to logging ", name); + if(path && file) + fprintf(stderr, "at %s/%s\n", path, file); + else + fprintf(stderr, "\n"); + if(val == XINFO_TOPWINS) + { + print_default(fd, root_win, num_children); + fprintf( fd, "----------------------------------[ %s ]-------------------------------------------------------------------------------\n", name); + fprintf( fd, " No PID WinID w h Rel_x Rel_y Abs_x Abs_y Depth WinName AppName\n" ); + fprintf( fd, "----------------------------------------------------------------------------------------------------------------------------\n" ); + + for(i = 0; i < win_cnt; i++) + { + fprintf(fd, "%3i %6ld 0x%-7lx %4i %4i %5i %5i %5i %5i %5i %-35s %-35s\n", + (w->idx+1),w->pid,w->winid,w->w,w->h,w->rel_x,w->rel_y,w->abs_x,w->abs_y,w->depth,w->winname,w->appname_brief); + + w = w->next; + } + } + else if(val == XINFO_TOPVWINS) + { + print_default(fd, root_win, num_children); + fprintf( fd, "----------------------------------[ %s ]------------------------------------------------------------------------------------------------\n", name); + fprintf( fd, " No PID BorderID WinID w h Rel_x Rel_y Abs_x Abs_y Depth WinName AppName map state \n" ); + fprintf( fd, "----------------------------------------------------------------------------------------------------------------------------------------------\n" ); + + for(i = 0; i < win_cnt; i++) + { + fprintf( fd, "%3i %6ld 0x%-7lx 0x%-8lx %4i %4i %5i %5i %5i %5i %5i %-25s %-25s %-30s\n", + (w->idx+1),w->pid,w->BDid,w->winid,w->w,w->h,w->rel_x,w->rel_y,w->abs_x,w->abs_y,w->depth,w->winname, w->appname_brief,w->map_state); + + w = w->next; + } + } + else if(val == XINFO_TOPVWINS_PROPS) + { + print_default(fd, root_win, num_children); + + fprintf( fd, "###[ Root Window ]###\n"); + fprintf( fd, "ID: 0x%lx\n", root_win); + fprintf( fd, "######\n" ); + argument_props_root[0] = strdup("/usr/bin/xprop"); + argument_props_root[1] = strdup("-root"); + argument_props_root[2] = NULL; + fflush(fd); + switch(pid = fork()) + { + case 0: + if (execv("/usr/bin/xprop", argument_props_root) == -1) + { + fprintf(fd, "failed to excute 'xprop -root'\n"); + exit(1); + } + break; + default: + break; + } + waitpid(pid, &child_status, WUNTRACED); + fflush(fd); + + argument_props_id[0] = strdup("/usr/bin/xprop"); + argument_props_id[1] = strdup("-id"); + argument_props_id[2] = (char *)malloc(sizeof(char)*15); + argument_props_id[3] = NULL; + for(i = 0; i < win_cnt; i++) + { + fprintf( fd, "\n###[ Window ID: 0x%x ]###\n", (unsigned int)w->winid); + fprintf( fd, "PID: %ld\n", w->pid); + fprintf( fd, "Border ID: 0x%x\n", (unsigned int)w->BDid); + fprintf( fd, "###\n" ); + snprintf(argument_props_id[2], 15, "0x%-7x", (unsigned int)w->BDid); + fflush(fd); + switch(pid = fork()) + { + case 0: + if (execv("/usr/bin/xprop", argument_props_id) == -1) + { + fprintf(stderr, "failed to excute 'xprop' \n"); + exit(1); + } + break; + default: + break; + } + waitpid(pid, &child_status, WUNTRACED); + fflush(fd); + fprintf( fd, "###\n" ); + fprintf( fd, "Win Name : %s\n", w->winname); + fprintf( fd, "Window ID: 0x%x\n", (unsigned int)w->winid); + fprintf( fd, "######\n" ); + snprintf(argument_props_id[2], 15, "0x%-7x", (unsigned int)w->winid); + fflush(fd); + switch(pid = fork()) + { + case 0: + if (execv("/usr/bin/xprop", argument_props_id) == -1) + { + fprintf(stderr, "failed to excute 'xprop' \n"); + exit(1); + } + break; + default: + break; + } + waitpid(pid, &child_status, WUNTRACED); + fflush(fd); + fprintf( fd, "######\n" ); + + w = w->next; + } + free(argument_props_id[0]); + free(argument_props_id[1]); + free(argument_props_id[2]); + + free(argument_props_root[0]); + free(argument_props_root[1]); + } + else if(val == XINFO_PING) + { + print_default(fd, root_win, num_children); + fprintf( fd, "----------------------------------[ %s ]-----------------------------------------------------------------------------------------------------\n", name); + fprintf( fd, " No PID WinID w h WinName AppName Ping Command\n" ); + fprintf( fd, "-----------------------------------------------------------------------------------------------------------------------------------------------\n" ); + + for(i = 0; i < win_cnt; i++) + { + fprintf( fd, "%3i %6ld 0x%-7lx %4i %4i %-30s %-30s %-20s %-40s\n", + (w->idx+1),w->pid,w->winid,w->w,w->h, w->winname, w->appname_brief,w->ping_result,w->appname); + + w = w->next; + } + } + else if(val == XINFO_XWD_TOPVWINS) + { + fprintf( stderr, " [START] %s : the path to store the xwd files is %s \n", name, path); + + /* dump root window */ + snprintf(argument[2], 15,"0x%-7lx", root_win); + snprintf(argument[4], 255,"%s/root_win.xwd", path); + + switch(pid = fork()) + { + case 0: + if (execv("/usr/bin/xwd", argument) == -1) + { + fprintf(stderr, "execv error root xwd\n"); + exit(1); + } + break; + default: + break; + } + + for(i = 0; i < win_cnt; i++) + { + snprintf(argument[2], 15, "0x%-7lx", w->winid); + snprintf(argument[4], 255, "%s/0x%-7lx.xwd", path, w->winid); + + switch(pid = fork()) + { + case 0: + if (execv("/usr/bin/xwd", argument) == -1) + { + fprintf(stderr, "execv error other xwd\n"); + exit(1); + } + break; + default: + break; + } + w = w->next; + } + fprintf( stderr, " [FINISH] %s : the path to store the xwd files is %s \n", name, path); + } + else if(val == XINFO_XWD_WIN) + { + fprintf( stderr, " [START] %s : the path to store the xwd files is %s \n", name, path); + + snprintf(argument[2], 15, "0x%-7x", pXinfo->win); + snprintf(argument[4], 255, "%s/0x%-7x.xwd", path, pXinfo->win); + + switch(pid = fork()) + { + case 0: + if (execv("/usr/bin/xwd", argument) == -1) + { + fprintf(stderr, "execv error window xwd\n"); + exit(1); + } + break; + default: + break; + } + fprintf( stderr, " [FINISH] %s : the path to store the xwd files is %s \n", name, path); + } + fprintf(stderr, "[%s] Finish to logging ", name); + if(path && file) + fprintf(stderr, "at %s/%s\n", path, file); + else + fprintf(stderr, "\n"); + free(name); + if (argument[1]) + free (argument[1]); + if(argument[2]) + free(argument[2]); + if(argument[3]) + free(argument[3]); + if(argument[4]) + free(argument[4]); +} + + +static Window get_user_created_window(Window win) +{ + + Atom type_ret = 0; + int ret, size_ret = 0; + unsigned long num_ret = 0, bytes = 0; + unsigned char *prop_ret = NULL; + unsigned int xid; + Atom prop_user_created_win; + + prop_user_created_win = XInternAtom(dpy, "_E_USER_CREATED_WINDOW", False); + + ret = XGetWindowProperty(dpy, win, prop_user_created_win, 0L, 1L, + False, XA_WINDOW, &type_ret, &size_ret, + &num_ret, &bytes, &prop_ret); + + if( ret != Success ) + { + if( prop_ret ) XFree( (void*)prop_ret ); + return win; + } + else if( !prop_ret ) + { + return win; + } + + memcpy( &xid, prop_ret, sizeof(unsigned int) ); + XFree( (void *)prop_ret ); + + return xid; + +} + +#if 0 +static int cb_x_error(Display *disp, XErrorEvent *ev) +{ + return 0; +} +#endif + + void +display_topwins(XinfoPtr pXinfo) +{ + int i; + int rel_x, rel_y, abs_x, abs_y; + unsigned int width, height, border, depth; + Window root_win, parent_win; + unsigned int num_children; + Window *child_list; + long *pid = NULL; + // char *command_name = NULL; + // char *class_name = NULL; + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + Window window; + + int wininfo_val = pXinfo->xinfo_val; + + /* open a display and get a default screen */ + dpy = XOpenDisplay(0); + if(!dpy) + { + printf("Fail to open display\n"); + exit(0); + } + + /* get a screen*/ + screen = DefaultScreen(dpy); + + /* get a root window id */ + window = RootWindow(dpy, screen); + + // /* set a error handler */ + // m_old_error = XSetErrorHandler(cb_x_error); + + if(wininfo_val == XINFO_PING) + XSelectInput (dpy, window, ExposureMask| SubstructureNotifyMask); + + /* XINFO_XWD_WIN do not need to gethering window information */ + if(wininfo_val == XINFO_XWD_WIN) + { + gen_output(pXinfo, NULL); + return; + } + + /* query a window tree */ + if (!XQueryTree(dpy, window, &root_win, &parent_win, &child_list, &num_children)) + Fatal_Error("Can't query window tree."); + + /* get a properties */ + prop_pid = XInternAtom(dpy, "_NET_WM_PID", False); + prop_c_pid = XInternAtom(dpy, "X_CLIENT_PID", False); + prop_class = XInternAtom(dpy, "WM_CLASS", False); + prop_command = XInternAtom(dpy, "WM_COMMAND", False); + + /* gathering the wininfo infomation */ + WininfoPtr prev_wininfo = NULL; + WininfoPtr cur_wininfo = NULL; + WininfoPtr origin_wininfo = NULL; + int map_state; + + /* Make the wininfo list */ + for (i = (int)num_children - 1; i >= 0; i--) + { + if(wininfo_val == XINFO_TOPVWINS || wininfo_val == XINFO_XWD_TOPVWINS || wininfo_val == XINFO_TOPVWINS_PROPS) + { + /* figure out whether the window is mapped or not */ + map_state = get_map_status(child_list[i]); + if(!map_state) + continue; + else + { + cur_wininfo = alloc_wininfo(); + cur_wininfo->map_state = (char*) calloc(1, 255*sizeof(char)); + snprintf(cur_wininfo->map_state, 255, " %s ", Lookup(map_state, _map_states)); + + /* get the winid */ + cur_wininfo->winid = child_list[i]; + cur_wininfo->BDid = child_list[i]; + } + } + else if(wininfo_val == XINFO_TOPWINS || wininfo_val == XINFO_PING) + { + cur_wininfo = alloc_wininfo(); + + /* get the winid */ + cur_wininfo->winid = child_list[i]; + cur_wininfo->BDid = child_list[i]; + } + else + { + printf("Error . no valid win_state\n"); + exit(1); + } + + if(prev_wininfo) + { + prev_wininfo->next = cur_wininfo; + cur_wininfo->prev = prev_wininfo; + } + else + origin_wininfo = cur_wininfo; + + /* set the pre_wininfo is the cur_wininfo now */ + prev_wininfo = cur_wininfo; + } + + if (origin_wininfo == NULL) + return; + + /* check the window generated in client side not is done by window manager */ + WininfoPtr w = origin_wininfo; + Window winid = 0; + for(i = 0; i < win_cnt; i++) + { + winid = get_user_created_window(w->winid); + w->winid = winid; + + /* move to the next wininfo */ + w = w->next; + } + + + /* check other infomation out */ + w = origin_wininfo; + for(i = 0; i < win_cnt; i++) + { + /* get pid */ + if (XGetWindowProperty(dpy, w->winid, prop_pid, + 0, 2L, + False, XA_CARDINAL, + &actual_type, &actual_format, &nitems, + &bytes_after, (unsigned char **)&pid) == Success + && nitems && pid != NULL) + { + w->pid = *pid; + } + else if (XGetWindowProperty(dpy, w->winid, prop_c_pid, + 0, 2L, + False, XA_CARDINAL, + &actual_type, &actual_format, &nitems, + &bytes_after, (unsigned char **)&pid) == Success + && nitems && pid != NULL) + { + w->pid = *pid; + } + else + { + w->pid = 0; + } + + Window child; + /* get the geometry info and depth*/ + if (XGetGeometry(dpy, w->winid, &root_win, &rel_x, &rel_y, &width, &height, &border, &depth)) + { + w->w = width; + w->h = height; + w->rel_x = rel_x; + w->rel_y = rel_y; + + if (XTranslateCoordinates (dpy, w->winid, root_win, 0 ,0, &abs_x, &abs_y, &child)) + { + w->abs_x = abs_x -border; + w->abs_y = abs_y - border; + } + } + + /* get the depth */ + w->depth = depth; + + /* get the winname */ + w->winname = (char*) calloc(1, 255*sizeof(char)); + get_winname(w->winid, w->winname); +#if 0 + /* get app_name from WM_COMMAND or WM_CLASS */ + w->appname = (char*) calloc(1, 255*sizeof(char)); + if (XGetWindowProperty(dpy, w->winid, prop_command, + 0, 10000000L, + False, AnyPropertyType, + &actual_type, &actual_format, &nitems, + &bytes_after, (unsigned char **)&command_name) == Success + && nitems && command_name != NULL) + { + strncpy(w->appname, command_name, strlen(command_name)+1); + } + else + { + if (XGetWindowProperty(dpy, w->winid, prop_class, + 0, 10000000L, + False, AnyPropertyType, + &actual_type, &actual_format, &nitems, + &bytes_after, (unsigned char **)&class_name) == Success + && nitems && class_name != NULL) + { + strncpy(w->appname, class_name, strlen(class_name)+1); + } + else + { + if (w->appname) + free (w->appname); + w->appname = NULL; + } + } + if(command_name) + { + XFree(command_name); + command_name = NULL; + } + if(class_name) + { + XFree(class_name); + class_name = NULL; + } + + if (w->appname) { + w->appname_brief = (char*) calloc(1, 255*sizeof(char)); + + strncpy(w->appname_brief, w->appname, 255*sizeof(char)-1); + + get_appname_brief (w->appname_brief); + } +#else + /* get app_name from pid */ + if(w->pid) + { + w->appname = (char*) calloc(1, 255*sizeof(char)); + get_appname_from_pid(w->pid, w->appname); + + w->appname_brief = (char*) calloc(1, 255*sizeof(char)); + strncpy(w->appname_brief, w->appname, 255*sizeof(char)-1); + get_appname_brief (w->appname_brief); + } + else + w->appname = NULL; +#endif + if (pid) + { + XFree(pid); + pid = NULL; + } + + /* ping test info */ + if(wininfo_val == XINFO_PING) + { + Send_Ping_to_Window(w->winid); + usleep(50000); + w->ping_result = (char*) calloc(1, 255*sizeof(char)); + if(Ping_Event_Loop()) + snprintf(w->ping_result, 255, " Success "); + else + snprintf(w->ping_result, 255, " Fail "); + } + + /* move to the next wininfo */ + w = w->next; + } + + + + /* ping test */ + gen_output(pXinfo, origin_wininfo); + + if (child_list) + XFree((char *)child_list); + + free_wininfo(origin_wininfo); + +} + + + + diff --git a/src/xinfo.c b/src/xinfo.c new file mode 100755 index 0000000..fe2e6b0 --- /dev/null +++ b/src/xinfo.c @@ -0,0 +1,325 @@ +/************************************************************************** + +xinfo + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +void display_topwins(XinfoPtr pXinfo); + +static long parse_long (char *s) +{ + const char *fmt = "%lu"; + long retval = 0L; + int thesign = 1; + + if (s && s[0]) { + if (s[0] == '-') s++, thesign = -1; + if (s[0] == '0') s++, fmt = "%lo"; + if (s[0] == 'x' || s[0] == 'X') s++, fmt = "%lx"; + (void) sscanf (s, fmt, &retval); + } + return (thesign * retval); +} + +static void free_xinfo(XinfoPtr pXinfo) +{ + FILE *fd; + if(pXinfo) + { + fd = pXinfo->output_fd; + if(fd != stderr) + fclose(fd); + free(pXinfo); + } +} + +static void +make_directory(XinfoPtr pXinfo, char *args) +{ + char tmp1[255], tmp2[255], tmp3[255]; + time_t timer; + struct tm *t, *buf; + pid_t pid; + char *argument[4]; + + timer = time(NULL); + if (!timer) + { + fprintf(stderr,"fail to get time\n"); + exit(1); + } + + buf = calloc (1, sizeof (struct tm)); + t = localtime_r(&timer, buf); + if (!t) + { + fprintf(stderr,"fail to get local time\n"); + exit(1); + } + + pXinfo->pathname = (char*) calloc(1, 255*sizeof(char)); + + if(pXinfo->xinfo_val == XINFO_XWD_TOPVWINS) + { + if(args) + snprintf(tmp1, 255, "%s", args); + else + snprintf(tmp1, 255, "./"); + } + else if(pXinfo->xinfo_val == XINFO_XWD_WIN) + { + if(args) + snprintf(tmp1, 255, "./"); + } + + /* make the folder for the result of xwd files */ + snprintf(tmp2, 255, "%s_%02d%02d-%02d%02d%02d", pXinfo->xinfovalname, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); + snprintf(pXinfo->pathname, 255, "%s/%s",tmp1, tmp2); + snprintf(tmp3, 255, "%s", pXinfo->pathname); + argument[0] = strdup ("/bin/mkdir"); + argument[1] = strdup ("-p"); + argument[2] = tmp3; + argument[3] = NULL; + switch(pid = fork()) + { + case 0: + if (execv("/bin/mkdir", argument) == -1) + { + free (argument [0]); + free (argument [1]); + free (buf); + fprintf(stderr, "error execv: mkdir\n"); + exit(1); + } + break; + default: + break; + } + free (argument [0]); + free (argument [1]); + free (buf); +} + +static void +init_xinfo(XinfoPtr pXinfo, int xinfo_val, char* args) +{ + char full_pathfile[255]; + time_t timer; + struct tm *t, *buf; + int is_xwd = FALSE; + int is_xwd_win = FALSE; + + timer = time(NULL); + if (!timer) + { + fprintf(stderr,"fail to get time\n"); + exit(1); + } + + buf = calloc (1, sizeof(struct tm)); + t = localtime_r(&timer, buf); + if (!t) + { + fprintf(stderr,"fail to get local time\n"); + free(buf); + exit(1); + } + + pXinfo->xinfo_val = xinfo_val; + + pXinfo->xinfovalname = (char*) calloc(1, 255*sizeof(char)); + switch(pXinfo->xinfo_val) + { + case XINFO_TOPWINS: + snprintf(pXinfo->xinfovalname, 255, "%s", "topwins"); + break; + case XINFO_TOPVWINS: + snprintf(pXinfo->xinfovalname, 255, "%s", "topvwins"); + break; + case XINFO_PING: + snprintf(pXinfo->xinfovalname, 255, "%s", "ping"); + break; + case XINFO_XWD_TOPVWINS: + snprintf(pXinfo->xinfovalname, 255, "%s", "xwd_topvwins"); + is_xwd = TRUE; + break; + case XINFO_XWD_WIN: + snprintf(pXinfo->xinfovalname, 255, "%s", "xwd_win"); + is_xwd = TRUE; + is_xwd_win = TRUE; + break; + case XINFO_TOPVWINS_PROPS: + snprintf(pXinfo->xinfovalname, 255, "%s", "topvwins_props"); + break; + default: + break; + } + + if(is_xwd) + { + make_directory(pXinfo, args); + pXinfo->output_fd = stderr; + pXinfo->filename = NULL; + if(is_xwd_win) + pXinfo->win = parse_long(args); + goto out; + } + + /* set the path and output_fd */ + if(!args) + { + pXinfo->output_fd = stderr; + pXinfo->filename = NULL; + pXinfo->pathname = NULL; + goto out; + } + else + { + pXinfo->pathname = (char*) calloc(1, 255*sizeof(char)); + pXinfo->filename = (char*) calloc(1, 255*sizeof(char)); + + snprintf(pXinfo->pathname, 255, "%s", args); + snprintf(pXinfo->filename, 255, "%s_%02d%02d-%02d%02d%02d.log", pXinfo->xinfovalname, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); + snprintf(full_pathfile, 255, "%s/%s", pXinfo->pathname, pXinfo->filename); + pXinfo->output_fd = fopen(full_pathfile, "a+"); + if(pXinfo->output_fd == NULL) + { + fprintf(stderr, "Error - can open file \n"); + free_xinfo(pXinfo); + free(buf); + exit(1); + } + } +out: + free(buf); + return; +} + + + +static void +usage() +{ + fprintf(stderr,"usage : xinfo [-options] [output_path] \n\n"); + fprintf(stderr,"where options include: \n"); + fprintf(stderr," -topwins [output_path] : print all top level windows. (default output_path : stdout) \n"); + fprintf(stderr," -topvwins [output_path] : print all top level visible windows (default output_path : stdout) \n"); + fprintf(stderr," -ping or -p [output_path] : ping test for all top level windows (default output_path : stdout) \n"); + fprintf(stderr," -xwd_topvwins [output_path] : dump topvwins (default output_path : current working directory) \n"); + fprintf(stderr," -xwd_win [window id] : dump window id (a xwd file stores in current working directory) \n"); + fprintf(stderr," -topvwins_props : print all top level visible windows's property \n"); + fprintf(stderr,"\n\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + XinfoPtr pXinfo; + + int xinfo_value = -1; + if(argv[1]) + { + if( !strcmp(argv[1],"-h") || !strcmp(argv[1],"-help")) + usage(); + else if(!strcmp(argv[1], "-topwins")) + { + xinfo_value = XINFO_TOPWINS; + } + else if(!strcmp(argv[1], "-topvwins")) + { + xinfo_value = XINFO_TOPVWINS; + } + else if(!strcmp(argv[1], "-ping") || !strcmp(argv[1], "-p") ) + { + xinfo_value = XINFO_PING; + } + else if(!strcmp(argv[1], "-xwd_topvwins")) + { + xinfo_value = XINFO_XWD_TOPVWINS; + } + else if(!strcmp(argv[1], "-xwd_win")) + { + xinfo_value = XINFO_XWD_WIN; + if(!argv[2]) + { + fprintf(stderr, "Error : no window id \n"); + usage(); + exit(1); + } + } + else if(!strcmp(argv[1], "-topvwins_props")) + { + xinfo_value = XINFO_TOPVWINS_PROPS; + } + + else + usage(); + + pXinfo = (XinfoPtr) malloc(sizeof(Xinfo)); + if(!pXinfo) + { + fprintf(stderr, " alloc error \n"); + exit(1); + } + + if(argv[2]) + init_xinfo(pXinfo, xinfo_value, argv[2]); + else + init_xinfo(pXinfo, xinfo_value, NULL); + + if(xinfo_value == XINFO_TOPWINS || xinfo_value == XINFO_TOPVWINS || xinfo_value == XINFO_PING || + xinfo_value == XINFO_XWD_TOPVWINS || xinfo_value == XINFO_XWD_WIN || xinfo_value == XINFO_TOPVWINS_PROPS) + { + display_topwins(pXinfo); + } + else + { + fprintf(stderr, "error unsupported xinfo vaule\n"); + goto error; + } + + + } + else + usage(); + +error: + free_xinfo(pXinfo); + + return 0; +} + + + diff --git a/src/xinfo.h b/src/xinfo.h new file mode 100755 index 0000000..b8b25dd --- /dev/null +++ b/src/xinfo.h @@ -0,0 +1,59 @@ +/************************************************************************** + +xinfo + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef _XINFO_ +#define _XINFO_ 1 + +#define TRUE 1 +#define FALSE 0 + +enum XINFO_VAL +{ + XINFO_TOPWINS, + XINFO_TOPVWINS, + XINFO_PING, + XINFO_XWD_TOPVWINS, + XINFO_XWD_WIN, + XINFO_TOPVWINS_PROPS +}; + +typedef struct _Xinfo { + int xinfo_val; + FILE* output_fd; + char* xinfovalname; + char* filename; + char* pathname; + unsigned int win; /* window id from command line */ +} Xinfo, *XinfoPtr; + +#endif + + + diff --git a/xinfo.manifest b/xinfo.manifest new file mode 100755 index 0000000..34e771a --- /dev/null +++ b/xinfo.manifest @@ -0,0 +1,8 @@ + + + + + + + + -- 2.7.4