⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dlg.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
    v = 0;
    for (i = 0; i < h->count; i++){
	if (w == (void *) p->widget){
	    v = send_message (h, p->widget, msg, par);
	    break;
	}
	p = p->next;
    }
    return v;
}

#define callback(h) (h->current->widget->callback)

void update_cursor (Dlg_head *h)
{
    if (!h->current)
         return;
    if (h->current->widget->options & W_WANT_CURSOR)
	send_message (h, h->current->widget, WIDGET_CURSOR, 0);
    else {
	Widget_Item *p = h->current;

	do {
	    if (p->widget->options & W_WANT_CURSOR)
		if ((*p->widget->callback)(h, p->widget, WIDGET_CURSOR, 0)){
		    x_focus_widget (p);
		    break;
		}
	    p = p->next;
	} while (h->current != p);
    }
}

/* Redraw the widgets in reverse order, leaving the current widget
 * as the last one
 */
void dlg_redraw (Dlg_head *h)
{
    (h->callback)(h, 0, DLG_DRAW);

    dlg_broadcast_msg (h, WIDGET_DRAW, 1);

    update_cursor (h);
}

void dlg_refresh (void *parameter)
{
    dlg_redraw ((Dlg_head *) parameter);
}

void dlg_stop (Dlg_head *h)
{
    h->running = 0;
    x_dialog_stop (h);
}

static INLINE void dialog_handle_key (Dlg_head *h, int d_key)
{
   char *hlpfile;

    switch (d_key){
    case KEY_LEFT:
    case KEY_UP:
	dlg_one_up (h);
	break;

    case KEY_RIGHT:
    case KEY_DOWN:
	dlg_one_down (h);
	break;

    case KEY_F(1):
        hlpfile = concat_dir_and_file (mc_home, "mc.hlp");
	interactive_display (hlpfile, h->help_ctx);
        free (hlpfile);
	do_refresh ();
	break;

    case XCTRL('z'):
	suspend_cmd ();
	/* Fall through */

    case XCTRL('l'):
#ifndef HAVE_SLANG
	/* Use this if the refreshes fail */
	clr_scr ();
	do_refresh ();
#else
	touchwin (stdscr);
#endif
	mc_refresh ();
	doupdate ();
	break;

    case '\n':
    case KEY_ENTER:
	h->ret_value = B_ENTER;
	h->running = 0;
	x_dialog_stop (h);
	break;

    case ESC_CHAR:
    case KEY_F (10):
    case XCTRL ('c'):
    case XCTRL ('g'):
	h->ret_value = B_CANCEL;
	dlg_stop (h);
	break;
    }
}

static int dlg_try_hotkey (Dlg_head *h, int d_key)
{
    Widget_Item *hot_cur;
    Widget_Item *previous;
    int    handled, c;
    extern input_event ();

    /*
     * Explanation: we don't send letter hotkeys to other widgets if
     * the currently selected widget is an input line
     */

    if (h->current->widget->options & W_IS_INPUT){
		if(d_key < 255 && isalpha(d_key))
			return 0;
    }

    /* If it's an alt key, send the message */
    c = d_key & ~ALT(0);
    if (d_key & ALT(0) && c < 255 && isalpha(c))
	d_key = tolower(c);

#ifdef _OS_NT
	/* .ado: fix problem with file_permission under Win95 */
    if (d_key == 0) return 0;
#endif

    handled = 0;
    if (h->current->widget->options & W_WANT_HOTKEY)
	handled = callback (h) (h, h->current->widget, WIDGET_HOTKEY, d_key);

    /* If not used, send hotkey to other widgets */
    if (handled)
	return handled;

    hot_cur = h->current;

    /* send it to all widgets */
    do {
	if (hot_cur->widget->options & W_WANT_HOTKEY)
	    handled |= (*hot_cur->widget->callback)
		(h, hot_cur->widget, WIDGET_HOTKEY, d_key);

	if (!handled)
	    hot_cur = hot_cur->next;
    } while (h->current != hot_cur && !handled);

    if (!handled)
	return 0;

    (*h->callback) (h, 0, DLG_HOTKEY_HANDLED);
    previous = h->current;
    if (!dlg_unfocus (h))
	return handled;

    h->current = hot_cur;
    if (!dlg_focus (h)){
	h->current = previous;
	dlg_focus (h);
    }
    return handled;
}

