~ubuntu-branches/ubuntu/natty/ibm-3270/natty

« back to all changes in this revision

Viewing changes to ws3270/idle.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2009-12-14 11:48:53 UTC
  • mfrom: (1.1.4 upstream) (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091214114853-mywixml32hct9jr1
Tags: 3.3.10ga4-2
* Fix section to match override.
* Use debhelper compat level 7.
* Use 3.0 (quilt) source format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1993-2009, Paul Mattes.
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions are met:
 
7
 *     * Redistributions of source code must retain the above copyright
 
8
 *       notice, this list of conditions and the following disclaimer.
 
9
 *     * Redistributions in binary form must reproduce the above copyright
 
10
 *       notice, this list of conditions and the following disclaimer in the
 
11
 *       documentation and/or other materials provided with the distribution.
 
12
 *     * Neither the names of Paul Mattes nor the names of his contributors
 
13
 *       may be used to endorse or promote products derived from this software
 
14
 *       without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY PAUL MATTES "AS IS" AND ANY EXPRESS OR IMPLIED
 
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 
19
 * EVENT SHALL PAUL MATTES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
20
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
21
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
22
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
23
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
24
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
25
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
26
 */
 
27
 
 
28
/*
 
29
 *      idle.c
 
30
 *              This module handles the idle command.
 
31
 */
 
32
 
 
33
#include "globals.h"
 
34
 
 
35
#if defined(X3270_DISPLAY) || defined(C3270) /*[*/
 
36
 
 
37
#if defined(X3270_DISPLAY) /*[*/
 
38
#include <X11/StringDefs.h>
 
39
#include <X11/Xaw/Toggle.h>
 
40
#include <X11/Xaw/Command.h>
 
41
#include <X11/Xaw/Form.h>
 
42
#include <X11/Shell.h>
 
43
#include <X11/Xaw/AsciiText.h>
 
44
#include <X11/Xaw/TextSrc.h>
 
45
#include <X11/Xaw/TextSink.h>
 
46
#include <X11/Xaw/AsciiSrc.h>
 
47
#include <X11/Xaw/AsciiSink.h>
 
48
#endif /*]*/
 
49
#include <errno.h>
 
50
 
 
51
#include "appres.h"
 
52
#include "dialogc.h"
 
53
#include "hostc.h"
 
54
#include "idlec.h"
 
55
#include "macrosc.h"
 
56
#include "objects.h"
 
57
#include "popupsc.h"
 
58
#include "resources.h"
 
59
#include "trace_dsc.h"
 
60
#include "utilc.h"
 
61
 
 
62
/* Macros. */
 
63
#define MSEC_PER_SEC    1000L
 
64
#define IDLE_SEC        1L
 
65
#define IDLE_MIN        60L
 
66
#define IDLE_HR         (60L * 60L)
 
67
#define IDLE_MS         (7L * IDLE_MIN * MSEC_PER_SEC)
 
68
 
 
69
#if defined(X3270_DISPLAY) /*[*/
 
70
#define FILE_WIDTH      300     /* width of file name widgets */
 
71
#define MARGIN          3       /* distance from margins to widgets */
 
72
#define CLOSE_VGAP      0       /* distance between paired toggles */
 
73
#define FAR_VGAP        10      /* distance between single toggles and groups */
 
74
#define BUTTON_GAP      5       /* horizontal distance between buttons */
 
75
#endif /*]*/
 
76
 
 
77
#define BN      (Boolean *)NULL
 
78
 
 
79
/* Externals. */
 
80
#if defined(X3270_DISPLAY) && defined(X3270_MENUS) /*[*/
 
81
extern Pixmap diamond;
 
82
extern Pixmap no_diamond;
 
83
extern Pixmap dot;
 
84
extern Pixmap no_dot;
 
85
#endif /*]*/
 
86
 
 
87
/* Globals. */
 
88
Boolean idle_changed = False;
 
89
char *idle_command = CN;
 
90
char *idle_timeout_string = CN;
 
91
enum idle_enum idle_user_enabled = IDLE_DISABLED;
 
92
 
 
93
/* Statics. */
 
94
static Boolean idle_enabled = False;    /* validated and user-enabled */
 
95
static unsigned long idle_n = 0L;
 
96
static unsigned long idle_multiplier = IDLE_SEC;
 
97
static unsigned long idle_id;
 
98
static unsigned long idle_ms;
 
99
static Boolean idle_randomize = False;
 
100
static Boolean idle_ticking = False;
 
101
 
 
102
static void idle_in3270(Boolean in3270);
 
103
static int process_timeout_value(char *t);
 
104
 
 
105
#if defined(X3270_DISPLAY) && defined(X3270_MENUS) /*[*/
 
106
static enum idle_enum s_disabled = IDLE_DISABLED;
 
107
static enum idle_enum s_session = IDLE_SESSION;
 
108
static enum idle_enum s_perm = IDLE_PERM;
 
109
static char hms = 'm';
 
110
static Boolean fuzz = False;
 
111
static char s_hours = 'h';
 
112
static char s_minutes = 'm';
 
113
static char s_seconds = 's';
 
114
static Widget idle_dialog, idle_shell, command_value, timeout_value;
 
115
static Widget enable_toggle, enable_perm_toggle, disable_toggle;
 
116
static Widget hours_toggle, minutes_toggle, seconds_toggle, fuzz_toggle;
 
117
static sr_t *idle_sr = (sr_t *)NULL;
 
118
 
 
119
static void idle_cancel(Widget w, XtPointer client_data, XtPointer call_data);
 
120
static void idle_popup_callback(Widget w, XtPointer client_data,
 
121
    XtPointer call_data);
 
122
static void idle_popup_init(void);
 
123
static int idle_start(void);
 
124
static void okay_callback(Widget w, XtPointer call_parms,
 
125
    XtPointer call_data);
 
126
static void toggle_enable(Widget w, XtPointer client_data,
 
127
    XtPointer call_data);
 
128
static void mark_toggle(Widget w, Pixmap p);
 
129
static void toggle_hms(Widget w, XtPointer client_data,
 
130
    XtPointer call_data);
 
131
static void toggle_fuzz(Widget w, XtPointer client_data,
 
132
    XtPointer call_data);
 
133
#endif /*]*/
 
134
 
 
135
/* Initialization. */
 
136
void
 
137
idle_init(void)
 
138
{
 
139
        char *cmd, *tmo;
 
140
 
 
141
        /* Register for state changes. */
 
142
        register_schange(ST_3270_MODE, idle_in3270);
 
143
        register_schange(ST_CONNECT, idle_in3270);
 
144
 
 
145
        /* Get values from resources. */
 
146
        cmd = appres.idle_command;
 
147
        idle_command = cmd? NewString(cmd): CN;
 
148
        tmo = appres.idle_timeout;
 
149
        idle_timeout_string = tmo? NewString(tmo): CN;
 
150
        if (appres.idle_command_enabled)
 
151
                idle_user_enabled = IDLE_PERM;
 
152
        else
 
153
                idle_user_enabled = IDLE_DISABLED;
 
154
        if (idle_user_enabled &&
 
155
            idle_command != CN &&
 
156
            process_timeout_value(idle_timeout_string) == 0)
 
157
                idle_enabled = True;
 
158
 
 
159
        /* Seed the random number generator (we seem to be the only user). */
 
160
#if defined(_WIN32) /*[*/
 
161
        srand(time(NULL));
 
162
#else /*][*/
 
163
        srandom(time(NULL));
 
164
#endif /*]*/
 
165
}
 
166
 
 
167
/*
 
168
 * Process a timeout value: <empty> or ~?[0-9]+[HhMmSs]
 
169
 * Returns 0 for success, -1 for failure.
 
170
 * Sets idle_ms and idle_randomize as side-effects.
 
171
 */
 
172
static int
 
173
process_timeout_value(char *t)
 
174
{
 
175
        char *s = t;
 
176
        char *ptr;
 
177
 
 
178
        if (s == CN || *s == '\0') {
 
179
                idle_ms = IDLE_MS;
 
180
                idle_randomize = True;
 
181
                return 0;
 
182
        }
 
183
 
 
184
        if (*s == '~') {
 
185
                idle_randomize = True;
 
186
                s++;
 
187
        }
 
188
        idle_n = strtoul(s, &ptr, 0);
 
189
        if (idle_n <= 0)
 
190
                goto bad_idle;
 
191
        switch (*ptr) {
 
192
            case 'H':
 
193
            case 'h':
 
194
                idle_multiplier = IDLE_HR;
 
195
                break;
 
196
            case 'M':
 
197
            case 'm':
 
198
                idle_multiplier = IDLE_MIN;
 
199
                break;
 
200
            case 'S':
 
201
            case 's':
 
202
            case '\0':
 
203
                idle_multiplier = IDLE_SEC;
 
204
                break;
 
205
            default:
 
206
                goto bad_idle;
 
207
        }
 
208
        idle_ms = idle_n * idle_multiplier * MSEC_PER_SEC;
 
209
        return 0;
 
210
 
 
211
    bad_idle:
 
212
        popup_an_error("Invalid idle timeout value '%s'", t);
 
213
        idle_ms = 0L;
 
214
        idle_randomize = False;
 
215
        return -1;
 
216
}
 
217
 
 
218
/* Called when a host connects or disconnects. */
 
219
static void
 
220
idle_in3270(Boolean in3270 _is_unused)
 
221
{
 
222
        if (IN_3270) {
 
223
                reset_idle_timer();
 
224
        } else {
 
225
                /* Not in 3270 mode any more, turn off the timeout. */
 
226
                if (idle_ticking) {
 
227
                        RemoveTimeOut(idle_id);
 
228
                        idle_ticking = False;
 
229
                }
 
230
 
 
231
                /* If the user didn't want it to be permanent, disable it. */
 
232
                if (idle_user_enabled != IDLE_PERM)
 
233
                        idle_user_enabled = IDLE_DISABLED;
 
234
        }
 
235
}
 
236
 
 
237
/*
 
238
 * Idle timeout.
 
239
 */
 
240
static void
 
241
idle_timeout(void)
 
242
{
 
243
        trace_event("Idle timeout\n");
 
244
        idle_ticking = False;
 
245
        push_idle(idle_command);
 
246
        reset_idle_timer();
 
247
}
 
248
 
 
249
/*
 
250
 * Reset (and re-enable) the idle timer.  Called when the user presses a key or
 
251
 * clicks with the mouse.
 
252
 */
 
253
void
 
254
reset_idle_timer(void)
 
255
{
 
256
        if (idle_enabled) {
 
257
                unsigned long idle_ms_now;
 
258
 
 
259
                if (idle_ticking) {
 
260
                        RemoveTimeOut(idle_id);
 
261
                        idle_ticking = False;
 
262
                }
 
263
                idle_ms_now = idle_ms;
 
264
                if (idle_randomize) {
 
265
                        idle_ms_now = idle_ms;
 
266
#if defined(_WIN32) /*[*/
 
267
                        idle_ms_now -= rand() % (idle_ms / 10L);
 
268
#else /*][*/
 
269
                        idle_ms_now -= random() % (idle_ms / 10L);
 
270
#endif /*]*/
 
271
                }
 
272
#if defined(DEBUG_IDLE_TIMEOUT) /*[*/
 
273
                trace_event("Setting idle timeout to %lu\n", idle_ms_now);
 
274
#endif /*]*/
 
275
                idle_id = AddTimeOut(idle_ms_now, idle_timeout);
 
276
                idle_ticking = True;
 
277
        }
 
278
}
 
279
 
 
280
/*
 
281
 * Cancel the idle timer.  This is called when there is an error in
 
282
 * processing the idle command.
 
283
 */
 
284
void
 
285
cancel_idle_timer(void)
 
286
{
 
287
        if (idle_ticking) {
 
288
                RemoveTimeOut(idle_id);
 
289
                idle_ticking = False;
 
290
        }
 
291
        idle_enabled = False;
 
292
}
 
293
 
 
294
char *
 
295
get_idle_command(void)
 
296
{
 
297
        return idle_command;
 
298
}
 
299
 
 
300
char *
 
301
get_idle_timeout(void)
 
302
{
 
303
        return idle_timeout_string;
 
304
}
 
305
 
 
306
#if defined(X3270_DISPLAY) && defined(X3270_MENUS) /*[*/
 
307
/* "Idle Command" dialog. */
 
308
 
 
309
/*
 
310
 * Pop up the "Idle" menu.
 
311
 * Called back from the "Configure Idle Command" option on the Options menu.
 
312
 */
 
313
void
 
314
popup_idle(void)
 
315
{
 
316
        char *its;
 
317
        char *s;
 
318
 
 
319
        /* Initialize it. */
 
320
        if (idle_shell == (Widget)NULL)
 
321
                idle_popup_init();
 
322
 
 
323
        /*
 
324
         * Split the idle_timeout_string (the raw resource value) into fuzz,
 
325
         * a number, and h/m/s.
 
326
         */
 
327
        its = NewString(idle_timeout_string);
 
328
        if (its != CN) {
 
329
                if (*its == '~') {
 
330
                        fuzz = True;
 
331
                        its++;
 
332
                } else {
 
333
                        fuzz = False;
 
334
                }
 
335
                s = its;
 
336
                while (isdigit(*s))
 
337
                        s++;
 
338
                switch (*s) {
 
339
                case 'h':
 
340
                case 'H':
 
341
                        hms = 'h';
 
342
                        break;
 
343
                case 'm':
 
344
                case 'M':
 
345
                        hms = 'm';
 
346
                        break;
 
347
                case 's':
 
348
                case 'S':
 
349
                        hms = 's';
 
350
                        break;
 
351
                default:
 
352
                        break;
 
353
                }
 
354
                *s = '\0';
 
355
        }
 
356
 
 
357
        /* Set the resource values. */
 
358
        dialog_set(&idle_sr, idle_dialog);
 
359
        XtVaSetValues(command_value,
 
360
            XtNstring, idle_command,
 
361
            NULL);
 
362
        XtVaSetValues(timeout_value, XtNstring, its, NULL);
 
363
        mark_toggle(enable_toggle, (idle_user_enabled == IDLE_SESSION)?
 
364
                        diamond : no_diamond);
 
365
        mark_toggle(enable_perm_toggle, (idle_user_enabled == IDLE_PERM)?
 
366
                        diamond : no_diamond);
 
367
        mark_toggle(disable_toggle, (idle_user_enabled == IDLE_DISABLED)?
 
368
                        diamond : no_diamond);
 
369
        mark_toggle(hours_toggle, (hms == 'h') ? diamond : no_diamond);
 
370
        mark_toggle(minutes_toggle, (hms == 'm') ? diamond : no_diamond);
 
371
        mark_toggle(seconds_toggle, (hms == 's') ? diamond : no_diamond);
 
372
        mark_toggle(fuzz_toggle, fuzz ? dot : no_dot);
 
373
 
 
374
        /* Pop it up. */
 
375
        popup_popup(idle_shell, XtGrabNone);
 
376
}
 
377
 
 
378
/* Initialize the idle pop-up. */
 
379
static void
 
380
idle_popup_init(void)
 
381
{
 
382
        Widget w;
 
383
        Widget cancel_button;
 
384
        Widget command_label, timeout_label;
 
385
        Widget okay_button;
 
386
 
 
387
        /* Prime the dialog functions. */
 
388
        dialog_set(&idle_sr, idle_dialog);
 
389
 
 
390
        /* Create the menu shell. */
 
391
        idle_shell = XtVaCreatePopupShell(
 
392
            "idlePopup", transientShellWidgetClass, toplevel,
 
393
            NULL);
 
394
        XtAddCallback(idle_shell, XtNpopupCallback, place_popup,
 
395
            (XtPointer)CenterP);
 
396
        XtAddCallback(idle_shell, XtNpopupCallback, idle_popup_callback,
 
397
            (XtPointer)NULL);
 
398
 
 
399
        /* Create the form within the shell. */
 
400
        idle_dialog = XtVaCreateManagedWidget(
 
401
            ObjDialog, formWidgetClass, idle_shell,
 
402
            NULL);
 
403
 
 
404
        /* Create the file name widgets. */
 
405
        command_label = XtVaCreateManagedWidget(
 
406
            "command", labelWidgetClass, idle_dialog,
 
407
            XtNvertDistance, FAR_VGAP,
 
408
            XtNhorizDistance, MARGIN,
 
409
            XtNborderWidth, 0,
 
410
            NULL);
 
411
        command_value = XtVaCreateManagedWidget(
 
412
            "value", asciiTextWidgetClass, idle_dialog,
 
413
            XtNeditType, XawtextEdit,
 
414
            XtNwidth, FILE_WIDTH,
 
415
            XtNvertDistance, FAR_VGAP,
 
416
            XtNfromHoriz, command_label,
 
417
            XtNhorizDistance, 0,
 
418
            NULL);
 
419
        dialog_match_dimension(command_label, command_value, XtNheight);
 
420
        w = XawTextGetSource(command_value);
 
421
        if (w == NULL)
 
422
                XtWarning("Cannot find text source in dialog");
 
423
        else
 
424
                XtAddCallback(w, XtNcallback, dialog_text_callback,
 
425
                    (XtPointer)&t_command);
 
426
        dialog_register_sensitivity(command_value,
 
427
            BN, False,
 
428
            BN, False,
 
429
            BN, False);
 
430
 
 
431
        timeout_label = XtVaCreateManagedWidget(
 
432
            "timeout", labelWidgetClass, idle_dialog,
 
433
            XtNfromVert, command_label,
 
434
            XtNvertDistance, 3,
 
435
            XtNhorizDistance, MARGIN,
 
436
            XtNborderWidth, 0,
 
437
            NULL);
 
438
        timeout_value = XtVaCreateManagedWidget(
 
439
            "value", asciiTextWidgetClass, idle_dialog,
 
440
            XtNeditType, XawtextEdit,
 
441
            XtNwidth, FILE_WIDTH,
 
442
            XtNdisplayCaret, False,
 
443
            XtNfromVert, command_label,
 
444
            XtNvertDistance, 3,
 
445
            XtNfromHoriz, timeout_label,
 
446
            XtNhorizDistance, 0,
 
447
            NULL);
 
448
        dialog_match_dimension(timeout_label, timeout_value, XtNheight);
 
449
        dialog_match_dimension(command_label, timeout_label, XtNwidth);
 
450
        w = XawTextGetSource(timeout_value);
 
451
        if (w == NULL)
 
452
                XtWarning("Cannot find text source in dialog");
 
453
        else
 
454
                XtAddCallback(w, XtNcallback, dialog_text_callback,
 
455
                    (XtPointer)&t_numeric);
 
456
        dialog_register_sensitivity(timeout_value,
 
457
            BN, False,
 
458
            BN, False,
 
459
            BN, False);
 
460
 
 
461
        /* Create the hour/minute/seconds radio buttons. */
 
462
        hours_toggle = XtVaCreateManagedWidget(
 
463
            "hours", commandWidgetClass, idle_dialog,
 
464
            XtNfromVert, timeout_value,
 
465
            XtNvertDistance, CLOSE_VGAP,
 
466
            XtNhorizDistance, MARGIN,
 
467
            XtNborderWidth, 0,
 
468
            XtNsensitive, True,
 
469
            NULL);
 
470
        dialog_apply_bitmap(hours_toggle, no_diamond);
 
471
        XtAddCallback(hours_toggle, XtNcallback, toggle_hms,
 
472
                        (XtPointer)&s_hours);
 
473
        minutes_toggle = XtVaCreateManagedWidget(
 
474
            "minutes", commandWidgetClass, idle_dialog,
 
475
            XtNfromVert, timeout_value,
 
476
            XtNvertDistance, CLOSE_VGAP,
 
477
            XtNfromHoriz, hours_toggle,
 
478
            XtNhorizDistance, MARGIN,
 
479
            XtNborderWidth, 0,
 
480
            XtNsensitive, True,
 
481
            NULL);
 
482
        dialog_apply_bitmap(minutes_toggle, diamond);
 
483
        XtAddCallback(minutes_toggle, XtNcallback, toggle_hms,
 
484
                        (XtPointer)&s_minutes);
 
485
        seconds_toggle = XtVaCreateManagedWidget(
 
486
            "seconds", commandWidgetClass, idle_dialog,
 
487
            XtNfromVert, timeout_value,
 
488
            XtNvertDistance, CLOSE_VGAP,
 
489
            XtNfromHoriz, minutes_toggle,
 
490
            XtNhorizDistance, MARGIN,
 
491
            XtNborderWidth, 0,
 
492
            XtNsensitive, True,
 
493
            NULL);
 
494
        dialog_apply_bitmap(seconds_toggle, no_diamond);
 
495
        XtAddCallback(seconds_toggle, XtNcallback, toggle_hms,
 
496
                        (XtPointer)&s_seconds);
 
497
 
 
498
        /* Create the fuzz toggle. */
 
499
        fuzz_toggle = XtVaCreateManagedWidget(
 
500
            "fuzz", commandWidgetClass, idle_dialog,
 
501
            XtNfromVert, hours_toggle,
 
502
            XtNvertDistance, CLOSE_VGAP,
 
503
            XtNhorizDistance, MARGIN,
 
504
            XtNborderWidth, 0,
 
505
            XtNsensitive, True,
 
506
            NULL);
 
507
        dialog_apply_bitmap(fuzz_toggle, no_dot);
 
508
        XtAddCallback(fuzz_toggle, XtNcallback, toggle_fuzz, (XtPointer)NULL);
 
509
 
 
510
        /* Create enable/disable toggles. */
 
511
        enable_toggle = XtVaCreateManagedWidget(
 
512
            "enable", commandWidgetClass, idle_dialog,
 
513
            XtNfromVert, fuzz_toggle,
 
514
            XtNvertDistance, FAR_VGAP,
 
515
            XtNhorizDistance, MARGIN,
 
516
            XtNborderWidth, 0,
 
517
            NULL);
 
518
        dialog_apply_bitmap(enable_toggle,
 
519
                        (idle_user_enabled == IDLE_SESSION)?
 
520
                            diamond : no_diamond);
 
521
        XtAddCallback(enable_toggle, XtNcallback, toggle_enable,
 
522
            (XtPointer)&s_session);
 
523
        enable_perm_toggle = XtVaCreateManagedWidget(
 
524
            "enablePerm", commandWidgetClass, idle_dialog,
 
525
            XtNfromVert, enable_toggle,
 
526
            XtNvertDistance, CLOSE_VGAP,
 
527
            XtNhorizDistance, MARGIN,
 
528
            XtNborderWidth, 0,
 
529
            NULL);
 
530
        dialog_apply_bitmap(enable_perm_toggle,
 
531
                        (idle_user_enabled == IDLE_PERM)?
 
532
                            diamond : no_diamond);
 
533
        XtAddCallback(enable_perm_toggle, XtNcallback, toggle_enable,
 
534
            (XtPointer)&s_perm);
 
535
        disable_toggle = XtVaCreateManagedWidget(
 
536
            "disable", commandWidgetClass, idle_dialog,
 
537
            XtNfromVert, enable_perm_toggle,
 
538
            XtNvertDistance, CLOSE_VGAP,
 
539
            XtNhorizDistance, MARGIN,
 
540
            XtNborderWidth, 0,
 
541
            NULL);
 
542
        dialog_apply_bitmap(disable_toggle,
 
543
                        (idle_user_enabled == IDLE_DISABLED)?
 
544
                            diamond : no_diamond);
 
545
        XtAddCallback(disable_toggle, XtNcallback, toggle_enable,
 
546
            (XtPointer)&s_disabled);
 
547
 
 
548
        /* Set up the buttons at the bottom. */
 
549
        okay_button = XtVaCreateManagedWidget(
 
550
            ObjConfirmButton, commandWidgetClass, idle_dialog,
 
551
            XtNfromVert, disable_toggle,
 
552
            XtNvertDistance, FAR_VGAP,
 
553
            XtNhorizDistance, MARGIN,
 
554
            NULL);
 
555
        XtAddCallback(okay_button, XtNcallback, okay_callback,
 
556
            (XtPointer)NULL);
 
557
 
 
558
        cancel_button = XtVaCreateManagedWidget(
 
559
            ObjCancelButton, commandWidgetClass, idle_dialog,
 
560
            XtNfromVert, disable_toggle,
 
561
            XtNvertDistance, FAR_VGAP,
 
562
            XtNfromHoriz, okay_button,
 
563
            XtNhorizDistance, BUTTON_GAP,
 
564
            NULL);
 
565
        XtAddCallback(cancel_button, XtNcallback, idle_cancel, 0);
 
566
}
 
567
 
 
568
/* Callbacks for all the idle widgets. */
 
569
 
 
570
/* Idle pop-up popping up. */
 
571
static void
 
572
idle_popup_callback(Widget w _is_unused, XtPointer client_data _is_unused,
 
573
        XtPointer call_data _is_unused)
 
574
{
 
575
        /* Set the focus to the command widget. */
 
576
        PA_dialog_focus_action(command_value, (XEvent *)NULL, (String *)NULL,
 
577
            (Cardinal *)NULL);
 
578
}
 
579
 
 
580
/* Cancel button pushed. */
 
581
static void
 
582
idle_cancel(Widget w _is_unused, XtPointer client_data _is_unused,
 
583
        XtPointer call_data _is_unused)
 
584
{
 
585
        XtPopdown(idle_shell);
 
586
}
 
587
 
 
588
/* OK button pushed. */
 
589
static void
 
590
okay_callback(Widget w _is_unused, XtPointer call_parms _is_unused,
 
591
        XtPointer call_data _is_unused)
 
592
{
 
593
        if (idle_start() == 0) {
 
594
                idle_changed = True;
 
595
                XtPopdown(idle_shell);
 
596
        }
 
597
}
 
598
 
 
599
/* Mark a toggle. */
 
600
static void
 
601
mark_toggle(Widget w, Pixmap p)
 
602
{
 
603
        XtVaSetValues(w, XtNleftBitmap, p, NULL);
 
604
}
 
605
 
 
606
/* Hour/minute/second options. */
 
607
static void
 
608
toggle_hms(Widget w _is_unused, XtPointer client_data,
 
609
        XtPointer call_data _is_unused)
 
610
{
 
611
        /* Toggle the flag */
 
612
        hms = *(char *)client_data;
 
613
 
 
614
        /* Change the widget states. */
 
615
        mark_toggle(hours_toggle, (hms == 'h') ? diamond : no_diamond);
 
616
        mark_toggle(minutes_toggle, (hms == 'm') ? diamond : no_diamond);
 
617
        mark_toggle(seconds_toggle, (hms == 's') ? diamond : no_diamond);
 
618
}
 
619
 
 
620
/* Fuzz option. */
 
621
static void
 
622
toggle_fuzz(Widget w _is_unused, XtPointer client_data,
 
623
        XtPointer call_data _is_unused)
 
624
{
 
625
        /* Toggle the flag */
 
626
        fuzz = !fuzz;
 
627
 
 
628
        /* Change the widget state. */
 
629
        mark_toggle(fuzz_toggle, fuzz ? dot : no_dot);
 
630
}
 
631
 
 
632
/* Enable/disable options. */
 
633
static void
 
634
toggle_enable(Widget w _is_unused, XtPointer client_data,
 
635
        XtPointer call_data _is_unused)
 
636
{
 
637
        /* Toggle the flag */
 
638
        idle_user_enabled = *(enum idle_enum *)client_data;
 
639
 
 
640
        /* Change the widget states. */
 
641
        mark_toggle(enable_toggle,
 
642
                        (idle_user_enabled == IDLE_SESSION)?
 
643
                            diamond: no_diamond);
 
644
        mark_toggle(enable_perm_toggle,
 
645
                        (idle_user_enabled == IDLE_PERM)?
 
646
                            diamond: no_diamond);
 
647
        mark_toggle(disable_toggle,
 
648
                        (idle_user_enabled == IDLE_DISABLED)?
 
649
                            diamond: no_diamond);
 
650
}
 
651
 
 
652
/*
 
653
 * Called when the user presses the OK button on the idle command dialog.
 
654
 * Returns 0 for success, -1 otherwise.
 
655
 */
 
656
static int
 
657
idle_start(void)
 
658
{
 
659
        char *cmd, *tmo, *its;
 
660
 
 
661
        /* Update the globals, so the dialog has the same values next time. */
 
662
        XtVaGetValues(command_value, XtNstring, &cmd, NULL);
 
663
        Replace(idle_command, NewString(cmd));
 
664
        XtVaGetValues(timeout_value, XtNstring, &tmo, NULL);
 
665
        its = Malloc(strlen(tmo) + 3);
 
666
        (void) sprintf(its, "%s%s%c", fuzz? "~": "", tmo, hms);
 
667
        Replace(idle_timeout_string, its);
 
668
 
 
669
        /* See if they've turned it off. */
 
670
        if (!idle_user_enabled) {
 
671
                /* If they're turned it off, cancel the timer. */
 
672
                idle_enabled = False;
 
673
                if (idle_ticking) {
 
674
                        RemoveTimeOut(idle_id);
 
675
                        idle_ticking = False;
 
676
                }
 
677
                return 0;
 
678
        }
 
679
 
 
680
        /* They've turned it on, and possibly reconfigured it. */
 
681
 
 
682
        /* Validate the timeout.  It should work, yes? */
 
683
        if (process_timeout_value(its) < 0) {
 
684
                return -1;
 
685
        }
 
686
 
 
687
        /* Seems okay.  Reset to the new interval and command. */
 
688
        idle_enabled = True;
 
689
        if (IN_3270) {
 
690
                reset_idle_timer();
 
691
        }
 
692
        return 0;
 
693
}
 
694
 
 
695
#endif /*]*/
 
696
 
 
697
#endif /*]*/