This source file includes following definitions.
- dlg_default_get_colors
- dlg_read_history
- refresh_cmd
- dlg_help
- dlg_execute_cmd
- dlg_handle_key
- dlg_key_event
- dlg_handle_mouse_event
- frontend_dlg_run
- dlg_default_destroy
- dlg_default_callback
- dlg_default_mouse_callback
- dlg_create
- dlg_set_default_colors
- dlg_close
- dlg_init
- dlg_process_event
- dlg_run_done
- dlg_run
- dlg_save_history
- dlg_get_title
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include <config.h>
28
29 #include <ctype.h>
30 #include <errno.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36
37 #include "lib/global.h"
38
39 #include "lib/tty/tty.h"
40 #include "lib/skin.h"
41 #include "lib/tty/key.h"
42 #include "lib/strutil.h"
43 #include "lib/fileloc.h"
44 #include "lib/event.h"
45 #include "lib/util.h"
46 #include "lib/mcconfig.h"
47
48 #include "lib/widget.h"
49 #include "lib/widget/mouse.h"
50
51
52
53
54 dlg_colors_t dialog_colors;
55 dlg_colors_t alarm_colors;
56 dlg_colors_t listbox_colors;
57 dlg_colors_t help_colors;
58
59
60 hook_t *idle_hook = NULL;
61
62
63 gboolean mouse_close_dialog = FALSE;
64
65 const global_keymap_t *dialog_map = NULL;
66
67
68
69
70
71
72
73
74
75
76
77
78
79 static const int *
80 dlg_default_get_colors (const Widget *w)
81 {
82 return CONST_DIALOG (w)->colors;
83 }
84
85
86
87
88
89 static void
90 dlg_read_history (WDialog *h)
91 {
92 char *profile;
93 ev_history_load_save_t event_data;
94
95 if (num_history_items_recorded == 0)
96 return;
97
98 profile = mc_config_get_full_path (MC_HISTORY_FILE);
99 event_data.cfg = mc_config_init (profile, TRUE);
100 event_data.receiver = NULL;
101
102
103 mc_event_raise (h->event_group, MCEVENT_HISTORY_LOAD, &event_data);
104
105 mc_config_deinit (event_data.cfg);
106 g_free (profile);
107 }
108
109
110
111 static void
112 refresh_cmd (void)
113 {
114 #ifdef HAVE_SLANG
115 tty_touch_screen ();
116 mc_refresh ();
117 #else
118
119 tty_clear_screen ();
120 repaint_screen ();
121 #endif
122 }
123
124
125
126 static void
127 dlg_help (const WDialog *h)
128 {
129 ev_help_t event_data = { NULL, h->help_ctx };
130
131 mc_event_raise (MCEVENT_GROUP_CORE, "help", &event_data);
132 }
133
134
135
136 static cb_ret_t
137 dlg_execute_cmd (WDialog *h, long command)
138 {
139 WGroup *g = GROUP (h);
140 cb_ret_t ret = MSG_HANDLED;
141
142 if (send_message (h, NULL, MSG_ACTION, command, NULL) == MSG_HANDLED)
143 return MSG_HANDLED;
144
145 switch (command)
146 {
147 case CK_Ok:
148 h->ret_value = B_ENTER;
149 dlg_close (h);
150 break;
151 case CK_Cancel:
152 h->ret_value = B_CANCEL;
153 dlg_close (h);
154 break;
155
156 case CK_Up:
157 case CK_Left:
158 group_select_prev_widget (g);
159 break;
160 case CK_Down:
161 case CK_Right:
162 group_select_next_widget (g);
163 break;
164
165 case CK_Help:
166 dlg_help (h);
167 break;
168
169 case CK_Suspend:
170 mc_event_raise (MCEVENT_GROUP_CORE, "suspend", NULL);
171 refresh_cmd ();
172 break;
173 case CK_Refresh:
174 refresh_cmd ();
175 break;
176
177 case CK_ScreenList:
178 if (!widget_get_state (WIDGET (h), WST_MODAL))
179 dialog_switch_list ();
180 else
181 ret = MSG_NOT_HANDLED;
182 break;
183 case CK_ScreenNext:
184 if (!widget_get_state (WIDGET (h), WST_MODAL))
185 dialog_switch_next ();
186 else
187 ret = MSG_NOT_HANDLED;
188 break;
189 case CK_ScreenPrev:
190 if (!widget_get_state (WIDGET (h), WST_MODAL))
191 dialog_switch_prev ();
192 else
193 ret = MSG_NOT_HANDLED;
194 break;
195
196 default:
197 ret = MSG_NOT_HANDLED;
198 }
199
200 return ret;
201 }
202
203
204
205 static cb_ret_t
206 dlg_handle_key (WDialog *h, int d_key)
207 {
208 long command;
209
210 command = widget_lookup_key (WIDGET (h), d_key);
211 if (command == CK_IgnoreKey)
212 command = keybind_lookup_keymap_command (dialog_map, d_key);
213 if (command != CK_IgnoreKey)
214 return dlg_execute_cmd (h, command);
215
216 return MSG_NOT_HANDLED;
217 }
218
219
220
221 static void
222 dlg_key_event (WDialog *h, int d_key)
223 {
224 Widget *w = WIDGET (h);
225 WGroup *g = GROUP (h);
226 cb_ret_t handled;
227
228 if (g->widgets == NULL)
229 return;
230
231 if (g->current == NULL)
232 g->current = g->widgets;
233
234
235 if (!widget_get_options (w, WOP_WANT_TAB))
236 {
237 if (d_key == '\t')
238 {
239 group_select_next_widget (g);
240 return;
241 }
242 else if ((d_key & ~(KEY_M_SHIFT | KEY_M_CTRL)) == '\t')
243 {
244 group_select_prev_widget (g);
245 return;
246 }
247 }
248
249
250 handled = send_message (h, NULL, MSG_KEY, d_key, NULL);
251
252 if (handled == MSG_NOT_HANDLED)
253 handled = group_default_callback (w, NULL, MSG_KEY, d_key, NULL);
254
255 if (handled == MSG_NOT_HANDLED)
256 handled = dlg_handle_key (h, d_key);
257
258 (void) handled;
259 send_message (h, NULL, MSG_POST_KEY, d_key, NULL);
260 }
261
262
263
264 static int
265 dlg_handle_mouse_event (Widget *w, Gpm_Event *event)
266 {
267 if (w->mouse_callback != NULL)
268 {
269 int mou;
270
271 mou = mouse_handle_event (w, event);
272 if (mou != MOU_UNHANDLED)
273 return mou;
274 }
275
276 return group_handle_mouse_event (w, event);
277 }
278
279
280
281 static void
282 frontend_dlg_run (WDialog *h)
283 {
284 Widget *wh = WIDGET (h);
285 Gpm_Event event;
286
287 event.x = -1;
288
289
290 if (!widget_get_state (wh, WST_MODAL) && mc_global.midnight_shutdown)
291 {
292 send_message (h, NULL, MSG_VALIDATE, 0, NULL);
293 return;
294 }
295
296 while (widget_get_state (wh, WST_ACTIVE))
297 {
298 int d_key;
299
300 if (tty_got_winch ())
301 dialog_change_screen_size ();
302
303 if (is_idle ())
304 {
305 if (idle_hook)
306 execute_hooks (idle_hook);
307
308 while (widget_get_state (wh, WST_IDLE) && is_idle ())
309 send_message (wh, NULL, MSG_IDLE, 0, NULL);
310
311
312 if (!widget_get_state (wh, WST_ACTIVE))
313 break;
314 }
315
316 widget_update_cursor (wh);
317
318
319 tty_got_interrupt ();
320 d_key = tty_get_event (&event, GROUP (h)->mouse_status == MOU_REPEAT, TRUE);
321
322 dlg_process_event (h, d_key, &event);
323
324 if (widget_get_state (wh, WST_CLOSED))
325 send_message (h, NULL, MSG_VALIDATE, 0, NULL);
326 }
327 }
328
329
330
331 static void
332 dlg_default_destroy (Widget *w)
333 {
334 WDialog *h = DIALOG (w);
335
336
337 dlg_save_history (h);
338 group_default_callback (w, NULL, MSG_DESTROY, 0, NULL);
339 send_message (w, NULL, MSG_DESTROY, 0, NULL);
340 mc_event_group_del (h->event_group);
341 g_free (h->event_group);
342 g_free (h);
343
344 do_refresh ();
345 }
346
347
348
349
350
351
352 cb_ret_t
353 dlg_default_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
354 {
355 switch (msg)
356 {
357 case MSG_INIT:
358
359 return MSG_HANDLED;
360
361 case MSG_IDLE:
362
363 widget_idle (w, FALSE);
364 return MSG_HANDLED;
365
366 case MSG_DESTROY:
367
368 return MSG_HANDLED;
369
370 default:
371 return group_default_callback (w, sender, msg, parm, data);
372 }
373 }
374
375
376
377 void
378 dlg_default_mouse_callback (Widget *w, mouse_msg_t msg, mouse_event_t *event)
379 {
380 switch (msg)
381 {
382 case MSG_MOUSE_CLICK:
383 if (event->y < 0 || event->y >= w->rect.lines || event->x < 0 || event->x >= w->rect.cols)
384 {
385 DIALOG (w)->ret_value = B_CANCEL;
386 dlg_close (DIALOG (w));
387 }
388 break;
389
390 default:
391
392 event->result.abort = TRUE;
393 break;
394 }
395 }
396
397
398
399 WDialog *
400 dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flags_t pos_flags,
401 gboolean compact, const int *colors, widget_cb_fn callback,
402 widget_mouse_cb_fn mouse_callback, const char *help_ctx, const char *title)
403 {
404 WRect r = { y1, x1, lines, cols };
405 WDialog *new_d;
406 Widget *w;
407 WGroup *g;
408
409 new_d = g_new0 (WDialog, 1);
410 w = WIDGET (new_d);
411 g = GROUP (new_d);
412 widget_adjust_position (pos_flags, &r);
413 group_init (g, &r, callback != NULL ? callback : dlg_default_callback,
414 mouse_callback != NULL ? mouse_callback : dlg_default_mouse_callback);
415
416 w->pos_flags = pos_flags;
417 w->options |= WOP_SELECTABLE | WOP_TOP_SELECT;
418 w->state |= WST_FOCUSED;
419
420 w->owner = g;
421
422 w->keymap = dialog_map;
423
424 w->mouse_handler = dlg_handle_mouse_event;
425 w->mouse.forced_capture = mouse_close_dialog && (w->pos_flags & WPOS_FULLSCREEN) == 0;
426
427 w->destroy = dlg_default_destroy;
428 w->get_colors = dlg_default_get_colors;
429
430 new_d->colors = colors;
431 new_d->help_ctx = help_ctx;
432 new_d->compact = compact;
433 new_d->data.p = NULL;
434
435 if (modal)
436 {
437 w->state |= WST_MODAL;
438
439 new_d->bg =
440 WIDGET (frame_new (0, 0, w->rect.lines, w->rect.cols, title, FALSE, new_d->compact));
441 group_add_widget (g, new_d->bg);
442 frame_set_title (FRAME (new_d->bg), title);
443 }
444
445
446 new_d->event_group = g_strdup_printf ("%s_%p", MCEVENT_GROUP_DIALOG, (void *) new_d);
447
448 return new_d;
449 }
450
451
452
453 void
454 dlg_set_default_colors (void)
455 {
456 dialog_colors[DLG_COLOR_NORMAL] = COLOR_NORMAL;
457 dialog_colors[DLG_COLOR_FOCUS] = COLOR_FOCUS;
458 dialog_colors[DLG_COLOR_HOT_NORMAL] = COLOR_HOT_NORMAL;
459 dialog_colors[DLG_COLOR_HOT_FOCUS] = COLOR_HOT_FOCUS;
460 dialog_colors[DLG_COLOR_SELECTED_NORMAL] = COLOR_SELECTED_NORMAL;
461 dialog_colors[DLG_COLOR_SELECTED_FOCUS] = COLOR_SELECTED_FOCUS;
462 dialog_colors[DLG_COLOR_TITLE] = COLOR_TITLE;
463
464 alarm_colors[DLG_COLOR_NORMAL] = ERROR_COLOR;
465 alarm_colors[DLG_COLOR_FOCUS] = ERROR_FOCUS;
466 alarm_colors[DLG_COLOR_HOT_NORMAL] = ERROR_HOT_NORMAL;
467 alarm_colors[DLG_COLOR_HOT_FOCUS] = ERROR_HOT_FOCUS;
468 alarm_colors[DLG_COLOR_SELECTED_NORMAL] = ERROR_HOT_FOCUS;
469 alarm_colors[DLG_COLOR_SELECTED_FOCUS] = ERROR_FOCUS;
470 alarm_colors[DLG_COLOR_TITLE] = ERROR_TITLE;
471
472 listbox_colors[DLG_COLOR_NORMAL] = PMENU_ENTRY_COLOR;
473 listbox_colors[DLG_COLOR_FOCUS] = PMENU_SELECTED_COLOR;
474 listbox_colors[DLG_COLOR_HOT_NORMAL] = PMENU_ENTRY_COLOR;
475 listbox_colors[DLG_COLOR_HOT_FOCUS] = PMENU_SELECTED_COLOR;
476 listbox_colors[DLG_COLOR_SELECTED_NORMAL] = PMENU_SELECTED_COLOR;
477 listbox_colors[DLG_COLOR_SELECTED_FOCUS] = PMENU_SELECTED_COLOR;
478 listbox_colors[DLG_COLOR_TITLE] = PMENU_TITLE_COLOR;
479
480 help_colors[DLG_COLOR_NORMAL] = HELP_NORMAL_COLOR;
481 help_colors[DLG_COLOR_FOCUS] = 0;
482 help_colors[DLG_COLOR_HOT_NORMAL] = HELP_BOLD_COLOR;
483 help_colors[DLG_COLOR_HOT_FOCUS] = 0;
484 help_colors[DLG_COLOR_SELECTED_NORMAL] = 0;
485 help_colors[DLG_COLOR_SELECTED_FOCUS] = 0;
486 help_colors[DLG_COLOR_TITLE] = HELP_TITLE_COLOR;
487 }
488
489
490
491 void
492 dlg_close (WDialog *h)
493 {
494 widget_set_state (WIDGET (h), WST_CLOSED, TRUE);
495 }
496
497
498
499
500 void
501 dlg_init (WDialog *h)
502 {
503 WGroup *g = GROUP (h);
504 Widget *wh = WIDGET (h);
505
506 if (top_dlg != NULL && widget_get_state (WIDGET (top_dlg->data), WST_MODAL))
507 widget_set_state (wh, WST_MODAL, TRUE);
508
509
510 top_dlg = g_list_prepend (top_dlg, h);
511
512
513 if (widget_get_state (wh, WST_CONSTRUCT))
514 {
515 if (!widget_get_state (wh, WST_MODAL))
516 dialog_switch_add (h);
517
518 send_message (h, NULL, MSG_INIT, 0, NULL);
519 group_default_callback (wh, NULL, MSG_INIT, 0, NULL);
520 dlg_read_history (h);
521 }
522
523
524 while (g->current != NULL && !widget_is_focusable (g->current->data))
525 group_set_current_widget_next (g);
526
527 widget_set_state (wh, WST_ACTIVE, TRUE);
528 widget_draw (wh);
529
530 h->ret_value = 0;
531 }
532
533
534
535 void
536 dlg_process_event (WDialog *h, int key, Gpm_Event *event)
537 {
538 switch (key)
539 {
540 case EV_NONE:
541 if (tty_got_interrupt ())
542 dlg_execute_cmd (h, CK_Cancel);
543 break;
544
545 case EV_MOUSE:
546 {
547 Widget *w = WIDGET (h);
548
549 GROUP (h)->mouse_status = w->mouse_handler (w, event);
550 break;
551 }
552
553 default:
554 dlg_key_event (h, key);
555 break;
556 }
557 }
558
559
560
561
562 void
563 dlg_run_done (WDialog *h)
564 {
565 top_dlg = g_list_remove (top_dlg, h);
566
567 if (widget_get_state (WIDGET (h), WST_CLOSED))
568 {
569 send_message (h, GROUP (h)->current == NULL ? NULL : WIDGET (GROUP (h)->current->data),
570 MSG_END, 0, NULL);
571 if (!widget_get_state (WIDGET (h), WST_MODAL))
572 dialog_switch_remove (h);
573 }
574 }
575
576
577
578
579
580
581
582
583
584 int
585 dlg_run (WDialog *h)
586 {
587 dlg_init (h);
588 frontend_dlg_run (h);
589 dlg_run_done (h);
590 return h->ret_value;
591 }
592
593
594
595
596
597
598 void
599 dlg_save_history (WDialog *h)
600 {
601 char *profile;
602 int i;
603
604 if (num_history_items_recorded == 0)
605 return;
606
607 profile = mc_config_get_full_path (MC_HISTORY_FILE);
608 i = open (profile, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
609 if (i != -1)
610 close (i);
611
612
613 if (chmod (profile, S_IRUSR | S_IWUSR) != -1 || errno == ENOENT)
614 {
615 ev_history_load_save_t event_data;
616
617 event_data.cfg = mc_config_init (profile, FALSE);
618 event_data.receiver = NULL;
619
620
621 mc_event_raise (h->event_group, MCEVENT_HISTORY_SAVE, &event_data);
622
623 mc_config_save_file (event_data.cfg, NULL);
624 mc_config_deinit (event_data.cfg);
625 }
626
627 g_free (profile);
628 }
629
630
631
632 char *
633 dlg_get_title (const WDialog *h, const ssize_t width)
634 {
635 char *t;
636
637 if (h == NULL)
638 abort ();
639
640 if (h->get_title != NULL)
641 t = h->get_title (h, width);
642 else
643 t = g_strdup ("");
644
645 return t;
646 }
647
648