void dlg_key_event (Dlg_head *h, int d_key)
{
    int handled;

    /* TAB used to cycle */
    if (!h->raw && (d_key == '\t' || d_key == KEY_BTAB))
	if (d_key == '\t')
	    dlg_one_down (h);
        else
	    dlg_one_up (h);
    else {

	/* first can dlg_callback handle the key */
	handled = (*h->callback) (h, d_key, DLG_KEY);

	/* next try the hotkey */
	if (!handled)
	    handled = dlg_try_hotkey (h, d_key);

	/* not used - then try widget_callback */
	if (!handled)
	    handled |= callback (h)(h, h->current->widget, WIDGET_KEY, d_key);

	/* not used- try to use the unhandled case */
	if (!handled)
	    handled |= (*h->callback) (h, d_key, DLG_UNHANDLED_KEY);

	if (!handled)
	    dialog_handle_key (h, d_key);
	(*h->callback) (h, d_key, DLG_POST_KEY);
    }
}

static INLINE int dlg_mouse_event (Dlg_head *h, Gpm_Event *event)
{
    Widget_Item *item;
    Widget_Item *starting_widget = h->current;
    Gpm_Event   new_event;
    int x = event->x;
    int y = event->y;
    int ret_value;

    /* kludge for the menubar: start at h->first, not current  */
    /* Must be carefull in the insertion order to the dlg list */
    if (y == 1 && h->has_menubar)
	starting_widget = h->first;

    item = starting_widget;
    do {
	Widget *widget = item->widget;

	item = item->next;

	if (!((x > widget->x) && (x <= widget->x+widget->cols)
	    && (y > widget->y) && (y <= widget->y+widget->lines)))
	    continue;

	new_event = *event;
	new_event.x -= widget->x;
	new_event.y -= widget->y;

	ret_value = widget->mouse ? (*widget->mouse) (&new_event, widget) :
	    MOU_NORMAL;

	return ret_value;
    } while (item != starting_widget);
    return 0;
}

/* Run dialog routines */

/* Init the process */
void init_dlg (Dlg_head *h)
{
    int refresh_mode;

    tk_end_frame ();

    /* Initialize dialog manager and widgets */
    (*h->callback) (h, 0, DLG_INIT);
    dlg_broadcast_msg (h, WIDGET_INIT, 0);

    if (h->x == 0 && h->y == 0 && h->cols == COLS && h->lines == LINES)
	refresh_mode = REFRESH_COVERS_ALL;
    else
	refresh_mode = REFRESH_COVERS_PART;
    push_refresh (dlg_refresh, h, refresh_mode);
    h->refresh_pushed = 1;

    /* Initialize direction */
    if (!h->direction)
	h->current =  h->first;

    if (h->initfocus != NULL)
        h->current = h->initfocus;

    h->previous_dialog = current_dlg;
    current_dlg = h;

    /* Initialize the mouse status */
    h->mouse_status = 0;

    /* Redraw the screen */
    dlg_redraw (h);

    while (!dlg_focus (h))
	h->current = h->current->next;

    h->ret_value = 0;
    h->running = 1;
    x_init_dlg (h);
}

/* Shutdown the run_dlg */
void dlg_run_done (Dlg_head *h)
{
    (*h->callback) (h, h->current->dlg_id, DLG_END);
    current_dlg = (Dlg_head *) h->previous_dialog;
    if (current_dlg)
	    x_focus_widget (current_dlg->current);
}

void dlg_process_event (Dlg_head *h, int key, Gpm_Event *event)
{
    if (key == EV_NONE){
	if (got_interrupt ())
	    key = XCTRL('g');
	else
	    return;
    }

    if (key == EV_MOUSE)
	h->mouse_status = dlg_mouse_event (h, event);
    else
	dlg_key_event (h, key);
}

#ifndef PORT_HAS_FRONTEND_RUN_DLG
static inline void
frontend_run_dlg (Dlg_head *h)
{
    int d_key;
    Gpm_Event event;

    event.x = -1;
    while (h->running) {
#if defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4
	/* It does not work with ncurses before 1.9.9g, it will break */
	if (winch_flag)
	    change_screen_size ();
#endif
	if (is_idle ()){
	    if (idle_hook)
		execute_hooks (idle_hook);

	    while (h->send_idle_msg && is_idle ()){
		(*h->callback) (h, 0, DLG_IDLE);
	    }
	}

	update_cursor (h);
	(*h->callback)(h, 0, DLG_PRE_EVENT);

	/* Clear interrupt flag */
	got_interrupt ();
	d_key = get_event (&event, h->mouse_status == MOU_REPEAT, 1);

	dlg_process_event (h, d_key, &event);
    }
}
#endif /* PORT_HAS_FRONTEND_RUN_DLG */

