📄 vtswitch-lite.c
字号:
/*** $Id: vtswitch-lite.c,v 1.9 2003/09/04 03:38:26 weiym Exp $**** vtswitch-lite.c: VT switching.**** Copyright (C) 2003 Feynman Software.** Copyright (C) 2001 ~ 2002 Song Lixin and Wei Yongming**** Created by Song Lixin, 2000/10/17** Clean code for MiniGUI 1.1.x by Wei Yongming, 20001/11/28*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <signal.h>#include <sys/ioctl.h>#include <sys/time.h>#include <linux/vt.h>#include "common.h"#include "minigui.h"#ifdef _LITE_VERSION#include "gdi.h"#include "window.h"#include "cliprect.h"#include "gal.h"#include "internals.h"#include "ctrlclass.h"#include "dc.h"#include "ial.h"#include "native.h"static int vtswitch_initialised = 0;static struct vt_mode startup_vtmode;volatile static int console_active = 1; /* are we active? */volatile static int console_should_be_active = 1; /* should we be? */static int ttyfd = -1;static int current_vt;static void vt_switch_requested(int signo);static void poll_console_switch (void);static void come_back(void);static void go_away(void);int init_vtswitch (int kbd_fd) { struct sigaction sa; struct vt_mode vtm; struct vt_stat stat; if (vtswitch_initialised) return 0; /* shouldn't happen */ if (kbd_fd >= 0) ttyfd = kbd_fd; else { ttyfd = open("/dev/tty0", O_RDONLY); if (ttyfd == -1) { fprintf (stderr, "Error can't open tty: %m.\n"); return -1; } } ioctl (ttyfd, VT_GETSTATE, &stat); current_vt = stat.v_active; console_active = console_should_be_active = 1; /* Hook the signals */ sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); /* block async IO during the VT switch */ sa.sa_flags = 0; sa.sa_handler = vt_switch_requested; if ((sigaction(SIGRELVT, &sa, NULL) < 0) || (sigaction(SIGACQVT, &sa, NULL) < 0)) { fprintf (stderr, "init_vtswitch: Unable to control VT switch.\n"); return -1; } /* Save old mode, take control, and arrange for the signals * to be raised. */ ioctl(ttyfd, VT_GETMODE, &startup_vtmode); vtm = startup_vtmode; vtm.mode = VT_PROCESS; vtm.relsig = SIGRELVT; vtm.acqsig = SIGACQVT; ioctl(ttyfd, VT_SETMODE, &vtm); vtswitch_initialised = 1; return 0;}/* vt_switch_requested: * This is our signal handler; it gets called whenever a switch is * requested, because either SIGRELVT or SIGACQVT is raised. */static void vt_switch_requested(int signo){ switch (signo) { case SIGRELVT: console_should_be_active = 0; break; case SIGACQVT: console_should_be_active = 1; break; default: return; } poll_console_switch();}/* poll_console_switch: * Checks whether a switch is needed and not blocked; if so, * makes the switch. */static void poll_console_switch (void){ if (console_active == console_should_be_active) return; if (console_should_be_active) come_back(); else go_away();}/* come_back: * Performs a switch back. */static void come_back (void){ int new_fd; IAL_ResumeMouse(); if ((new_fd = IAL_ResumeKeyboard()) >= 0) ttyfd = new_fd; ioctl (ttyfd, VT_RELDISP, VT_ACKACQ); console_active = 1; __mg_switch_away = FALSE; SendNotifyMessage (HWND_DESKTOP, MSG_PAINT, 0, 0);#ifndef _STAND_ALONE ClientCanDrawNowEx (TRUE, NULL);#endif}/* go_away: * Performs a switch away. */static void go_away (void){#ifndef _STAND_ALONE OnlyMeCanDraw ();#endif if (ioctl (ttyfd, VT_RELDISP, 1) == -1) { fprintf (stderr, "Error can't switch away from VT: %m\n"); return; } console_active = 0; __mg_switch_away = TRUE; IAL_SuspendKeyboard(); IAL_SuspendMouse();}/* done_vtswitch: * Undoes the effect of `init_vtswitch'. */int done_vtswitch (int kbd_fd){ struct sigaction sa; if (!vtswitch_initialised) return 0; /* shouldn't really happen either */ /* !trout gfoot. Must turn off the signals before unhooking them... */ ioctl (ttyfd, VT_SETMODE, &startup_vtmode); sigemptyset (&sa.sa_mask); sa.sa_handler = SIG_DFL; sa.sa_flags = SA_RESTART; sigaction (SIGRELVT, &sa, NULL); sigaction (SIGACQVT, &sa, NULL); vtswitch_initialised = 0; if (ttyfd != kbd_fd) close (ttyfd); return 0;}int vtswitch_try(int vt) { if (!vtswitch_initialised) return 1; if(vt == current_vt) return 1; ioctl(ttyfd, VT_ACTIVATE, vt); return 0;}#endif /* _LITE_VERSION */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -