Codepage messages related translated & other stuff...
[midnight-commander.git] / src / dlg.c
blob85b09c0d5f65d1dd110e6dcbb06c75a568ec896b
1 /* Dlg box features module for the Midnight Commander
2 Copyright (C) 1994, 1995 Radek Doulik, Miguel de Icaza
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #include <config.h>
20 /* "$Id$" */
21 #include <string.h>
22 #include <stdio.h>
23 #include <ctype.h>
24 #include "tty.h"
25 #include <stdarg.h>
26 #include "global.h"
27 #include "x.h"
28 #include "menu.h"
29 #include "win.h"
30 #include "color.h"
31 #include "mouse.h"
32 #include "help.h"
33 #include "key.h" /* For mi_getch() */
34 #include "dlg.h"
35 #include "dialog.h" /* For push_refresh() and pop_refresh() */
36 #include "layout.h"
37 #include "main.h"
39 /* This is the current frame, used to group Tk packings */
40 char *the_frame = "";
42 #define waddc(w,y1,x1,c) move (w->y+y1, w->x+x1); addch (c)
44 /* Primitive way to check if the the current dialog is our dialog */
45 /* This is needed by async routines like load_prompt */
46 Dlg_head *current_dlg = 0;
48 /* A hook list for idle events */
49 Hook *idle_hook = 0;
51 #ifndef PORT_HAS_SET_IDLE
52 # define x_set_idle(d,x)
53 #endif
55 #ifndef PORT_HAS_DIALOG_STOP
56 # define x_dialog_stop(d)
57 #endif
59 #ifdef HAVE_X
60 void widget_erase (Widget *w)
64 void dlg_erase (Dlg_head *h)
67 #else
68 static void slow_box (Dlg_head *h, int y, int x, int ys, int xs)
70 move (h->y+y, h->x+x);
71 hline (' ', xs);
72 vline (' ', ys);
73 move (h->y+y, h->x+x+xs-1);
74 vline (' ', ys);
75 move (h->y+y+ys-1, h->x+x);
76 hline (' ', xs);
79 /* draw box in window */
80 void draw_box (Dlg_head *h, int y, int x, int ys, int xs)
82 extern int slow_terminal;
84 if (slow_terminal){
85 slow_box (h, y, x, ys, xs);
86 return;
89 #ifndef HAVE_SLANG
90 waddc (h, y, x, ACS_ULCORNER);
91 hline (ACS_HLINE, xs - 2);
92 waddc (h, y + ys - 1, x, ACS_LLCORNER);
93 hline (ACS_HLINE, xs - 2);
95 waddc (h, y, x + xs - 1, ACS_URCORNER);
96 waddc (h, y + ys - 1, x + xs - 1, ACS_LRCORNER);
98 move (h->y+y+1, h->x+x);
99 vline (ACS_VLINE, ys - 2);
100 move (h->y+y+1, h->x+x+xs-1);
101 vline (ACS_VLINE, ys - 2);
102 #else
103 SLsmg_draw_box (h->y+y, h->x+x, ys, xs);
104 #endif
107 /* draw box in window */
108 void draw_double_box (Dlg_head *h, int y, int x, int ys, int xs)
110 #ifndef HAVE_SLANG
111 draw_box (h, y, x, ys, xs);
112 #else
113 SLsmg_draw_double_box (h->y+y, h->x+x, ys, xs);
114 #endif
117 void widget_erase (Widget *w)
119 int x, y;
121 for (y = 0; y < w->lines; y++){
122 widget_move (w, y, 0);
123 for (x = 0; x < w->cols; x++)
124 addch (' ');
128 void dlg_erase (Dlg_head *h)
130 int x, y;
132 for (y = 0; y < h->lines; y++){
133 move (y+h->y, h->x); /* FIXME: should test if ERR */
134 for (x = 0; x < h->cols; x++){
135 addch (' ');
139 #endif /* HAVE_X */
141 void init_widget (Widget *w, int y, int x, int lines, int cols,
142 int (*callback)(Dlg_head *, void *, int, int),
143 destroy_fn destroy, mouse_h mouse_handler, char *tkname)
145 w->x = x;
146 w->y = y;
147 w->cols = cols;
148 w->lines = lines;
149 w->color = -1;
150 w->callback = callback;
151 w->destroy = destroy;
152 w->mouse = mouse_handler;
153 w->wdata = 0;
154 w->wcontainer = 0;
155 w->frame = "";
156 w->parent = 0;
157 w->tkname = tkname;
159 if (tkname && *tkname == 0){
160 fprintf (stderr, "Got a null string for the tkname\n");
161 abort ();
163 /* Almost all widgets want to put the cursor in a suitable place */
164 w->options = W_WANT_CURSOR;
167 int default_proc (Dlg_head *h, int Msg, int Par)
169 switch (Msg){
171 case WIDGET_HOTKEY: /* Didn't use the key */
172 return 0;
174 case WIDGET_INIT: /* We could tell if something went wrong */
175 return 1;
177 case WIDGET_KEY:
178 return 0; /* Didn't use the key */
180 case WIDGET_FOCUS: /* We accept FOCUSes */
181 if (h->current)
182 x_focus_widget (h->current);
183 return 1;
185 case WIDGET_UNFOCUS: /* We accept loose FOCUSes */
186 if (h->current)
187 x_unfocus_widget (h->current);
188 return 1;
190 case WIDGET_DRAW:
191 return 1;
193 case WIDGET_DESTROY:
194 return 1;
196 case WIDGET_CURSOR:
197 /* Move the cursor to the default widget position */
198 return 1;
200 case WIDGET_IDLE:
201 return 1;
203 printf ("Internal error: unhandled message: %d\n", Msg);
204 return 1;
207 int default_dlg_callback (Dlg_head *h, int id, int msg)
209 if (msg == DLG_IDLE){
210 dlg_broadcast_msg_to (h, WIDGET_IDLE, 0, W_WANT_IDLE);
212 return 0;
215 #ifdef HAVE_X
216 int midnight_callback (struct Dlg_head *h, int id, int msg);
217 #endif
218 Dlg_head *create_dlg (int y1, int x1, int lines, int cols,
219 int *color_set,
220 int (*callback) (struct Dlg_head *, int, int),
221 char *help_ctx, char *name,
222 int flags)
224 Dlg_head *new_d;
226 #ifndef HAVE_X
227 if (flags & DLG_CENTER){
228 y1 = (LINES-lines)/2;
229 x1 = (COLS-cols)/2;
231 #endif
233 if ((flags & DLG_TRYUP) && (y1 > 3))
234 y1 -= 2;
236 new_d = g_new (Dlg_head, 1);
237 new_d->current = NULL;
238 new_d->count = 0;
239 new_d->direction = DIR_FORWARD;
240 new_d->color = color_set;
241 new_d->help_ctx = help_ctx;
242 new_d->callback = callback ? callback : default_dlg_callback;
243 new_d->send_idle_msg = 0;
244 new_d->x = x1;
245 new_d->y = y1;
246 new_d->title = 0;
247 new_d->cols = cols;
248 new_d->lines = lines;
249 new_d->refresh_pushed = 0;
250 new_d->has_menubar = 0;
251 new_d->name = name;
252 new_d->raw = 0;
253 new_d->grided = 0;
254 new_d->initfocus = NULL;
255 new_d->running = 0;
256 #ifdef HAVE_X
257 if (callback != midnight_callback)
258 new_d->wdata = xtoolkit_create_dialog (new_d, flags);
259 else
260 new_d->wdata = xtoolkit_get_main_dialog (new_d);
261 #endif
262 return (new_d);
265 void set_idle_proc (Dlg_head *d, int state)
267 d->send_idle_msg = state;
268 x_set_idle (d, state);
271 /* add component to dialog buffer */
272 int add_widget (Dlg_head *where, void *what)
274 Widget_Item *back;
275 Widget *widget = (Widget *) what;
277 /* Only used by Tk */
278 widget->frame = the_frame;
280 /* Don't accept 0 widgets, this could be from widgets that could not */
281 /* initialize properly */
282 if (!what)
283 return 0;
285 widget->x += where->x;
286 widget->y += where->y;
288 if (where->running){
289 Widget_Item *point = where->current;
291 where->current = g_new (Widget_Item, 1);
293 if (point){
294 where->current->next = point->next;
295 where->current->prev = point;
296 point->next->prev = where->current;
297 point->next = where->current;
298 } else {
299 where->current->next = where->current;
300 where->first = where->current;
301 where->current->prev = where->first;
302 where->last = where->current;
303 where->first->next = where->last;
305 } else {
306 back = where->current;
307 where->current = g_new (Widget_Item, 1);
308 if (back){
309 back->prev = where->current;
310 where->current->next = back;
311 } else {
312 where->current->next = where->current;
313 where->first = where->current;
316 where->current->prev = where->first;
317 where->last = where->current;
318 where->first->next = where->last;
321 where->current->dlg_id = where->count;
322 where->current->widget = what;
323 where->current->widget->parent = where;
325 where->count++;
327 /* If the widget is inserted in a running dialog */
328 if (where->running){
329 send_message (where, widget, WIDGET_INIT, 0);
330 send_message (where, widget, WIDGET_DRAW, 0);
331 #ifdef HAVE_GNOME
332 x_add_widget (where, where->current);
333 #endif
335 return (where->count - 1);
338 int remove_widget (Dlg_head *h, void *what)
340 Widget_Item *first, *p;
342 if (!h->current)
343 return 0;
345 first = p = h->current;
347 do {
348 if (p->widget == what){
349 /* Remove links to this Widget_Item */
350 p->prev->next = p->next;
351 p->next->prev = p->prev;
353 /* Make sure h->current is always valid */
354 if (p == h->current){
355 h->current = h->current->next;
356 if (h->current == p)
357 h->current = 0;
359 h->count--;
360 g_free (p);
361 return 1;
363 p = p->next;
364 } while (p != first);
365 return 0;
368 int destroy_widget (Widget *w)
370 send_message (w->parent, w, WIDGET_DESTROY, 0);
371 if (w->destroy)
372 w->destroy (w);
373 g_free (w);
374 return 1;
377 int send_message (Dlg_head *h, Widget *w, int msg, int par)
379 return (*(w->callback))(h, w, msg, par);
382 /* broadcast a message to all the widgets in a dialog that have
383 * the options set to flags.
385 void dlg_broadcast_msg_to (Dlg_head *h, int message, int reverse, int flags)
387 Widget_Item *p, *first, *wi;
388 #ifdef HAVE_GNOME
389 int was_panel;
390 #endif
392 if (!h->current)
393 return;
395 if (reverse)
396 first = p = h->current->prev;
397 else
398 /* FIXME: On XView the layout for the widget->next widget is
399 invoked, and we should change the buttons order on query_dialog
400 in order to use the HAVE_X part of the statement */
401 #ifdef HAVE_X
402 first = p = h->current;
403 #else
404 first = p = h->current->next;
405 #endif
407 #ifdef HAVE_GNOME
408 was_panel = FALSE;
409 #endif
410 do {
411 wi = p;
412 if (reverse)
413 p = p->prev;
414 else
415 p = p->next;
416 /* if (p->widget->options & flags) */
417 #ifdef HAVE_GNOME
418 if (is_a_panel (wi->widget))
419 was_panel |= TRUE;
420 #endif
421 send_message (h, wi->widget, message, 0);
422 } while (first != p);
423 #ifdef HAVE_GNOME
424 if (was_panel && message == WIDGET_INIT)
425 h->current = h->current->prev;
426 #endif
429 /* broadcast a message to all the widgets in a dialog */
430 void dlg_broadcast_msg (Dlg_head *h, int message, int reverse)
432 dlg_broadcast_msg_to (h, message, reverse, ~0);
435 int dlg_focus (Dlg_head *h)
437 if (!h->current)
438 return 0;
440 if (send_message (h, h->current->widget, WIDGET_FOCUS, 0)){
441 (*h->callback) (h, h->current->dlg_id, DLG_FOCUS);
442 return 1;
444 return 0;
447 int dlg_unfocus (Dlg_head *h)
449 if (!h->current)
450 return 0;
452 if (send_message (h, h->current->widget, WIDGET_UNFOCUS, 0)){
453 (*h->callback) (h, h->current->dlg_id, DLG_UNFOCUS);
454 return 1;
456 return 0;
459 static void select_a_widget (Dlg_head *h, int down)
461 int direction = h->direction;
463 if (!h->current)
464 return;
466 if (!down)
467 direction = !direction;
469 do {
470 if (direction)
471 h->current = h->current->next;
472 else
473 h->current = h->current->prev;
475 (*h->callback) (h, h->current->dlg_id, DLG_ONE_DOWN);
476 } while (!dlg_focus (h));
479 /* Return true if the windows overlap */
480 int dlg_overlap (Widget *a, Widget *b)
482 if ((b->x >= a->x + a->cols)
483 || (a->x >= b->x + b->cols)
484 || (b->y >= a->y + a->lines)
485 || (a->y >= b->y + b->lines))
486 return 0;
487 return 1;
491 /* Searches a widget, uses the callback as a signature in the dialog h */
492 Widget *find_widget_type (Dlg_head *h, callback_fn signature)
494 Widget *w;
495 Widget_Item *item;
496 int i;
498 if (!h)
499 return 0;
500 if (!h->current)
501 return 0;
503 w = 0;
504 for (i = 0, item = h->current; i < h->count; i++, item = item->next){
505 if (item->widget->callback == signature){
506 w = item->widget;
507 break;
510 return w;
513 void dlg_one_up (Dlg_head *h)
515 Widget_Item *old;
517 old = h->current;
519 if (!old)
520 return;
522 /* If it accepts unFOCUSion */
523 if (!dlg_unfocus(h))
524 return;
526 select_a_widget (h, 0);
527 if (dlg_overlap (old->widget, h->current->widget)){
528 send_message (h, h->current->widget, WIDGET_DRAW, 0);
529 send_message (h, h->current->widget, WIDGET_FOCUS, 0);
533 void dlg_one_down (Dlg_head *h)
535 Widget_Item *old;
537 old = h->current;
538 if (!old)
539 return;
541 if (!dlg_unfocus (h))
542 return;
544 select_a_widget (h, 1);
545 if (dlg_overlap (old->widget, h->current->widget)){
546 send_message (h, h->current->widget, WIDGET_DRAW, 0);
547 send_message (h, h->current->widget, WIDGET_FOCUS, 0);
551 int dlg_select_widget (Dlg_head *h, void *w)
553 if (!h->current)
554 return 0;
556 if (dlg_unfocus (h)){
557 while (h->current->widget != w)
558 h->current = h->current->next;
559 while (!dlg_focus (h))
560 h->current = h->current->next;
562 return 1;
564 return 0;
567 int send_message_to (Dlg_head *h, Widget *w, int msg, int par)
569 Widget_Item *p = h->current;
570 int v, i;
572 if (!h->current)
573 return 0;
575 v = 0;
576 for (i = 0; i < h->count; i++){
577 if (w == (void *) p->widget){
578 v = send_message (h, p->widget, msg, par);
579 break;
581 p = p->next;
583 return v;
586 #define callback(h) (h->current->widget->callback)
588 void update_cursor (Dlg_head *h)
590 if (!h->current)
591 return;
592 if (h->current->widget->options & W_WANT_CURSOR)
593 send_message (h, h->current->widget, WIDGET_CURSOR, 0);
594 else {
595 Widget_Item *p = h->current;
597 do {
598 if (p->widget->options & W_WANT_CURSOR)
599 if ((*p->widget->callback)(h, p->widget, WIDGET_CURSOR, 0)){
600 x_focus_widget (p);
601 break;
603 p = p->next;
604 } while (h->current != p);
608 /* Redraw the widgets in reverse order, leaving the current widget
609 * as the last one
611 void dlg_redraw (Dlg_head *h)
613 (h->callback)(h, 0, DLG_DRAW);
615 dlg_broadcast_msg (h, WIDGET_DRAW, 1);
617 update_cursor (h);
620 void dlg_refresh (void *parameter)
622 dlg_redraw ((Dlg_head *) parameter);
625 void dlg_stop (Dlg_head *h)
627 h->running = 0;
628 x_dialog_stop (h);
631 static INLINE void dialog_handle_key (Dlg_head *h, int d_key)
633 char *hlpfile;
635 switch (d_key){
636 case KEY_LEFT:
637 case KEY_UP:
638 dlg_one_up (h);
639 break;
641 case KEY_RIGHT:
642 case KEY_DOWN:
643 dlg_one_down (h);
644 break;
646 case KEY_F(1):
647 hlpfile = concat_dir_and_file (mc_home, _("mc.hlp"));
648 interactive_display (hlpfile, h->help_ctx);
649 g_free (hlpfile);
650 do_refresh ();
651 break;
653 #ifndef HAVE_X
654 case XCTRL('z'):
655 suspend_cmd ();
656 /* Fall through */
658 case XCTRL('l'):
659 #ifndef HAVE_SLANG
660 /* Use this if the refreshes fail */
661 clr_scr ();
662 do_refresh ();
663 #else
664 touchwin (stdscr);
665 #endif /* HAVE_SLANG */
666 mc_refresh ();
667 doupdate ();
668 #endif /* !HAVE_X */
669 break;
671 case '\n':
672 case KEY_ENTER:
673 h->ret_value = B_ENTER;
674 h->running = 0;
675 x_dialog_stop (h);
676 break;
678 case ESC_CHAR:
679 case KEY_F (10):
680 case XCTRL ('c'):
681 case XCTRL ('g'):
682 h->ret_value = B_CANCEL;
683 dlg_stop (h);
684 break;
688 static int dlg_try_hotkey (Dlg_head *h, int d_key)
690 Widget_Item *hot_cur;
691 Widget_Item *previous;
692 int handled, c;
694 if (!h->current)
695 return 0;
698 * Explanation: we don't send letter hotkeys to other widgets if
699 * the currently selected widget is an input line
702 if (h->current->widget->options & W_IS_INPUT){
703 if(d_key < 255 && isalpha(d_key))
704 return 0;
707 /* If it's an alt key, send the message */
708 c = d_key & ~ALT(0);
709 if (d_key & ALT(0) && c < 255 && isalpha(c))
710 d_key = tolower(c);
712 #ifdef _OS_NT
713 /* .ado: fix problem with file_permission under Win95 */
714 if (d_key == 0) return 0;
715 #endif
717 handled = 0;
718 if (h->current->widget->options & W_WANT_HOTKEY)
719 handled = callback (h) (h, h->current->widget, WIDGET_HOTKEY, d_key);
721 /* If not used, send hotkey to other widgets */
722 if (handled)
723 return handled;
725 hot_cur = h->current;
727 /* send it to all widgets */
728 do {
729 if (hot_cur->widget->options & W_WANT_HOTKEY)
730 handled |= (*hot_cur->widget->callback)
731 (h, hot_cur->widget, WIDGET_HOTKEY, d_key);
733 if (!handled)
734 hot_cur = hot_cur->next;
735 } while (h->current != hot_cur && !handled);
737 if (!handled)
738 return 0;
740 (*h->callback) (h, 0, DLG_HOTKEY_HANDLED);
741 previous = h->current;
742 if (!dlg_unfocus (h))
743 return handled;
745 h->current = hot_cur;
746 if (!dlg_focus (h)){
747 h->current = previous;
748 dlg_focus (h);
750 return handled;
753 int dlg_key_event (Dlg_head *h, int d_key)
755 int handled;
757 if (!h->current)
758 return 0;
760 /* TAB used to cycle */
761 if (!h->raw && (d_key == '\t' || d_key == KEY_BTAB))
762 if (d_key == '\t')
763 dlg_one_down (h);
764 else
765 dlg_one_up (h);
766 else {
768 /* first can dlg_callback handle the key */
769 handled = (*h->callback) (h, d_key, DLG_KEY);
771 /* next try the hotkey */
772 if (!handled)
773 handled = dlg_try_hotkey (h, d_key);
775 /* not used - then try widget_callback */
776 if (!handled)
777 handled |= callback (h)(h, h->current->widget, WIDGET_KEY, d_key);
779 /* not used- try to use the unhandled case */
780 if (!handled)
781 handled |= (*h->callback) (h, d_key, DLG_UNHANDLED_KEY);
783 if (!handled)
784 dialog_handle_key (h, d_key);
785 (*h->callback) (h, d_key, DLG_POST_KEY);
787 return handled;
789 return 1;
792 static INLINE int dlg_mouse_event (Dlg_head *h, Gpm_Event *event)
794 Widget_Item *item;
795 Widget_Item *starting_widget = h->current;
796 Gpm_Event new_event;
797 int x = event->x;
798 int y = event->y;
799 int ret_value;
801 /* kludge for the menubar: start at h->first, not current */
802 /* Must be carefull in the insertion order to the dlg list */
803 if (y == 1 && h->has_menubar)
804 starting_widget = h->first;
806 item = starting_widget;
807 do {
808 Widget *widget = item->widget;
810 item = item->next;
812 if (!((x > widget->x) && (x <= widget->x+widget->cols)
813 && (y > widget->y) && (y <= widget->y+widget->lines)))
814 continue;
816 new_event = *event;
817 new_event.x -= widget->x;
818 new_event.y -= widget->y;
820 ret_value = widget->mouse ? (*widget->mouse) (&new_event, widget) :
821 MOU_NORMAL;
823 return ret_value;
824 } while (item != starting_widget);
825 return 0;
828 /* Run dialog routines */
830 /* Init the process */
831 void init_dlg (Dlg_head *h)
833 int refresh_mode;
835 /* Initialize dialog manager and widgets */
836 (*h->callback) (h, 0, DLG_INIT);
837 dlg_broadcast_msg (h, WIDGET_INIT, 0);
839 #ifdef HAVE_X
840 refresh_mode = REFRESH_COVERS_PART;
841 #else
842 if (h->x == 0 && h->y == 0 && h->cols == COLS && h->lines == LINES)
843 refresh_mode = REFRESH_COVERS_ALL;
844 else
845 refresh_mode = REFRESH_COVERS_PART;
847 #endif
848 push_refresh (dlg_refresh, h, refresh_mode);
849 h->refresh_pushed = 1;
851 /* Initialize direction */
852 if (!h->direction)
853 h->current = h->first;
855 if (h->initfocus != NULL)
856 h->current = h->initfocus;
858 h->previous_dialog = current_dlg;
859 current_dlg = h;
861 /* Initialize the mouse status */
862 h->mouse_status = 0;
864 /* Redraw the screen */
865 dlg_redraw (h);
867 while (!dlg_focus (h) && h->current)
868 h->current = h->current->next;
870 h->ret_value = 0;
871 h->running = 1;
872 x_init_dlg (h);
875 /* Shutdown the run_dlg */
876 void dlg_run_done (Dlg_head *h)
878 if (h->current)
879 (*h->callback) (h, h->current->dlg_id, DLG_END);
881 current_dlg = (Dlg_head *) h->previous_dialog;
882 if (current_dlg){
885 * Special case for the GNOME desktop:
886 * The desktop will not have any widgets
888 if (current_dlg->current)
889 x_focus_widget (current_dlg->current);
893 void dlg_process_event (Dlg_head *h, int key, Gpm_Event *event)
895 if (key == EV_NONE){
896 if (got_interrupt ())
897 key = XCTRL('g');
898 else
899 return;
902 if (key == EV_MOUSE)
903 h->mouse_status = dlg_mouse_event (h, event);
904 else
905 dlg_key_event (h, key);
908 #ifndef PORT_HAS_FRONTEND_RUN_DLG
909 static inline void
910 frontend_run_dlg (Dlg_head *h)
912 int d_key;
913 Gpm_Event event;
915 event.x = -1;
916 while (h->running) {
917 #if defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4
918 /* It does not work with ncurses before 1.9.9g, it will break */
919 if (winch_flag)
920 change_screen_size ();
921 #endif
922 if (is_idle ()){
923 if (idle_hook)
924 execute_hooks (idle_hook);
926 while (h->send_idle_msg && is_idle ()){
927 (*h->callback) (h, 0, DLG_IDLE);
931 update_cursor (h);
932 (*h->callback)(h, 0, DLG_PRE_EVENT);
934 /* Clear interrupt flag */
935 got_interrupt ();
936 d_key = get_event (&event, h->mouse_status == MOU_REPEAT, 1);
938 dlg_process_event (h, d_key, &event);
941 #endif /* PORT_HAS_FRONTEND_RUN_DLG */
943 /* Standard run dialog routine
944 * We have to keep this routine small so that we can duplicate it's
945 * behavior on complex routines like the file routines, this way,
946 * they can call the dlg_process_event without rewriting all the code
948 void run_dlg (Dlg_head *h)
950 init_dlg (h);
951 frontend_run_dlg (h);
952 dlg_run_done (h);
955 void
956 destroy_dlg (Dlg_head *h)
958 int i;
959 Widget_Item *c;
961 if (h->refresh_pushed)
962 pop_refresh ();
964 x_destroy_dlg_start (h);
965 dlg_broadcast_msg (h, WIDGET_DESTROY, 0);
966 c = h->current;
967 for (i = 0; i < h->count; i++){
968 if (c->widget->destroy)
969 c->widget->destroy (c->widget);
970 c = c->next;
971 if (h->current){
972 g_free (h->current->widget);
973 g_free (h->current);
975 h->current = c;
977 if (h->title)
978 g_free (h->title);
979 x_destroy_dlg (h);
980 g_free (h);
982 #ifndef HAVE_X
983 if (refresh_list)
984 do_refresh ();
985 #endif
988 int std_callback (Dlg_head *h, int Msg, int Par)
990 return 0;
993 void widget_set_size (Widget *widget, int y, int x, int lines, int cols)
995 widget->x = x;
996 widget->y = y;
997 widget->cols = cols;
998 widget->lines = lines;
1001 /* Replace widget old for widget new in the h dialog */
1002 void dlg_replace_widget (Dlg_head *h, Widget *old, Widget *new)
1004 Widget_Item *p = h->current;
1005 int should_focus = 0;
1007 if (!h->current)
1008 return;
1010 do {
1011 if (p->widget == old){
1013 if (old == h->current->widget)
1014 should_focus = 1;
1016 /* We found the widget */
1017 /* First kill the widget */
1018 new->focused = old->focused;
1019 new->parent = h;
1020 send_message_to (h, old, WIDGET_DESTROY, 0);
1021 (*old->destroy) (old);
1023 /* We insert the new widget */
1024 p->widget = new;
1025 send_message_to (h, new, WIDGET_INIT, 0);
1026 if (should_focus){
1027 if (dlg_focus (h) == 0)
1028 select_a_widget (h, 1);
1030 send_message_to (h, new, WIDGET_DRAW, 0);
1031 break;
1033 p = p->next;
1034 } while (p != h->current);
1037 void widget_redraw (Dlg_head *h, Widget_Item *w)
1039 Widget_Item *save = h->current;
1041 if (!h->current)
1042 return;
1044 h->current = w;
1045 (*w->widget->callback)(h, h->current->widget, WIDGET_DRAW, 0);
1046 h->current = save;
1049 /* Returns the index of h->current from h->first */
1050 int dlg_item_number (Dlg_head *h)
1052 Widget_Item *p;
1053 int i = 0;
1055 p = h->first;
1057 do {
1058 if (p == h->current)
1059 return i;
1060 i++;
1061 p = p->next;
1062 } while (p != h->first);
1063 fprintf (stderr, "Internal error: current not in dialog list\n\r");
1064 exit (1);
1067 int dlg_select_nth_widget (Dlg_head *h, int n)
1069 Widget_Item *w;
1070 int i;
1072 w = h->first;
1073 for (i = 0; i < n; i++)
1074 w = w->next;
1076 return dlg_select_widget (h, w->widget);
1079 #ifndef PORT_HAS_DIALOG_TITLE
1080 void
1081 x_set_dialog_title (Dlg_head *h, char *title)
1083 h->title = g_strdup (title);
1085 #endif