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