3 * This file is partly derived from FvwmForm.c, this is the original
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. */
44 #include "libs/fvwmlib.h"
45 #include "libs/Colorset.h"
52 #include <X11/Xutil.h>
53 #include <X11/cursorfont.h>
55 #include <X11/keysymdef.h>
56 #include <X11/Xatom.h> /* for XA_CUT_BUFFER0 */
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);
68 void ReadXServer (void)
71 int old_cursor
= 0, keypress
;
72 Item
*item
, *old_item
;
75 static unsigned char buf
[10]; /* unsigned for international */
78 while (FEventsQueued(dpy
, QueuedAfterReading
)) {
79 FNextEvent(dpy
, &event
);
80 if (event
.xany
.window
== CF
.frame
) {
84 if(event
.xclient
.format
== 32 &&
85 event
.xclient
.data
.l
[0] == wm_del_win
)
91 case ConfigureNotify
: /* has window be reconfigured */
95 while (FCheckTypedWindowEvent(
96 dpy
, CF
.frame
, ConfigureNotify
, &tmpe
))
98 if (!tmpe
.xconfigure
.send_event
)
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 */
109 CF
.max_width
= event
.xconfigure
.width
;
110 CF
.total_height
= event
.xconfigure
.height
;
111 UpdateRootTransapency(False
, True
);
112 if (!CSET_IS_TRANSPARENT(colorset
))
117 else if (event
.xconfigure
.send_event
)
119 UpdateRootTransapency(False
, True
);
127 case SelectionNotify
:
130 case SelectionRequest
:
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
;
152 if (CF
.grab_server
&& !CF
.server_grabbed
)
155 XGrabPointer(dpy
, CF
.frame
, True
, 0,
156 GrabModeAsync
, GrabModeAsync
,
157 None
, None
, CurrentTime
))
158 CF
.server_grabbed
= 1;
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
);
171 case KeyPress
: /* we do text input here */
172 n
= XLookupString(&event
.xkey
, (char *)buf
, sizeof(buf
), &ks
, NULL
);
174 myfprintf((stderr
, "Keypress [%s]\n", buf
));
175 if (n
== 0) { /* not a regular key, translate it into one */
179 buf
[0] = '\001'; /* ^A */
182 buf
[0] = '\005'; /* ^E */
185 buf
[0] = '\002'; /* ^B */
188 buf
[0] = '\006'; /* ^F */
191 buf
[0] = '\020'; /* ^P */
194 buf
[0] = '\016'; /* ^N */
197 if (ks
>= XK_F1
&& ks
<= XK_F35
) {
199 keypress
= 257 + ks
- XK_F1
;
201 goto no_redraw
; /* no action for this event */
204 switch (ks
) { /* regular key, may need adjustment */
207 case XK_ISO_Left_Tab
:
209 if (event
.xkey
.state
& ShiftMask
) { /* shifted key */
210 buf
[0] = '\020'; /* chg shift tab to ^P */
214 if (event
.xkey
.state
& Mod1Mask
) { /* Meta, shift > */
216 goto redraw_newcursor
;
220 if (event
.xkey
.state
& Mod1Mask
) { /* Meta, shift < */
222 goto redraw_newcursor
;
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
);
238 } else if (CF
.cur_input
== CF
.cur_input
->input
.next_input
) {
241 case '\020': /* ^P previous field */
243 goto redraw_newcursor
;
245 case '\016': /* ^N next field */
247 goto redraw_newcursor
;
250 } /* end one input field */
252 case '\001': /* ^A */
253 old_cursor
= CF
.abs_cursor
;
256 CF
.cur_input
->input
.left
= 0;
257 goto redraw_newcursor
;
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
;
268 case '\002': /* ^B */
269 old_cursor
= CF
.abs_cursor
;
270 if (CF
.rel_cursor
> 0) {
273 if (CF
.abs_cursor
<= 0 && CF
.rel_cursor
> 0) {
275 CF
.cur_input
->input
.left
--;
278 goto redraw_newcursor
;
280 case '\006': /* ^F */
281 old_cursor
= CF
.abs_cursor
;
282 if (CF
.rel_cursor
< CF
.cur_input
->input
.n
) {
285 if (CF
.abs_cursor
>= CF
.cur_input
->input
.size
&&
286 CF
.rel_cursor
< CF
.cur_input
->input
.n
) {
288 CF
.cur_input
->input
.left
++;
291 goto redraw_newcursor
;
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
;
298 for (; *dp
= *sp
, *sp
!= '\0'; dp
++, sp
++);
299 CF
.cur_input
->input
.n
--;
301 if (CF
.rel_cursor
< CF
.abs_cursor
) {
303 if (CF
.abs_cursor
<= 0 && CF
.rel_cursor
> 0) {
305 CF
.cur_input
->input
.left
--;
308 CF
.cur_input
->input
.left
--;
310 goto redraw_newcursor
;
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;
317 for (; *dp
= *sp
, *sp
!= '\0'; dp
++, sp
++);
318 CF
.cur_input
->input
.n
--;
319 goto redraw_newcursor
;
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 */
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;
348 old_cursor
= CF
.abs_cursor
;
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
)
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
);
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
);
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
,
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
)
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
));
423 break; /* end of case KeyPress */
424 } /* end of switch (event.type) */
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
) {
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
);
453 if (item
->type
== I_INPUT
) {
454 old_item
= CF
.cur_input
;
456 RedrawItem(old_item
, 1, NULL
);
461 while(CF
.abs_cursor
<= item
->input
.size
&& !done
)
463 if (FlocaleTextWidth(item
->header
.dt_ptr
->dt_Ffont
,
466 event
.xbutton
.x
- BOX_SPC
- TEXT_SPC
)
477 if (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)
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
)
488 if (CF
.rel_cursor
< item
->input
.n
&&
489 CF
.rel_cursor
== item
->input
.left
+ item
->input
.size
)
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
)
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 */
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 */
519 } /* end activate on press */
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.
530 XGrabPointer(dpy
, CF
.frame
, True
, 0, GrabModeAsync
, GrabModeAsync
,
531 None
, None
, CurrentTime
);
534 XUngrabPointer(dpy
, CurrentTime
);
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
) {
547 } /* end of for (i = 0) */
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
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
) {
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
;
583 CF
.cur_input
->input
.left
= 0;
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 */
601 item
= item
->header
.next
) {/* find next input item */
602 if (item
->type
== I_INPUT
) {
603 old_item
= CF
.cur_input
;
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
);
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
;
629 RedrawItem(old_item
, 1, NULL
);
630 CF
.abs_cursor
= CF
.rel_cursor
- item
->input
.left
;
631 return (1); /* goto redraw */
637 static void process_regular_char_input(unsigned char *buf
) {
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
;
651 ep
= CF
.cur_input
->input
.value
+ CF
.rel_cursor
;
652 for (; *dp
= *sp
, sp
!= ep
; sp
--, dp
--);
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;
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
) {
671 unsigned long nitems
, bytes_after
, nread
;
672 unsigned char *data
, *h
, buf
[256];
675 nread
= 0; /* init read offset */
676 h
= buf
; /* starting point */
678 if (XGetWindowProperty (dpy
,
679 DefaultRootWindow (dpy
),
681 nread
/4, 1024L, /* offset, length */
683 AnyPropertyType
, /* request 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 */
695 if (CF
.cur_input
== CF
.cur_input
->input
.next_input
) { /* 1 ip field */
696 process_regular_char_input((unsigned char *)" "); /* paste space */
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 */
705 /* change \n to \r for pasting */
706 process_tabtypes((unsigned char *)"\r");
709 process_regular_char_input(c
);
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
));
717 } while (bytes_after
> 0);
719 static void ToggleChoice (Item
*item
)
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
);
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) {
742 /* unfinished dje. */
743 /* If you ever finish this, please make sure to check the return code of
744 * XGetGeometry below. dv */
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;
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??
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
;