11c5ac21333f543680ce306d46f287d62c175d873mridge/* 21c5ac21333f543680ce306d46f287d62c175d873mridge * Add more stress to X server by moving, resizing and activating windows 31c5ac21333f543680ce306d46f287d62c175d873mridge * Author: Darrick Wong <djwong@us.ibm.com> 41c5ac21333f543680ce306d46f287d62c175d873mridge */ 51c5ac21333f543680ce306d46f287d62c175d873mridge 61e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper/* 71c5ac21333f543680ce306d46f287d62c175d873mridge * Copyright (C) 2003-2006 IBM 81e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper * 91c5ac21333f543680ce306d46f287d62c175d873mridge * This program is free software; you can redistribute it and/or 101c5ac21333f543680ce306d46f287d62c175d873mridge * modify it under the terms of the GNU General Public License as 111c5ac21333f543680ce306d46f287d62c175d873mridge * published by the Free Software Foundation; either version 2 of the 121c5ac21333f543680ce306d46f287d62c175d873mridge * License, or (at your option) any later version. 131c5ac21333f543680ce306d46f287d62c175d873mridge * 141c5ac21333f543680ce306d46f287d62c175d873mridge * This program is distributed in the hope that it will be useful, but 151c5ac21333f543680ce306d46f287d62c175d873mridge * WITHOUT ANY WARRANTY; without even the implied warranty of 161c5ac21333f543680ce306d46f287d62c175d873mridge * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 171c5ac21333f543680ce306d46f287d62c175d873mridge * General Public License for more details. 181e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper * 191c5ac21333f543680ce306d46f287d62c175d873mridge * You should have received a copy of the GNU General Public License 201c5ac21333f543680ce306d46f287d62c175d873mridge * along with this program; if not, write to the Free Software 211c5ac21333f543680ce306d46f287d62c175d873mridge * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 221c5ac21333f543680ce306d46f287d62c175d873mridge * 02111-1307, USA. 231c5ac21333f543680ce306d46f287d62c175d873mridge */ 241c5ac21333f543680ce306d46f287d62c175d873mridge 251c5ac21333f543680ce306d46f287d62c175d873mridge#include <stdio.h> 261c5ac21333f543680ce306d46f287d62c175d873mridge#include <sys/types.h> 271c5ac21333f543680ce306d46f287d62c175d873mridge#include <sys/stat.h> 281c5ac21333f543680ce306d46f287d62c175d873mridge#include <fcntl.h> 291c5ac21333f543680ce306d46f287d62c175d873mridge#include <unistd.h> 301c5ac21333f543680ce306d46f287d62c175d873mridge#include <stdlib.h> 311c5ac21333f543680ce306d46f287d62c175d873mridge#include <X11/Xlib.h> 321c5ac21333f543680ce306d46f287d62c175d873mridge#include <X11/Xatom.h> 331c5ac21333f543680ce306d46f287d62c175d873mridge#include <string.h> 341c5ac21333f543680ce306d46f287d62c175d873mridge#include <stdint.h> 351c5ac21333f543680ce306d46f287d62c175d873mridge#include <limits.h> 361c5ac21333f543680ce306d46f287d62c175d873mridge 371c5ac21333f543680ce306d46f287d62c175d873mridgestatic int enable_fullscreen = 0; 381c5ac21333f543680ce306d46f287d62c175d873mridge 391c5ac21333f543680ce306d46f287d62c175d873mridge#define MAX_PROPERTY_VALUE_LEN 4096 401c5ac21333f543680ce306d46f287d62c175d873mridge#define _NET_WM_STATE_TOGGLE 2 411c5ac21333f543680ce306d46f287d62c175d873mridge#define SLIDE_THRESHOLD 32 421c5ac21333f543680ce306d46f287d62c175d873mridge 431c5ac21333f543680ce306d46f287d62c175d873mridge/* We assume that the workspace number will either be -1 or some 441c5ac21333f543680ce306d46f287d62c175d873mridge * huge number for "On All Workspaces" windows. Presumably there 451c5ac21333f543680ce306d46f287d62c175d873mridge * aren't 1,000,000 workspaces, so that should be a safe number. 461c5ac21333f543680ce306d46f287d62c175d873mridge */ 471c5ac21333f543680ce306d46f287d62c175d873mridge#define DESKTOP_MAX 1000000 481c5ac21333f543680ce306d46f287d62c175d873mridge 491c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_MOVE_WINDOW 0 501c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_ACTIVATE_WINDOW 1 511c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_MAXIMIZE_WINDOW 2 521c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_FULLSCREEN_WINDOW 3 531c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_HIDDEN_WINDOW 4 541c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_SLIDE_WINDOW_0 5 551c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_SLIDE_WINDOW_1 6 561c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_SLIDE_WINDOW_2 7 571c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_SLIDE_WINDOW_3 8 581c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_SLIDE_WINDOW_4 9 591c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_SLIDE_WINDOW_5 10 601c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_MIN ACTION_MOVE_WINDOW 611c5ac21333f543680ce306d46f287d62c175d873mridge#define ACTION_MAX ACTION_SLIDE_WINDOW_5 621c5ac21333f543680ce306d46f287d62c175d873mridge 631c5ac21333f543680ce306d46f287d62c175d873mridge/* The goal of this program: 641c5ac21333f543680ce306d46f287d62c175d873mridge * 0. Seed random number generator 651c5ac21333f543680ce306d46f287d62c175d873mridge * 1. Grab the list of windows and the desktop size. 661c5ac21333f543680ce306d46f287d62c175d873mridge * 2. Filter out the panel/desktop/whatever. We're going to make 671c5ac21333f543680ce306d46f287d62c175d873mridge * a cheesy assumption that a window on desktop -1 should be left 681c5ac21333f543680ce306d46f287d62c175d873mridge * alone. (Actually, the -1 denotes "all desktops") 691c5ac21333f543680ce306d46f287d62c175d873mridge * 3. For each window: 701c5ac21333f543680ce306d46f287d62c175d873mridge * a. Figure out what we're going to do--activate, move/resize, 711c5ac21333f543680ce306d46f287d62c175d873mridge * or maximize it. 721c5ac21333f543680ce306d46f287d62c175d873mridge * b. If we're going to move/resize, grab 4 random numbers. 731c5ac21333f543680ce306d46f287d62c175d873mridge * c. Actually perform the action. 741c5ac21333f543680ce306d46f287d62c175d873mridge * 4. Every so often, jump back to (2) in case there are new windows. 751c5ac21333f543680ce306d46f287d62c175d873mridge * Maybe every 10,000 moves or so. 761c5ac21333f543680ce306d46f287d62c175d873mridge * 771c5ac21333f543680ce306d46f287d62c175d873mridge * Note that you do NOT want to run this on any X session you care about. 781c5ac21333f543680ce306d46f287d62c175d873mridge * It shouldn't take down X, but YMMV and in any case mad window resizing 791c5ac21333f543680ce306d46f287d62c175d873mridge * makes it hard to get work done. 801c5ac21333f543680ce306d46f287d62c175d873mridge */ 811c5ac21333f543680ce306d46f287d62c175d873mridgestatic int seed_random(void); 82354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int get_desktop_size(Display * disp, unsigned long *w, unsigned long *h); 83354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic char *get_property(Display * disp, Window win, Atom xa_prop_type, 84354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *prop_name, unsigned long *size, 85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long *items); 86354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void go_bonkers(Display * disp, unsigned long iterations, 87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long sleep); 88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic Window *get_interesting_windows(Display * disp, 89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long *num_windows); 90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic Window *get_client_list(Display * disp, unsigned long *size, 91354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long *items); 921c5ac21333f543680ce306d46f287d62c175d873mridgestatic long get_randnum(long min, long max); 93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int send_client_msg(Display * disp, Window win, char *msg, 94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long data0, unsigned long data1, 95354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long data2, unsigned long data3, 96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long data4); 97354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int activate_window(Display * disp, Window * win); 98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int wm_supports(Display * disp, const char *prop); 99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void move_window(Display * disp, Window * win, unsigned long desk_w, 100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long desk_h); 101354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int toggle_property(Display * disp, Window * win, const char *property); 1021c5ac21333f543680ce306d46f287d62c175d873mridgestatic inline unsigned long clamp_value(unsigned long value, 103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long min, unsigned long max); 104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int ignore_xlib_error(Display * disp, XErrorEvent * xee); 1051c5ac21333f543680ce306d46f287d62c175d873mridge 1061c5ac21333f543680ce306d46f287d62c175d873mridge/* Actual functions begin here. */ 1071c5ac21333f543680ce306d46f287d62c175d873mridge 108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int seed_random(void) 109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 1101c5ac21333f543680ce306d46f287d62c175d873mridge int fp; 1111c5ac21333f543680ce306d46f287d62c175d873mridge long seed; 1121c5ac21333f543680ce306d46f287d62c175d873mridge 1131c5ac21333f543680ce306d46f287d62c175d873mridge fp = open("/dev/urandom", O_RDONLY); 1141c5ac21333f543680ce306d46f287d62c175d873mridge if (fp < 0) { 1151c5ac21333f543680ce306d46f287d62c175d873mridge perror("/dev/urandom"); 1161c5ac21333f543680ce306d46f287d62c175d873mridge return 0; 1171c5ac21333f543680ce306d46f287d62c175d873mridge } 1181c5ac21333f543680ce306d46f287d62c175d873mridge 1191c5ac21333f543680ce306d46f287d62c175d873mridge if (read(fp, &seed, sizeof(seed)) != sizeof(seed)) { 1201c5ac21333f543680ce306d46f287d62c175d873mridge perror("read random seed"); 1211c5ac21333f543680ce306d46f287d62c175d873mridge return 0; 1221c5ac21333f543680ce306d46f287d62c175d873mridge } 1231c5ac21333f543680ce306d46f287d62c175d873mridge 1241c5ac21333f543680ce306d46f287d62c175d873mridge close(fp); 1251c5ac21333f543680ce306d46f287d62c175d873mridge srand(seed); 1261c5ac21333f543680ce306d46f287d62c175d873mridge 1271c5ac21333f543680ce306d46f287d62c175d873mridge return 1; 1281c5ac21333f543680ce306d46f287d62c175d873mridge} 1291c5ac21333f543680ce306d46f287d62c175d873mridge 130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int get_desktop_size(Display * disp, unsigned long *w, unsigned long *h) 131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 1321c5ac21333f543680ce306d46f287d62c175d873mridge *w = DisplayWidth(disp, 0); 1331c5ac21333f543680ce306d46f287d62c175d873mridge *h = DisplayHeight(disp, 0); 1341c5ac21333f543680ce306d46f287d62c175d873mridge 1351c5ac21333f543680ce306d46f287d62c175d873mridge return 1; 1361c5ac21333f543680ce306d46f287d62c175d873mridge} 1371c5ac21333f543680ce306d46f287d62c175d873mridge 138354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic char *get_property(Display * disp, Window win, Atom xa_prop_type, 139354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *prop_name, unsigned long *size, 140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long *items) 1411c5ac21333f543680ce306d46f287d62c175d873mridge{ 1421c5ac21333f543680ce306d46f287d62c175d873mridge Atom xa_prop_name; 1431c5ac21333f543680ce306d46f287d62c175d873mridge Atom xa_ret_type; 1441c5ac21333f543680ce306d46f287d62c175d873mridge int ret_format; 1451c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long ret_nitems; 1461c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long ret_bytes_after; 1471c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long tmp_size; 1481c5ac21333f543680ce306d46f287d62c175d873mridge unsigned char *ret_prop; 1491c5ac21333f543680ce306d46f287d62c175d873mridge char *ret; 1501e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 1511c5ac21333f543680ce306d46f287d62c175d873mridge xa_prop_name = XInternAtom(disp, prop_name, False); 1521e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 153354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (XGetWindowProperty 154354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (disp, win, xa_prop_name, 0, MAX_PROPERTY_VALUE_LEN / 4, False, 155354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao xa_prop_type, &xa_ret_type, &ret_format, &ret_nitems, 156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao &ret_bytes_after, &ret_prop) != Success) { 1571c5ac21333f543680ce306d46f287d62c175d873mridge fprintf(stderr, "Cannot get %s property.\n", prop_name); 1581c5ac21333f543680ce306d46f287d62c175d873mridge return NULL; 1591c5ac21333f543680ce306d46f287d62c175d873mridge } 1601e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 1611c5ac21333f543680ce306d46f287d62c175d873mridge if (xa_ret_type != xa_prop_type) { 1621c5ac21333f543680ce306d46f287d62c175d873mridge fprintf(stderr, "Invalid type of %s property.\n", prop_name); 1631c5ac21333f543680ce306d46f287d62c175d873mridge XFree(ret_prop); 1641c5ac21333f543680ce306d46f287d62c175d873mridge return NULL; 1651c5ac21333f543680ce306d46f287d62c175d873mridge } 1661c5ac21333f543680ce306d46f287d62c175d873mridge 1671c5ac21333f543680ce306d46f287d62c175d873mridge /* XXX: EVIL HACK to get around a bug when sizeof(Window) is 8 yet ret_format 1681c5ac21333f543680ce306d46f287d62c175d873mridge * is listed as 32bits and we're trying to get the client list. Just double 1691c5ac21333f543680ce306d46f287d62c175d873mridge * ret_format and proceed. */ 1701c5ac21333f543680ce306d46f287d62c175d873mridge if (ret_format == 32 && strcmp(prop_name, "_NET_CLIENT_LIST") == 0 && 171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(Window) == 8) { 1721c5ac21333f543680ce306d46f287d62c175d873mridge ret_format *= 2; 1731c5ac21333f543680ce306d46f287d62c175d873mridge } 1741c5ac21333f543680ce306d46f287d62c175d873mridge 1751c5ac21333f543680ce306d46f287d62c175d873mridge /* null terminate the result to make string handling easier */ 1761c5ac21333f543680ce306d46f287d62c175d873mridge tmp_size = (ret_format / 8) * ret_nitems; 1771c5ac21333f543680ce306d46f287d62c175d873mridge ret = calloc(tmp_size + 1, 1); 1781c5ac21333f543680ce306d46f287d62c175d873mridge if (!ret) { 1791c5ac21333f543680ce306d46f287d62c175d873mridge perror("get_property malloc failed"); 1801c5ac21333f543680ce306d46f287d62c175d873mridge return NULL; 1811c5ac21333f543680ce306d46f287d62c175d873mridge } 1821c5ac21333f543680ce306d46f287d62c175d873mridge memcpy(ret, ret_prop, tmp_size); 1831c5ac21333f543680ce306d46f287d62c175d873mridge ret[tmp_size] = '\0'; 1841c5ac21333f543680ce306d46f287d62c175d873mridge 1851c5ac21333f543680ce306d46f287d62c175d873mridge if (size) { 1861c5ac21333f543680ce306d46f287d62c175d873mridge *size = ret_format / 8; 1871c5ac21333f543680ce306d46f287d62c175d873mridge } 1881c5ac21333f543680ce306d46f287d62c175d873mridge if (items) { 1891c5ac21333f543680ce306d46f287d62c175d873mridge *items = ret_nitems; 1901c5ac21333f543680ce306d46f287d62c175d873mridge } 1911e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 1921c5ac21333f543680ce306d46f287d62c175d873mridge XFree(ret_prop); 1931c5ac21333f543680ce306d46f287d62c175d873mridge return ret; 1941c5ac21333f543680ce306d46f287d62c175d873mridge} 1951c5ac21333f543680ce306d46f287d62c175d873mridge 196354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic long get_randnum(long min, long max) 197354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 1981c5ac21333f543680ce306d46f287d62c175d873mridge return min + (long)((float)max * (rand() / (RAND_MAX + 1.0))); 1991c5ac21333f543680ce306d46f287d62c175d873mridge} 2001c5ac21333f543680ce306d46f287d62c175d873mridge 201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int wm_supports(Display * disp, const char *prop) 202354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 2031c5ac21333f543680ce306d46f287d62c175d873mridge Atom xa_prop = XInternAtom(disp, prop, False); 2041c5ac21333f543680ce306d46f287d62c175d873mridge Atom *list; 2051c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long size, items; 2061c5ac21333f543680ce306d46f287d62c175d873mridge int i; 2071c5ac21333f543680ce306d46f287d62c175d873mridge 208354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!(list = (Atom *) get_property(disp, DefaultRootWindow(disp), 209354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao XA_ATOM, "_NET_SUPPORTED", &size, 210354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao &items))) { 2111c5ac21333f543680ce306d46f287d62c175d873mridge fprintf(stderr, "Cannot get _NET_SUPPORTED property.\n"); 2121c5ac21333f543680ce306d46f287d62c175d873mridge return 0; 2131c5ac21333f543680ce306d46f287d62c175d873mridge } 2141c5ac21333f543680ce306d46f287d62c175d873mridge 2151c5ac21333f543680ce306d46f287d62c175d873mridge size *= items; 2161c5ac21333f543680ce306d46f287d62c175d873mridge 2171c5ac21333f543680ce306d46f287d62c175d873mridge for (i = 0; i < size / sizeof(Atom); i++) { 2181c5ac21333f543680ce306d46f287d62c175d873mridge if (list[i] == xa_prop) { 2191c5ac21333f543680ce306d46f287d62c175d873mridge free(list); 2201c5ac21333f543680ce306d46f287d62c175d873mridge return 1; 2211c5ac21333f543680ce306d46f287d62c175d873mridge } 2221c5ac21333f543680ce306d46f287d62c175d873mridge } 2231e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 2241c5ac21333f543680ce306d46f287d62c175d873mridge free(list); 2251c5ac21333f543680ce306d46f287d62c175d873mridge return 0; 2261c5ac21333f543680ce306d46f287d62c175d873mridge} 2271c5ac21333f543680ce306d46f287d62c175d873mridge 2281c5ac21333f543680ce306d46f287d62c175d873mridgestatic inline unsigned long clamp_value(unsigned long value, 229354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long min, unsigned long max) 2301c5ac21333f543680ce306d46f287d62c175d873mridge{ 2311c5ac21333f543680ce306d46f287d62c175d873mridge return (value < min ? min : (value > max ? max : value)); 2321c5ac21333f543680ce306d46f287d62c175d873mridge} 2331c5ac21333f543680ce306d46f287d62c175d873mridge 234354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int ignore_xlib_error(Display * disp, XErrorEvent * xee) 235354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 2361c5ac21333f543680ce306d46f287d62c175d873mridge char errbuf[256]; 2371c5ac21333f543680ce306d46f287d62c175d873mridge 2381c5ac21333f543680ce306d46f287d62c175d873mridge XGetErrorText(disp, xee->error_code, errbuf, 256); 239354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 240354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "IGNORING Xlib error %d (%s) on request (%d.%d), sernum = %lu.\n", 2411c5ac21333f543680ce306d46f287d62c175d873mridge xee->error_code, errbuf, xee->request_code, xee->minor_code, 2421c5ac21333f543680ce306d46f287d62c175d873mridge xee->serial); 2431c5ac21333f543680ce306d46f287d62c175d873mridge return 1; 2441c5ac21333f543680ce306d46f287d62c175d873mridge} 2451c5ac21333f543680ce306d46f287d62c175d873mridge 246354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void slide_window(Display * disp, Window * win, unsigned long desk_w, 247354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long desk_h) 248354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 2491c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long x, y; 2501c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long w, h; 2511c5ac21333f543680ce306d46f287d62c175d873mridge XWindowAttributes moo; 2521c5ac21333f543680ce306d46f287d62c175d873mridge Window junk; 2531c5ac21333f543680ce306d46f287d62c175d873mridge 2541c5ac21333f543680ce306d46f287d62c175d873mridge if (XGetWindowAttributes(disp, *win, &moo) != 1) { 255354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "Cannot get attributes of window 0x%lx.\n", 256354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao *win); 2571c5ac21333f543680ce306d46f287d62c175d873mridge return; 2581c5ac21333f543680ce306d46f287d62c175d873mridge } 2591c5ac21333f543680ce306d46f287d62c175d873mridge 2601e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper if (XTranslateCoordinates(disp, *win, moo.root, 261354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao -moo.border_width, -moo.border_width, &moo.x, 262354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao &moo.y, &junk) != 1) { 263354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 264354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Cannot translate coordinates of window 0x%lx.\n", 265354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao *win); 2661c5ac21333f543680ce306d46f287d62c175d873mridge return; 2671c5ac21333f543680ce306d46f287d62c175d873mridge } 2681c5ac21333f543680ce306d46f287d62c175d873mridge 2691c5ac21333f543680ce306d46f287d62c175d873mridge x = moo.x + get_randnum(-SLIDE_THRESHOLD, SLIDE_THRESHOLD); 2701c5ac21333f543680ce306d46f287d62c175d873mridge y = moo.y + get_randnum(-SLIDE_THRESHOLD, SLIDE_THRESHOLD); 2711c5ac21333f543680ce306d46f287d62c175d873mridge w = moo.width + get_randnum(-SLIDE_THRESHOLD, SLIDE_THRESHOLD); 2721c5ac21333f543680ce306d46f287d62c175d873mridge h = moo.height + get_randnum(-SLIDE_THRESHOLD, SLIDE_THRESHOLD); 2731c5ac21333f543680ce306d46f287d62c175d873mridge 2741c5ac21333f543680ce306d46f287d62c175d873mridge x = clamp_value(x, 0, desk_w); 2751c5ac21333f543680ce306d46f287d62c175d873mridge y = clamp_value(y, 0, desk_h); 2761c5ac21333f543680ce306d46f287d62c175d873mridge w = clamp_value(w, 0, desk_w); 2771c5ac21333f543680ce306d46f287d62c175d873mridge h = clamp_value(h, 0, desk_h); 2781c5ac21333f543680ce306d46f287d62c175d873mridge 27943088e16aa60d69e3ec5a69cdd8bdd45b8891127Garrett Cooper if (wm_supports(disp, "_NET_MOVERESIZE_WINDOW")) { 2801e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper send_client_msg(disp, *win, "_NET_MOVERESIZE_WINDOW", 281354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 0, x, y, w, h); 2821c5ac21333f543680ce306d46f287d62c175d873mridge } else { 2831c5ac21333f543680ce306d46f287d62c175d873mridge XMoveResizeWindow(disp, *win, x, y, w, h); 2841c5ac21333f543680ce306d46f287d62c175d873mridge } 2851c5ac21333f543680ce306d46f287d62c175d873mridge} 2861c5ac21333f543680ce306d46f287d62c175d873mridge 287354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void move_window(Display * disp, Window * win, unsigned long desk_w, 288354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long desk_h) 289354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 2901c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long x, y, w, h; 2911c5ac21333f543680ce306d46f287d62c175d873mridge 2921c5ac21333f543680ce306d46f287d62c175d873mridge x = get_randnum(0, desk_w); 2931c5ac21333f543680ce306d46f287d62c175d873mridge y = get_randnum(0, desk_h); 2941c5ac21333f543680ce306d46f287d62c175d873mridge w = get_randnum(150, desk_w); 2951c5ac21333f543680ce306d46f287d62c175d873mridge h = get_randnum(150, desk_h); 2961e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 29743088e16aa60d69e3ec5a69cdd8bdd45b8891127Garrett Cooper if (wm_supports(disp, "_NET_MOVERESIZE_WINDOW")) { 2981e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper send_client_msg(disp, *win, "_NET_MOVERESIZE_WINDOW", 299354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 0, x, y, w, h); 3001c5ac21333f543680ce306d46f287d62c175d873mridge } else { 3011c5ac21333f543680ce306d46f287d62c175d873mridge XMoveResizeWindow(disp, *win, x, y, w, h); 3021c5ac21333f543680ce306d46f287d62c175d873mridge } 3031c5ac21333f543680ce306d46f287d62c175d873mridge} 3041c5ac21333f543680ce306d46f287d62c175d873mridge 305354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int toggle_property(Display * disp, Window * win, const char *property) 306354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 3071c5ac21333f543680ce306d46f287d62c175d873mridge Atom prop; 3081c5ac21333f543680ce306d46f287d62c175d873mridge 3091c5ac21333f543680ce306d46f287d62c175d873mridge prop = XInternAtom(disp, property, False); 3101c5ac21333f543680ce306d46f287d62c175d873mridge return send_client_msg(disp, *win, "_NET_WM_STATE", 311354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao _NET_WM_STATE_TOGGLE, prop, 0, 0, 0); 3121c5ac21333f543680ce306d46f287d62c175d873mridge} 3131c5ac21333f543680ce306d46f287d62c175d873mridge 314354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void go_bonkers(Display * disp, unsigned long iterations, 315354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long sleep) 316354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 3171c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long desk_w, desk_h; 3181c5ac21333f543680ce306d46f287d62c175d873mridge Window *windows, *window; 3191c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long windows_length = 0, i; 3201c5ac21333f543680ce306d46f287d62c175d873mridge 3211c5ac21333f543680ce306d46f287d62c175d873mridge if (!get_desktop_size(disp, &desk_w, &desk_h)) { 3221c5ac21333f543680ce306d46f287d62c175d873mridge fprintf(stderr, "WARNING: Assuming desktop to be 1024x768!\n"); 3231c5ac21333f543680ce306d46f287d62c175d873mridge desk_w = 1024; 3241c5ac21333f543680ce306d46f287d62c175d873mridge desk_h = 768; 3251c5ac21333f543680ce306d46f287d62c175d873mridge } 3261c5ac21333f543680ce306d46f287d62c175d873mridge printf("Desktop is %lu by %lu.\n", desk_w, desk_h); 3271c5ac21333f543680ce306d46f287d62c175d873mridge 3281c5ac21333f543680ce306d46f287d62c175d873mridge windows = get_interesting_windows(disp, &windows_length); 3291c5ac21333f543680ce306d46f287d62c175d873mridge if (!windows) { 3301c5ac21333f543680ce306d46f287d62c175d873mridge usleep(1000000); 3311c5ac21333f543680ce306d46f287d62c175d873mridge return; 3321c5ac21333f543680ce306d46f287d62c175d873mridge } 3331c5ac21333f543680ce306d46f287d62c175d873mridge printf("There are %lu interesting windows.\n", windows_length); 3341c5ac21333f543680ce306d46f287d62c175d873mridge 3351c5ac21333f543680ce306d46f287d62c175d873mridge /* Bump up the iteration count so that all windows get 3361c5ac21333f543680ce306d46f287d62c175d873mridge * some exercise. */ 3371c5ac21333f543680ce306d46f287d62c175d873mridge iterations += iterations % windows_length; 3381c5ac21333f543680ce306d46f287d62c175d873mridge 3391c5ac21333f543680ce306d46f287d62c175d873mridge for (i = 0; i < iterations; i++) { 3401c5ac21333f543680ce306d46f287d62c175d873mridge window = &windows[i % windows_length]; 3411c5ac21333f543680ce306d46f287d62c175d873mridge switch (get_randnum(ACTION_MIN, ACTION_MAX)) { 342354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_MOVE_WINDOW: 343354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao move_window(disp, window, desk_w, desk_h); 344354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 345354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_ACTIVATE_WINDOW: 346354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao activate_window(disp, window); 347354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 348354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_MAXIMIZE_WINDOW: 349354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao toggle_property(disp, window, 3501c5ac21333f543680ce306d46f287d62c175d873mridge "_NET_WM_STATE_MAXIMIZED_VERT"); 351354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao toggle_property(disp, window, 3521c5ac21333f543680ce306d46f287d62c175d873mridge "_NET_WM_STATE_MAXIMIZED_HORZ"); 353354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 354354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_FULLSCREEN_WINDOW: 355354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!enable_fullscreen) 3561c5ac21333f543680ce306d46f287d62c175d873mridge break; 357354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao toggle_property(disp, window, 3581c5ac21333f543680ce306d46f287d62c175d873mridge "_NET_WM_STATE_FULLSCREEN"); 359354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 360354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_HIDDEN_WINDOW: 361354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao toggle_property(disp, window, "_NET_WM_STATE_HIDDEN"); 362354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 363354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_SLIDE_WINDOW_0: 364354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_SLIDE_WINDOW_1: 365354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_SLIDE_WINDOW_2: 366354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_SLIDE_WINDOW_3: 367354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_SLIDE_WINDOW_4: 368354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case ACTION_SLIDE_WINDOW_5: 369354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao slide_window(disp, window, desk_w, desk_h); 370354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 3711c5ac21333f543680ce306d46f287d62c175d873mridge } 3721c5ac21333f543680ce306d46f287d62c175d873mridge usleep(sleep); 3731c5ac21333f543680ce306d46f287d62c175d873mridge } 3741c5ac21333f543680ce306d46f287d62c175d873mridge 3751c5ac21333f543680ce306d46f287d62c175d873mridge free(windows); 3761c5ac21333f543680ce306d46f287d62c175d873mridge} 3771c5ac21333f543680ce306d46f287d62c175d873mridge 378354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int send_client_msg(Display * disp, Window win, char *msg, 379354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long data0, unsigned long data1, 380354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long data2, unsigned long data3, 381354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long data4) 3821c5ac21333f543680ce306d46f287d62c175d873mridge{ 3831c5ac21333f543680ce306d46f287d62c175d873mridge XEvent event; 3841c5ac21333f543680ce306d46f287d62c175d873mridge long mask = SubstructureRedirectMask | SubstructureNotifyMask; 3851c5ac21333f543680ce306d46f287d62c175d873mridge 3861c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.type = ClientMessage; 3871c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.serial = 0; 3881c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.send_event = True; 3891c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.message_type = XInternAtom(disp, msg, False); 3901c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.window = win; 3911c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.format = 32; 3921c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.data.l[0] = data0; 3931c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.data.l[1] = data1; 3941c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.data.l[2] = data2; 3951c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.data.l[3] = data3; 3961c5ac21333f543680ce306d46f287d62c175d873mridge event.xclient.data.l[4] = data4; 3971e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 3981c5ac21333f543680ce306d46f287d62c175d873mridge if (XSendEvent(disp, DefaultRootWindow(disp), False, mask, &event)) { 3991c5ac21333f543680ce306d46f287d62c175d873mridge return 1; 4001c5ac21333f543680ce306d46f287d62c175d873mridge } else { 4011c5ac21333f543680ce306d46f287d62c175d873mridge fprintf(stderr, "Cannot send %s event.\n", msg); 4021c5ac21333f543680ce306d46f287d62c175d873mridge return 0; 4031c5ac21333f543680ce306d46f287d62c175d873mridge } 4041c5ac21333f543680ce306d46f287d62c175d873mridge} 4051c5ac21333f543680ce306d46f287d62c175d873mridge 406354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int activate_window(Display * disp, Window * win) 407354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 4081c5ac21333f543680ce306d46f287d62c175d873mridge int ret; 4091e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 410354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ret = send_client_msg(disp, *win, "_NET_ACTIVE_WINDOW", 0, 0, 0, 0, 0); 4111c5ac21333f543680ce306d46f287d62c175d873mridge XMapRaised(disp, *win); 4121c5ac21333f543680ce306d46f287d62c175d873mridge 4131c5ac21333f543680ce306d46f287d62c175d873mridge return ret; 4141c5ac21333f543680ce306d46f287d62c175d873mridge} 4151c5ac21333f543680ce306d46f287d62c175d873mridge 416354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic Window *get_client_list(Display * disp, unsigned long *size, 417354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long *items) 418354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 4191c5ac21333f543680ce306d46f287d62c175d873mridge void *res; 4201c5ac21333f543680ce306d46f287d62c175d873mridge 421354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((res = (Window *) get_property(disp, DefaultRootWindow(disp), 422354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao XA_WINDOW, "_NET_CLIENT_LIST", size, 423354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao items)) == NULL) { 424354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((res = 425354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (Window *) get_property(disp, DefaultRootWindow(disp), 426354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao XA_CARDINAL, "_WIN_CLIENT_LIST", 427354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao size, items)) == NULL) { 428354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 429354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Cannot get client list properties. \n" 430354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "(_NET_CLIENT_LIST or _WIN_CLIENT_LIST)" "\n"); 4311c5ac21333f543680ce306d46f287d62c175d873mridge return NULL; 4321c5ac21333f543680ce306d46f287d62c175d873mridge } 4331c5ac21333f543680ce306d46f287d62c175d873mridge } 4341c5ac21333f543680ce306d46f287d62c175d873mridge 435354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return (Window *) res; 4361c5ac21333f543680ce306d46f287d62c175d873mridge} 4371c5ac21333f543680ce306d46f287d62c175d873mridge 438354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic Window *get_interesting_windows(Display * disp, 439354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned long *num_windows) 440354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 4411c5ac21333f543680ce306d46f287d62c175d873mridge Window *client_list, *ret, *tmp; 4421c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long client_list_size, client_list_items, i; 4431c5ac21333f543680ce306d46f287d62c175d873mridge long *desktop; 4441c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long num_needed = 0; 4451c5ac21333f543680ce306d46f287d62c175d873mridge 4461c5ac21333f543680ce306d46f287d62c175d873mridge if ((client_list = get_client_list(disp, &client_list_size, 447354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao &client_list_items)) == NULL) { 4481c5ac21333f543680ce306d46f287d62c175d873mridge return NULL; 4491c5ac21333f543680ce306d46f287d62c175d873mridge } 4501c5ac21333f543680ce306d46f287d62c175d873mridge 4511c5ac21333f543680ce306d46f287d62c175d873mridge /* Figure out how many Window structs we'll ultimately need. */ 4521c5ac21333f543680ce306d46f287d62c175d873mridge for (i = 0; i < client_list_items; i++) { 4531c5ac21333f543680ce306d46f287d62c175d873mridge /* desktop ID */ 4541c5ac21333f543680ce306d46f287d62c175d873mridge if ((desktop = (long *)get_property(disp, client_list[i], 455354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao XA_CARDINAL, 456354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "_NET_WM_DESKTOP", NULL, 457354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao NULL)) == NULL) { 458354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao desktop = 459354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (long *)get_property(disp, client_list[i], 460354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao XA_CARDINAL, "_WIN_WORKSPACE", 461354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao NULL, NULL); 4621c5ac21333f543680ce306d46f287d62c175d873mridge } 4631e6f5a673655551de5734ff31ef48cd63b604e6dGarrett Cooper 4641c5ac21333f543680ce306d46f287d62c175d873mridge /* Ignore windows on unknown desktops */ 4651c5ac21333f543680ce306d46f287d62c175d873mridge if (desktop && *desktop >= 0 && *desktop < DESKTOP_MAX) { 4661c5ac21333f543680ce306d46f287d62c175d873mridge num_needed++; 4671c5ac21333f543680ce306d46f287d62c175d873mridge free(desktop); 4681c5ac21333f543680ce306d46f287d62c175d873mridge } 4691c5ac21333f543680ce306d46f287d62c175d873mridge } 4701c5ac21333f543680ce306d46f287d62c175d873mridge 4711c5ac21333f543680ce306d46f287d62c175d873mridge ret = calloc(num_needed, sizeof(Window)); 4721c5ac21333f543680ce306d46f287d62c175d873mridge if (!ret) { 4731c5ac21333f543680ce306d46f287d62c175d873mridge perror("get_interesting_window allocations"); 4741c5ac21333f543680ce306d46f287d62c175d873mridge free(client_list); 4751c5ac21333f543680ce306d46f287d62c175d873mridge return NULL; 4761c5ac21333f543680ce306d46f287d62c175d873mridge } 4771c5ac21333f543680ce306d46f287d62c175d873mridge tmp = ret; 4781c5ac21333f543680ce306d46f287d62c175d873mridge 4791c5ac21333f543680ce306d46f287d62c175d873mridge /* Now copy all that crud. */ 4801c5ac21333f543680ce306d46f287d62c175d873mridge for (i = 0; i < client_list_items; i++) { 4811c5ac21333f543680ce306d46f287d62c175d873mridge /* desktop ID */ 4821c5ac21333f543680ce306d46f287d62c175d873mridge if ((desktop = (long *)get_property(disp, client_list[i], 483354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao XA_CARDINAL, 484354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "_NET_WM_DESKTOP", NULL, 485354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao NULL)) == NULL) { 486354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao desktop = 487354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (long *)get_property(disp, client_list[i], 488354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao XA_CARDINAL, "_WIN_WORKSPACE", 489354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao NULL, NULL); 4901c5ac21333f543680ce306d46f287d62c175d873mridge } 4911c5ac21333f543680ce306d46f287d62c175d873mridge 4921c5ac21333f543680ce306d46f287d62c175d873mridge if (desktop && *desktop >= 0 && *desktop < DESKTOP_MAX) { 4931c5ac21333f543680ce306d46f287d62c175d873mridge memcpy(tmp, &client_list[i], sizeof(Window)); 4941c5ac21333f543680ce306d46f287d62c175d873mridge tmp++; 4951c5ac21333f543680ce306d46f287d62c175d873mridge free(desktop); 4961c5ac21333f543680ce306d46f287d62c175d873mridge } 4971c5ac21333f543680ce306d46f287d62c175d873mridge } 4981c5ac21333f543680ce306d46f287d62c175d873mridge free(client_list); 4991c5ac21333f543680ce306d46f287d62c175d873mridge 5001c5ac21333f543680ce306d46f287d62c175d873mridge *num_windows = num_needed; 5011c5ac21333f543680ce306d46f287d62c175d873mridge return ret; 5021c5ac21333f543680ce306d46f287d62c175d873mridge} 5031c5ac21333f543680ce306d46f287d62c175d873mridge 504354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint main(int argc, char *argv[]) 505354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao{ 5061c5ac21333f543680ce306d46f287d62c175d873mridge char *disp_string = NULL; 5071c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long iterations = 10000, rounds = -1, i; 5081c5ac21333f543680ce306d46f287d62c175d873mridge unsigned long sleep = 100000; 5091c5ac21333f543680ce306d46f287d62c175d873mridge int opt; 5101c5ac21333f543680ce306d46f287d62c175d873mridge Display *disp; 5111c5ac21333f543680ce306d46f287d62c175d873mridge 5121c5ac21333f543680ce306d46f287d62c175d873mridge while ((opt = getopt(argc, argv, "d:i:r:s:f")) != -1) { 5131c5ac21333f543680ce306d46f287d62c175d873mridge switch (opt) { 514354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'd': 515354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao disp_string = optarg; 516354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 517354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'i': 518354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao iterations = atoi(optarg); 519354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 520354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'r': 521354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao rounds = atoi(optarg); 522354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 523354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 's': 524354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sleep = atoi(optarg); 525354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 526354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao case 'f': 527354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao enable_fullscreen = 1; 528354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao break; 529354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao default: 530354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 531354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "Usage: %s [-d DISPLAY] [-i ITERATIONS] [-r ROUNDS] [-s SLEEP] [-f]\n\ 5321c5ac21333f543680ce306d46f287d62c175d873mridge DISPLAY is an X11 display string.\n\ 5331c5ac21333f543680ce306d46f287d62c175d873mridge ITERATIONS is the approximate number of windows to play with before generating a new window list.\n\ 5341c5ac21333f543680ce306d46f287d62c175d873mridge SLEEP is the amount of time (in usec) to sleep between window tweaks.\n\ 5351c5ac21333f543680ce306d46f287d62c175d873mridge -f enables fullscreen toggling.\n\ 536354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ROUNDS is the number of iterations to run, or -1 to run forever.\n", 537354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao argv[0]); 538354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return 0; 5391c5ac21333f543680ce306d46f287d62c175d873mridge } 5401c5ac21333f543680ce306d46f287d62c175d873mridge } 5411c5ac21333f543680ce306d46f287d62c175d873mridge 5421c5ac21333f543680ce306d46f287d62c175d873mridge if (!(disp = XOpenDisplay(disp_string))) { 5431c5ac21333f543680ce306d46f287d62c175d873mridge fprintf(stderr, "Unable to connect to display '%s'.\n", 544354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (disp_string != 545354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao NULL ? disp_string : getenv("DISPLAY"))); 5461c5ac21333f543680ce306d46f287d62c175d873mridge return 1; 5471c5ac21333f543680ce306d46f287d62c175d873mridge } 5481c5ac21333f543680ce306d46f287d62c175d873mridge 5491c5ac21333f543680ce306d46f287d62c175d873mridge seed_random(); 5501c5ac21333f543680ce306d46f287d62c175d873mridge 5511c5ac21333f543680ce306d46f287d62c175d873mridge XSetErrorHandler(&ignore_xlib_error); 5521c5ac21333f543680ce306d46f287d62c175d873mridge 5531c5ac21333f543680ce306d46f287d62c175d873mridge for (i = 0; i < rounds || rounds == -1; i++) { 5541c5ac21333f543680ce306d46f287d62c175d873mridge go_bonkers(disp, iterations, sleep); 5551c5ac21333f543680ce306d46f287d62c175d873mridge } 5561c5ac21333f543680ce306d46f287d62c175d873mridge 5571c5ac21333f543680ce306d46f287d62c175d873mridge printf("Enough of that; I'm done.\n"); 5581c5ac21333f543680ce306d46f287d62c175d873mridge 5591c5ac21333f543680ce306d46f287d62c175d873mridge XCloseDisplay(disp); 5601c5ac21333f543680ce306d46f287d62c175d873mridge 5611c5ac21333f543680ce306d46f287d62c175d873mridge return 0; 562ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 563