/* Standard run dialog routine
 * We have to keep this routine small so that we can duplicate it's
 * behavior on complex routines like the file routines, this way,
 * they can call the dlg_process_event without rewriting all the code
 */
void run_dlg (Dlg_head *h)
{
    init_dlg (h);
    frontend_run_dlg (h);
    dlg_run_done (h);
}

void
destroy_dlg (Dlg_head *h)
{
    int i;
    Widget_Item *c;

    if (h->refresh_pushed)
	pop_refresh ();

    x_destroy_dlg_start (h);
    dlg_broadcast_msg (h, WIDGET_DESTROY, 0);
    c = h->current;
    for (i = 0; i < h->count; i++){
	if (c->widget->destroy)
	    c->widget->destroy (c->widget);
	c = c->next;
	free (h->current->widget);
	free (h->current);
	h->current = c;
    }
    if (h->title)
	free (h->title);
    x_destroy_dlg (h);
    free (h);
    if (refresh_list)
	do_refresh ();
}

int std_callback (Dlg_head *h, int Msg, int Par)
{
    return 0;
}

void widget_set_size (Widget *widget, int y, int x, int lines, int cols)
{
    widget->x = x;
    widget->y = y;
    widget->cols = cols;
    widget->lines = lines;
}

/* Replace widget old for widget new in the h dialog */
void dlg_replace_widget (Dlg_head *h, Widget *old, Widget *new)
{
    Widget_Item *p = h->current;
    int should_focus = 0;

    do {
	if (p->widget == old){

	    if (old == h->current->widget)
		should_focus = 1;

	    /* We found the widget */
	    /* First kill the widget */
	    new->focused = old->focused;
	    new->parent  = h;
	    send_message_to (h, old, WIDGET_DESTROY, 0);
	    (*old->destroy) (old);

	    /* We insert the new widget */
	    p->widget = new;
	    send_message_to (h, new, WIDGET_INIT, 0);
	    if (should_focus){
		if (dlg_focus (h) == 0)
		    select_a_widget (h, 1);
	    }
	    send_message_to (h, new, WIDGET_DRAW, 0);
	    break;
	}
	p = p->next;
    } while (p != h->current);
}

void widget_redraw (Dlg_head *h, Widget_Item *w)
{
    Widget_Item *save = h->current;

    h->current = w;
    (*w->widget->callback)(h, h->current->widget, WIDGET_DRAW, 0);
    h->current = save;
}

/* Returns the index of h->current from h->first */
int dlg_item_number (Dlg_head *h)
{
    Widget_Item *p;
    int i = 0;

    p = h->first;

    do {
	if (p == h->current)
	    return i;
	i++;
	p = p->next;
    } while (p != h->first);
    fprintf (stderr, "Internal error: current not in dialog list\n\r");
    exit (1);
}

int dlg_select_nth_widget (Dlg_head *h, int n)
{
    Widget_Item *w;
    int i;

    w = h->first;
    for (i = 0; i < n; i++)
	w = w->next;

    return dlg_select_widget (h, w->widget);
}

#ifdef HAVE_TK
/* Frames must include a trailing dot */
static void tk_frame_proc (Dlg_head *h, char *frame, int new_frame)
{
    char *s = strdup (frame);

    if (frame [strlen (frame)-1] != '.'){
	fprintf (stderr, "Invalid frame name\n");
	exit (1);
    }
    s [strlen (frame)-1] = 0;
    the_frame = frame;

    if (new_frame)
	tk_evalf ("frame %s.%s", (char *)h->wdata, s);
}

/* If passed a null string, it returns */
void tk_new_frame (Dlg_head *h, char *frame)
{
    if (!*frame)
	return;
    tk_frame_proc (h, frame, 1);
}

void tk_frame (Dlg_head *h, char *frame)
{
    tk_frame_proc (h, frame, 0);
}

void tk_end_frame ()
{
    the_frame = "";
}
#else
void tk_new_frame (Dlg_head *h, char *x)
{
}

void tk_frame (Dlg_head *h, char *x)
{
}

void tk_end_frame (void)
{
}
#endif

#ifndef PORT_HAS_DIALOG_TITLE
void
x_set_dialog_title (Dlg_head *h, char *title)
{
  h->title = strdup(title);
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -