Add init code
[platform/core/uifw/xinfo.git] / src / wininfo.c
1 /**************************************************************************
2   xinfo
3
4   Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
5
6   Contact: SooChan Lim <sc1.lim@samsung.com>
7
8   Permission is hereby granted, free of charge, to any person obtaining a
9   copy of this software and associated documentation files (the
10   "Software"), to deal in the Software without restriction, including
11   without limitation the rights to use, copy, modify, merge, publish,
12   distribute, sub license, and/or sell copies of the Software, and to
13   permit persons to whom the Software is furnished to do so, subject to
14   the following conditions:
15
16   The above copyright notice and this permission notice (including the
17   next paragraph) shall be included in all copies or substantial portions
18   of the Software.
19
20   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23   IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24   ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28  **************************************************************************/
29
30 #include <X11/Xlib.h>
31 #include <X11/Xutil.h>
32 #include <X11/Xatom.h>
33 #include <X11/Xos.h>
34 #ifndef NO_I18N
35 #include <X11/Xlocale.h>
36 #endif
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <stdarg.h>
40 #include <unistd.h>
41 #include <xinfo.h>
42 #include <wait.h>
43
44
45 static void Display_Window_Id(FILE* fd, Window window, Bool newline_wanted);
46 static void Display_Pointed_Window_Info(FILE* fd);
47 static void Display_Focused_Window_Info(FILE* fd);
48
49 Display *dpy;
50 Atom prop_pid;
51 Atom prop_c_pid;
52 Atom prop_class;
53 Atom prop_command;
54
55 int      screen = 0;
56 static const char *window_id_format = "0x%lx";
57 static int win_cnt = 0;
58
59
60 typedef struct {
61     long code;
62     const char *name;
63 } binding;
64
65 static const binding _map_states[] = {
66     { IsUnmapped, "IsUnMapped" },
67     { IsUnviewable, "IsUnviewable" },
68     { IsViewable, "IsViewable" },
69     { 0, 0 } };
70
71 typedef struct  _Wininfo {
72     struct _Wininfo *prev, *next;
73     int idx;
74     /*" PID   WinID     w  h Rel_x Rel_y Abs_x Abs_y Depth          WinName      App_Name*/
75     long pid;
76     Window winid;
77     Window BDid;
78     int w;
79     int h;
80     int rel_x;
81     int rel_y;
82     int abs_x;
83     int abs_y;
84     unsigned int depth;
85     char *winname;
86     char *appname;
87     char *appname_brief;
88     char *map_state;
89     char *ping_result;
90 } Wininfo, *WininfoPtr;
91
92 /*
93  * Standard fatal error routine - call like printf
94  * Does not require dpy or screen defined.
95  */
96 void Fatal_Error(const char *msg, ...)
97 {
98     va_list args;
99     fflush(stdout);
100     fflush(stderr);
101     va_start(args, msg);
102     vfprintf(stderr, msg, args);
103     va_end(args);
104     fprintf(stderr, "\n");
105     exit(0);
106 }
107
108     static void
109 Display_Pointed_Window_Info(FILE* fd)
110 {
111     int rel_x, rel_y, abs_x, abs_y;
112     Window root_win, pointed_win;
113     unsigned int mask;
114
115     XQueryPointer(dpy, RootWindow(dpy, 0), &root_win, &pointed_win, &abs_x,
116             &abs_y, &rel_x, &rel_y, &mask);
117
118     if(pointed_win)
119     {
120         Display_Window_Id(fd, pointed_win, True);
121     }
122     else
123     {
124         fprintf(fd, "no pointed window\n");
125     }
126
127
128 }
129
130     static void
131 Display_Focused_Window_Info(FILE* fd)
132 {
133     int revert_to;
134     Window focus_win;
135
136     XGetInputFocus( dpy, &focus_win, &revert_to);
137
138     if(focus_win)
139     {
140         Display_Window_Id(fd, focus_win, True);
141     }
142
143 }
144
145     static void
146 Display_Window_Id(FILE* fd, Window window, Bool newline_wanted)
147 {
148 #ifdef NO_I18N
149     char *win_name;
150 #else
151     XTextProperty tp;
152 #endif
153     fprintf(fd, "[winID:");
154     fprintf(fd, window_id_format, window);         /* print id # in hex/dec */
155     fprintf(fd, "]");
156     if (!window) {
157         fprintf(fd, " (none)");
158     } else {
159         if (window == RootWindow(dpy, screen)) {
160             fprintf(fd, " (the root window)");
161         }
162 #ifdef NO_I18N
163         if (!XFetchName(dpy, window, &win_name)) { /* Get window name if any */
164             fprintf(fd, " (has no name)");
165         } else if (win_name) {
166             fprintf(fd, " \"%s\"", win_name);
167             XFree(win_name);
168         }
169 #else
170         if (!XGetWMName(dpy, window, &tp)) { /* Get window name if any */
171             fprintf(fd, " (has no name)");
172         } else if (tp.nitems > 0) {
173             fprintf(fd, " \"");
174             {
175                 int count = 0, i, ret;
176                 char **list = NULL;
177                 ret = XmbTextPropertyToTextList(dpy, &tp, &list, &count);
178                 if((ret == Success || ret > 0) && list != NULL){
179                     for(i=0; i<count; i++)
180                         fprintf(fd, "%s", list[i]);
181                     XFreeStringList(list);
182                 } else {
183                     fprintf(fd, "%s", tp.value);
184                 }
185             }
186             fprintf(fd, "\"");
187         }
188 #endif
189         else
190             fprintf(fd, " (has no name)");
191     }
192
193     if (newline_wanted)
194         fprintf(fd, "\n");
195
196     return;
197 }
198
199     static WininfoPtr
200 alloc_wininfo()
201 {
202     WininfoPtr wininfo;
203     wininfo = (WininfoPtr) malloc(sizeof(Wininfo));
204     if(!wininfo)
205     {
206         fprintf(stderr, " alloc error \n");
207         exit(1);
208     }
209     wininfo->idx = win_cnt++;
210     wininfo->next = NULL;
211     wininfo->prev = NULL;
212     return wininfo;
213 }
214
215     static void
216 free_wininfo(WininfoPtr wininfo)
217 {
218     WininfoPtr w;
219     /* TODO : free winname and appname map_state*/
220     w = wininfo;
221     while(1)
222     {
223
224         if(w && w->next)
225             w = w->next;
226         else
227             break;
228
229     }
230
231     while(1)
232     {
233         if(w && w->prev)
234         {
235             w = w->prev;
236             if(w && w->next)
237                 free(w->next);
238         }
239         else
240         {
241             if(w)
242                 free(w);
243             break;
244         }
245     }
246 }
247
248
249
250     static void
251 get_winname(Window window, char* str)
252 {
253     XTextProperty tp;
254     Atom actual_type;
255     int actual_format;
256     unsigned long nitems, bytes_after;
257     char *class_name = NULL;
258
259
260     if (window)
261     {
262         if (window == RootWindow(dpy, screen))
263         {
264             printf(" (the root window)");
265         }
266
267         if (XGetWMName(dpy, window, &tp))
268         {
269             if (tp.nitems > 0)
270             {
271                 int count = 0, i, ret;
272                 char **list = NULL;
273                 ret = XmbTextPropertyToTextList(dpy, &tp, &list, &count);
274                 if((ret == Success || ret > 0) && list != NULL)
275                 {
276                     for(i=0; i<count; i++)
277                         snprintf(str, 255, "%s", *list);
278                     XFreeStringList(list);
279                 }
280             }
281         }
282         else if (XGetWindowProperty(dpy, window, prop_class,
283                     0, 10000000L,
284                     False, AnyPropertyType,
285                     &actual_type, &actual_format, &nitems,
286                     &bytes_after, (unsigned char **)&class_name) == Success
287                 && nitems && class_name != NULL)
288         {
289             strncpy(str, class_name, strlen(class_name)+1);
290             if(class_name)
291             {
292                 XFree(class_name);
293                 class_name = NULL;
294             }
295
296
297         }
298     }
299 }
300
301 static void
302 get_appname_brief(char* brief)
303 {
304     char delim[] = "/";
305     char *token = NULL;
306     char temp[255] = {0,};
307     char *tokp = NULL;
308
309     token = strtok_r(brief, delim, &tokp);
310     while (token != NULL) {
311         memset(temp, 0x00, 255*sizeof(char));
312         strncpy(temp, token, 255*sizeof(char)-1);
313
314         token = strtok_r(NULL, delim, &tokp);
315     }
316
317     snprintf(brief, 255, "%s", temp);
318 }
319
320 static void
321 get_appname_from_pid(long pid, char* str)
322 {
323     FILE* fp;
324     int len;
325     long app_pid = pid;
326     char fn_cmdline[255] = {0,};
327     char cmdline[255] = {0,};
328
329     snprintf(fn_cmdline, 255,"/proc/%ld/cmdline",app_pid);
330
331     fp = fopen(fn_cmdline, "r");
332     if(fp==0)
333     {
334         fprintf(stderr,"cannot file open /proc/%ld/cmdline", app_pid);
335         exit(1);
336     }
337     if (!fgets(cmdline, 255, fp)) {
338         fprintf(stderr,"cannot fgets /proc/%ld/cmdline", app_pid);
339     }
340     fclose(fp);
341
342     len = strlen(cmdline);
343     if(len < 1)
344         memset(cmdline, 0x00,255);
345     else
346         cmdline[len] = 0;
347
348 #if 0
349     if(strstr(cmdline, "app-domain") != NULL)
350     {
351         char temp_buf[255] = {0,};
352         char* buf = NULL;
353         memset(fn_cmdline, 0x00, 255);
354         snprintf(fn_cmdline, 255, "/proc/%ld/maps", app_pid);
355         fp = fopen(fn_cmdline, "r");
356         if(fp==0)
357         {
358             fprintf(stderr,"cannot file open /proc/%ld/maps", app_pid);
359             exit(1);
360         }
361
362         while(!feof(fp))
363         {
364             fgets(temp_buf, 255, fp);
365             if(!(buf = strstr(temp_buf, "/com.samsung")))
366                 continue;
367             if(buf != NULL) {
368                 buf = strstr(buf, "/lib");
369                 if(buf != NULL) {
370                     if(buf[strlen(buf)-1] == '\n')
371                         buf[strlen(buf)-4] = 0;
372                     buf += 8;
373                     memset(cmdline, 0x00, 255);
374                     strncpy(cmdline, buf, strlen(buf)+1);
375                 }
376             }
377             break;
378         }
379
380         fclose(fp);
381     }
382 #endif
383     snprintf(str, 255, "%s", cmdline);
384 }
385
386 /*
387  * Lookup: lookup a code in a table.
388  */
389 static char _lookup_buffer[100];
390
391     static const char *
392 LookupL(long code, const binding *table)
393 {
394     const char *name;
395
396     snprintf(_lookup_buffer, sizeof(_lookup_buffer),
397             "unknown (code = %ld. = 0x%lx)", code, code);
398     name = _lookup_buffer;
399
400     while (table->name) {
401         if (table->code == code) {
402             name = table->name;
403             break;
404         }
405         table++;
406     }
407
408     return(name);
409 }
410
411     static const char *
412 Lookup(int code, const binding *table)
413 {
414     return LookupL((long)code, table);
415 }
416
417     static int
418 get_map_status(Window window)
419 {
420     XWindowAttributes win_attributes;
421
422     if (!XGetWindowAttributes(dpy, window, &win_attributes))
423         printf("Can't get window attributes.");
424
425     if( win_attributes.map_state == 0 )
426         return 0;
427     else
428         return win_attributes.map_state;
429 }
430
431 static int Ping_Event_Loop()
432 {
433     XEvent e;
434
435     while (XPending (dpy)) {
436         XFlush( dpy );
437         XNextEvent(dpy, &e);
438         /* draw or redraw the window */
439         if (e.type == Expose) {
440             fprintf(stderr," Expose \n");
441         }
442         /* exit on key press */
443         if (e.type == KeyPress) {
444             fprintf(stderr,"  KeyPress  \n");
445             break;
446         }
447         if (e.type ==  ClientMessage ) {
448             return 1;
449         }
450     }
451     return 0;
452 }
453
454     static void
455 Send_Ping_to_Window(Window window)
456 {
457     XClientMessageEvent xclient;
458     Display* display = dpy;
459
460     memset (&xclient, 0, sizeof (xclient));
461     xclient.type = ClientMessage;
462     xclient.window = window;
463
464     xclient.message_type = XInternAtom (display, "WM_PROTOCOLS",0);
465
466     xclient.format = 32;
467
468     xclient.data.l[0] = XInternAtom (display, "_NET_WM_PING",0);
469     xclient.data.l[1] = 0;
470     //    fprintf(stderr,"<0x%x>\n", window);
471     XSendEvent (display, window, 0,
472             None,
473             (XEvent *)&xclient);
474     XFlush( dpy );
475
476 }
477
478
479
480 void print_default(FILE* fd, Window root_win, int num_children)
481 {
482     fprintf(fd, " \n");
483     fprintf(fd, "  Root window id         :");
484     Display_Window_Id(fd, root_win, True);
485     fprintf(fd, "  Pointed window         :");
486     Display_Pointed_Window_Info(fd);
487     fprintf(fd, "  Input Focused window   :");
488     Display_Focused_Window_Info(fd);
489     fprintf(fd, "\n");
490     fprintf(fd, "%d Top level windows\n", num_children);
491 }
492
493 void gen_output(XinfoPtr pXinfo, WininfoPtr pWininfo)
494 {
495     int i;
496     FILE* fd;
497     pid_t pid;
498
499     int val = pXinfo->xinfo_val;
500     WininfoPtr w = pWininfo;
501     char* name = pXinfo->xinfovalname;
502     char* path = pXinfo->pathname;
503     char* file = pXinfo->filename;
504     char *argument[6];
505     char *argument_props_root[3];
506     char *argument_props_id[4];
507     int child_status=0;
508
509     Window root_win = RootWindow(dpy, screen);
510     int num_children = win_cnt;
511
512     argument[2] = (char *)malloc(sizeof(char)*15);
513     argument[4] = (char *)malloc(sizeof(char)*255);
514
515     argument[0] = strdup("xwd");
516     argument[1] = strdup("-id");
517     argument[3] = strdup("-out");
518     argument[5] = NULL;
519
520     fd = pXinfo->output_fd;
521     fprintf(stderr, "[%s] Start to logging ", name);
522     if(path && file)
523         fprintf(stderr, "at %s/%s\n", path, file);
524     else
525         fprintf(stderr, "\n");
526     if(val == XINFO_TOPWINS)
527     {
528         print_default(fd, root_win, num_children);
529         fprintf( fd, "----------------------------------[ %s ]-------------------------------------------------------------------------------\n", name);
530         fprintf( fd, " No    PID    WinID     w    h   Rel_x Rel_y Abs_x Abs_y Depth          WinName                      AppName\n" );
531         fprintf( fd, "----------------------------------------------------------------------------------------------------------------------------\n" );
532
533         for(i = 0; i < win_cnt; i++)
534         {
535             fprintf(fd, "%3i %6ld  0x%-7lx %4i %4i %5i %5i %5i %5i %5i  %-35s %-35s\n",
536                     (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);
537
538             w = w->next;
539         }
540     }
541     else if(val == XINFO_TOPVWINS)
542     {
543         print_default(fd, root_win, num_children);
544         fprintf( fd, "----------------------------------[ %s ]------------------------------------------------------------------------------------------------\n", name);
545         fprintf( fd, " No    PID  BorderID    WinID      w    h   Rel_x Rel_y Abs_x Abs_y Depth          WinName              AppName                    map state \n" );
546         fprintf( fd, "----------------------------------------------------------------------------------------------------------------------------------------------\n" );
547
548         for(i = 0; i < win_cnt; i++)
549         {
550             fprintf( fd, "%3i %6ld  0x%-7lx 0x%-8lx %4i %4i %5i %5i %5i %5i %5i    %-25s %-25s %-30s\n",
551                     (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);
552
553             w = w->next;
554         }
555     }
556     else if(val == XINFO_TOPVWINS_PROPS)
557     {
558         print_default(fd, root_win, num_children);
559
560         fprintf( fd, "###[ Root  Window ]###\n");
561         fprintf( fd, "ID: 0x%lx\n", root_win);
562         fprintf( fd, "######\n" );
563         argument_props_root[0] = strdup("/usr/bin/xprop");
564         argument_props_root[1] = strdup("-root");
565         argument_props_root[2] = NULL;
566         fflush(fd);
567         switch(pid = fork())
568         {
569             case 0:
570                 if (execv("/usr/bin/xprop", argument_props_root) == -1)
571                 {
572                     fprintf(fd, "failed to excute 'xprop -root'\n");
573                     exit(1);
574                 }
575                 break;
576             default:
577                 break;
578         }
579         waitpid(pid, &child_status, WUNTRACED);
580         fflush(fd);
581
582         argument_props_id[0] = strdup("/usr/bin/xprop");
583         argument_props_id[1] = strdup("-id");
584         argument_props_id[2] = (char *)malloc(sizeof(char)*15);
585         argument_props_id[3] = NULL;
586         for(i = 0; i < win_cnt; i++)
587         {
588             fprintf( fd, "\n###[ Window ID: 0x%x ]###\n", (unsigned int)w->winid);
589             fprintf( fd, "PID: %ld\n",  w->pid);
590             fprintf( fd, "Border ID: 0x%x\n",  (unsigned int)w->BDid);
591             fprintf( fd, "###\n" );
592             snprintf(argument_props_id[2], 15, "0x%-7x", (unsigned int)w->BDid);
593             fflush(fd);
594             switch(pid = fork())
595             {
596                 case 0:
597                     if (execv("/usr/bin/xprop", argument_props_id) == -1)
598                     {
599                         fprintf(stderr, "failed to excute 'xprop' \n");
600                         exit(1);
601                     }
602                     break;
603                 default:
604                     break;
605             }
606             waitpid(pid, &child_status, WUNTRACED);
607             fflush(fd);
608             fprintf( fd, "###\n" );
609             fprintf( fd, "Win Name : %s\n",  w->winname);
610             fprintf( fd, "Window ID: 0x%x\n",  (unsigned int)w->winid);
611             fprintf( fd, "######\n" );
612             snprintf(argument_props_id[2], 15, "0x%-7x", (unsigned int)w->winid);
613             fflush(fd);
614             switch(pid = fork())
615             {
616                 case 0:
617                     if (execv("/usr/bin/xprop", argument_props_id) == -1)
618                     {
619                         fprintf(stderr, "failed to excute 'xprop' \n");
620                         exit(1);
621                     }
622                     break;
623                 default:
624                     break;
625             }
626             waitpid(pid, &child_status, WUNTRACED);
627             fflush(fd);
628             fprintf( fd, "######\n" );
629
630             w = w->next;
631         }
632         free(argument_props_id[0]);
633         free(argument_props_id[1]);
634         free(argument_props_id[2]);
635
636         free(argument_props_root[0]);
637         free(argument_props_root[1]);
638     }
639     else if(val == XINFO_PING)
640     {
641         print_default(fd, root_win, num_children);
642         fprintf( fd, "----------------------------------[ %s ]-----------------------------------------------------------------------------------------------------\n", name);
643         fprintf( fd, " No    PID    WinID     w    h           WinName              AppName                           Ping                         Command\n" );
644         fprintf( fd, "-----------------------------------------------------------------------------------------------------------------------------------------------\n" );
645
646         for(i = 0; i < win_cnt; i++)
647         {
648             fprintf( fd, "%3i %6ld  0x%-7lx %4i %4i %-30s %-30s %-20s %-40s\n",
649                     (w->idx+1),w->pid,w->winid,w->w,w->h, w->winname, w->appname_brief,w->ping_result,w->appname);
650
651             w = w->next;
652         }
653     }
654     else if(val == XINFO_XWD_TOPVWINS)
655     {
656         fprintf( stderr,  " [START] %s : the path to store the xwd files is %s \n", name, path);
657
658         /* dump root window */
659         snprintf(argument[2], 15,"0x%-7lx", root_win);
660         snprintf(argument[4], 255,"%s/root_win.xwd", path);
661
662         switch(pid = fork())
663         {
664             case 0:
665                 if (execv("/usr/bin/xwd", argument) == -1)
666                 {
667                     fprintf(stderr, "execv error root xwd\n");
668                     exit(1);
669                 }
670                 break;
671             default:
672                 break;
673         }
674
675         for(i = 0; i < win_cnt; i++)
676         {
677             snprintf(argument[2], 15, "0x%-7lx", w->winid);
678             snprintf(argument[4], 255, "%s/0x%-7lx.xwd", path, w->winid);
679
680             switch(pid = fork())
681             {
682                 case 0:
683                     if (execv("/usr/bin/xwd", argument) == -1)
684                     {
685                         fprintf(stderr, "execv error other xwd\n");
686                         exit(1);
687                     }
688                     break;
689                 default:
690                     break;
691             }
692             w = w->next;
693         }
694         fprintf( stderr,  " [FINISH] %s : the path to store the xwd files is %s \n", name, path);
695     }
696     else if(val == XINFO_XWD_WIN)
697     {
698         fprintf( stderr,  " [START] %s : the path to store the xwd files is %s \n", name, path);
699
700         snprintf(argument[2], 15, "0x%-7x", pXinfo->win);
701         snprintf(argument[4], 255, "%s/0x%-7x.xwd", path, pXinfo->win);
702
703         switch(pid = fork())
704         {
705             case 0:
706                 if (execv("/usr/bin/xwd", argument) == -1)
707                 {
708                     fprintf(stderr, "execv error window xwd\n");
709                     exit(1);
710                 }
711                 break;
712             default:
713                 break;
714         }
715         fprintf( stderr,  " [FINISH] %s : the path to store the xwd files is %s \n", name, path);
716     }
717     fprintf(stderr, "[%s] Finish to logging ", name);
718     if(path && file)
719         fprintf(stderr, "at %s/%s\n", path, file);
720     else
721         fprintf(stderr, "\n");
722     free(name);
723     if (argument[1])
724         free (argument[1]);
725     if(argument[2])
726         free(argument[2]);
727     if(argument[3])
728         free(argument[3]);
729     if(argument[4])
730         free(argument[4]);
731 }
732
733
734 static Window get_user_created_window(Window win)
735 {
736
737     Atom type_ret = 0;
738     int ret, size_ret = 0;
739     unsigned long num_ret = 0, bytes = 0;
740     unsigned char *prop_ret = NULL;
741     unsigned int xid;
742     Atom prop_user_created_win;
743
744     prop_user_created_win = XInternAtom(dpy, "_E_USER_CREATED_WINDOW", False);
745
746     ret = XGetWindowProperty(dpy, win, prop_user_created_win, 0L, 1L,
747             False, XA_WINDOW, &type_ret, &size_ret,
748             &num_ret, &bytes, &prop_ret);
749
750     if( ret != Success )
751     {
752         if( prop_ret ) XFree( (void*)prop_ret );
753         return win;
754     }
755     else if( !prop_ret )
756     {
757         return win;
758     }
759
760     memcpy( &xid, prop_ret, sizeof(unsigned int) );
761     XFree( (void *)prop_ret );
762
763     return xid;
764
765 }
766
767 #if 0
768 static int cb_x_error(Display *disp, XErrorEvent *ev)
769 {
770     return 0;
771 }
772 #endif
773
774     void
775 display_topwins(XinfoPtr pXinfo)
776 {
777     int i;
778     int rel_x, rel_y, abs_x, abs_y;
779     unsigned int width, height, border, depth;
780     Window root_win, parent_win;
781     unsigned int num_children;
782     Window *child_list;
783     long *pid = NULL;
784     //    char *command_name = NULL;
785     //    char *class_name = NULL;
786     Atom actual_type;
787     int actual_format;
788     unsigned long nitems, bytes_after;
789     Window window;
790
791     int wininfo_val = pXinfo->xinfo_val;
792
793     /* open a display and get a default screen */
794     dpy = XOpenDisplay(0);
795     if(!dpy)
796     {
797         printf("Fail to open display\n");
798         exit(0);
799     }
800
801     /* get a screen*/
802     screen = DefaultScreen(dpy);
803
804     /* get a root window id */
805     window = RootWindow(dpy, screen);
806
807     //    /* set a error handler */
808     //    m_old_error = XSetErrorHandler(cb_x_error);
809
810     if(wininfo_val == XINFO_PING)
811         XSelectInput (dpy, window, ExposureMask|     SubstructureNotifyMask);
812
813     /* XINFO_XWD_WIN do not need to gethering window information */
814     if(wininfo_val == XINFO_XWD_WIN)
815     {
816         gen_output(pXinfo, NULL);
817         return;
818     }
819
820     /* query a window tree */
821     if (!XQueryTree(dpy, window, &root_win, &parent_win, &child_list, &num_children))
822         Fatal_Error("Can't query window tree.");
823
824     /* get a properties */
825     prop_pid = XInternAtom(dpy, "_NET_WM_PID", False);
826     prop_c_pid = XInternAtom(dpy, "X_CLIENT_PID", False);
827     prop_class = XInternAtom(dpy, "WM_CLASS", False);
828     prop_command = XInternAtom(dpy, "WM_COMMAND", False);
829
830     /* gathering the wininfo infomation */
831     WininfoPtr prev_wininfo = NULL;
832     WininfoPtr cur_wininfo = NULL;
833     WininfoPtr origin_wininfo = NULL;
834     int map_state;
835
836     /* Make the wininfo list */
837     for (i = (int)num_children - 1; i >= 0; i--)
838     {
839         if(wininfo_val == XINFO_TOPVWINS || wininfo_val == XINFO_XWD_TOPVWINS || wininfo_val == XINFO_TOPVWINS_PROPS)
840         {
841             /* figure out whether the window is mapped or not */
842             map_state = get_map_status(child_list[i]);
843             if(!map_state)
844                 continue;
845             else
846             {
847                 cur_wininfo = alloc_wininfo();
848                 cur_wininfo->map_state = (char*) calloc(1, 255*sizeof(char));
849                 snprintf(cur_wininfo->map_state, 255, "  %s  ",  Lookup(map_state, _map_states));
850
851                 /* get the winid */
852                 cur_wininfo->winid = child_list[i];
853                 cur_wininfo->BDid = child_list[i];
854             }
855         }
856         else if(wininfo_val == XINFO_TOPWINS || wininfo_val == XINFO_PING)
857         {
858             cur_wininfo = alloc_wininfo();
859
860             /* get the winid */
861             cur_wininfo->winid = child_list[i];
862             cur_wininfo->BDid = child_list[i];
863         }
864         else
865         {
866             printf("Error . no valid win_state\n");
867             exit(1);
868         }
869
870         if(prev_wininfo)
871         {
872             prev_wininfo->next = cur_wininfo;
873             cur_wininfo->prev = prev_wininfo;
874         }
875         else
876             origin_wininfo = cur_wininfo;
877
878         /* set the pre_wininfo is the cur_wininfo now */
879         prev_wininfo = cur_wininfo;
880     }
881
882     if (origin_wininfo == NULL)
883         return;
884
885     /* check the window generated in client side not is done by window manager */
886     WininfoPtr w = origin_wininfo;
887     Window winid = 0;
888     for(i = 0; i < win_cnt; i++)
889     {
890         winid = get_user_created_window(w->winid);
891         w->winid = winid;
892
893         /* move to the next wininfo */
894         w = w->next;
895     }
896
897
898     /* check other infomation out  */
899     w = origin_wininfo;
900     for(i = 0; i < win_cnt; i++)
901     {
902         /* get pid */
903         if (XGetWindowProperty(dpy, w->winid, prop_pid,
904                     0, 2L,
905                     False, XA_CARDINAL,
906                     &actual_type, &actual_format, &nitems,
907                     &bytes_after, (unsigned char **)&pid) == Success
908                 && nitems && pid != NULL)
909         {
910             w->pid = *pid;
911         }
912         else if (XGetWindowProperty(dpy, w->winid, prop_c_pid,
913                     0, 2L,
914                     False, XA_CARDINAL,
915                     &actual_type, &actual_format, &nitems,
916                     &bytes_after, (unsigned char **)&pid) == Success
917                 && nitems && pid != NULL)
918         {
919             w->pid = *pid;
920         }
921         else
922         {
923             w->pid = 0;
924         }
925
926         Window child;
927         /* get the geometry info and depth*/
928         if (XGetGeometry(dpy, w->winid, &root_win, &rel_x, &rel_y, &width, &height, &border, &depth))
929         {
930             w->w = width;
931             w->h = height;
932             w->rel_x = rel_x;
933             w->rel_y = rel_y;
934
935             if (XTranslateCoordinates (dpy, w->winid, root_win, 0 ,0, &abs_x, &abs_y, &child))
936             {
937                 w->abs_x = abs_x -border;
938                 w->abs_y = abs_y - border;
939             }
940         }
941
942         /* get the depth */
943         w->depth = depth;
944
945         /* get the winname */
946         w->winname = (char*) calloc(1, 255*sizeof(char));
947         get_winname(w->winid, w->winname);
948 #if 0
949         /* get app_name from WM_COMMAND or WM_CLASS */
950         w->appname = (char*) calloc(1, 255*sizeof(char));
951         if (XGetWindowProperty(dpy, w->winid, prop_command,
952                     0, 10000000L,
953                     False, AnyPropertyType,
954                     &actual_type, &actual_format, &nitems,
955                     &bytes_after, (unsigned char **)&command_name) == Success
956                 && nitems && command_name != NULL)
957         {
958             strncpy(w->appname, command_name, strlen(command_name)+1);
959         }
960         else
961         {
962             if (XGetWindowProperty(dpy, w->winid, prop_class,
963                         0, 10000000L,
964                         False, AnyPropertyType,
965                         &actual_type, &actual_format, &nitems,
966                         &bytes_after, (unsigned char **)&class_name) == Success
967                     && nitems && class_name != NULL)
968             {
969                 strncpy(w->appname, class_name, strlen(class_name)+1);
970             }
971             else
972             {
973                 if (w->appname)
974                     free (w->appname);
975                 w->appname = NULL;
976             }
977         }
978         if(command_name)
979         {
980             XFree(command_name);
981             command_name = NULL;
982         }
983         if(class_name)
984         {
985             XFree(class_name);
986             class_name = NULL;
987         }
988
989         if (w->appname) {
990             w->appname_brief = (char*) calloc(1, 255*sizeof(char));
991
992             strncpy(w->appname_brief, w->appname, 255*sizeof(char)-1);
993
994             get_appname_brief (w->appname_brief);
995         }
996 #else
997         /* get app_name from pid */
998         if(w->pid)
999         {
1000             w->appname = (char*) calloc(1, 255*sizeof(char));
1001             get_appname_from_pid(w->pid, w->appname);
1002
1003             w->appname_brief = (char*) calloc(1, 255*sizeof(char));
1004             strncpy(w->appname_brief, w->appname, 255*sizeof(char)-1);
1005             get_appname_brief (w->appname_brief);
1006         }
1007         else
1008             w->appname = NULL;
1009 #endif
1010         if (pid)
1011         {
1012             XFree(pid);
1013             pid = NULL;
1014         }
1015
1016         /* ping test info */
1017         if(wininfo_val == XINFO_PING)
1018         {
1019             Send_Ping_to_Window(w->winid);
1020             usleep(50000);
1021             w->ping_result = (char*) calloc(1, 255*sizeof(char));
1022             if(Ping_Event_Loop())
1023                 snprintf(w->ping_result, 255, "  Success  ");
1024             else
1025                 snprintf(w->ping_result, 255, "  Fail  ");
1026         }
1027
1028         /* move to the next wininfo */
1029         w = w->next;
1030     }
1031
1032
1033
1034     /* ping test */
1035     gen_output(pXinfo, origin_wininfo);
1036
1037     if (child_list)
1038         XFree((char *)child_list);
1039
1040     free_wininfo(origin_wininfo);
1041
1042 }
1043
1044
1045
1046