WhiteBoard Project using C RPC
A Project in Distributed Computing at IIIT-Delhi
xwindow.c
Go to the documentation of this file.
1 /*
2  * xwindow.c
3  */
4 
5 #include <stdio.h>
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 
9 #include "oneln.h"
10 typedef struct OneLn OneLn;
11 
12 typedef struct {
13  Display *display;
14  Window window;
15  GC gc;
16 } Xwindow;
17 
18 static Xwindow xw;
19 
20 /*
21  * Open an X window on display screen whose name is given in dispnm[]; the
22  * title of the window will be wintitle[]. The private var xw of this module
23  * gets initialized as a result. The window so created will appear as soon
24  * as trackpointer() is called. dispnm[] is of the form "machinename:0.0",
25  * wintitle[] is any arbitrary C string of non-control chars.
26  */
27 int openxwindow(char dispnm[], char wintitle[])
28 {
29  Display *d = XOpenDisplay(dispnm); /* connect to X */
30  int screen;
31  int dw, dh;
32  XGCValues values;
33 
34  if (d == NULL) {
35  /* "can't connect to X server; was dispnm bad? */
36  return -1;
37  }
38  xw.display = d;
39 
40  /* get screen size from display structure macro */
41  screen = DefaultScreen(d);
42  dw = DisplayWidth(d, screen);
43  dh = DisplayHeight(d, screen);
44 
45  /* create opaque window */
46  xw.window = XCreateSimpleWindow
47  (d, RootWindow(d, screen),
48  dw / 3, dh / 3, 350, dh / 4, 4,
49  BlackPixel(d, screen), WhitePixel(d, screen));
50 
51  /* set window/icon titles */
52  XSetStandardProperties
53  (d, xw.window, wintitle, "Doodle", None, 0, 0, 0);
54 
55  /* Select event types wanted; 0x00FFFFFF selects all! */
56  XSelectInput(xw.display, xw.window, 0x00FFFFFF);
57 
58  /* Display window */
59  XMapWindow(d, xw.window);
60 
61  /* Create Graphics Context */
62  xw.gc = XCreateGC(d, xw.window, 0L, &values);
63 
64  /* Set Foreground color to black */
65  XSetForeground(d, xw.gc, BlackPixel(d, screen));
66 
67  return 0;
68 }
69 
70 /*
71  * Close the X window opened by openxwindow().
72  */
73 int closexwindow(void)
74 {
75  return XCloseDisplay(xw.display);
76 }
77 
78 /*
79  * Draw a straight line from (coord.x1, coord.y1) to (coord.x2, coord.y2).
80  */
81 void drawline(OneLn * coord)
82 {
83  XSetForeground(xw.display, xw.gc, coord->color);
84  XDrawLine(xw.display, xw.window, xw.gc,
85  coord->x1, coord->y1, coord->x2, coord->y2);
86  XFlush(xw.display);
87 }
88 
89 /*
90  * "Track" the mouse ptr of the X window server to which we
91  * established connection via openxwindow(). The routine does *not*
92  * draw an individual line (unless "exposed"), *nor* does it return
93  * until the mouseptr (a) enters our window from outside, (b) leaves
94  * our window, or (c) mouse ptr is inside the window, and one of the
95  * three mouse buttons is pressed. Events (a) and (b) return 0, event
96  * (c) returns the number of the button 1, 2, or 3. The routine
97  * remembers upto 2000 points, which is a kludge. When our window
98  * gets (partially) hidden, and later revealed again (i.e.,
99  * "exposed"), the routine draws the lines it had (subject to this
100  * limit).
101  */
102 int trackpointer(OneLn * newseg, int pending)
103 {
104  XEvent report;
105  Window rootw, childw;
106  int rootx, rooty, wx, wy;
107  unsigned int keys_buttons;
108  static XPoint points[2000] = { {0}, {0} };
109  static int index = 0;
110 
111  if (pending && !XPending(xw.display)) {
112  return 0;
113  }
114 
115  XNextEvent(xw.display, &report);
116  switch (report.type) {
117  case EnterNotify:
118  return 6;
119 
120  case LeaveNotify:
121  return 7;
122 
123  case ButtonPress:
124  if (report.xbutton.button == 3)
125  return 3;
126 
127  /* get rid of any other motion events still on queue */
128  while (XCheckMaskEvent
129  (xw.display,
130  PointerMotionMask | ButtonMotionMask,
131  &report)
132  );
133 
134  /* now get current position */
135  XQueryPointer
136  (xw.display, report.xmotion.window,
137  &rootw, &childw, &rootx, &rooty, &wx, &wy, &keys_buttons);
138 
139  newseg->x1 = points[index].x;
140  newseg->y1 = points[index].y;
141 
142  index++;
143  if (index >= 2000)
144  index = 0;
145 
146  newseg->x2 = points[index].x = wx;
147  newseg->y2 = points[index].y = wy;
148  return report.xbutton.button;
149 
150  case Expose:
151  /* XDrawLines (xw.display, xw.window, xw.gc, points, index,
152  CoordModeOrigin); */
153  return 5;
154  }
155  return 0;
156 }
157 
158 /*
159  * Convert string p of digits given in radix r into a long integer.
160  * Typical r values are 10 and 16. When r==16, do not give 0x prefix.
161  * Our own because there is no stdlib one; but see strtoq()
162  */
163 long atoir(char *p, int r)
164 {
165  if (p == NULL) return 0;
166  long x = 0L, d;
167  char c, sign = '+';
168  if (*p == '-') {
169  sign = '-';
170  p++;
171  }
172  while((c = *p++)) {
173  d = r;
174  if (r == 16) {
175  if ('A' <= c && c <= 'F') d = (long)(c + 10 - 'A');
176  if ('a' <= c && c <= 'f') d = (long)(c + 10 - 'a');
177  }
178  if ('0' <= c && c <= '9') d = (long)(c - '0');
179  if (d >= r) break;
180  x = x * r + d;
181  }
182  if (sign == '-') x = -x;
183  return x;
184 }
185 
186 #ifdef MAIN
187 #include <stdio.h>
188 
189 /*
190  * A little test harness. Invoke the resulting program with arguments:
191  * (1) name of the display screen (e.g., "diamond:0.0"), and (2) a
192  * name that shows up in the title-bar of the window (e.g., "hello"),
193  * (3) RGB color value in two hex digits for each. Also try illegal
194  * args.
195  */
196 int main(int argc, char *argv[], char **envp)
197 {
198  OneLn seg = { 0, 0, 100, 100, 0 };
199 
200 
201  if (argc < 4) {
202  fprintf(stderr,
203  "usage: %s <display-hostname> <color-number> <window-title>\n",
204  argv[0]);
205  }
206  seg.color = atoir(argv[3], 16);
207  if (seg.color < 0)
208  seg.color = 0;
209 
210 
211  int b = openxwindow(argv[1], argv[2]);
212  printf("openxwindow(%s, %s, %s) returned %d\n",
213  argv[1], argv[2], argv[3], b);
214 
215  printf("press button 3 (Right) to terminate; color %ld", seg.color);
216 
217  do {
218  b = trackpointer(&seg, 0);
219  printf("line from (%2d, %2d) to (%2d, %2d) button %d\n",
220  seg.x1, seg.y1, seg.x2, seg.y2, b);
221  drawline(&seg);
222  } while (b != 3);
223  return closexwindow();
224 }
225 #endif
226 
227 /* -eof- */
Definition: oneln.h:2
int trackpointer(OneLn *newseg, int pending)
Definition: xwindow.c:102
int openxwindow(char dispnm[], char wintitle[])
Definition: xwindow.c:27
int closexwindow(void)
Definition: xwindow.c:73
static Xwindow xw
Definition: xwindow.c:18
int main(int argc, char *argv[])
Definition: deregall.c:10
int y1
Definition: oneln.h:4
long atoir(char *p, int r)
Definition: xwindow.c:163
int x1
Definition: oneln.h:3
void drawline(OneLn *coord)
Definition: xwindow.c:81
Window window
Definition: xwindow.c:14
int x2
Definition: oneln.h:5
long color
Definition: oneln.h:7
GC gc
Definition: xwindow.c:15
int y2
Definition: oneln.h:6
Display * display
Definition: xwindow.c:13