Restructure how we look for Read files slightly.
[fvwm.git] / modules / FvwmForm / ReadXServer.c
blobaa0daedcbc62ec56982520ff8734e3369a14c346
1 /* -*-c-*- */
2 /*
3 * This file is partly derived from FvwmForm.c, this is the original
4 * copyright:
6 * FvwmForm is original work of Thomas Zuwei Feng.
8 * Copyright Feb 1995, Thomas Zuwei Feng. No guarantees or warantees are
9 * provided or implied in any way whatsoever. Use this program at your own
10 * risk. Permission to use, modify, and redistribute this program is hereby
11 * given, provided that this copyright is kept intact.
13 * And the same goes for me, Dan Espen, March 10, 1999.
16 /* This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 /* Modification History */
33 /* Changed on 03/19/99 by DanEspen (dje): */
34 /* - paste tab as space if there is one input field. */
36 /* Changed on 03/10/99 by DanEspen (dje): */
37 /* - Make button 2 paste work. */
39 /* Changed on 02/27/99 by DanEspen (dje): */
40 /* - Add logic to allow international characters, bug id 179 */
41 /* - Split into separate file. */
43 #include "config.h"
44 #include "libs/fvwmlib.h"
45 #include "libs/Colorset.h"
47 #include <stdio.h>
48 #include <ctype.h>
50 #include <X11/Xlib.h>
51 #include <X11/X.h>
52 #include <X11/Xutil.h>
53 #include <X11/cursorfont.h>
54 #define XK_MISCELLANY
55 #include <X11/keysymdef.h>
56 #include <X11/Xatom.h> /* for XA_CUT_BUFFER0 */
58 #include <FvwmForm.h>
60 static void process_regular_char_input(unsigned char *buf);
61 static int process_tabtypes(unsigned char * buf);
62 static void process_history(int direction);
63 static void process_paste_request (XEvent *event, Item *item);
64 static void ToggleChoice (Item *item);
65 static void ResizeFrame (void);
67 /* read an X event */
68 void ReadXServer (void)
70 static XEvent event;
71 int old_cursor = 0, keypress;
72 Item *item, *old_item;
73 KeySym ks;
74 char *sp, *dp;
75 static unsigned char buf[10]; /* unsigned for international */
76 static int n;
78 while (FEventsQueued(dpy, QueuedAfterReading)) {
79 FNextEvent(dpy, &event);
80 if (event.xany.window == CF.frame) {
81 switch (event.type) {
82 case ClientMessage:
84 if(event.xclient.format == 32 &&
85 event.xclient.data.l[0] == wm_del_win)
87 exit(0);
90 break;
91 case ConfigureNotify: /* has window be reconfigured */
93 XEvent tmpe;
95 while (FCheckTypedWindowEvent(
96 dpy, CF.frame, ConfigureNotify, &tmpe))
98 if (!tmpe.xconfigure.send_event)
99 continue;
100 event.xconfigure.x = tmpe.xconfigure.x;
101 event.xconfigure.y = tmpe.xconfigure.y;
102 event.xconfigure.send_event = True;
104 if (CF.max_width != event.xconfigure.width ||
105 CF.total_height != event.xconfigure.height)
107 /* adjust yourself... do noting */
108 ResizeFrame();
109 CF.max_width = event.xconfigure.width;
110 CF.total_height = event.xconfigure.height;
111 UpdateRootTransapency(False, True);
112 if (!CSET_IS_TRANSPARENT(colorset))
114 RedrawFrame(NULL);
117 else if (event.xconfigure.send_event)
119 UpdateRootTransapency(False, True);
122 break;
123 #if 0
124 case SelectionClear:
125 selection_clear ();
126 break;
127 case SelectionNotify:
128 selection_paste ();
129 break;
130 case SelectionRequest:
131 selection_send ();
132 break;
133 #endif
134 case Expose:
136 int ex = event.xexpose.x;
137 int ey = event.xexpose.y;
138 int ex2 = event.xexpose.x + event.xexpose.width;
139 int ey2 = event.xexpose.y + event.xexpose.height;
140 while (FCheckTypedWindowEvent(dpy, CF.frame, Expose, &event))
142 ex = min(ex, event.xexpose.x);
143 ey = min(ey, event.xexpose.y);
144 ex2 = max(ex2, event.xexpose.x + event.xexpose.width);
145 ey2 = max(ey2 , event.xexpose.y + event.xexpose.height);
147 event.xexpose.x = ex;
148 event.xexpose.y = ey;
149 event.xexpose.width = ex2 - ex;
150 event.xexpose.height = ey2 - ey;
151 RedrawFrame(&event);
152 if (CF.grab_server && !CF.server_grabbed)
154 if (GrabSuccess ==
155 XGrabPointer(dpy, CF.frame, True, 0,
156 GrabModeAsync, GrabModeAsync,
157 None, None, CurrentTime))
158 CF.server_grabbed = 1;
161 break;
162 case VisibilityNotify:
163 if (CF.server_grabbed &&
164 event.xvisibility.state != VisibilityUnobscured)
166 /* raise our window to the top */
167 XRaiseWindow(dpy, CF.frame);
168 XSync(dpy, 0);
170 break;
171 case KeyPress: /* we do text input here */
172 n = XLookupString(&event.xkey, (char *)buf, sizeof(buf), &ks, NULL);
173 keypress = buf[0];
174 myfprintf((stderr, "Keypress [%s]\n", buf));
175 if (n == 0) { /* not a regular key, translate it into one */
176 switch (ks) {
177 case XK_Home:
178 case XK_Begin:
179 buf[0] = '\001'; /* ^A */
180 break;
181 case XK_End:
182 buf[0] = '\005'; /* ^E */
183 break;
184 case XK_Left:
185 buf[0] = '\002'; /* ^B */
186 break;
187 case XK_Right:
188 buf[0] = '\006'; /* ^F */
189 break;
190 case XK_Up:
191 buf[0] = '\020'; /* ^P */
192 break;
193 case XK_Down:
194 buf[0] = '\016'; /* ^N */
195 break;
196 default:
197 if (ks >= XK_F1 && ks <= XK_F35) {
198 buf[0] = '\0';
199 keypress = 257 + ks - XK_F1;
200 } else
201 goto no_redraw; /* no action for this event */
204 switch (ks) { /* regular key, may need adjustment */
205 case XK_Tab:
206 #ifdef XK_XKB_KEYS
207 case XK_ISO_Left_Tab:
208 #endif
209 if (event.xkey.state & ShiftMask) { /* shifted key */
210 buf[0] = '\020'; /* chg shift tab to ^P */
212 break;
213 case '>':
214 if (event.xkey.state & Mod1Mask) { /* Meta, shift > */
215 process_history(1);
216 goto redraw_newcursor;
218 break;
219 case '<':
220 if (event.xkey.state & Mod1Mask) { /* Meta, shift < */
221 process_history(-1);
222 goto redraw_newcursor;
224 break;
226 if (!CF.cur_input) { /* no text input fields */
227 for (item = root_item_ptr; item != 0;
228 item = item->header.next) {/* all items */
229 if (item->type == I_BUTTON && item->button.keypress == keypress) {
230 RedrawItem(item, 1, NULL);
231 usleep(MICRO_S_FOR_10MS);
232 RedrawItem(item, 0, NULL);
233 DoCommand(item);
234 goto no_redraw;
237 break;
238 } else if (CF.cur_input == CF.cur_input->input.next_input) {
239 /* 1 ip field */
240 switch (buf[0]) {
241 case '\020': /* ^P previous field */
242 process_history(-1);
243 goto redraw_newcursor;
244 break;
245 case '\016': /* ^N next field */
246 process_history(1);
247 goto redraw_newcursor;
248 break;
249 } /* end switch */
250 } /* end one input field */
251 switch (buf[0]) {
252 case '\001': /* ^A */
253 old_cursor = CF.abs_cursor;
254 CF.rel_cursor = 0;
255 CF.abs_cursor = 0;
256 CF.cur_input->input.left = 0;
257 goto redraw_newcursor;
258 break;
259 case '\005': /* ^E */
260 old_cursor = CF.abs_cursor;
261 CF.rel_cursor = CF.cur_input->input.n;
262 if ((CF.cur_input->input.left =
263 CF.rel_cursor - CF.cur_input->input.size) < 0)
264 CF.cur_input->input.left = 0;
265 CF.abs_cursor = CF.rel_cursor - CF.cur_input->input.left;
266 goto redraw_newcursor;
267 break;
268 case '\002': /* ^B */
269 old_cursor = CF.abs_cursor;
270 if (CF.rel_cursor > 0) {
271 CF.rel_cursor--;
272 CF.abs_cursor--;
273 if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) {
274 CF.abs_cursor++;
275 CF.cur_input->input.left--;
278 goto redraw_newcursor;
279 break;
280 case '\006': /* ^F */
281 old_cursor = CF.abs_cursor;
282 if (CF.rel_cursor < CF.cur_input->input.n) {
283 CF.rel_cursor++;
284 CF.abs_cursor++;
285 if (CF.abs_cursor >= CF.cur_input->input.size &&
286 CF.rel_cursor < CF.cur_input->input.n) {
287 CF.abs_cursor--;
288 CF.cur_input->input.left++;
291 goto redraw_newcursor;
292 break;
293 case '\010': /* ^H */
294 old_cursor = CF.abs_cursor;
295 if (CF.rel_cursor > 0) {
296 sp = CF.cur_input->input.value + CF.rel_cursor;
297 dp = sp - 1;
298 for (; *dp = *sp, *sp != '\0'; dp++, sp++);
299 CF.cur_input->input.n--;
300 CF.rel_cursor--;
301 if (CF.rel_cursor < CF.abs_cursor) {
302 CF.abs_cursor--;
303 if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) {
304 CF.abs_cursor++;
305 CF.cur_input->input.left--;
307 } else
308 CF.cur_input->input.left--;
310 goto redraw_newcursor;
311 break;
312 case '\177': /* DEL */
313 case '\004': /* ^D */
314 if (CF.rel_cursor < CF.cur_input->input.n) {
315 sp = CF.cur_input->input.value + CF.rel_cursor + 1;
316 dp = sp - 1;
317 for (; *dp = *sp, *sp != '\0'; dp++, sp++);
318 CF.cur_input->input.n--;
319 goto redraw_newcursor;
321 break;
322 case '\013': /* ^K */
323 CF.cur_input->input.value[CF.rel_cursor] = '\0';
324 CF.cur_input->input.n = CF.rel_cursor;
325 goto redraw_newcursor;
326 case '\025': /* ^U */
327 CF.cur_input->input.value[0] = '\0';
328 CF.cur_input->input.n = CF.cur_input->input.left = 0;
329 CF.rel_cursor = CF.abs_cursor = 0;
330 goto redraw_newcursor;
331 case '\020': /* ^P previous field */
332 old_item = CF.cur_input;
333 CF.cur_input = old_item->input.prev_input; /* new current input fld */
334 RedrawItem(old_item, 1, NULL);
335 CF.rel_cursor = CF.abs_cursor = 0; /* home cursor in new input field */
336 goto redraw;
337 break;
338 case '\t':
339 case '\n':
340 case '\015':
341 case '\016': /* LINEFEED, TAB, RETURN, ^N, jump to the next field */
342 switch (process_tabtypes(&buf[0])) {
343 case 0: goto no_redraw;break;
344 case 1: goto redraw;break;
346 break;
347 default:
348 old_cursor = CF.abs_cursor;
349 if((buf[0] >= ' ' &&
350 buf[0] < '\177') ||
351 (buf[0] >= 160)) { /* regular or intl char */
352 process_regular_char_input(&buf[0]); /* insert into input field */
353 goto redraw_newcursor;
355 /* unrecognized key press, check for buttons */
356 for (item = root_item_ptr; item != 0; item = item->header.next)
358 /* all items */
359 myfprintf((stderr, "Button: keypress==%d\n",
360 item->button.keypress));
361 if (item->type == I_BUTTON && item->button.keypress == keypress) {
362 RedrawItem(item, 1, NULL);
363 usleep(MICRO_S_FOR_10MS); /* .1 seconds */
364 RedrawItem(item, 0, NULL);
365 DoCommand(item);
366 goto no_redraw;
369 break;
371 redraw_newcursor:
373 XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC,
374 CF.cur_input->header.dt_ptr->dt_colors[c_item_bg]);
375 /* Since DrawString is being used, I changed this to clear the
376 entire input field. dje 10/24/99. */
377 XClearArea(dpy, CF.cur_input->header.win,
378 BOX_SPC + TEXT_SPC - 1, BOX_SPC,
379 CF.cur_input->header.size_x
380 - (2 * BOX_SPC) - 2 - TEXT_SPC,
381 (CF.cur_input->header.size_y - 1)
382 - 2 * BOX_SPC + 1, False);
384 redraw:
386 int len, x, dy;
387 len = CF.cur_input->input.n - CF.cur_input->input.left;
388 XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC,
389 CF.cur_input->header.dt_ptr->dt_colors[c_item_fg]);
390 if (len > CF.cur_input->input.size)
391 len = CF.cur_input->input.size;
392 CF.cur_input->header.dt_ptr->dt_Fstr->win = CF.cur_input->header.win;
393 CF.cur_input->header.dt_ptr->dt_Fstr->gc =
394 CF.cur_input->header.dt_ptr->dt_item_GC;
395 CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = False;
396 if (itemcolorset >= 0)
398 CF.cur_input->header.dt_ptr->dt_Fstr->colorset =
399 &Colorset[itemcolorset];
400 CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = True;
402 CF.cur_input->header.dt_ptr->dt_Fstr->str = CF.cur_input->input.value;
403 CF.cur_input->header.dt_ptr->dt_Fstr->x = BOX_SPC + TEXT_SPC;
404 CF.cur_input->header.dt_ptr->dt_Fstr->y = BOX_SPC + TEXT_SPC
405 + CF.cur_input->header.dt_ptr->dt_Ffont->ascent;
406 CF.cur_input->header.dt_ptr->dt_Fstr->len = len;
407 FlocaleDrawString(dpy,
408 CF.cur_input->header.dt_ptr->dt_Ffont,
409 CF.cur_input->header.dt_ptr->dt_Fstr,
410 FWS_HAVE_LENGTH);
411 x = BOX_SPC + TEXT_SPC +
412 FlocaleTextWidth(CF.cur_input->header.dt_ptr->dt_Ffont,
413 CF.cur_input->input.value,CF.abs_cursor)
414 - 1;
415 dy = CF.cur_input->header.size_y - 1;
416 XDrawLine(dpy, CF.cur_input->header.win,
417 CF.cur_input->header.dt_ptr->dt_item_GC,
418 x, BOX_SPC, x, dy - BOX_SPC);
419 myfprintf((stderr,"Line %d/%d - %d/%d (char)\n",
420 x, BOX_SPC, x, dy - BOX_SPC));
422 no_redraw:
423 break; /* end of case KeyPress */
424 } /* end of switch (event.type) */
425 continue;
426 } /* end of if (event.xany.window == CF.frame) */
427 for (item = root_item_ptr; item != 0;
428 item = item->header.next) { /* all items */
429 if (event.xany.window == item->header.win) {
430 switch (event.type) {
431 case Expose:
433 int ex = event.xexpose.x;
434 int ey = event.xexpose.y;
435 int ex2 = event.xexpose.x + event.xexpose.width;
436 int ey2 = event.xexpose.y + event.xexpose.height;
437 while (FCheckTypedWindowEvent(
438 dpy, item->header.win, Expose, &event))
440 ex = min(ex, event.xexpose.x);
441 ey = min(ey, event.xexpose.y);
442 ex2 = max(ex2, event.xexpose.x + event.xexpose.width);
443 ey2 = max(ey2 , event.xexpose.y + event.xexpose.height);
445 event.xexpose.x = ex;
446 event.xexpose.y = ey;
447 event.xexpose.width = ex2 - ex;
448 event.xexpose.height = ey2 - ey;
449 RedrawItem(item, 0, &event);
451 break;
452 case ButtonPress:
453 if (item->type == I_INPUT) {
454 old_item = CF.cur_input;
455 CF.cur_input = item;
456 RedrawItem(old_item, 1, NULL);
458 Bool done = False;
460 CF.abs_cursor = 0;
461 while(CF.abs_cursor <= item->input.size && !done)
463 if (FlocaleTextWidth(item->header.dt_ptr->dt_Ffont,
464 item->input.value,
465 CF.abs_cursor) >=
466 event.xbutton.x - BOX_SPC - TEXT_SPC)
468 done = True;
469 CF.abs_cursor--;
471 else
473 CF.abs_cursor++;
477 if (CF.abs_cursor < 0)
478 CF.abs_cursor = 0;
479 if (CF.abs_cursor > item->input.size)
480 CF.abs_cursor = item->input.size;
481 CF.rel_cursor = CF.abs_cursor + item->input.left;
482 if (CF.rel_cursor < 0)
483 CF.rel_cursor = 0;
484 if (CF.rel_cursor > item->input.n)
485 CF.rel_cursor = item->input.n;
486 if (CF.rel_cursor > 0 && CF.rel_cursor == item->input.left)
487 item->input.left--;
488 if (CF.rel_cursor < item->input.n &&
489 CF.rel_cursor == item->input.left + item->input.size)
490 item->input.left++;
491 CF.abs_cursor = CF.rel_cursor - item->input.left;
492 if (event.xbutton.button == Button2) { /* if paste request */
493 process_paste_request (&event, item);
495 RedrawItem(item, 0, NULL);
497 if (item->type == I_CHOICE)
498 ToggleChoice(item);
499 if (item->type == I_BUTTON) {
500 RedrawItem(item, 1, NULL); /* push button in */
501 if (CF.activate_on_press) {
502 usleep(MICRO_S_FOR_10MS); /* make sure its visible */
503 RedrawItem(item, 0, NULL); /* pop button out */
504 DoCommand(item); /* execute the button command */
505 } else {
506 XGrabPointer(dpy, item->header.win,
507 False, /* owner of events */
508 ButtonReleaseMask, /* events to report */
509 GrabModeAsync, /* keyboard mode */
510 GrabModeAsync, /* pointer mode */
511 None, /* confine to */
512 /* I sort of like this, the hand points in
513 the other direction and the color is
514 reversed. I don't know what other GUIs do,
515 Java doesn't do anything, neither does anything
516 else I can find...dje */
517 CF.pointer[button_in_pointer], /* cursor */
518 CurrentTime);
519 } /* end activate on press */
521 break;
522 case ButtonRelease:
523 if (!CF.activate_on_press) {
524 RedrawItem(item, 0, NULL);
525 if (CF.grab_server && CF.server_grabbed) {
526 /* You have to regrab the pointer, or focus
527 can go to another window.
528 grab...
530 XGrabPointer(dpy, CF.frame, True, 0, GrabModeAsync, GrabModeAsync,
531 None, None, CurrentTime);
532 XFlush(dpy);
533 } else {
534 XUngrabPointer(dpy, CurrentTime);
535 XFlush(dpy);
537 if (event.xbutton.x >= 0 &&
538 event.xbutton.x < item->header.size_x &&
539 event.xbutton.y >= 0 &&
540 event.xbutton.y < item->header.size_y) {
541 DoCommand(item);
544 break;
547 } /* end of for (i = 0) */
548 } /* while loop */
551 /* Each input field has a history, depending on the passed
552 direction, get the desired history item into the input field.
553 After "Restart" the yank point is one entry beyond the last
554 inserted item.
555 Normal yanks, going backward, go down the array decrementing
556 yank count before extracting.
557 Forward yanks increment before extracting. */
558 static void process_history(int direction) {
559 int count;
560 if (!CF.cur_input /* no input fields */
561 || !CF.cur_input->input.value_history_ptr) { /* or no history */
562 return; /* bail out */
564 /* yankat is always one beyond slot to yank from. */
565 count = CF.cur_input->input.value_history_yankat + direction;
566 if (count < 0 || count >= VH_SIZE ||
567 CF.cur_input->input.value_history_ptr[count] == 0 ) {
568 if (direction <= 0) { /* going down */
569 for (count = VH_SIZE - 1;
570 CF.cur_input->input.value_history_ptr[count] == 0;
571 --count); /* find last used slot */
572 } else { /* going up */
573 count = 0; /* up is the bottom */
576 CF.cur_input->input.value =
577 safestrdup(CF.cur_input->input.value_history_ptr[count]);
578 CF.cur_input->input.n = strlen(CF.cur_input->input.value);
579 CF.cur_input->input.value_history_yankat = count; /* new yank point */
580 CF.cur_input->input.buf = CF.cur_input->input.n;
581 CF.rel_cursor = 0;
582 CF.abs_cursor = 0;
583 CF.cur_input->input.left = 0;
584 return;
587 /* Note that tab, return, linefeed, ^n, all do the same thing
588 except when it comes to matching a command button hotkey.
590 Return 1 to redraw, 0 for no redraw */
591 static int process_tabtypes(unsigned char * buf) {
592 Item *item, *old_item;
593 /* Note: the input field ring used with ^P above
594 could probably make this a lot simpler. dje 12/20/98 */
595 /* Code tracks cursor. */
596 item = root_item_ptr; /* init item ptr */
597 if (CF.cur_input != 0) { /* if in text */
598 item = CF.cur_input->header.next; /* move to next item */
600 for ( ; item != 0;
601 item = item->header.next) {/* find next input item */
602 if (item->type == I_INPUT) {
603 old_item = CF.cur_input;
604 CF.cur_input = item;
605 RedrawItem(old_item, 1, NULL);
606 CF.rel_cursor = CF.abs_cursor = 0; /* home cursor in new input field */
607 return (1); /* cause redraw */
610 /* end of all text input fields, check for buttons */
611 for (item = root_item_ptr; item != 0;
612 item = item->header.next) {/* all items */
613 myfprintf((stderr, "Button: keypress==%d vs buf %d\n",
614 item->button.keypress, buf[0]));
615 if (item->type == I_BUTTON && item->button.keypress == buf[0]) {
616 RedrawItem(item, 1, NULL);
617 usleep(MICRO_S_FOR_10MS);
618 RedrawItem(item, 0, NULL);
619 DoCommand(item);
620 return (0); /* cause no_redraw */
623 /* goto the first text input field */
624 for (item = root_item_ptr; item != 0;
625 item = item->header.next) {/* all items */
626 if (item->type == I_INPUT) {
627 old_item = CF.cur_input;
628 CF.cur_input = item;
629 RedrawItem(old_item, 1, NULL);
630 CF.abs_cursor = CF.rel_cursor - item->input.left;
631 return (1); /* goto redraw */
634 return (-1);
637 static void process_regular_char_input(unsigned char *buf) {
638 char *sp, *dp, *ep;
639 /* n is the space actually used.
640 buf is the size of the buffer
641 size is the size of the field on the screen
642 size is used as the increment, arbitrarily. */
643 if (++(CF.cur_input->input.n) >= CF.cur_input->input.buf) {
644 CF.cur_input->input.buf += CF.cur_input->input.size;
645 CF.cur_input->input.value =
646 (char *)saferealloc(CF.cur_input->input.value,
647 CF.cur_input->input.buf);
649 dp = CF.cur_input->input.value + CF.cur_input->input.n;
650 sp = dp - 1;
651 ep = CF.cur_input->input.value + CF.rel_cursor;
652 for (; *dp = *sp, sp != ep; sp--, dp--);
653 *ep = buf[0];
654 CF.rel_cursor++;
655 CF.abs_cursor++;
656 if (CF.abs_cursor >= CF.cur_input->input.size) {
657 if (CF.rel_cursor < CF.cur_input->input.n)
658 CF.abs_cursor = CF.cur_input->input.size - 1;
659 else
660 CF.abs_cursor = CF.cur_input->input.size;
661 CF.cur_input->input.left = CF.rel_cursor - CF.abs_cursor;
664 /* Process a paste. This can be any size.
665 Right now, the input loop can't just be fed characters.
666 Send plain text and newlines to the 2 subroutines that want them.
668 static void process_paste_request (XEvent *event, Item *item) {
669 Atom actual_type;
670 int actual_format;
671 unsigned long nitems, bytes_after, nread;
672 unsigned char *data, *h, buf[256];
673 unsigned char *c;
675 nread = 0; /* init read offset */
676 h = buf; /* starting point */
677 do {
678 if (XGetWindowProperty (dpy,
679 DefaultRootWindow (dpy),
680 XA_CUT_BUFFER0,
681 nread/4, 1024L, /* offset, length */
682 False, /* delete */
683 AnyPropertyType, /* request type */
684 &actual_type,
685 &actual_format, &nitems, &bytes_after,
686 (unsigned char **)&data) != Success) {
687 return; /* didn't work, give up */
688 } /* end didn't work */
689 if (actual_type != XA_STRING) { /* if something other than text */
690 return; /* give up */
692 for (c = data; c != data + nitems; c++) { /* each char */
693 switch (*c) {
694 case '\t': /* TAB */
695 if (CF.cur_input == CF.cur_input->input.next_input) { /* 1 ip field */
696 process_regular_char_input((unsigned char *)" "); /* paste space */
697 } else {
698 process_tabtypes(c); /* jump to the next field */
700 case '\015': /* LINEFEED */
701 case '\016': /* ^N */
702 process_tabtypes(c); /* jump to the next field */
703 break;
704 case '\n':
705 /* change \n to \r for pasting */
706 process_tabtypes((unsigned char *)"\r");
707 break;
708 default:
709 process_regular_char_input(c);
710 break;
711 } /* end swtich on char type */
712 } /* end each char */
713 myfprintf((stderr,"See paste data, %s, nread %d, nitems %d\n",
714 data, (int)nread, (int)nitems));
715 nread += nitems;
716 XFree (data);
717 } while (bytes_after > 0);
719 static void ToggleChoice (Item *item)
721 int i;
722 Item *sel = item->choice.sel;
724 if (sel->selection.key == IS_SINGLE) {
725 if (!item->choice.on) {
726 for (i = 0; i < sel->selection.n; i++) {
727 if (sel->selection.choices[i]->choice.on) {
728 sel->selection.choices[i]->choice.on = 0;
729 RedrawItem(sel->selection.choices[i], 0, NULL);
732 item->choice.on = 1;
733 RedrawItem(item, 0, NULL);
735 } else { /* IS_MULTIPLE */
736 item->choice.on = !item->choice.on;
737 RedrawItem(item, 0, NULL);
740 static void ResizeFrame (void) {
741 #if 0
742 /* unfinished dje. */
743 /* If you ever finish this, please make sure to check the return code of
744 * XGetGeometry below. dv */
745 Window root;
746 XEvent dummy;
747 int x, y;
748 unsigned int border, depth, width, height;
749 /* get anything queued */
750 while (FCheckTypedWindowEvent(dpy, CF.frame, ConfigureNotify, &dummy))
752 XGetGeometry(dpy, CF.frame, &root, &x, &y, &width, &height, &border, &depth);
753 if (width != CF.max_width) {
754 if (CF.last_error != 0) { /* if form has message area */
755 fprintf(stderr, "Frame was %d, is %d\n",CF.max_width,width);
756 /* RedrawText sets x = item->header.pos_x + TEXT_SPC;
757 MassageConfig does :
758 line->size_x += (line->n + 1) * ITEM_HSPC; =(10)=
759 if (line->size_x > CF.max_width)
760 CF.max_width = line->size_x;
761 (70 + 1) * 10 = 700??
763 int delta;
764 int curr_x;
765 delta = width - CF.max_width; /* new width - curr width */
766 curr_x = CF.last_error->header.pos_x + TEXT_SPC;
767 curr_end = curr_x + CF.last_error->size_x;
771 #endif