AutomateXWin.C

Go to the documentation of this file.
00001 /*!@file GUI/AutomateXWin.C Automate X windows by sending keys and getting images */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Lior Elazary
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/GUI/AutomateXWin.C $
00035 // $Id: AutomateXWin.C 9129 2008-01-14 20:27:55Z lior $
00036 //
00037 
00038 #include "Image/Image.H"
00039 #include "Image/Pixels.H"
00040 #include "GUI/AutomateXWin.H"
00041 
00042 
00043 // shift x left by i, where i can be positive or negative
00044 #define SHIFTL(x,i) (((i) >= 0) ? ((x) << (i)) : ((x) >> (-i)))
00045 
00046 // ######################################################################
00047 AutomateXWin::AutomateXWin(const char* win_name) :
00048   itsDisplay(NULL),
00049   itsScreen(0),
00050   itsImage(NULL),
00051   itsWidth(0),
00052   itsHeight(0),
00053   itsDepth(0)
00054 
00055 {
00056   char *dispName = XDisplayName(NULL);
00057   unsigned num_tries;
00058   int event_base, error_base;
00059   int major_version, minor_version;
00060 
00061   itsDisplay = XOpenDisplay(dispName);
00062   if(!itsDisplay)
00063     LFATAL("XOpenDisplay(%s) failed\n", dispName);
00064 
00065   if (!XTestQueryExtension (itsDisplay, &event_base, &error_base, &major_version, &minor_version)) {
00066     XCloseDisplay(itsDisplay);
00067     LFATAL("XTest extension not supported on server");
00068   }
00069 
00070   LINFO("XTestQueryExtension passed.");
00071   LINFO("XTest information for server \"%s\":", DisplayString(itsDisplay));
00072   LINFO("  Major version:       %d", major_version);
00073   LINFO("  Minor version:       %d", minor_version);
00074   LINFO("  First event number:  %d", event_base);
00075   LINFO("  First error number:  %d", error_base);
00076 
00077 
00078   itsScreen = DefaultScreen(itsDisplay);
00079 
00080   itsRootWin = RootWindow(itsDisplay, itsScreen);
00081 
00082   for(num_tries=0;;)
00083   {
00084     itsWindow = XWindowByName(itsDisplay, itsRootWin, win_name);
00085     if(itsWindow) break;
00086     if(++num_tries == 100)
00087       LFATAL("XWindowByName\n");
00088     usleep(20000);
00089   }
00090 
00091   XFlush(itsDisplay);
00092   XSync(itsDisplay, False);
00093 #ifdef USE_SHM
00094   if(!XShmQueryExtension(itsDisplay))
00095     LFATAL("XShmQueryExtension");
00096 #endif
00097   GetWindowGeometry();
00098 
00099   if(!XMatchVisualInfo(itsDisplay, itsScreen, itsDepth, DirectColor, &itsVInfo))
00100   {
00101     return;
00102   }
00103 
00104 }
00105 
00106 
00107 // ######################################################################
00108 AutomateXWin::~AutomateXWin()
00109 {
00110   if(!itsImage) return;
00111 
00112 #ifdef USE_SHM
00113   XShmDetach(itsDisplay, &itsShminfo);
00114   XDestroyImage(itsImage);
00115   itsImage = NULL;
00116   shmdt(itsShminfo.shmaddr);
00117 #endif
00118 
00119 }
00120 
00121 // ######################################################################
00122 void AutomateXWin::setFocus()
00123 {
00124   XSetInputFocus(itsDisplay, itsWindow, RevertToNone, CurrentTime);
00125 }
00126 
00127 // ######################################################################
00128 Image<PixRGB<byte> > AutomateXWin::getImage()
00129 {
00130 
00131 
00132   DeleteImage();
00133 #ifdef USE_SHM
00134   if(!itsImage)
00135   {
00136     itsImage = XShmCreateImage(itsDisplay, itsVInfo.visual,
00137         itsDepth,
00138         ZPixmap,
00139         NULL,
00140         &itsShminfo,
00141         itsWidth,
00142         itsHeight);
00143     if(!itsImage)
00144     {
00145       LERROR("XShmCreateImage");
00146       return Image<PixRGB<byte> >();
00147     }
00148 
00149     itsShminfo.shmid = shmget(IPC_PRIVATE,
00150         itsImage->bytes_per_line * itsImage->height,
00151         IPC_CREAT | 0777);
00152     if(itsShminfo.shmid < 0)
00153     {
00154       LERROR("shmget");
00155       XDestroyImage(itsImage);
00156       itsImage=NULL;
00157       return Image<PixRGB<byte> >();
00158     }
00159     itsShminfo.shmaddr = (char *) shmat(itsShminfo.shmid, 0, 0);
00160     if(itsShminfo.shmaddr == (char *)-1)
00161     {
00162       LERROR("shmat");
00163       XDestroyImage(itsImage);
00164       return Image<PixRGB<byte> >();
00165     }
00166     shmctl(itsShminfo.shmid, IPC_RMID, 0),
00167       itsImage->data = itsShminfo.shmaddr;
00168     itsShminfo.readOnly = False;
00169     XShmAttach(itsDisplay, &itsShminfo);
00170 
00171     XSync(itsDisplay, False);
00172   }
00173 #endif
00174   /* If SHM failed or was disabled, try non-SHM way */
00175   if(!itsImage)
00176   {
00177     itsImage = XGetImage(itsDisplay, itsWindow,
00178         0, 0,
00179         itsWidth,
00180         itsHeight,
00181         AllPlanes,
00182         XYPixmap);
00183     if(!itsImage)
00184       LERROR("XGetImage\n");
00185   }
00186 #ifdef USE_SHM
00187   if(!XShmGetImage(itsDisplay, itsWindow, itsImage,
00188         0, 0,
00189         AllPlanes))
00190     LERROR("XSHMGetImage");
00191 #endif
00192 
00193   Image<PixRGB<byte> > img(itsWidth,itsHeight,NO_INIT);
00194   int rshift = 7 - getHighBitIndex (itsImage->red_mask);
00195   int gshift = 7 - getHighBitIndex (itsImage->green_mask);
00196   int bshift = 7 - getHighBitIndex (itsImage->blue_mask);
00197 
00198   for (int y=0; y<itsImage->height; y++) {
00199     for (int x=0; x<itsImage->width; x++) {
00200       unsigned long pixel = XGetPixel (itsImage,x,y);
00201       PixRGB<byte> pixVal(
00202        SHIFTL(pixel & itsImage->red_mask,rshift),
00203        SHIFTL(pixel & itsImage->green_mask,gshift),
00204        SHIFTL(pixel & itsImage->blue_mask,bshift)
00205       );
00206       img.setVal(x,y, pixVal);
00207     }
00208   }
00209 
00210   return img;
00211 
00212 }
00213 
00214 void AutomateXWin::DeleteImage(void)
00215 {
00216   if(!itsImage) return;
00217 
00218 #ifndef USE_SHM
00219   XDestroyImage(itsImage);
00220   itsImage = NULL;
00221 #endif
00222 }
00223 
00224 // ######################################################################
00225 void AutomateXWin::sendKey(const int key)
00226 {
00227   XTestFakeKeyEvent(itsDisplay, key, True, CurrentTime); //key down
00228   XTestFakeKeyEvent(itsDisplay, key, False, CurrentTime); //key up
00229   XSync(itsDisplay, True);
00230 }
00231 
00232 
00233 // ######################################################################
00234 // return the index of the highest bit
00235 int AutomateXWin::getHighBitIndex (unsigned int x)
00236 {
00237   int i = 0;
00238   while (x) {
00239     i++;
00240     x >>= 1;
00241   }
00242   return i-1;
00243 }
00244 
00245 // ######################################################################
00246 void AutomateXWin::GetWindowGeometry()
00247 {
00248   unsigned border_width;
00249   int xpos, ypos;
00250   Window root;
00251 
00252   if(!XGetGeometry(
00253         itsDisplay, itsWindow, &root,
00254         &xpos, &ypos,
00255         &itsWidth, &itsHeight,
00256         &border_width,
00257         &itsDepth))
00258   {
00259     LERROR("XGetGeometry\n");
00260   }
00261   LINFO("width=%u, height=%u, depth=%u\n", itsWidth, itsHeight, itsDepth);
00262 
00263 }
00264 
00265 // ######################################################################
00266 Window AutomateXWin::XWindowByName(Display *display, const Window rootwin, const char *name)
00267 {
00268   unsigned int num_children;
00269   Window *children, child, window;
00270   XTextProperty windowname;
00271 
00272   if(XGetWMName(display, rootwin, &windowname) != 0)
00273   {
00274     LINFO("Window='%s'\n", (const char *)windowname.value);
00275     if(!strcmp((const char *)windowname.value, name))
00276       return rootwin;
00277   }
00278 
00279   window = (Window) NULL;
00280 
00281   if(XQueryTree(display, rootwin, &child, &child, &children, &num_children))
00282   {
00283     unsigned i;
00284     for(i=0; i < num_children; ++i)
00285     {
00286       /* Search each child and their children. */
00287       window = XWindowByName(display, children[i], name);
00288       if(window != (Window) NULL)
00289         break;
00290     }
00291     if (children != (Window *)NULL)
00292       XFree((void *)children);
00293   }
00294   return window;
00295 }
00296 
00297 // ######################################################################
00298 void AutomateXWin::XListWindows(Display *display, const Window rootwin)
00299 {
00300   unsigned int num_children;
00301   Window *children, child;
00302   XTextProperty windowname;
00303 
00304   if(XGetWMName(display, rootwin, &windowname) != 0)
00305     LINFO("  '%s'\n", (const char *)windowname.value);
00306 
00307   if(XQueryTree(display, rootwin, &child, &child, &children, &num_children))
00308   {
00309     unsigned i;
00310     for(i=0; i < num_children; ++i)
00311     {
00312       /* Search each child and their children. */
00313       XListWindows(display, children[i]);
00314     }
00315     if (children != (Window *)NULL)
00316       XFree((void *)children);
00317   }
00318 }
00319 
00320 
00321 
00322 // ######################################################################
00323 /* So things look consistent in everyone's emacs... */
00324 /* Local Variables: */
00325 /* indent-tabs-mode: nil */
00326 /* End: */
Generated on Sun May 8 08:40:39 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3