Initial git import
[sxemacs] / etc / tests / external-widget / test-ew-xlib.c
1 /*
2  * Copyright 1989 O'Reilly and Associates, Inc.
3  * See ../Copyright for complete rights and liability information.
4  */
5 #include <X11/Xlib.h>
6 #include <X11/Xutil.h>
7 #include <X11/Xos.h>
8 #include <X11/Xatom.h>
9
10 #include <stdio.h>
11
12 #define BITMAPDEPTH 1
13 #define TOO_SMALL 0
14 #define BIG_ENOUGH 1
15
16 /* These are used as arguments to nearly every Xlib routine, so it saves 
17  * routine arguments to declare them global.  If there were 
18  * additional source files, they would be declared extern there. */
19 Display *display;
20 int screen_num;
21
22 static char *progname;          /* name this program was invoked by */
23
24 void main(argc, argv)
25 int argc;
26 char **argv;
27 {
28         Window topwin, win, win2;
29         unsigned int width, height;     /* window size */
30         int x, y;               /* window position */
31         unsigned int border_width = 4;  /* four pixels */
32         unsigned int display_width, display_height;
33         char *window_name = "Basic Window Program";
34         char *icon_name = "basicwin";
35         XSizeHints size_hints;
36         int count;
37         XEvent report;
38         GC gc;
39         XFontStruct *font_info;
40         char *display_name = NULL;
41         int window_size = BIG_ENOUGH;   /* or TOO_SMALL to display contents */
42
43         progname = argv[0];
44
45         /* connect to X server */
46         if ((display = XOpenDisplay(display_name)) == NULL) {
47                 (void)fprintf(stderr, "%s: cannot connect to X server %s\n",
48                               progname, XDisplayName(display_name));
49                 exit(-1);
50         }
51
52         /* get screen size from display structure macro */
53         screen_num = DefaultScreen(display);
54         display_width = DisplayWidth(display, screen_num);
55         display_height = DisplayHeight(display, screen_num);
56
57         /* Note that in a real application, x and y would default to 0
58          * but would be settable from the command line or resource database.  
59          */
60         x = y = 0;
61
62         /* size window with enough room for text */
63         width = display_width / 2, height = display_height / 3;
64
65         /* ------------------------------------------------------------ */
66
67         /* create top-level window */
68         topwin = XCreateSimpleWindow(display, RootWindow(display, screen_num),
69                                      x, y, width, 2 * height, border_width,
70                                      BlackPixel(display, screen_num),
71                                      WhitePixel(display, screen_num));
72
73         /* Set size hints for window manager.  The window manager may
74          * override these settings.  Note that in a real
75          * application if size or position were set by the user
76          * the flags would be UPosition and USize, and these would
77          * override the window manager's preferences for this window. */
78
79         /* x, y, width, and height hints are now taken from
80          * the actual settings of the window when mapped. Note
81          * that PPosition and PSize must be specified anyway. */
82
83         size_hints.flags = PPosition | PSize | PMinSize;
84         size_hints.min_width = 300;
85         size_hints.min_height = 200;
86
87         {
88                 XWMHints wm_hints;
89                 XClassHint class_hints;
90
91                 /* format of the window name and icon name 
92                  * arguments has changed in R4 */
93                 XTextProperty windowName, iconName;
94
95                 /* These calls store window_name and icon_name into
96                  * XTextProperty structures and set their other 
97                  * fields properly. */
98                 if (XStringListToTextProperty(&window_name, 1, &windowName) ==
99                     0) {
100                         (void)fprintf(stderr,
101                                       "%s: structure allocation for windowName failed.\n",
102                                       progname);
103                         exit(-1);
104                 }
105
106                 if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) {
107                         (void)fprintf(stderr,
108                                       "%s: structure allocation for iconName failed.\n",
109                                       progname);
110                         exit(-1);
111                 }
112
113                 wm_hints.initial_state = NormalState;
114                 wm_hints.input = True;
115                 wm_hints.flags = StateHint | InputHint;
116
117                 class_hints.res_name = progname;
118                 class_hints.res_class = "Basicwin";
119
120                 XSetWMProperties(display, topwin, &windowName, &iconName,
121                                  argv, argc, &size_hints, &wm_hints,
122                                  &class_hints);
123         }
124
125         /* ------------------------------------------------------------ */
126
127         /* create the window we're in charge of */
128
129         win = XCreateSimpleWindow(display, topwin,
130                                   x, y, width, height, border_width,
131                                   BlackPixel(display, screen_num),
132                                   WhitePixel(display, screen_num));
133
134         /* Select event types wanted */
135         XSelectInput(display, win, ExposureMask | KeyPressMask |
136                      ButtonPressMask | StructureNotifyMask);
137
138         load_font(&font_info);
139
140         /* create GC for text and drawing */
141         getGC(win, &gc, font_info);
142
143         /* ------------------------------------------------------------ */
144
145         /* create the external-client window */
146
147         win2 = XCreateSimpleWindow(display, topwin,
148                                    x, y + height, width, height, border_width,
149                                    BlackPixel(display, screen_num),
150                                    WhitePixel(display, screen_num));
151         printf("external window: %d\n", win2);
152         ExternalClientInitialize(display, win2);
153
154         /* ------------------------------------------------------------ */
155
156         /* Display windows */
157         XMapWindow(display, topwin);
158         XMapWindow(display, win);
159         XMapWindow(display, win2);
160
161         /* get events, use first to display text and graphics */
162         while (1) {
163                 XNextEvent(display, &report);
164                 if (report.xany.window == win2)
165                         ExternalClientEventHandler(display, win2, &report);
166                 else
167                         switch (report.type) {
168                         case Expose:
169                                 /* unless this is the last contiguous expose,
170                                  * don't draw the window */
171                                 if (report.xexpose.count != 0)
172                                         break;
173
174                                 /* if window too small to use */
175                                 if (window_size == TOO_SMALL)
176                                         TooSmall(win, gc, font_info);
177                                 else {
178                                         /* place text in window */
179                                         draw_text(win, gc, font_info, width,
180                                                   height);
181
182                                         /* place graphics in window, */
183                                         draw_graphics(win, gc, width, height);
184                                 }
185                                 break;
186                         case ConfigureNotify:
187                                 /* window has been resized, change width and
188                                  * height to send to draw_text and draw_graphics
189                                  * in next Expose */
190                                 width = report.xconfigure.width;
191                                 height = report.xconfigure.height;
192                                 if ((width < size_hints.min_width) ||
193                                     (height < size_hints.min_height))
194                                         window_size = TOO_SMALL;
195                                 else
196                                         window_size = BIG_ENOUGH;
197                                 break;
198                         case ButtonPress:
199                                 /* trickle down into KeyPress (no break) */
200                         case KeyPress:
201                                 XUnloadFont(display, font_info->fid);
202                                 XFreeGC(display, gc);
203                                 XCloseDisplay(display);
204                                 exit(1);
205                         default:
206                                 /* all events selected by StructureNotifyMask
207                                  * except ConfigureNotify are thrown away here,
208                                  * since nothing is done with them */
209                                 break;
210                         }       /* end switch */
211         }                       /* end while */
212 }
213
214 getGC(win, gc, font_info)
215 Window win;
216 GC *gc;
217 XFontStruct *font_info;
218 {
219         unsigned long valuemask = 0;    /* ignore XGCvalues and use defaults */
220         XGCValues values;
221         unsigned int line_width = 6;
222         int line_style = LineOnOffDash;
223         int cap_style = CapRound;
224         int join_style = JoinRound;
225         int dash_offset = 0;
226         static char dash_list[] = { 12, 24 };
227         int list_length = 2;
228
229         /* Create default Graphics Context */
230         *gc = XCreateGC(display, win, valuemask, &values);
231
232         /* specify font */
233         XSetFont(display, *gc, font_info->fid);
234
235         /* specify black foreground since default window background is 
236          * white and default foreground is undefined. */
237         XSetForeground(display, *gc, BlackPixel(display, screen_num));
238
239         /* set line attributes */
240         XSetLineAttributes(display, *gc, line_width, line_style,
241                            cap_style, join_style);
242
243         /* set dashes */
244         XSetDashes(display, *gc, dash_offset, dash_list, list_length);
245 }
246
247 load_font(font_info)
248 XFontStruct **font_info;
249 {
250         char *fontname = "9x15";
251
252         /* Load font and get font information structure. */
253         if ((*font_info = XLoadQueryFont(display, fontname)) == NULL) {
254                 (void)fprintf(stderr, "%s: Cannot open 9x15 font\n", progname);
255                 exit(-1);
256         }
257 }
258
259 draw_text(win, gc, font_info, win_width, win_height)
260 Window win;
261 GC gc;
262 XFontStruct *font_info;
263 unsigned int win_width, win_height;
264 {
265         char *string1 = "Hi! I'm a window, who are you?";
266         char *string2 = "To terminate program; Press any key";
267         char *string3 = "or button while in this window.";
268         char *string4 = "Screen Dimensions:";
269         int len1, len2, len3, len4;
270         int width1, width2, width3;
271         char cd_height[50], cd_width[50], cd_depth[50];
272         int font_height;
273         int initial_y_offset, x_offset;
274
275         /* need length for both XTextWidth and XDrawString */
276         len1 = strlen(string1);
277         len2 = strlen(string2);
278         len3 = strlen(string3);
279
280         /* get string widths for centering */
281         width1 = XTextWidth(font_info, string1, len1);
282         width2 = XTextWidth(font_info, string2, len2);
283         width3 = XTextWidth(font_info, string3, len3);
284
285         font_height = font_info->ascent + font_info->descent;
286
287         /* output text, centered on each line */
288         XDrawString(display, win, gc, (win_width - width1) / 2,
289                     font_height, string1, len1);
290         XDrawString(display, win, gc, (win_width - width2) / 2,
291                     (int)(win_height - (2 * font_height)), string2, len2);
292         XDrawString(display, win, gc, (win_width - width3) / 2,
293                     (int)(win_height - font_height), string3, len3);
294
295         /* copy numbers into string variables */
296         (void)sprintf(cd_height, " Height - %d pixels",
297                       DisplayHeight(display, screen_num));
298         (void)sprintf(cd_width, " Width  - %d pixels",
299                       DisplayWidth(display, screen_num));
300         (void)sprintf(cd_depth, " Depth  - %d plane(s)",
301                       DefaultDepth(display, screen_num));
302
303         /* reuse these for same purpose */
304         len4 = strlen(string4);
305         len1 = strlen(cd_height);
306         len2 = strlen(cd_width);
307         len3 = strlen(cd_depth);
308
309         /* To center strings vertically, we place the first string
310          * so that the top of it is two font_heights above the center
311          * of the window.  Since the baseline of the string is what we
312          * need to locate for XDrawString, and the baseline is one
313          * font_info->ascent below the top of the character,
314          * the final offset of the origin up from the center of the 
315          * window is one font_height + one descent. */
316
317         initial_y_offset = win_height / 2 - font_height - font_info->descent;
318         x_offset = (int)win_width / 4;
319         XDrawString(display, win, gc, x_offset, (int)initial_y_offset,
320                     string4, len4);
321
322         XDrawString(display, win, gc, x_offset, (int)initial_y_offset +
323                     font_height, cd_height, len1);
324         XDrawString(display, win, gc, x_offset, (int)initial_y_offset +
325                     2 * font_height, cd_width, len2);
326         XDrawString(display, win, gc, x_offset, (int)initial_y_offset +
327                     3 * font_height, cd_depth, len3);
328 }
329
330 draw_graphics(win, gc, window_width, window_height)
331 Window win;
332 GC gc;
333 unsigned int window_width, window_height;
334 {
335         int x, y;
336         int width, height;
337
338         height = window_height / 2;
339         width = 3 * window_width / 4;
340         x = window_width / 2 - width / 2;       /* center */
341         y = window_height / 2 - height / 2;
342         XDrawRectangle(display, win, gc, x, y, width, height);
343 }
344
345 TooSmall(win, gc, font_info)
346 Window win;
347 GC gc;
348 XFontStruct *font_info;
349 {
350         char *string1 = "Too Small";
351         int y_offset, x_offset;
352
353         y_offset = font_info->ascent + 2;
354         x_offset = 2;
355
356         /* output text, centered on each line */
357         XDrawString(display, win, gc, x_offset, y_offset, string1,
358                     strlen(string1));
359 }