Esempio n. 1
0
/*
 * putting the input tty in polling mode lets us check for
 * user typeahead
 */
static void
set_kbd_polling(int yes)
{
    static int kbd_flags = -1;	/* initial keyboard flags       */
    static int kbd_is_polled;	/* are we in O_NDELAY mode?     */

    if (kbd_flags == -1) {
	kbd_flags = fcntl(0, F_GETFL, 0);
	if (kbd_flags == -1)
	    imdying(SIGINT);
	kbd_is_polled = FALSE;
    }

    if (yes) {			/* turn polling on -- put us in NDELAY mode */
	if (!kbd_is_polled) {
	    if (fcntl(0, F_SETFL, kbd_flags | O_NDELAY) < 0)
		imdying(SIGINT);
	}
	kbd_is_polled = TRUE;	/* I think */
    } else {			/* turn polling off -- clear NDELAY mode */
	if (kbd_is_polled) {
	    if (fcntl(0, F_SETFL, kbd_flags) < 0)
		imdying(SIGINT);
	}
	kbd_is_polled = FALSE;
    }
}
Esempio n. 2
0
static BOOL WINAPI
nthandler(DWORD ctrl_type)
{
    switch (ctrl_type) {
    case CTRL_CLOSE_EVENT:
    case CTRL_LOGOFF_EVENT:
    case CTRL_SHUTDOWN_EVENT:
	imdying(1);
	break;
    }
    return TRUE;
}
Esempio n. 3
0
static int
vl_getchar(void)
{
    char c;
    int n;

    n = (int) read(0, &c, (size_t) 1);
    if (n <= 0) {
	if (n < 0 && errno == EINTR)
	    return -1;
	imdying(SIGINT);
    }
    return (c & 0xff);
}
Esempio n. 4
0
static int
ntconio_getch(void)
{
    INPUT_RECORD ir;
    DWORD nr;
    int key;
#ifdef VAL_AUTOCOLOR
    int milli_ac, orig_milli_ac;
#endif

    if (saveCount > 0) {
	saveCount--;
	return savedChar;
    }
#ifdef VAL_AUTOCOLOR
    orig_milli_ac = global_b_val(VAL_AUTOCOLOR);
#endif
    for_ever {
#ifdef VAL_AUTOCOLOR
	milli_ac = orig_milli_ac;
	while (milli_ac > 0) {
	    if (PeekConsoleInput(hConsoleInput, &ir, 1, &nr) == 0)
		break;		/* ?? system call failed ?? */
	    if (nr > 0)
		break;		/* something in the queue */
	    Sleep(20);		/* sleep a bit, but be responsive to keybd input */
	    milli_ac -= 20;
	}
	if (orig_milli_ac && milli_ac <= 0) {
	    ac_active = TRUE;
	    autocolor();
	    ac_active = FALSE;
	}
#endif
	if (!ReadConsoleInput(hConsoleInput, &ir, 1, &nr))
	    imdying(0);
	switch (ir.EventType) {

	case KEY_EVENT:
	    key = decode_key_event(&ir);
	    if (key == NOKYMAP)
		continue;
	    if (ir.Event.KeyEvent.wRepeatCount > 1) {
		saveCount = ir.Event.KeyEvent.wRepeatCount - 1;
		savedChar = key;
	    }
	    return key;

	case WINDOW_BUFFER_SIZE_EVENT:
	    newscreensize(
			     ir.Event.WindowBufferSizeEvent.dwSize.Y,
			     ir.Event.WindowBufferSizeEvent.dwSize.X
		);
	    GetConsoleScreenBufferInfo(hConsoleOutput, &csbi);
	    continue;

	case MOUSE_EVENT:
	    handle_mouse_event(ir.Event.MouseEvent);
	    continue;

	}
    }
}
Esempio n. 5
0
static void
handle_mouse_event(MOUSE_EVENT_RECORD mer)
{
    static DWORD lastclick = 0;
    static int clicks = 0;

    int onmode = FALSE;
    COORD current, first, latest;
    MARK lmbdn_mark;		/* left mouse button down here */
    int sel_pending = 0, state;
    DWORD thisclick;
    UINT clicktime = GetDoubleClickTime();

    buttondown = FALSE;
    for_ever {
	current = mer.dwMousePosition;
	switch (mer.dwEventFlags) {
	case 0:
	    state = mer.dwButtonState;
	    if (state == 0) {	/* button released */
		thisclick = GetTickCount();
		TRACE(("CLICK %d/%d\n", lastclick, thisclick));
		if (thisclick - lastclick < clicktime) {
		    clicks++;
		    TRACE(("MOUSE CLICKS %d\n", clicks));
		} else {
		    clicks = 0;
		}
		lastclick = thisclick;

		switch (clicks) {
		case 1:
		    on_double_click();
		    break;
		case 2:
		    on_triple_click();
		    break;
		}

		if (buttondown) {
		    int dummy;

		    halt_autoscroll_thread();

		    /* Finalize cursor position. */
		    (void) MouseClickSetPos(&current, &dummy);
		    if (!(onmode || sel_pending))
			sel_yank(0);
		}
		return;
	    }
	    if (state & FROM_LEFT_1ST_BUTTON_PRESSED) {
		if (MouseClickSetPos(&current, &onmode)) {
		    first = latest = current;
		    lmbdn_mark = DOT;
		    sel_pending = FALSE;
		    mouse_wp = row2window(latest.Y);
		    if (onmode) {
			buttondown = TRUE;
			sel_release();
			update(TRUE);
		    } else {
			HWND hwnd;

			(void) update(TRUE);	/* possible wdw change */
			buttondown = FALSE;	/* until all inits are successful */

			/* Capture mouse to console vile's window handle. */
			hwnd = GetVileWindow();
			(void) SetCapture(hwnd);

			/* Compute pixel height of each row on screen. */
			(void) GetClientRect(hwnd, &client_rect);
			row_height = client_rect.bottom / term.rows;

			/*
			 * Create mutex to ensure that main thread and worker
			 * thread don't update display at the same time.
			 */
			if ((hAsMutex = CreateMutex(0, FALSE, 0)) == NULL)
			    mlforce("[Can't create autoscroll mutex]");
			else {
			    /*
			     * Setup a worker thread to act as a pseudo
			     * timer that kicks off autoscroll when
			     * necessary.
			     */

			    if (_beginthread(autoscroll_thread,
					     0,
					     NULL) == (unsigned long) -1) {
				(void) CloseHandle(hAsMutex);
				mlforce("[Can't create autoscroll thread]");
			    } else
				sel_pending = buttondown = TRUE;
			}
			if (!buttondown)
			    (void) ReleaseCapture();
		    }
		}
	    } else if (state & FROM_LEFT_2ND_BUTTON_PRESSED) {
		if (MouseClickSetPos(&current, &onmode)
		    && !onmode) {
		    sel_yank(0);
		    sel_release();
		    paste_selection();
		    (void) update(TRUE);
		}
		return;
	    } else {
		if (MouseClickSetPos(&current, &onmode)
		    && onmode) {
		    sel_release();
		    update(TRUE);
		} else {
		    kbd_alarm();
		}
	    }
	    break;

	case MOUSE_MOVED:
	    if (!buttondown)
		return;
	    if (onmode) {
		/* on mode line, resize window (if possible). */

		if (!adjust_window(mouse_wp, &current, &latest)) {
		    /*
		     * left mouse button still down, but cursor moved off mode
		     * line.  Update latest to keep track of cursor in case
		     * it wanders back on the mode line.
		     */

		    latest = current;
		}
	    } else {
		mousemove(&sel_pending,
			  &first,
			  &current,
			  &lmbdn_mark,
			  (mer.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
		    );
	    }
	    break;

#ifdef MOUSE_WHEELED
	case MOUSE_WHEELED:
	    /*
	     * Trial and error experimentation shows that dwButtonState
	     * has its high bit set when the wheel moves back and not
	     * set otherwise.
	     */
	    mvupwind(TRUE, ((long) mer.dwButtonState < 0) ? -3 : 3);
	    update(TRUE);
	    return;
#endif /* MOUSE_WHEELED */
	}

	for_ever {
	    INPUT_RECORD ir;
	    DWORD nr;
	    int key;

	    if (!ReadConsoleInput(hConsoleInput, &ir, 1, &nr))
		imdying(0);
	    switch (ir.EventType) {
	    case KEY_EVENT:
		key = decode_key_event(&ir);
		if (key == ESC) {
		    if (buttondown)
			halt_autoscroll_thread();
		    sel_release();
		    (void) update(TRUE);
		    return;
		}
		continue;

	    case MOUSE_EVENT:
		mer = ir.Event.MouseEvent;
		break;
	    }
	    break;
	}
    }
}