… | |
… | |
33 | You must define either the 'ATHENA' or 'MOTIF' symbol when compiling. |
33 | You must define either the 'ATHENA' or 'MOTIF' symbol when compiling. |
34 | #endif |
34 | #endif |
35 | |
35 | |
36 | #include <ctype.h> |
36 | #include <ctype.h> |
37 | #include <stdio.h> |
37 | #include <stdio.h> |
38 | #include <string.h> /* for strcmp() */ |
38 | #include <string.h> /* for strcmp() */ |
39 | #ifdef __STDC__ |
39 | #include <stdarg.h> |
40 | #include <stdlib.h> /* for exit()... */ |
40 | #include <stdlib.h> /* for exit()... */ |
41 | #endif |
|
|
42 | #ifndef VMS |
|
|
43 | #include <unistd.h> /* for read(), write() */ |
41 | #include <unistd.h> /* for read(), write() */ |
44 | #endif |
|
|
45 | #include <X11/Xatom.h> /* for pre-defined atom names */ |
42 | #include <X11/Xatom.h> /* for pre-defined atom names */ |
46 | #include <X11/StringDefs.h> /* for XtNforeground et.al. */ |
43 | #include <X11/StringDefs.h> /* for XtNforeground et.al. */ |
47 | #include <X11/Intrinsic.h> |
44 | #include <X11/Intrinsic.h> |
|
|
45 | #include <locale.h> |
48 | |
46 | |
49 | #ifdef ATHENA |
47 | #ifdef ATHENA |
50 | #ifndef VMS |
48 | #ifndef VMS |
51 | #include <X11/Xaw/Form.h> |
49 | #include <X11/Xaw/Form.h> |
52 | #else |
50 | #else |
… | |
… | |
60 | #endif |
58 | #endif |
61 | |
59 | |
62 | #include "cb.h" |
60 | #include "cb.h" |
63 | #include "patchlevel.h" |
61 | #include "patchlevel.h" |
64 | |
62 | |
65 | #define eq(a,b) (strcmp((a),(b)) == 0) |
63 | #define eq(a,b) (strcmp((a),(b)) == 0) |
66 | #define max(a,b) ((a) > (b)? (a): (b)) |
64 | #define max(a,b) ((a) > (b)? (a): (b)) |
67 | |
65 | |
68 | #define XtNbufferCount "bufferCount" /* Application resources */ |
66 | #define XtNbufferCount "bufferCount" /* Application resources */ |
69 | #define XtCBufferCount "BufferCount" |
67 | #define XtCBufferCount "BufferCount" |
70 | #define XtNlayout "layout" |
68 | #define XtNlayout "layout" |
71 | #define XtCLayout "Layout" |
69 | #define XtCLayout "Layout" |
72 | |
70 | |
73 | #define PGM_NAME "xcb" |
71 | #define PGM_NAME "xcb" |
74 | #define PGM_CLASS "Xcb" |
72 | #define PGM_CLASS "Xcb" |
75 | #define BUFINC 2048 |
73 | #define BUFINC 2048 |
76 | |
74 | |
77 | static Display *dpy; |
75 | static Display *dpy; |
78 | static Window root; |
76 | static Window root; |
79 | static XtAppContext app; |
77 | static XtAppContext app; |
80 | static Widget top, box, *wdg; |
78 | static Widget top, box, *wdg; |
… | |
… | |
83 | static Atom *atom; |
81 | static Atom *atom; |
84 | static int natoms, nbuffs; |
82 | static int natoms, nbuffs; |
85 | static Window seln; |
83 | static Window seln; |
86 | static int use_utf8 = 0; |
84 | static int use_utf8 = 0; |
87 | |
85 | |
88 | static Atom convert_to; /* convert selection to this cut buffer */ |
86 | static Atom convert_to; /* convert selection to this cut buffer */ |
89 | |
|
|
90 | #ifdef XVIEW |
|
|
91 | static Atom caret, clipboard, yield; |
|
|
92 | static Atom length, lengthc; |
|
|
93 | #endif |
|
|
94 | |
87 | |
95 | #ifndef X_HAVE_UTF8_STRING |
88 | #ifndef X_HAVE_UTF8_STRING |
96 | #define Xutf8TextPropertyToTextList XmbTextPropertyToTextList |
89 | #define Xutf8TextPropertyToTextList XmbTextPropertyToTextList |
97 | #define Xutf8TextListToTextProperty XmbTextListToTextProperty |
90 | #define Xutf8TextListToTextProperty XmbTextListToTextProperty |
98 | #endif |
91 | #endif |
|
|
92 | |
|
|
93 | #define FONT_ELEMENT_SIZE 50 |
|
|
94 | |
|
|
95 | static const char * |
|
|
96 | i_strstr (const char *str, const char *ptn) |
|
|
97 | { |
|
|
98 | const char *s2, *p2; |
|
|
99 | for (; *str; str++) |
|
|
100 | { |
|
|
101 | for (s2 = str, p2 = ptn;; s2++, p2++) |
|
|
102 | { |
|
|
103 | if (!*p2) |
|
|
104 | return str; |
|
|
105 | if (toupper (*s2) != toupper (*p2)) |
|
|
106 | break; |
|
|
107 | } |
|
|
108 | } |
|
|
109 | return NULL; |
|
|
110 | } |
|
|
111 | |
|
|
112 | static const char * |
|
|
113 | Font_GetElement (const char *pattern, char *buf, int bufsiz, ...) |
|
|
114 | { |
|
|
115 | const char *p, *v; |
|
|
116 | char *p2; |
|
|
117 | va_list va; |
|
|
118 | |
|
|
119 | va_start (va, bufsiz); |
|
|
120 | buf[bufsiz - 1] = 0; |
|
|
121 | buf[bufsiz - 2] = '*'; |
|
|
122 | while ((v = va_arg (va, char *)) != NULL) |
|
|
123 | { |
|
|
124 | p = i_strstr (pattern, v); |
|
|
125 | if (p) |
|
|
126 | { |
|
|
127 | strncpy (buf, p + 1, bufsiz - 2); |
|
|
128 | p2 = strchr (buf, '-'); |
|
|
129 | if (p2) |
|
|
130 | *p2 = 0; |
|
|
131 | va_end (va); |
|
|
132 | return p; |
|
|
133 | } |
|
|
134 | } |
|
|
135 | va_end (va); |
|
|
136 | strncpy (buf, "*", bufsiz); |
|
|
137 | return NULL; |
|
|
138 | } |
|
|
139 | |
|
|
140 | static const char * |
|
|
141 | Font_GetSize (const char *pattern, int *size) |
|
|
142 | { |
|
|
143 | const char *p; |
|
|
144 | const char *p2 = NULL; |
|
|
145 | int n = 0; |
|
|
146 | |
|
|
147 | for (p = pattern; 1; p++) |
|
|
148 | { |
|
|
149 | if (!*p) |
|
|
150 | { |
|
|
151 | if (p2 != NULL && n > 1 && n < 72) |
|
|
152 | { |
|
|
153 | *size = n; |
|
|
154 | return p2 + 1; |
|
|
155 | } |
|
|
156 | else |
|
|
157 | { |
|
|
158 | *size = 16; |
|
|
159 | return NULL; |
|
|
160 | } |
|
|
161 | } |
|
|
162 | else if (*p == '-') |
|
|
163 | { |
|
|
164 | if (n > 1 && n < 72 && p2 != NULL) |
|
|
165 | { |
|
|
166 | *size = n; |
|
|
167 | return p2 + 1; |
|
|
168 | } |
|
|
169 | p2 = p; |
|
|
170 | n = 0; |
|
|
171 | } |
|
|
172 | else if (*p >= '0' && *p <= '9' && p2 != NULL) |
|
|
173 | { |
|
|
174 | n *= 10; |
|
|
175 | n += *p - '0'; |
|
|
176 | } |
|
|
177 | else |
|
|
178 | { |
|
|
179 | p2 = NULL; |
|
|
180 | n = 0; |
|
|
181 | } |
|
|
182 | } |
|
|
183 | } |
|
|
184 | |
|
|
185 | /* from http://www.debian.org/doc/manuals/intro-i18n/ */ |
|
|
186 | static XFontSet |
|
|
187 | XCreateFontSetWithGuess (Display * d, const char *pattern, char ***miss, int *n_miss, char **def) |
|
|
188 | { |
|
|
189 | XFontSet fs; |
|
|
190 | char *pattern2; |
|
|
191 | int pixel_size, bufsiz; |
|
|
192 | char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE]; |
|
|
193 | |
|
|
194 | /* No problem? or 'fs' for pattern analysis */ |
|
|
195 | fs = XCreateFontSet (d, pattern, miss, n_miss, def); |
|
|
196 | if (fs && !*n_miss) |
|
|
197 | return fs; /* no need for font guessing */ |
|
|
198 | |
|
|
199 | /* for non-iso8859-1 language and iso8859-1 specification */ |
|
|
200 | /* This 'fs' is only for pattern analysis. */ |
|
|
201 | if (!fs) |
|
|
202 | { |
|
|
203 | if (*n_miss) |
|
|
204 | XFreeStringList (*miss); |
|
|
205 | |
|
|
206 | setlocale (LC_CTYPE, "C"); |
|
|
207 | fs = XCreateFontSet (d, pattern, miss, n_miss, def); |
|
|
208 | setlocale (LC_CTYPE, ""); |
|
|
209 | } |
|
|
210 | |
|
|
211 | /* make XLFD font name for pattern analysis */ |
|
|
212 | if (fs) |
|
|
213 | { |
|
|
214 | XFontStruct **fontstructs; |
|
|
215 | char **fontnames; |
|
|
216 | XFontsOfFontSet (fs, &fontstructs, &fontnames); |
|
|
217 | pattern = fontnames[0]; |
|
|
218 | } |
|
|
219 | |
|
|
220 | /* read elements of font name */ |
|
|
221 | Font_GetElement (pattern, weight, FONT_ELEMENT_SIZE, |
|
|
222 | "-medium-", "-bold-", "-demibold-", "-regular-", NULL); |
|
|
223 | Font_GetElement (pattern, slant, FONT_ELEMENT_SIZE, |
|
|
224 | "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL); |
|
|
225 | Font_GetSize (pattern, &pixel_size); |
|
|
226 | |
|
|
227 | /* modify elements of font name to fit usual font names */ |
|
|
228 | if (!strcmp (weight, "*")) |
|
|
229 | strncpy (weight, "medium", FONT_ELEMENT_SIZE); |
|
|
230 | |
|
|
231 | if (!strcmp (slant, "*")) |
|
|
232 | strncpy (slant, "r", FONT_ELEMENT_SIZE); |
|
|
233 | |
|
|
234 | if (pixel_size < 3) |
|
|
235 | pixel_size = 3; |
|
|
236 | else if (pixel_size > 97) |
|
|
237 | pixel_size = 97; |
|
|
238 | |
|
|
239 | /* build font pattern for better matching for various charsets */ |
|
|
240 | bufsiz = strlen (pattern) + FONT_ELEMENT_SIZE * 2 + 2 * 2 + 58; |
|
|
241 | pattern2 = (char *) malloc (bufsiz); |
|
|
242 | if (pattern2) |
|
|
243 | { |
|
|
244 | snprintf (pattern2, bufsiz - 1, "%s," |
|
|
245 | "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*," |
|
|
246 | "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*", |
|
|
247 | pattern, |
|
|
248 | weight, slant, pixel_size, |
|
|
249 | pixel_size); |
|
|
250 | pattern = pattern2; |
|
|
251 | } |
|
|
252 | |
|
|
253 | if (*n_miss) |
|
|
254 | XFreeStringList (*miss); |
|
|
255 | |
|
|
256 | if (fs) |
|
|
257 | XFreeFontSet (d, fs); |
|
|
258 | |
|
|
259 | /* create fontset */ |
|
|
260 | fs = XCreateFontSet (d, pattern, miss, n_miss, def); |
|
|
261 | if (pattern2) |
|
|
262 | free (pattern2); |
|
|
263 | |
|
|
264 | return fs; |
|
|
265 | } |
|
|
266 | |
|
|
267 | static |
|
|
268 | Boolean |
|
|
269 | CvtStringToFontSet (dpy, args, num_args, fromVal, toVal, closure_ret) |
|
|
270 | Display *dpy; |
|
|
271 | XrmValuePtr args; |
|
|
272 | Cardinal *num_args; |
|
|
273 | XrmValuePtr fromVal; |
|
|
274 | XrmValuePtr toVal; |
|
|
275 | XtPointer *closure_ret; |
|
|
276 | { |
|
|
277 | XFontSet f; |
|
|
278 | char **missing_charset_list; |
|
|
279 | int missing_charset_count; |
|
|
280 | char *def_string; |
|
|
281 | |
|
|
282 | f = XCreateFontSetWithGuess (dpy, (char *) fromVal->addr, |
|
|
283 | &missing_charset_list, &missing_charset_count, &def_string); |
|
|
284 | /* Free any returned missing charset list */ |
|
|
285 | if (missing_charset_count) |
|
|
286 | { |
|
|
287 | fprintf (stderr, "Missing charsets in String to FontSet conversion (%s)\n", missing_charset_list[0]); |
|
|
288 | XFreeStringList (missing_charset_list); |
|
|
289 | } |
|
|
290 | |
|
|
291 | if (!f) |
|
|
292 | { |
|
|
293 | f = XCreateFontSetWithGuess (dpy, "-*-*-*-R-*-*-*-120-*-*-*-*", |
|
|
294 | &missing_charset_list, &missing_charset_count, &def_string); |
|
|
295 | } |
|
|
296 | |
|
|
297 | *(XFontSet *) (toVal->addr) = f; |
|
|
298 | |
|
|
299 | return f ? True : False; |
|
|
300 | } |
99 | |
301 | |
100 | /* |
302 | /* |
101 | * Fetch the contents of cut buffer n from the root window. |
303 | * Fetch the contents of cut buffer n from the root window. |
102 | */ |
304 | */ |
103 | static char * |
305 | static char * |
… | |
… | |
112 | int count; |
314 | int count; |
113 | XTextProperty pt; |
315 | XTextProperty pt; |
114 | |
316 | |
115 | *nb = 0; |
317 | *nb = 0; |
116 | if (XGetWindowProperty (dpy, root, a, |
318 | if (XGetWindowProperty (dpy, root, a, |
117 | 0L, 10000000L, False, AnyPropertyType, |
319 | 0L, 10000000L, False, AnyPropertyType, |
118 | &pt.encoding, &pt.format, &pt.nitems, |
320 | &pt.encoding, &pt.format, &pt.nitems, |
119 | &after, &pt.value) != Success || !pt.nitems) |
321 | &after, &pt.value) != Success || !pt.nitems) |
120 | return strdup (""); |
322 | return strdup (""); |
121 | |
323 | |
122 | if (pt.nitems) |
324 | if (pt.nitems && pt.format == 8) |
123 | { |
325 | { |
124 | (force_mb ? XmbTextPropertyToTextList : Xutf8TextPropertyToTextList) |
326 | (force_mb ? XmbTextPropertyToTextList : Xutf8TextPropertyToTextList) |
125 | (dpy, &pt, &list, &count); |
327 | (dpy, &pt, &list, &count); |
126 | |
328 | |
127 | data = strdup (list[0]); |
329 | data = strdup (list[0]); |
128 | *nb = strlen (data); |
330 | *nb = strlen (data); |
129 | |
331 | |
130 | XFreeStringList (list); |
332 | XFreeStringList (list); |
… | |
… | |
150 | |
352 | |
151 | (force_mb ? XmbTextListToTextProperty : Xutf8TextListToTextProperty) |
353 | (force_mb ? XmbTextListToTextProperty : Xutf8TextListToTextProperty) |
152 | (dpy, &p, 1, XStdICCTextStyle, &pt); |
354 | (dpy, &p, 1, XStdICCTextStyle, &pt); |
153 | |
355 | |
154 | XChangeProperty (dpy, root, atom, pt.encoding, |
356 | XChangeProperty (dpy, root, atom, pt.encoding, |
155 | 8, PropModeReplace, pt.value, pt.nitems); |
357 | 8, PropModeReplace, pt.value, pt.nitems); |
156 | |
358 | |
157 | XFree (pt.value); |
359 | XFree (pt.value); |
158 | } |
360 | } |
159 | |
361 | |
160 | /* |
362 | /* |
… | |
… | |
168 | |
370 | |
169 | if (n >= natoms) |
371 | if (n >= natoms) |
170 | { |
372 | { |
171 | atom = (Atom *) XtRealloc ((char *) atom, (n + 1) * sizeof (Atom)); |
373 | atom = (Atom *) XtRealloc ((char *) atom, (n + 1) * sizeof (Atom)); |
172 | while (natoms < n + 1) |
374 | while (natoms < n + 1) |
173 | atom[natoms++] = 0; |
375 | atom[natoms++] = 0; |
174 | } |
376 | } |
175 | |
377 | |
176 | if (!atom[n]) |
378 | if (!atom[n]) |
177 | { |
379 | { |
178 | sprintf (tmp, "CUT_BUFFER%d", n); |
380 | sprintf (tmp, "CUT_BUFFER%d", n); |
… | |
… | |
219 | /* we rely on clipping... */ |
421 | /* we rely on clipping... */ |
220 | /*cols = ((int) cb->core.width + cb->font_width - 1) |
422 | /*cols = ((int) cb->core.width + cb->font_width - 1) |
221 | / cb->font_width; */ |
423 | / cb->font_width; */ |
222 | /*len = min(len, cols); */ |
424 | /*len = min(len, cols); */ |
223 | if (len > 0) |
425 | if (len > 0) |
224 | { |
426 | { |
225 | y -= cb->font_ascent; |
427 | y -= cb->font_ascent; |
226 | #if X_HAVE_UTF8_STRING |
428 | #if X_HAVE_UTF8_STRING |
227 | Xutf8DrawImageString |
429 | Xutf8DrawImageString |
228 | #else |
430 | #else |
229 | XmbDrawImageString |
431 | XmbDrawImageString |
230 | #endif |
432 | #endif |
231 | (dpy, cb->core.window, cb->fontset, gc, 0, y, str, len); |
433 | (dpy, cb->core.window, cb->fontset, gc, 0, y, str, len); |
232 | } |
434 | } |
233 | } |
435 | } |
234 | } |
436 | } |
235 | |
437 | |
236 | /* |
438 | /* |
237 | * ============================================================================ |
439 | * ============================================================================ |
… | |
… | |
239 | * the cb widget. Each cb widget displays a single cut buffer value |
441 | * the cb widget. Each cb widget displays a single cut buffer value |
240 | * in a window, and provides cut and paste access to that buffer. |
442 | * in a window, and provides cut and paste access to that buffer. |
241 | */ |
443 | */ |
242 | |
444 | |
243 | static void |
445 | static void |
244 | cb_initialize (req, wdg, args, nargs) /*ARGSUSED */ |
446 | cb_initialize (req, wdg, args, nargs) /*ARGSUSED */ |
245 | Widget req, wdg; |
447 | Widget req, wdg; |
246 | ArgList args; |
448 | ArgList args; |
247 | Cardinal *nargs; |
449 | Cardinal *nargs; |
248 | { |
450 | { |
249 | CbWidget cb = (CbWidget) wdg; |
451 | CbWidget cb = (CbWidget) wdg; |
… | |
… | |
287 | * Lines which extend beyond the subwindow's borders are clipped; no |
489 | * Lines which extend beyond the subwindow's borders are clipped; no |
288 | * wrap-around processing is done. |
490 | * wrap-around processing is done. |
289 | * Keep it simple. |
491 | * Keep it simple. |
290 | */ |
492 | */ |
291 | static void |
493 | static void |
292 | cb_redisplay (wdg, event, region) /*ARGSUSED */ |
494 | cb_redisplay (wdg, event, region) /*ARGSUSED */ |
293 | Widget wdg; |
495 | Widget wdg; |
294 | XEvent *event; |
496 | XEvent *event; |
295 | Region region; |
497 | Region region; |
296 | { |
498 | { |
297 | CbWidget cb = (CbWidget) wdg; |
499 | CbWidget cb = (CbWidget) wdg; |
… | |
… | |
301 | y = 0; |
503 | y = 0; |
302 | p = pp = base = fetch_buffer (cb->atom, &nbytes, 0); |
504 | p = pp = base = fetch_buffer (cb->atom, &nbytes, 0); |
303 | while (pp < base + nbytes) |
505 | while (pp < base + nbytes) |
304 | { |
506 | { |
305 | if (*pp == '\n') |
507 | if (*pp == '\n') |
306 | { |
508 | { |
307 | place_text (cb, p, pp - p, y); |
509 | place_text (cb, p, pp - p, y); |
308 | p = pp + 1; |
510 | p = pp + 1; |
309 | y += cb->font_height; |
511 | y += cb->font_height; |
310 | } |
512 | } |
311 | pp++; |
513 | pp++; |
312 | } |
514 | } |
313 | place_text (cb, p, pp - p, y); |
515 | place_text (cb, p, pp - p, y); |
314 | XFree (base); |
516 | XFree (base); |
315 | } |
517 | } |
… | |
… | |
340 | * which means it must know when another xcb widget has selection |
542 | * which means it must know when another xcb widget has selection |
341 | * ownership, which brings about the need for the 'seln' global variable. |
543 | * ownership, which brings about the need for the 'seln' global variable. |
342 | * This breaks all the rules for object oriented widgets. Disgusting, no? |
544 | * This breaks all the rules for object oriented widgets. Disgusting, no? |
343 | */ |
545 | */ |
344 | static void |
546 | static void |
345 | cb_cut (wdg, event, parms, nparms) /*ARGSUSED */ |
547 | cb_cut (wdg, event, parms, nparms) /*ARGSUSED */ |
346 | Widget wdg; |
548 | Widget wdg; |
347 | XEvent *event; |
549 | XEvent *event; |
348 | String *parms; |
550 | String *parms; |
349 | Cardinal *nparms; |
551 | Cardinal *nparms; |
350 | { |
552 | { |
… | |
… | |
368 | if (w == win) |
570 | if (w == win) |
369 | { |
571 | { |
370 | seln = win; |
572 | seln = win; |
371 | XClearArea (dpy, win, 0, 0, 0, 0, False); |
573 | XClearArea (dpy, win, 0, 0, 0, 0, False); |
372 | cb_redisplay (wdg, (XEvent *) 0, (Region) 0); |
574 | cb_redisplay (wdg, (XEvent *) 0, (Region) 0); |
373 | #ifdef XVIEW |
|
|
374 | XSetSelectionOwner (dpy, caret, win, event->xbutton.time); |
|
|
375 | XSetSelectionOwner (dpy, clipboard, win, event->xbutton.time); |
|
|
376 | #endif |
|
|
377 | } |
575 | } |
378 | } |
576 | } |
379 | |
577 | |
380 | static void |
578 | static void |
381 | cb_paste (wdg, event, parms, nparms) /*ARGSUSED */ |
579 | cb_paste (wdg, event, parms, nparms) /*ARGSUSED */ |
382 | Widget wdg; |
580 | Widget wdg; |
383 | XEvent *event; |
581 | XEvent *event; |
384 | String *parms; |
582 | String *parms; |
385 | Cardinal *nparms; |
583 | Cardinal *nparms; |
386 | { |
584 | { |
… | |
… | |
390 | int n; |
588 | int n; |
391 | |
589 | |
392 | w = XGetSelectionOwner (dpy, XA_PRIMARY); |
590 | w = XGetSelectionOwner (dpy, XA_PRIMARY); |
393 | if (w == None) |
591 | if (w == None) |
394 | { |
592 | { |
395 | ptr = fetch_buffer (atom[0], &n, 0); /* copy from cb0 */ |
593 | ptr = fetch_buffer (atom[0], &n, 0); /* copy from cb0 */ |
396 | store_buffer (ptr, n, cb->atom, 0); |
594 | store_buffer (ptr, n, cb->atom, 0); |
397 | XFree (ptr); |
595 | XFree (ptr); |
398 | } |
596 | } |
399 | else if (w != cb->core.window) |
597 | else if (w != cb->core.window) |
400 | XConvertSelection (dpy, XA_PRIMARY, xa_utf8_string, |
598 | XConvertSelection (dpy, XA_PRIMARY, xa_utf8_string, |
401 | convert_to = cb->atom, XtWindow(wdg), event->xbutton.time); |
599 | convert_to = cb->atom, XtWindow (wdg), event->xbutton.time); |
402 | } |
600 | } |
403 | |
601 | |
404 | static void |
602 | static void |
405 | cb_clear (wdg, event, parms, nparms) /*ARGSUSED */ |
603 | cb_clear (wdg, event, parms, nparms) /*ARGSUSED */ |
406 | Widget wdg; |
604 | Widget wdg; |
407 | XEvent *event; |
605 | XEvent *event; |
408 | String *parms; |
606 | String *parms; |
409 | Cardinal *nparms; |
607 | Cardinal *nparms; |
410 | { |
608 | { |
… | |
… | |
418 | XSetSelectionOwner (dpy, XA_PRIMARY, None, event->xbutton.time); |
616 | XSetSelectionOwner (dpy, XA_PRIMARY, None, event->xbutton.time); |
419 | } |
617 | } |
420 | } |
618 | } |
421 | |
619 | |
422 | static void |
620 | static void |
423 | cb_rotate (wdg, event, parms, nparms) /*ARGSUSED */ |
621 | cb_rotate (wdg, event, parms, nparms) /*ARGSUSED */ |
424 | Widget wdg; |
622 | Widget wdg; |
425 | XEvent *event; |
623 | XEvent *event; |
426 | String *parms; |
624 | String *parms; |
427 | Cardinal *nparms; |
625 | Cardinal *nparms; |
428 | { |
626 | { |
… | |
… | |
434 | if (n != 0) |
632 | if (n != 0) |
435 | XRotateWindowProperties (dpy, root, atom, nbuffs, n); |
633 | XRotateWindowProperties (dpy, root, atom, nbuffs, n); |
436 | } |
634 | } |
437 | |
635 | |
438 | static void |
636 | static void |
439 | cb_quit (wdg, event, parms, nparms) /*ARGSUSED */ |
637 | cb_quit (wdg, event, parms, nparms) /*ARGSUSED */ |
440 | Widget wdg; |
638 | Widget wdg; |
441 | XEvent *event; |
639 | XEvent *event; |
442 | String *parms; |
640 | String *parms; |
443 | Cardinal *nparms; |
641 | Cardinal *nparms; |
444 | { |
642 | { |
… | |
… | |
447 | |
645 | |
448 | /* |
646 | /* |
449 | * Clear and redraw the widget's window. |
647 | * Clear and redraw the widget's window. |
450 | */ |
648 | */ |
451 | static void |
649 | static void |
452 | cb_refresh (wdg, event, parms, nparms) /*ARGSUSED */ |
650 | cb_refresh (wdg, event, parms, nparms) /*ARGSUSED */ |
453 | Widget wdg; |
651 | Widget wdg; |
454 | XEvent *event; |
652 | XEvent *event; |
455 | String *parms; |
653 | String *parms; |
456 | Cardinal *nparms; |
654 | Cardinal *nparms; |
457 | { |
655 | { |
… | |
… | |
465 | * (No conversion facilities are provided by this program). |
663 | * (No conversion facilities are provided by this program). |
466 | * The selection request is met by copying the current contents |
664 | * The selection request is met by copying the current contents |
467 | * of the cut buffer to the target window+atom. |
665 | * of the cut buffer to the target window+atom. |
468 | */ |
666 | */ |
469 | static void |
667 | static void |
470 | cb_selreq (wdg, event, parms, nparms) /*ARGSUSED */ |
668 | cb_selreq (wdg, event, parms, nparms) /*ARGSUSED */ |
471 | Widget wdg; |
669 | Widget wdg; |
472 | XEvent *event; |
670 | XEvent *event; |
473 | String *parms; |
671 | String *parms; |
474 | Cardinal *nparms; |
672 | Cardinal *nparms; |
475 | { |
673 | { |
… | |
… | |
477 | char *ptr; |
675 | char *ptr; |
478 | XSelectionEvent notify; |
676 | XSelectionEvent notify; |
479 | XSelectionRequestEvent *rq; |
677 | XSelectionRequestEvent *rq; |
480 | CbWidget cb = (CbWidget) wdg; |
678 | CbWidget cb = (CbWidget) wdg; |
481 | Window win = cb->core.window; |
679 | Window win = cb->core.window; |
482 | |
|
|
483 | #ifdef XVIEW |
|
|
484 | unsigned long data; |
|
|
485 | #endif |
|
|
486 | |
680 | |
487 | rq = (XSelectionRequestEvent *) event; |
681 | rq = (XSelectionRequestEvent *) event; |
488 | |
682 | |
489 | notify.type = SelectionNotify; |
683 | notify.type = SelectionNotify; |
490 | notify.display = rq->display; |
684 | notify.display = rq->display; |
… | |
… | |
492 | notify.selection = rq->selection; |
686 | notify.selection = rq->selection; |
493 | notify.target = rq->target; |
687 | notify.target = rq->target; |
494 | notify.property = None; |
688 | notify.property = None; |
495 | notify.time = rq->time; |
689 | notify.time = rq->time; |
496 | |
690 | |
497 | #ifdef XVIEW |
691 | if (win == seln) |
498 | if (rq->selection == XA_PRIMARY) |
|
|
499 | { |
692 | { |
|
|
693 | XICCEncodingStyle style; |
|
|
694 | Atom target = None; |
|
|
695 | |
500 | if (rq->target == yield) |
696 | if (rq->target == XA_STRING) |
501 | { |
697 | { |
502 | /* tell 'em we'll give it up */ |
698 | target = XA_STRING; |
503 | data = 1; |
699 | style = XStringStyle; |
504 | XChangeProperty (dpy, rq->requestor, rq->property, |
700 | } |
505 | rq->target, 32, PropModeReplace, |
701 | else if (rq->target == xa_text) |
506 | (unsigned char *) &data, 1); |
702 | { |
507 | notify.property = rq->property; |
703 | target = xa_compound_text; |
508 | } |
704 | style = XStdICCTextStyle; |
509 | else |
705 | } |
510 | { |
706 | else if (rq->target == xa_compound_text) |
|
|
707 | { |
|
|
708 | target = xa_compound_text; |
|
|
709 | style = XCompoundTextStyle; |
|
|
710 | } |
|
|
711 | #ifdef X_HAVE_UTF8_STRING |
|
|
712 | else if (rq->target == xa_utf8_string) |
|
|
713 | { |
|
|
714 | target = xa_utf8_string; |
|
|
715 | style = XUTF8StringStyle; |
|
|
716 | } |
511 | #endif |
717 | #endif |
512 | |
718 | |
513 | if (win == seln) |
|
|
514 | { |
|
|
515 | XICCEncodingStyle style; |
|
|
516 | Atom target = None; |
|
|
517 | |
|
|
518 | if (rq->target == XA_STRING) |
|
|
519 | { |
|
|
520 | target = XA_STRING; |
|
|
521 | style = XStringStyle; |
|
|
522 | } |
|
|
523 | else if (rq->target == xa_text) |
|
|
524 | { |
|
|
525 | target = xa_compound_text; |
|
|
526 | style = XStdICCTextStyle; |
|
|
527 | } |
|
|
528 | else if (rq->target == xa_compound_text) |
|
|
529 | { |
|
|
530 | target = xa_compound_text; |
|
|
531 | style = XCompoundTextStyle; |
|
|
532 | } |
|
|
533 | #ifdef X_HAVE_UTF8_STRING |
|
|
534 | else if (rq->target == xa_utf8_string) |
|
|
535 | { |
|
|
536 | target = xa_utf8_string; |
|
|
537 | style = XUTF8StringStyle; |
|
|
538 | } |
|
|
539 | #endif |
|
|
540 | |
|
|
541 | if (target != None) |
719 | if (target != None) |
542 | { |
720 | { |
543 | XTextProperty pt; |
721 | XTextProperty pt; |
544 | char *fl; |
722 | char *fl; |
545 | |
723 | |
546 | fl = fetch_buffer (cb->atom, &nbytes, 0); |
724 | fl = fetch_buffer (cb->atom, &nbytes, 0); |
547 | Xutf8TextListToTextProperty (dpy, &fl, 1, style, &pt); |
725 | Xutf8TextListToTextProperty (dpy, &fl, 1, style, &pt); |
548 | XFree (fl); |
726 | XFree (fl); |
549 | |
727 | |
550 | XChangeProperty (dpy, rq->requestor, rq->property, |
|
|
551 | pt.encoding, 8, PropModeReplace, |
|
|
552 | pt.value, pt.nitems); |
|
|
553 | |
|
|
554 | notify.property = rq->property; |
|
|
555 | XFree (pt.value); |
|
|
556 | } |
|
|
557 | } |
|
|
558 | |
|
|
559 | #ifdef XVIEW |
|
|
560 | } |
|
|
561 | } |
|
|
562 | else if (rq->selection == caret) |
|
|
563 | { |
|
|
564 | if (rq->target == yield) |
|
|
565 | { |
|
|
566 | /* |
|
|
567 | * Give up the caret (which meant that we |
|
|
568 | * own the clipboard) |
|
|
569 | */ |
|
|
570 | XSetSelectionOwner (dpy, caret, None, |
|
|
571 | event->xselectionrequest.time); |
|
|
572 | data = 1; |
|
|
573 | XChangeProperty (dpy, rq->requestor, rq->property, |
728 | XChangeProperty (dpy, rq->requestor, rq->property, |
574 | rq->target, 32, PropModeReplace, |
729 | pt.encoding, 8, PropModeReplace, |
575 | (unsigned char *) &data, 1); |
730 | pt.value, pt.nitems); |
|
|
731 | |
576 | notify.property = rq->property; |
732 | notify.property = rq->property; |
577 | } |
733 | XFree (pt.value); |
578 | } |
734 | } |
579 | else if (rq->selection == clipboard && win == seln) |
|
|
580 | { |
735 | } |
581 | ptr = fetch_buffer (cb->atom, &nbytes, 0); |
|
|
582 | if (rq->target == lengthc || rq->target == length) |
|
|
583 | { |
|
|
584 | /* |
|
|
585 | * Send the length of the selection. |
|
|
586 | */ |
|
|
587 | data = nbytes; |
|
|
588 | XChangeProperty (dpy, rq->requestor, rq->property, |
|
|
589 | rq->target, 32, PropModeReplace, |
|
|
590 | (unsigned char *) &data, 1); |
|
|
591 | notify.property = rq->property; |
|
|
592 | } |
|
|
593 | else if (rq->target == XA_STRING || |
|
|
594 | rq->target == xa_text || rq->target == xa_compound_text) |
|
|
595 | { |
|
|
596 | /* |
|
|
597 | * Send the selection itself. |
|
|
598 | * All of our selections will be XA_STRING, |
|
|
599 | * but if they ask for COMPOUND_TEXT, it's ok |
|
|
600 | * to say that that's what we've got... |
|
|
601 | */ |
|
|
602 | XChangeProperty (dpy, rq->requestor, rq->property, |
|
|
603 | (rq->target == xa_compound_text ? xa_compound_text : XA_STRING), 8, |
|
|
604 | PropModeReplace, ptr, nbytes); |
|
|
605 | notify.property = rq->property; |
|
|
606 | } |
|
|
607 | XFree (ptr); |
|
|
608 | } |
|
|
609 | #endif |
|
|
610 | |
736 | |
611 | XSendEvent (dpy, rq->requestor, False, 0, (XEvent *) & notify); |
737 | XSendEvent (dpy, rq->requestor, False, 0, (XEvent *) & notify); |
612 | } |
738 | } |
613 | |
739 | |
614 | /* |
740 | /* |
615 | * Boo hiss, someone has taken the PRIMARY selection ownership |
741 | * Boo hiss, someone has taken the PRIMARY selection ownership |
616 | * away from this widget. The current window contents must |
742 | * away from this widget. The current window contents must |
617 | * be redrawn without highlighting. |
743 | * be redrawn without highlighting. |
618 | */ |
744 | */ |
619 | static void |
745 | static void |
620 | cb_selclear (wdg, event, parms, nparms) /*ARGSUSED */ |
746 | cb_selclear (wdg, event, parms, nparms) /*ARGSUSED */ |
621 | Widget wdg; |
747 | Widget wdg; |
622 | XEvent *event; |
748 | XEvent *event; |
623 | String *parms; |
749 | String *parms; |
624 | Cardinal *nparms; |
750 | Cardinal *nparms; |
625 | { |
751 | { |
626 | CbWidget cb = (CbWidget) wdg; |
752 | CbWidget cb = (CbWidget) wdg; |
627 | |
753 | |
628 | #ifdef XVIEW |
|
|
629 | Window w; |
|
|
630 | Time t; |
|
|
631 | #endif |
|
|
632 | |
|
|
633 | if (event->xproperty.atom != XA_PRIMARY) |
754 | if (event->xproperty.atom != XA_PRIMARY) |
634 | return; |
755 | return; |
635 | |
756 | |
636 | seln = 0; |
757 | seln = 0; |
637 | XClearArea (dpy, cb->core.window, 0, 0, 0, 0, False); |
758 | XClearArea (dpy, cb->core.window, 0, 0, 0, 0, False); |
638 | cb_redisplay (wdg, (XEvent *) 0, (Region) 0); |
759 | cb_redisplay (wdg, (XEvent *) 0, (Region) 0); |
639 | #ifdef XVIEW |
|
|
640 | /* |
|
|
641 | * Since we don't have ownership of PRIMARY anymore, |
|
|
642 | * we'd better get rid of CLIPBOARD and _SUN_SELN_CARET, |
|
|
643 | * if they're still ours. |
|
|
644 | */ |
|
|
645 | t = event->xselectionclear.time; |
|
|
646 | w = XGetSelectionOwner (dpy, caret); |
|
|
647 | if (w == cb->core.window) |
|
|
648 | XSetSelectionOwner (dpy, caret, None, t); |
|
|
649 | w = XGetSelectionOwner (dpy, clipboard); |
|
|
650 | if (w == cb->core.window) |
|
|
651 | XSetSelectionOwner (dpy, clipboard, None, t); |
|
|
652 | #endif |
|
|
653 | } |
760 | } |
654 | |
761 | |
655 | static XtResource resources[] = |
762 | static XtResource resources[] = |
656 | { |
763 | { |
657 | #define offset(field) XtOffset(CbWidget, field) |
764 | #define offset(field) XtOffset(CbWidget, field) |
658 | /* {name, class, type, size, offset, default_type, default_addr}, */ |
765 | /* {name, class, type, size, offset, default_type, default_addr}, */ |
659 | {XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel), |
766 | {XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel), |
660 | offset (fgnd), XtRString, (XtPointer) "XtDefaultForeground"}, |
767 | offset (fgnd), XtRString, (XtPointer) "XtDefaultForeground"}, |
661 | {XtNfontSet, XtCFontSet, XtRFontSet, sizeof (XFontSet), |
768 | {XtNfontSet, XtCFontSet, XtRFontSet, sizeof (XFontSet), |
662 | offset (fontset), XtRString, (XtPointer) "XtDefaultFontSet"}, |
769 | offset (fontset), XtRString, (XtPointer) "XtDefaultFontSet"}, |
663 | {XtNatom, XtCAtom, XtRAtom, sizeof (Atom), /* internal use */ |
770 | {XtNatom, XtCAtom, XtRAtom, sizeof (Atom), /* internal use */ |
664 | offset (atom), XtRImmediate, (XtPointer) 0}, |
771 | offset (atom), XtRImmediate, (XtPointer) 0}, |
665 | #undef offset |
772 | #undef offset |
666 | }; |
773 | }; |
667 | |
774 | |
668 | static XtActionsRec actions[] = |
775 | static XtActionsRec actions[] = |
… | |
… | |
676 | {"selreq", cb_selreq}, |
783 | {"selreq", cb_selreq}, |
677 | {"selclear", cb_selclear}, |
784 | {"selclear", cb_selclear}, |
678 | }; |
785 | }; |
679 | |
786 | |
680 | static char cb_transl[] = "\ |
787 | static char cb_transl[] = "\ |
681 | <Btn1Down>: cut() \n\ |
788 | <Btn1Down>: cut() \n\ |
682 | Shift <Btn2Down>: clear() \n\ |
789 | Shift <Btn2Down>: clear() \n\ |
683 | <Btn2Down>: paste() \n\ |
790 | <Btn2Down>: paste() \n\ |
684 | Shift <Btn3Down>: rotate(-1) \n\ |
791 | Shift <Btn3Down>: rotate(-1) \n\ |
685 | <Btn3Down>: rotate(1) \n\ |
792 | <Btn3Down>: rotate(1) \n\ |
686 | <Key>Left: rotate(-1) \n\ |
793 | <Key>Left: rotate(-1) \n\ |
687 | <Key>Right: rotate(1) \n\ |
794 | <Key>Right: rotate(1) \n\ |
688 | <Key>Up: rotate(-1) \n\ |
795 | <Key>Up: rotate(-1) \n\ |
689 | <Key>Down: rotate(1) \n\ |
796 | <Key>Down: rotate(1) \n\ |
690 | <Key>q: quit() \n\ |
797 | <Key>q: quit() \n\ |
691 | <SelReq>: selreq() \n\ |
798 | <SelReq>: selreq() \n\ |
692 | <SelClr>: selclear() \n\ |
799 | <SelClr>: selclear() \n\ |
693 | "; |
800 | "; |
694 | |
801 | |
695 | CbClassRec cbClassRec = |
802 | CbClassRec cbClassRec = |
696 | { |
803 | { |
697 | { |
804 | { |
698 | (WidgetClass) & widgetClassRec, /* superclass */ |
805 | (WidgetClass) & widgetClassRec, /* superclass */ |
699 | "Buffer", /* class_name */ |
806 | "Buffer", /* class_name */ |
700 | sizeof (CbRec), /* widget_size */ |
807 | sizeof (CbRec), /* widget_size */ |
701 | NULL, /* class_initialize */ |
808 | NULL, /* class_initialize */ |
702 | NULL, /* class_part_initialize */ |
809 | NULL, /* class_part_initialize */ |
703 | FALSE, /* class_inited */ |
810 | FALSE, /* class_inited */ |
704 | cb_initialize, /* initialize */ |
811 | cb_initialize, /* initialize */ |
705 | NULL, /* initialize_hook */ |
812 | NULL, /* initialize_hook */ |
706 | cb_realize, /* realize */ |
813 | cb_realize, /* realize */ |
707 | actions, /* actions */ |
814 | actions, /* actions */ |
708 | XtNumber (actions), /* num_actions */ |
815 | XtNumber (actions), /* num_actions */ |
709 | resources, /* resources */ |
816 | resources, /* resources */ |
710 | XtNumber (resources), /* num_resources */ |
817 | XtNumber (resources), /* num_resources */ |
711 | NULLQUARK, /* xrm_class */ |
818 | NULLQUARK, /* xrm_class */ |
712 | TRUE, /* compress_motion */ |
819 | TRUE, /* compress_motion */ |
713 | TRUE, /* compress_exposure */ |
820 | TRUE, /* compress_exposure */ |
714 | TRUE, /* compress_enterleave */ |
821 | TRUE, /* compress_enterleave */ |
715 | FALSE, /* visible_interest */ |
822 | FALSE, /* visible_interest */ |
716 | cb_destroy, /* destroy */ |
823 | cb_destroy, /* destroy */ |
717 | NULL, /* resize */ |
824 | NULL, /* resize */ |
718 | cb_redisplay, /* expose */ |
825 | cb_redisplay, /* expose */ |
719 | NULL, /* set_values */ |
826 | NULL, /* set_values */ |
720 | NULL, /* set_values_hook */ |
827 | NULL, /* set_values_hook */ |
721 | XtInheritSetValuesAlmost, /* set_values_almost */ |
828 | XtInheritSetValuesAlmost, /* set_values_almost */ |
722 | NULL, /* get_values_hook */ |
829 | NULL, /* get_values_hook */ |
723 | NULL, /* accept_focus */ |
830 | NULL, /* accept_focus */ |
724 | XtVersion, /* version */ |
831 | XtVersion, /* version */ |
725 | NULL, /* callback_private */ |
832 | NULL, /* callback_private */ |
726 | cb_transl, /* tm_table */ |
833 | cb_transl, /* tm_table */ |
727 | XtInheritQueryGeometry, /* query_geometry */ |
834 | XtInheritQueryGeometry, /* query_geometry */ |
728 | XtInheritDisplayAccelerator, /* display_accelerator */ |
835 | XtInheritDisplayAccelerator, /* display_accelerator */ |
729 | NULL /* extension */ |
836 | NULL /* extension */ |
730 | }, |
837 | }, |
731 | }; |
838 | }; |
732 | |
839 | |
733 | WidgetClass cbWidgetClass = (WidgetClass) & cbClassRec; |
840 | WidgetClass cbWidgetClass = (WidgetClass) & cbClassRec; |
734 | |
841 | |
… | |
… | |
741 | |
848 | |
742 | static void |
849 | static void |
743 | usage () |
850 | usage () |
744 | { |
851 | { |
745 | fprintf (stderr, |
852 | fprintf (stderr, |
746 | "Usage: %s [Xt option] [-l layout] [-n count] [-p|-s|-S list] [-r count]\n", |
853 | "Usage: %s [Xt option] [-l layout] [-n count] [-p|-s|-S list] [-r count]\n", |
747 | PGM_NAME); |
854 | PGM_NAME); |
748 | exit (1); |
855 | exit (1); |
749 | } |
856 | } |
750 | |
857 | |
751 | /* |
858 | /* |
752 | * Gracefully exit after an XIO error, or after a "delete window" |
859 | * Gracefully exit after an XIO error, or after a "delete window" |
753 | * directive from the window manager. |
860 | * directive from the window manager. |
754 | * xioerror() avoids messy error messages sometimes seen from xterm |
861 | * xioerror() avoids messy error messages sometimes seen from xterm |
755 | * or in the xdm-errors file when forcibly destroying the client program. |
862 | * or in the xdm-errors file when forcibly destroying the client program. |
756 | */ |
863 | */ |
757 | static int |
864 | static int |
758 | xioerror (d) /*ARGSUSED */ |
865 | xioerror (d) /*ARGSUSED */ |
759 | Display *d; |
866 | Display *d; |
760 | { |
867 | { |
761 | exit (1); /*NOTREACHED */ |
868 | exit (1); /*NOTREACHED */ |
762 | } |
869 | } |
763 | |
870 | |
764 | static void |
871 | static void |
765 | wmdel (wdg, ptr, ep, cont) /*ARGSUSED */ |
872 | wmdel (wdg, ptr, ep, cont) /*ARGSUSED */ |
766 | Widget wdg; |
873 | Widget wdg; |
767 | XtPointer ptr; |
874 | XtPointer ptr; |
768 | XEvent *ep; |
875 | XEvent *ep; |
769 | Boolean *cont; |
876 | Boolean *cont; |
770 | { |
877 | { |
… | |
… | |
787 | if (a) |
894 | if (a) |
788 | { |
895 | { |
789 | ptr = fetch_buffer (a, &nb, !use_utf8); |
896 | ptr = fetch_buffer (a, &nb, !use_utf8); |
790 | |
897 | |
791 | if (write (1, ptr, nb) != nb) |
898 | if (write (1, ptr, nb) != nb) |
792 | { |
899 | { |
793 | fprintf (stderr, "Write error\n"); |
900 | fprintf (stderr, "Write error\n"); |
794 | exit (1); |
901 | exit (1); |
795 | } |
902 | } |
796 | |
903 | |
797 | XFree (ptr); |
904 | XFree (ptr); |
798 | } |
905 | } |
799 | } |
906 | } |
800 | |
907 | |
… | |
… | |
840 | |
947 | |
841 | atm = get_atom (n, False); |
948 | atm = get_atom (n, False); |
842 | if (XGetSelectionOwner (dpy, XA_PRIMARY) == None) |
949 | if (XGetSelectionOwner (dpy, XA_PRIMARY) == None) |
843 | { |
950 | { |
844 | if (n != 0) |
951 | if (n != 0) |
845 | { |
952 | { |
846 | data = fetch_buffer (atom[0], &nbytes, 0); |
953 | data = fetch_buffer (atom[0], &nbytes, 0); |
847 | store_buffer (data, nbytes, atm, 0); |
954 | store_buffer (data, nbytes, atm, 0); |
848 | XFree (data); |
955 | XFree (data); |
849 | } |
956 | } |
850 | return; |
957 | return; |
851 | } |
958 | } |
852 | |
959 | |
853 | XSelectInput (dpy, root, PropertyChangeMask); |
960 | XSelectInput (dpy, root, PropertyChangeMask); |
854 | XConvertSelection (dpy, XA_PRIMARY, xa_utf8_string, atm, root, CurrentTime); |
961 | XConvertSelection (dpy, XA_PRIMARY, xa_utf8_string, atm, root, CurrentTime); |
… | |
… | |
856 | |
963 | |
857 | for (;;) |
964 | for (;;) |
858 | { |
965 | { |
859 | XtAppNextEvent (app, &event); |
966 | XtAppNextEvent (app, &event); |
860 | if (event.type == PropertyNotify |
967 | if (event.type == PropertyNotify |
861 | && event.xproperty.window == root |
968 | && event.xproperty.window == root |
862 | && event.xproperty.atom == atm |
969 | && event.xproperty.atom == atm |
863 | && event.xproperty.state == PropertyNewValue) |
970 | && event.xproperty.state == PropertyNewValue) |
864 | { |
971 | { |
865 | return; |
972 | return; |
866 | } |
973 | } |
867 | |
974 | |
868 | XtDispatchEvent (&event); /* This cannot happen. !!?? */ |
975 | XtDispatchEvent (&event); /* This cannot happen. !!?? */ |
869 | } |
976 | } |
870 | } |
977 | } |
871 | |
978 | |
872 | /* |
979 | /* |
873 | * Process an ASCII list of cut buffer numbers. |
980 | * Process an ASCII list of cut buffer numbers. |
… | |
… | |
887 | int m, n, x; |
994 | int m, n, x; |
888 | |
995 | |
889 | while (*list) |
996 | while (*list) |
890 | { |
997 | { |
891 | if (!isdigit (*list)) |
998 | if (!isdigit (*list)) |
892 | usage (); |
999 | usage (); |
893 | for (m = 0; isdigit (*list); list++) |
1000 | for (m = 0; isdigit (*list); list++) |
894 | m = m * 10 + *list - '0'; |
1001 | m = m * 10 + *list - '0'; |
895 | |
1002 | |
896 | (*fn) (m, data, nbytes); |
1003 | (*fn) (m, data, nbytes); |
897 | |
1004 | |
898 | if (*list == '-') |
1005 | if (*list == '-') |
899 | { |
1006 | { |
900 | list++; |
1007 | list++; |
901 | if (!isdigit (*list)) |
1008 | if (!isdigit (*list)) |
902 | usage (); |
1009 | usage (); |
903 | for (n = 0; isdigit (*list); list++) |
1010 | for (n = 0; isdigit (*list); list++) |
904 | n = n * 10 + *list - '0'; |
1011 | n = n * 10 + *list - '0'; |
905 | |
1012 | |
906 | x = (m > n) ? -1 : 1; |
1013 | x = (m > n) ? -1 : 1; |
907 | while (m != n) |
1014 | while (m != n) |
908 | { |
1015 | { |
909 | m += x; |
1016 | m += x; |
910 | (*fn) (m, data, nbytes); |
1017 | (*fn) (m, data, nbytes); |
911 | } |
1018 | } |
912 | } |
1019 | } |
913 | |
1020 | |
914 | if (*list == ',') |
1021 | if (*list == ',') |
915 | list++; |
1022 | list++; |
916 | else if (*list) |
1023 | else if (*list) |
917 | usage (); |
1024 | usage (); |
918 | } |
1025 | } |
919 | } |
1026 | } |
920 | |
1027 | |
921 | /* |
1028 | /* |
922 | * Perform a task mode command, i.e. |
1029 | * Perform a task mode command, i.e. |
… | |
… | |
934 | ptr = (char *) 0; |
1041 | ptr = (char *) 0; |
935 | n = nb = 0; |
1042 | n = nb = 0; |
936 | |
1043 | |
937 | switch (cmd) |
1044 | switch (cmd) |
938 | { |
1045 | { |
939 | case 'p': /* print one or more buffers */ |
1046 | case 'p': /* print one or more buffers */ |
940 | dolist (arg, doprint, (char *) 0, 0); |
1047 | dolist (arg, doprint, (char *) 0, 0); |
941 | break; |
1048 | break; |
942 | case 'r': /* rotate the buffer contents */ |
1049 | case 'r': /* rotate the buffer contents */ |
943 | n = atoi (arg); |
1050 | n = atoi (arg); |
944 | |
1051 | |
945 | if (n == 0) |
1052 | if (n == 0) |
946 | break; |
1053 | break; |
947 | |
1054 | |
948 | initialize_properties (); |
1055 | initialize_properties (); |
949 | |
1056 | |
950 | XRotateWindowProperties (dpy, root, atom, nbuffs, n); |
1057 | XRotateWindowProperties (dpy, root, atom, nbuffs, n); |
951 | break; |
1058 | break; |
952 | case 's': /* store data in one or more buffers */ |
1059 | case 's': /* store data in one or more buffers */ |
953 | do |
1060 | do |
954 | { |
1061 | { |
955 | ptr = XtRealloc (ptr, nb + BUFINC); |
1062 | ptr = XtRealloc (ptr, nb + BUFINC); |
956 | i = BUFINC; |
1063 | i = BUFINC; |
957 | do |
1064 | do |
958 | { |
1065 | { |
959 | n = read (0, ptr + nb, i); |
1066 | n = read (0, ptr + nb, i); |
960 | nb += n; |
1067 | nb += n; |
961 | i -= n; |
1068 | i -= n; |
962 | } |
1069 | } |
963 | while (n > 0 && i > 0); |
1070 | while (n > 0 && i > 0); |
964 | } |
1071 | } |
965 | while (n > 0); |
1072 | while (n > 0); |
966 | |
1073 | |
967 | if (n == -1) |
1074 | if (n == -1) |
968 | { |
1075 | { |
969 | fprintf (stderr, "Read error\n"); |
1076 | fprintf (stderr, "Read error\n"); |
970 | exit (1); |
1077 | exit (1); |
971 | } |
1078 | } |
972 | |
1079 | |
973 | dolist (arg, doset, ptr, nb); |
1080 | dolist (arg, doset, ptr, nb); |
974 | XtFree (ptr); |
1081 | XtFree (ptr); |
975 | break; |
1082 | break; |
976 | case 'S': |
1083 | case 'S': |
… | |
… | |
988 | |
1095 | |
989 | static ares_t ares; |
1096 | static ares_t ares; |
990 | |
1097 | |
991 | static XtResource res[] = |
1098 | static XtResource res[] = |
992 | { |
1099 | { |
993 | #define offset(field) XtOffset(ares_ptr, field) |
1100 | #define offset(field) XtOffset(ares_ptr, field) |
994 | {XtNbufferCount, XtCBufferCount, XtRInt, sizeof (int), |
1101 | {XtNbufferCount, XtCBufferCount, XtRInt, sizeof (int), |
995 | offset (nbuffs), XtRImmediate, (XtPointer) 8}, |
1102 | offset (nbuffs), XtRImmediate, (XtPointer) 8}, |
996 | {XtNlayout, XtCLayout, XtRString, sizeof (char *), |
1103 | {XtNlayout, XtCLayout, XtRString, sizeof (char *), |
997 | offset (layout), XtRImmediate, "horiz"}, |
1104 | offset (layout), XtRImmediate, "horiz"}, |
998 | #undef offset |
1105 | #undef offset |
999 | }; |
1106 | }; |
1000 | |
1107 | |
1001 | static char *def[] = |
1108 | static char *def[] = |
1002 | { /* default resource values */ |
1109 | { /* default resource values */ |
1003 | ".bufferCount: 8", |
1110 | ".bufferCount: 8", |
1004 | ".layout: horizontal", |
1111 | ".layout: horizontal", |
1005 | "*fontSet: XtDefaultFontSet", |
1112 | "*fontSet: XtDefaultFontSet", |
1006 | "*Buffer.width: 60", |
1113 | "*Buffer.width: 60", |
1007 | "*Buffer.height: 60", |
1114 | "*Buffer.height: 60", |
1008 | 0, |
1115 | 0, |
1009 | }; |
1116 | }; |
1010 | |
1117 | |
1011 | static XrmOptionDescRec opt[] = |
1118 | static XrmOptionDescRec opt[] = |
1012 | { |
1119 | { |
… | |
… | |
1050 | XtSetLanguageProc (0, 0, 0); |
1157 | XtSetLanguageProc (0, 0, 0); |
1051 | top = XtAppInitialize (&app, PGM_CLASS, opt, 2, &argc, argv, def, 0, 0); |
1158 | top = XtAppInitialize (&app, PGM_CLASS, opt, 2, &argc, argv, def, 0, 0); |
1052 | dpy = XtDisplay (top); |
1159 | dpy = XtDisplay (top); |
1053 | root = RootWindow (dpy, DefaultScreen (dpy)); |
1160 | root = RootWindow (dpy, DefaultScreen (dpy)); |
1054 | |
1161 | |
|
|
1162 | XtSetTypeConverter(XtRString, /* source type */ |
|
|
1163 | XtRFontSet, /* target type */ |
|
|
1164 | CvtStringToFontSet, /* converter routine */ |
|
|
1165 | (XtConvertArgList) NULL, |
|
|
1166 | /* args for converter routine */ |
|
|
1167 | 0, /*# args for converter routine */ |
|
|
1168 | XtCacheAll, /* caching instructions */ |
|
|
1169 | NULL); /* destructor function */ |
|
|
1170 | |
1055 | XtGetApplicationResources (top, &ares, res, XtNumber (res), 0, 0); |
1171 | XtGetApplicationResources (top, &ares, res, XtNumber (res), 0, 0); |
1056 | nbuffs = max (ares.nbuffs, 1); |
1172 | nbuffs = max (ares.nbuffs, 1); |
1057 | |
1173 | |
|
|
1174 | xa_compound_text = XInternAtom (dpy, "COMPOUND_TEXT", False); |
|
|
1175 | xa_utf8_string = XInternAtom (dpy, "UTF8_STRING", False); |
|
|
1176 | xa_text = XInternAtom (dpy, "TEXT", False); |
|
|
1177 | |
|
|
1178 | if (!xa_utf8_string) |
|
|
1179 | xa_utf8_string = xa_compound_text; |
|
|
1180 | |
1058 | /* search for the -u and -v switches first */ |
1181 | /* search for the -u and -v switches first */ |
1059 | for (p = argv + 1; p < argv + argc; p++) |
1182 | for (p = argv + 1; p < argv + argc; p++) |
1060 | { |
1183 | { |
1061 | if (eq (*p, "-u")) |
1184 | if (eq (*p, "-u")) |
1062 | use_utf8 = 1; |
1185 | use_utf8 = 1; |
1063 | else if (eq (*p, "-V")) |
1186 | else if (eq (*p, "-V")) |
1064 | { |
1187 | { |
1065 | printf ("xcb version %s\n", version); |
1188 | printf ("xcb version %s\n", version); |
1066 | exit (0); |
1189 | exit (0); |
1067 | } |
1190 | } |
1068 | } |
1191 | } |
1069 | |
1192 | |
1070 | /* |
1193 | /* |
1071 | * If the command line contains one of the task mode |
1194 | * If the command line contains one of the task mode |
1072 | * switches (print, set, rotate), it is processed here. |
1195 | * switches (print, set, rotate), it is processed here. |
… | |
… | |
1074 | * one is processed. |
1197 | * one is processed. |
1075 | */ |
1198 | */ |
1076 | for (p = argv + 1; p < argv + argc; p++) |
1199 | for (p = argv + 1; p < argv + argc; p++) |
1077 | { |
1200 | { |
1078 | if (eq (*p, "-p") || eq (*p, "-r") || eq (*p, "-s") || eq (*p, "-S")) |
1201 | if (eq (*p, "-p") || eq (*p, "-r") || eq (*p, "-s") || eq (*p, "-S")) |
1079 | { |
1202 | { |
1080 | if (p == argv + argc - 1) |
1203 | if (p == argv + argc - 1) |
1081 | usage (); |
1204 | usage (); |
1082 | |
1205 | |
1083 | dotask (p[0][1], p[1]); |
1206 | dotask (p[0][1], p[1]); |
1084 | XCloseDisplay (dpy); |
1207 | XCloseDisplay (dpy); |
1085 | exit (0); |
1208 | exit (0); |
1086 | } |
1209 | } |
1087 | } |
1210 | } |
1088 | |
1211 | |
1089 | /* |
1212 | /* |
1090 | * If no task mode request has been made of us, this code |
1213 | * If no task mode request has been made of us, this code |
1091 | * proceeds with the rest of the windows initialization. |
1214 | * proceeds with the rest of the windows initialization. |
… | |
… | |
1104 | for (i = 0; i < nbuffs; i++) |
1227 | for (i = 0; i < nbuffs; i++) |
1105 | { |
1228 | { |
1106 | XtSetArg (args[0], XtNatom, get_atom (i, False)); |
1229 | XtSetArg (args[0], XtNatom, get_atom (i, False)); |
1107 | n = 1; |
1230 | n = 1; |
1108 | if (i > 0) |
1231 | if (i > 0) |
1109 | { |
1232 | { |
1110 | if (ares.layout[0] == 'h') |
1233 | if (ares.layout[0] == 'h') |
1111 | { |
1234 | { |
1112 | XtSetArg (args[1], XtNfromHoriz, wdg[i - 1]); |
1235 | XtSetArg (args[1], XtNfromHoriz, wdg[i - 1]); |
1113 | XtSetArg (args[2], XtNfromVert, 0); |
1236 | XtSetArg (args[2], XtNfromVert, 0); |
1114 | n = 3; |
1237 | n = 3; |
1115 | } |
1238 | } |
1116 | |
1239 | |
1117 | if (ares.layout[0] == 'v') |
1240 | if (ares.layout[0] == 'v') |
1118 | { |
1241 | { |
1119 | XtSetArg (args[1], XtNfromVert, wdg[i - 1]); |
1242 | XtSetArg (args[1], XtNfromVert, wdg[i - 1]); |
1120 | XtSetArg (args[2], XtNfromHoriz, 0); |
1243 | XtSetArg (args[2], XtNfromHoriz, 0); |
1121 | n = 3; |
1244 | n = 3; |
1122 | } |
1245 | } |
1123 | } |
1246 | } |
1124 | |
1247 | |
1125 | sprintf (name, "buffer%d", i); |
1248 | sprintf (name, "buffer%d", i); |
1126 | wdg[i] = XtCreateWidget (name, cbWidgetClass, box, args, n); |
1249 | wdg[i] = XtCreateWidget (name, cbWidgetClass, box, args, n); |
1127 | XtManageChild (wdg[i]); |
1250 | XtManageChild (wdg[i]); |
1128 | } |
1251 | } |
… | |
… | |
1169 | XtRealizeWidget (top); |
1292 | XtRealizeWidget (top); |
1170 | |
1293 | |
1171 | delwin = XInternAtom (dpy, "WM_DELETE_WINDOW", False); |
1294 | delwin = XInternAtom (dpy, "WM_DELETE_WINDOW", False); |
1172 | XSetWMProtocols (dpy, XtWindow (top), &delwin, 1); |
1295 | XSetWMProtocols (dpy, XtWindow (top), &delwin, 1); |
1173 | XtAddEventHandler (top, 0, True, wmdel, (XtPointer) 0); |
1296 | XtAddEventHandler (top, 0, True, wmdel, (XtPointer) 0); |
1174 | |
|
|
1175 | xa_compound_text = XInternAtom (dpy, "COMPOUND_TEXT", False); |
|
|
1176 | xa_utf8_string = XInternAtom (dpy, "UTF8_STRING", False); |
|
|
1177 | xa_text = XInternAtom (dpy, "TEXT", False); |
|
|
1178 | |
|
|
1179 | if (!xa_utf8_string) |
|
|
1180 | xa_utf8_string = xa_compound_text; |
|
|
1181 | |
|
|
1182 | #ifdef XVIEW |
|
|
1183 | clipboard = XInternAtom (dpy, "CLIPBOARD", False); |
|
|
1184 | caret = XInternAtom (dpy, "_SUN_SELN_CARET", False); |
|
|
1185 | yield = XInternAtom (dpy, "_SUN_SELN_YIELD", False); |
|
|
1186 | length = XInternAtom (dpy, "LENGTH", False); |
|
|
1187 | lengthc = XInternAtom (dpy, "LENGTH_CHARS", False); |
|
|
1188 | #endif |
|
|
1189 | |
1297 | |
1190 | initialize_properties (); |
1298 | initialize_properties (); |
1191 | } |
1299 | } |
1192 | |
1300 | |
1193 | /* |
1301 | /* |
… | |
… | |
1240 | XConvertSelection (dpy, XA_PRIMARY, target, |
1348 | XConvertSelection (dpy, XA_PRIMARY, target, |
1241 | convert_to, event.xselection.requestor, event.xselection.time); |
1349 | convert_to, event.xselection.requestor, event.xselection.time); |
1242 | } |
1350 | } |
1243 | } |
1351 | } |
1244 | else |
1352 | else |
1245 | { |
|
|
1246 | (void) XtDispatchEvent (&event); |
1353 | (void) XtDispatchEvent (&event); |
1247 | } |
|
|
1248 | } |
1354 | } |
1249 | } |
1355 | } |
1250 | |
1356 | |
1251 | main (argc, argv) |
1357 | main (argc, argv) |
1252 | int argc; |
1358 | int argc; |