Back to index

unity  6.0.0
test-input-remover.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Canonical Ltd.
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  *
00018  * Authored By:
00019  * Sam Spilsbury <sam.spilsbury@canonical.com>
00020  */
00021 
00022 #include <inputremover.h>
00023 #include <cstdio>
00024 #include <cstdlib>
00025 #include <iostream>
00026 #include <iomanip>
00027 #include <unistd.h> 
00028 #include <sstream>
00029 
00030 void usage ()
00031 {
00032   std::cout << "test-input-remover [WINDOW] [TIME]" << std::endl;
00033 }
00034 
00035 bool
00036 print_rects (Display *dpy, Window xid)
00037 {
00038   XRectangle                *rects;
00039   int                       count = 0, ordering;
00040   int                       x, y;
00041   unsigned int              width, height, border, depth;
00042   Window                    root;
00043 
00044   XGetGeometry (dpy, xid, &root, &x, &y, &width, &height, &border, &depth);
00045 
00046   rects = XShapeGetRectangles (dpy, xid, ShapeInput,
00047                                &count, &ordering);
00048 
00049   if (count == 0)
00050     std::cout << "No Input Shape Set" << std::endl;
00051 
00052   /* check if the returned shape exactly matches the window shape -
00053      *      if that is true, the window currently has no set input shape */
00054   if ((count == 1) &&
00055       (rects[0].x == -((int) border)) &&
00056       (rects[0].y == -((int) border)) &&
00057       (rects[0].width == (width + border)) &&
00058       (rects[0].height == (height + border)))
00059   {
00060     std::cout << "No Input Shape Defined" << std::endl;
00061   }
00062 
00063   for (int i = 0; i < count; i++)
00064   {
00065     std::cout << "Rect - " << rects[i].x << ", " << rects[i].y << ", " << rects[i].width << ", " << rects[i].height << std::endl;
00066   }
00067 
00068   if (rects)
00069     XFree (rects);
00070 
00071   return count > 0;
00072 }
00073 
00074 int main (int argc, char **argv)
00075 {
00076   Display                    *dpy;
00077   Window                     xid;
00078   int                        time = 0;
00079   compiz::WindowInputRemover *remover;
00080   bool                     shapeExt;
00081   int                     shapeEvent;
00082   int                     shapeError;
00083   XEvent                     event;
00084 
00085   if ((argc == 2 && std::string (argv[1]) == "--help") || argc > 3)
00086   {
00087     usage ();
00088     return 1;
00089   }
00090 
00091   dpy = XOpenDisplay (NULL);
00092 
00093   if (!dpy)
00094   {
00095     std::cerr << "Failed to open display ... setting test to passed" << std::endl;
00096     return 0;
00097   }
00098 
00099   shapeExt = XShapeQueryExtension (dpy, &shapeEvent, &shapeError);
00100 
00101   if (!shapeExt)
00102   {
00103     std::cerr << "No shape extension .. setting test to passed" << std::endl;
00104     XCloseDisplay (dpy);
00105     return 0;
00106   }
00107 
00108   if (argc > 1)
00109     std::stringstream (argv[1]) >> std::hex >> xid;
00110   else
00111   {
00112     XSetWindowAttributes attrib;
00113 
00114     attrib.backing_pixel = 0x0;
00115 
00116     xid = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0, 100, 100, 0,
00117                          DefaultDepth (dpy, DefaultScreen (dpy)), InputOutput,
00118                          DefaultVisual (dpy, DefaultScreen (dpy)), CWBackingPixel, &attrib);
00119 
00120     XSelectInput (dpy, xid, ExposureMask | StructureNotifyMask);
00121     XMapRaised (dpy, xid);
00122     do
00123     {
00124       XNextEvent (dpy, &event);
00125       bool exposed = false;
00126 
00127       switch (event.type)
00128       {
00129         case Expose:
00130           if (event.xexpose.window == xid)
00131             exposed = true;
00132           break;
00133         default:
00134           break;
00135       }
00136 
00137       if (exposed)
00138         break;
00139 
00140     } while (XPending (dpy));
00141   }
00142 
00143   XShapeSelectInput (dpy, xid, ShapeNotifyMask);
00144 
00145   if (argc == 3)
00146     std::stringstream (argv[2]) >> std::dec >> time;
00147 
00148   remover = new compiz::WindowInputRemover (dpy, xid);
00149   if (!remover)
00150     return 1;
00151 
00152   print_rects (dpy, xid);
00153 
00154   std::cout << "Saving input shape of 0x" << std::hex << xid << std::dec << std::endl;
00155   remover->save ();
00156   std::cout << "Removing input shape of 0x" << std::hex << xid << std::dec << std::endl;
00157   remover->remove ();
00158 
00159   /* We won't get a synethetic ShapeNotify event if this
00160    * is on a window that we don't own */
00161 
00162   if (argc == 1)
00163   {
00164     do
00165     {
00166       XNextEvent (dpy, &event);
00167       if (event.type == shapeEvent + ShapeNotify &&
00168        event.xany.send_event)
00169       {
00170         std::cout << "received ShapeNotify on 0x" << std::hex << xid << std::endl;
00171        break;
00172       }
00173 
00174     } while (XPending (dpy));
00175   }
00176   else
00177     XSync (dpy, false);
00178 
00179   std::cout << "Getting input rects for 0x" << std::hex << xid << std::dec << std::endl;
00180   if (print_rects (dpy, xid))
00181   {
00182     std::cout << "Error! Window still has rects after shape was removed!" << std::endl;
00183     delete remover;
00184     XCloseDisplay (dpy);
00185     return 1;
00186   }
00187 
00188   std::cout << "Waiting " << std::dec << time << " seconds" << std::endl;
00189   sleep (time);
00190 
00191   std::cout << "Restoring input shape of 0x" << std::hex << xid << std::dec << std::endl;
00192   remover->restore ();
00193 
00194   if (argc == 1)
00195   {
00196     do
00197     {
00198       XNextEvent (dpy, &event);
00199       if (event.type == shapeEvent + ShapeNotify &&
00200        event.xany.send_event)
00201       {
00202           std::cout << "received ShapeNotify on 0x" << std::hex << xid << std::endl;
00203        break;
00204       }
00205 
00206     } while (XPending (dpy));
00207   }
00208   else
00209     XSync (dpy, false);
00210 
00211   if (!print_rects (dpy, xid))
00212   {
00213     std::cout << "Error! Failed to restore input shape for 0x" << std::hex << xid << std::dec << std::endl;
00214     delete remover;
00215     XCloseDisplay (dpy);
00216     return 1;
00217   }
00218 
00219   delete remover;
00220 
00221   XCloseDisplay (dpy);
00222 
00223   return 0;
00224 }