1 /*
2  *     xmineomatic - win xmines damn fast
3  */
4 
5 #include <stdio.h>
6 #include <X11/Xlib.h>
7 
8 
9 #define WIDTH     30
10 #define HEIGHT    16
11 #define NUM_MINES 99
12 
13 #define MINE 9
14 #define MISSMARKED 10
15 #define BOOM 11
16 #define MARKED  0x20
17 #define COVERED 0x10
18 
19 #define SWIDTH  20
20 #define SHEIGHT 20
21 #define BWIDTH  14
22 #define XOFFSET 14
23 #define YOFFSET 80
24 #define BHEIGHT 14
25 
26 #define IsMine(x,y) (map[x][y] & MINE)
27 
28 
29 /* Function prototypes: */
30 int main(int argc, char *argv[]);
31 static void RunXmines(void);
32 static void InitMap(void);
33 static void WaitForGameStart(void);
34 static void GetWindowID(void);
35 static void ClickOnSquare(int x, int y, int button);
36 static void WinGame(void);
37 static void InitXStuff(void);
38 
39 /* Global variables: */
40 int map[WIDTH][HEIGHT];
41 int pid;
42 Window xwid, root;
43 Display *dpy;
44 XButtonEvent event;
45 
46 int
main(int argc,char * argv[])47 main(int argc, char *argv[])
48 {
49   RunXmines();
50   InitMap();
51   WaitForGameStart();
52   GetWindowID();
53   InitXStuff();
54   WinGame();
55 
56   return 0;
57 }
58 
59 
60 static void
WinGame()61 WinGame()
62 {
63   int x, y;
64 
65   for (y=0; y < HEIGHT; y++)
66     for (x=0; x < WIDTH; x++)
67       ClickOnSquare(x, y, IsMine(x,y) ? 2 : 0);
68 
69   XSync(dpy, 0);
70 }
71 
72 static void
RunXmines()73 RunXmines()
74 {
75   if ((pid=fork()) == 0)  /* child */
76     execl("/zbt/games/xmines", "xmines", 0);  /* never return */
77 }
78 
79 
80 static void
InitMap()81 InitMap()
82 {
83   int i, x, y;
84 
85   srandom(pid);
86 
87   bzero(map, sizeof(map));
88   for (i=0; i < NUM_MINES; i++)
89     {
90       do
91 	{
92 	  x = random() % WIDTH;
93 	  y = random() % HEIGHT;
94 	}
95       while (IsMine(x,y));
96 
97       map[x][y] = MINE + COVERED;
98     }
99 }
100 
101 
102 static void
WaitForGameStart()103 WaitForGameStart()
104 {
105   printf("Press return when xmines is up and running.\n");
106   (void) getchar();
107 }
108 
109 static void
InitXStuff()110 InitXStuff()
111 {
112   unsigned int junk;
113 
114   dpy = XOpenDisplay("");
115   XGetGeometry(dpy, xwid, &root, (int *)&junk, (int *)&junk, &junk, &junk,
116                &junk, &junk);
117   XSync(dpy, 0);
118 
119 /* Be friendly and fill in all of the XSendEvent fields, but just do it once */  event.type        = ButtonPress;
120   event.serial      = 0;
121   event.send_event  = 0;
122   event.display     = dpy;
123   event.window      = xwid;
124   event.root        = root;
125   event.subwindow   = 0;
126   event.time        = CurrentTime;
127   event.x           = 0;
128   event.y           = 0;
129   event.x_root      = 0;
130   event.y_root      = 0;
131   event.state       = 0;
132   event.button      = 0;
133   event.same_screen = 1;
134 }
135 
136 static void
GetWindowID()137 GetWindowID()
138 {
139   FILE *xwidpipe;
140 
141   xwidpipe = popen("/usr/bin/X/xlswins | /bin/awk '/xmines/ {print $1}'", "r");
142 
143   if (xwidpipe == NULL)
144     fprintf(stderr, "Problem with xlswins.\n"), exit(-1);
145 
146   if (getc(xwidpipe) != EOF)    /* There is currently a window! Joy! */
147     {
148       getc(xwidpipe);    /* Strip off "0x" with these last two getc()'s */
149       fscanf(xwidpipe, "%lx", &xwid);
150       pclose(xwidpipe);
151     }
152 
153   else
154     fprintf(stderr, "Sorry, xmines window not found.\n"), exit(-1);
155 }
156 
157 static void
ClickOnSquare(int x,int y,int button)158 ClickOnSquare(int x, int y, int button)
159 {
160   event.x      = XOFFSET + x * SWIDTH;
161   event.y      = YOFFSET + y * SHEIGHT;
162   event.button = button;
163 
164   while (!XSendEvent(dpy, xwid, True, 0, (XEvent *) &event));
165 }
166