1993-07-26 21:21:11 +00:00
|
|
|
|
/*-
|
1997-01-15 18:16:32 +00:00
|
|
|
|
* Copyright (c) 1992-1997 S<EFBFBD>ren Schmidt
|
1993-07-26 21:21:11 +00:00
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
|
* are met:
|
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
1995-05-30 08:16:23 +00:00
|
|
|
|
* notice, this list of conditions and the following disclaimer
|
1994-09-29 08:29:21 +00:00
|
|
|
|
* in this position and unchanged.
|
1993-07-26 21:21:11 +00:00
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
1995-02-22 13:48:07 +00:00
|
|
|
|
* 3. The name of the author may not be used to endorse or promote products
|
|
|
|
|
* derived from this software withough specific prior written permission
|
1993-07-26 21:21:11 +00:00
|
|
|
|
*
|
1995-02-22 13:48:07 +00:00
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
1993-07-26 21:21:11 +00:00
|
|
|
|
*
|
1997-08-09 19:24:03 +00:00
|
|
|
|
* $Id: syscons.c,v 1.229 1997/08/08 22:52:30 sos Exp $
|
1993-07-26 21:21:11 +00:00
|
|
|
|
*/
|
|
|
|
|
|
1994-08-13 03:50:34 +00:00
|
|
|
|
#include "sc.h"
|
1995-02-25 20:09:44 +00:00
|
|
|
|
#include "apm.h"
|
1996-01-04 21:13:23 +00:00
|
|
|
|
#include "opt_ddb.h"
|
1996-09-06 23:35:54 +00:00
|
|
|
|
#include "opt_syscons.h"
|
1996-01-04 21:13:23 +00:00
|
|
|
|
|
1994-08-13 03:50:34 +00:00
|
|
|
|
#if NSC > 0
|
|
|
|
|
#include <sys/param.h>
|
1994-05-25 09:21:21 +00:00
|
|
|
|
#include <sys/systm.h>
|
1994-08-13 03:50:34 +00:00
|
|
|
|
#include <sys/conf.h>
|
|
|
|
|
#include <sys/proc.h>
|
1995-12-06 23:52:35 +00:00
|
|
|
|
#include <sys/signalvar.h>
|
1994-08-13 03:50:34 +00:00
|
|
|
|
#include <sys/tty.h>
|
|
|
|
|
#include <sys/kernel.h>
|
|
|
|
|
#include <sys/malloc.h>
|
1995-12-08 11:19:42 +00:00
|
|
|
|
#ifdef DEVFS
|
|
|
|
|
#include <sys/devfsext.h>
|
|
|
|
|
#endif
|
1994-10-23 21:28:03 +00:00
|
|
|
|
|
1994-10-26 21:51:22 +00:00
|
|
|
|
#include <machine/clock.h>
|
1995-09-10 21:36:12 +00:00
|
|
|
|
#include <machine/cons.h>
|
1994-08-17 19:32:23 +00:00
|
|
|
|
#include <machine/console.h>
|
1996-07-01 20:29:10 +00:00
|
|
|
|
#include <machine/md_var.h>
|
1994-08-17 19:32:23 +00:00
|
|
|
|
#include <machine/psl.h>
|
|
|
|
|
#include <machine/frame.h>
|
|
|
|
|
#include <machine/pc/display.h>
|
1995-02-25 20:09:44 +00:00
|
|
|
|
#include <machine/apm_bios.h>
|
1995-10-28 16:58:05 +00:00
|
|
|
|
#include <machine/random.h>
|
1994-10-23 21:28:03 +00:00
|
|
|
|
|
1995-12-06 23:52:35 +00:00
|
|
|
|
#include <vm/vm.h>
|
1995-12-07 12:48:31 +00:00
|
|
|
|
#include <vm/vm_param.h>
|
|
|
|
|
#include <vm/pmap.h>
|
1995-12-06 23:52:35 +00:00
|
|
|
|
|
1994-08-13 03:50:34 +00:00
|
|
|
|
#include <i386/isa/isa.h>
|
|
|
|
|
#include <i386/isa/isa_device.h>
|
|
|
|
|
#include <i386/isa/timerreg.h>
|
1994-08-17 08:51:59 +00:00
|
|
|
|
#include <i386/isa/kbdtables.h>
|
1996-11-14 22:19:17 +00:00
|
|
|
|
#include <i386/isa/kbdio.h>
|
1995-02-22 13:48:07 +00:00
|
|
|
|
#include <i386/isa/syscons.h>
|
1993-10-28 05:27:36 +00:00
|
|
|
|
|
1995-01-12 11:47:05 +00:00
|
|
|
|
#if !defined(MAXCONS)
|
1995-01-28 22:18:05 +00:00
|
|
|
|
#define MAXCONS 16
|
1994-12-31 17:09:58 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
#define COLD 0
|
|
|
|
|
#define WARM 1
|
1995-12-08 11:19:42 +00:00
|
|
|
|
|
1997-04-27 09:03:10 +00:00
|
|
|
|
/* XXX use sc_bcopy where video memory is concerned */
|
|
|
|
|
#define sc_bcopy generic_bcopy
|
|
|
|
|
extern void generic_bcopy(const void *, void *, size_t);
|
1993-07-30 02:20:26 +00:00
|
|
|
|
|
|
|
|
|
static default_attr user_default = {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(FG_LIGHTGREY | BG_BLACK) << 8,
|
|
|
|
|
(FG_BLACK | BG_LIGHTGREY) << 8
|
1993-07-30 02:20:26 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static default_attr kernel_default = {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(FG_WHITE | BG_BLACK) << 8,
|
|
|
|
|
(FG_BLACK | BG_LIGHTGREY) << 8
|
1993-07-30 02:20:26 +00:00
|
|
|
|
};
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
static scr_stat main_console;
|
|
|
|
|
static scr_stat *console[MAXCONS];
|
1996-06-17 17:21:35 +00:00
|
|
|
|
#ifdef DEVFS
|
1995-12-08 11:19:42 +00:00
|
|
|
|
static void *sc_devfs_token[MAXCONS];
|
1996-06-17 17:21:35 +00:00
|
|
|
|
#endif
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scr_stat *cur_console;
|
|
|
|
|
static scr_stat *new_scp, *old_scp;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static term_stat kernel_console;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
static default_attr *current_default;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
static int flags = 0;
|
1996-11-19 17:08:10 +00:00
|
|
|
|
static int sc_port = IO_KBD;
|
1997-01-15 18:16:32 +00:00
|
|
|
|
static KBDC sc_kbdc = NULL;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
static char init_done = COLD;
|
1996-10-26 20:16:58 +00:00
|
|
|
|
static u_short sc_buffer[ROW*COL];
|
1995-02-22 13:48:07 +00:00
|
|
|
|
static char switch_in_progress = FALSE;
|
|
|
|
|
static char write_in_progress = FALSE;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
static char blink_in_progress = FALSE;
|
|
|
|
|
static int blinkrate = 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
u_int crtc_addr = MONO_BASE;
|
1997-06-22 12:04:36 +00:00
|
|
|
|
char crtc_type = KD_MONO;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
char crtc_vga = FALSE;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0;
|
|
|
|
|
static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0;
|
|
|
|
|
static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab);
|
|
|
|
|
static int delayed_next_scr = FALSE;
|
|
|
|
|
static long scrn_blank_time = 0; /* screen saver timeout value */
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
int scrn_blanked = 0; /* screen saver active flag */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
static long scrn_time_stamp;
|
|
|
|
|
u_char scr_map[256];
|
1996-09-01 18:16:06 +00:00
|
|
|
|
u_char scr_rmap[256];
|
|
|
|
|
char *video_mode_ptr = NULL;
|
1997-07-25 11:53:30 +00:00
|
|
|
|
int fonts_loaded = 0
|
|
|
|
|
#ifdef STD8X16FONT
|
|
|
|
|
| FONT_16
|
|
|
|
|
#endif
|
|
|
|
|
;
|
|
|
|
|
|
1997-01-15 18:16:32 +00:00
|
|
|
|
char font_8[256*8];
|
|
|
|
|
char font_14[256*14];
|
1997-07-26 07:58:29 +00:00
|
|
|
|
#ifdef STD8X16FONT
|
|
|
|
|
extern
|
|
|
|
|
#endif
|
|
|
|
|
unsigned char font_16[256*16];
|
1997-01-15 18:16:32 +00:00
|
|
|
|
char palette[256*3];
|
1997-04-27 09:03:10 +00:00
|
|
|
|
static char vgaregs[64];
|
1996-10-02 22:00:38 +00:00
|
|
|
|
static char *cut_buffer;
|
|
|
|
|
static u_short mouse_and_mask[16] = {
|
|
|
|
|
0xc000, 0xe000, 0xf000, 0xf800,
|
|
|
|
|
0xfc00, 0xfe00, 0xff00, 0xff80,
|
|
|
|
|
0xfe00, 0x1e00, 0x1f00, 0x0f00,
|
|
|
|
|
0x0f00, 0x0000, 0x0000, 0x0000
|
|
|
|
|
};
|
|
|
|
|
static u_short mouse_or_mask[16] = {
|
|
|
|
|
0x0000, 0x4000, 0x6000, 0x7000,
|
|
|
|
|
0x7800, 0x7c00, 0x7e00, 0x6800,
|
|
|
|
|
0x0c00, 0x0c00, 0x0600, 0x0600,
|
|
|
|
|
0x0000, 0x0000, 0x0000, 0x0000
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void none_saver(int blank) { }
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
static void (*current_saver)(int blank) = none_saver;
|
1996-10-18 18:51:37 +00:00
|
|
|
|
int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data,
|
|
|
|
|
int flag, struct proc *p) = NULL;
|
1994-02-04 10:36:15 +00:00
|
|
|
|
|
1994-02-01 06:22:29 +00:00
|
|
|
|
/* OS specific stuff */
|
1995-01-28 22:18:05 +00:00
|
|
|
|
#ifdef not_yet_done
|
1995-02-22 13:48:07 +00:00
|
|
|
|
#define VIRTUAL_TTY(x) (sccons[x] = ttymalloc(sccons[x]))
|
|
|
|
|
struct CONSOLE_TTY (sccons[MAXCONS] = ttymalloc(sccons[MAXCONS]))
|
1996-09-08 21:31:56 +00:00
|
|
|
|
struct MOUSE_TTY (sccons[MAXCONS+1] = ttymalloc(sccons[MAXCONS+1]))
|
|
|
|
|
struct tty *sccons[MAXCONS+2];
|
1994-05-25 09:21:21 +00:00
|
|
|
|
#else
|
1995-02-22 13:48:07 +00:00
|
|
|
|
#define VIRTUAL_TTY(x) &sccons[x]
|
|
|
|
|
#define CONSOLE_TTY &sccons[MAXCONS]
|
1996-09-08 21:31:56 +00:00
|
|
|
|
#define MOUSE_TTY &sccons[MAXCONS+1]
|
|
|
|
|
static struct tty sccons[MAXCONS+2];
|
1994-05-25 09:21:21 +00:00
|
|
|
|
#endif
|
1996-09-08 21:31:56 +00:00
|
|
|
|
#define SC_MOUSE 128
|
|
|
|
|
#define SC_CONSOLE 255
|
1995-02-22 13:48:07 +00:00
|
|
|
|
#define MONO_BUF pa_to_va(0xB0000)
|
|
|
|
|
#define CGA_BUF pa_to_va(0xB8000)
|
1995-09-10 21:36:12 +00:00
|
|
|
|
u_short *Crtat;
|
1996-09-09 19:02:26 +00:00
|
|
|
|
static const int nsccons = MAXCONS+2;
|
1994-02-01 06:22:29 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
#define WRAPHIST(scp, pointer, offset)\
|
|
|
|
|
((scp->history) + ((((pointer) - (scp->history)) + (scp->history_size)\
|
|
|
|
|
+ (offset)) % (scp->history_size)))
|
1997-03-01 23:53:46 +00:00
|
|
|
|
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
1997-06-22 12:04:36 +00:00
|
|
|
|
/* this should really be in `rtc.h' */
|
|
|
|
|
#define RTC_EQUIPMENT 0x14
|
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
/* prototypes */
|
|
|
|
|
static int scattach(struct isa_device *dev);
|
|
|
|
|
static int scparam(struct tty *tp, struct termios *t);
|
|
|
|
|
static int scprobe(struct isa_device *dev);
|
1997-06-22 12:04:36 +00:00
|
|
|
|
static int scvidprobe(int unit, int flags);
|
|
|
|
|
static int sckbdprobe(int unit, int flags);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
static void scstart(struct tty *tp);
|
1996-09-10 19:14:49 +00:00
|
|
|
|
static void scmousestart(struct tty *tp);
|
1996-06-23 17:12:05 +00:00
|
|
|
|
static void scinit(void);
|
1996-10-26 20:16:58 +00:00
|
|
|
|
static u_int scgetc(u_int flags);
|
|
|
|
|
#define SCGETC_CN 1
|
|
|
|
|
#define SCGETC_NONBLOCK 2
|
1996-06-23 17:12:05 +00:00
|
|
|
|
static scr_stat *get_scr_stat(dev_t dev);
|
|
|
|
|
static scr_stat *alloc_scp(void);
|
|
|
|
|
static void init_scp(scr_stat *scp);
|
|
|
|
|
static int get_scr_num(void);
|
1997-04-20 16:05:33 +00:00
|
|
|
|
static timeout_t scrn_timer;
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
static void stop_scrn_saver(void (*saver)(int));
|
1996-06-23 17:12:05 +00:00
|
|
|
|
static void clear_screen(scr_stat *scp);
|
|
|
|
|
static int switch_scr(scr_stat *scp, u_int next_scr);
|
|
|
|
|
static void exchange_scr(void);
|
|
|
|
|
static inline void move_crsr(scr_stat *scp, int x, int y);
|
|
|
|
|
static void scan_esc(scr_stat *scp, u_char c);
|
1996-09-01 18:16:06 +00:00
|
|
|
|
static void draw_cursor_image(scr_stat *scp);
|
|
|
|
|
static void remove_cursor_image(scr_stat *scp);
|
1996-06-23 17:12:05 +00:00
|
|
|
|
static void ansi_put(scr_stat *scp, u_char *buf, int len);
|
|
|
|
|
static u_char *get_fstr(u_int c, u_int *len);
|
|
|
|
|
static void history_to_screen(scr_stat *scp);
|
|
|
|
|
static int history_up_line(scr_stat *scp);
|
|
|
|
|
static int history_down_line(scr_stat *scp);
|
1996-10-02 22:00:38 +00:00
|
|
|
|
static int mask2attr(struct term_stat *term);
|
1997-01-15 18:16:32 +00:00
|
|
|
|
static void set_keyboard(int command, int data);
|
1996-09-30 23:00:58 +00:00
|
|
|
|
static void update_leds(int which);
|
1996-06-23 17:12:05 +00:00
|
|
|
|
static void set_vgaregs(char *modetable);
|
1997-04-27 09:03:10 +00:00
|
|
|
|
static void read_vgaregs(char *buf);
|
|
|
|
|
static int comp_vgaregs(u_char *buf1, u_char *buf2);
|
|
|
|
|
static void dump_vgaregs(u_char *buf);
|
1996-06-23 17:12:05 +00:00
|
|
|
|
static void set_font_mode(void);
|
|
|
|
|
static void set_normal_mode(void);
|
1996-09-01 18:16:06 +00:00
|
|
|
|
static void set_destructive_cursor(scr_stat *scp);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
static void set_mouse_pos(scr_stat *scp);
|
|
|
|
|
static void mouse_cut_start(scr_stat *scp);
|
|
|
|
|
static void mouse_cut_end(scr_stat *scp);
|
|
|
|
|
static void mouse_paste(scr_stat *scp);
|
1996-06-23 17:12:05 +00:00
|
|
|
|
static void draw_mouse_image(scr_stat *scp);
|
1996-09-01 18:16:06 +00:00
|
|
|
|
static void remove_mouse_image(scr_stat *scp);
|
|
|
|
|
static void draw_cutmarking(scr_stat *scp);
|
|
|
|
|
static void remove_cutmarking(scr_stat *scp);
|
1996-06-23 17:12:05 +00:00
|
|
|
|
static void save_palette(void);
|
|
|
|
|
static void do_bell(scr_stat *scp, int pitch, int duration);
|
1997-04-20 16:05:33 +00:00
|
|
|
|
static timeout_t blink_screen;
|
1996-10-01 07:38:14 +00:00
|
|
|
|
#ifdef SC_SPLASH_SCREEN
|
1996-09-30 23:00:58 +00:00
|
|
|
|
static void toggle_splash_screen(scr_stat *scp);
|
1996-10-01 07:38:14 +00:00
|
|
|
|
#endif
|
1996-06-23 17:12:05 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
struct isa_driver scdriver = {
|
|
|
|
|
scprobe, scattach, "sc", 1
|
1993-07-30 02:20:26 +00:00
|
|
|
|
};
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-09-10 21:36:12 +00:00
|
|
|
|
static d_open_t scopen;
|
|
|
|
|
static d_close_t scclose;
|
1995-12-10 15:55:34 +00:00
|
|
|
|
static d_read_t scread;
|
|
|
|
|
static d_write_t scwrite;
|
1995-09-10 21:36:12 +00:00
|
|
|
|
static d_ioctl_t scioctl;
|
1995-12-10 15:55:34 +00:00
|
|
|
|
static d_devtotty_t scdevtotty;
|
1995-09-10 21:36:12 +00:00
|
|
|
|
static d_mmap_t scmmap;
|
|
|
|
|
|
1995-12-14 22:03:12 +00:00
|
|
|
|
#define CDEV_MAJOR 12
|
1995-09-10 21:36:12 +00:00
|
|
|
|
static struct cdevsw scdevsw = {
|
|
|
|
|
scopen, scclose, scread, scwrite,
|
|
|
|
|
scioctl, nullstop, noreset, scdevtotty,
|
1995-12-08 11:19:42 +00:00
|
|
|
|
ttselect, scmmap, nostrategy, "sc", NULL, -1 };
|
1995-09-10 21:36:12 +00:00
|
|
|
|
|
1995-11-28 00:17:32 +00:00
|
|
|
|
/*
|
1996-10-02 22:00:38 +00:00
|
|
|
|
* These functions need to be before calls to them so they can be inlined.
|
1995-11-28 00:17:32 +00:00
|
|
|
|
*/
|
1996-10-02 22:00:38 +00:00
|
|
|
|
static inline void
|
|
|
|
|
draw_cursor_image(scr_stat *scp)
|
1995-11-28 00:17:32 +00:00
|
|
|
|
{
|
1996-10-02 22:00:38 +00:00
|
|
|
|
u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf);
|
1997-06-30 13:31:49 +00:00
|
|
|
|
u_short prev_image;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
|
1996-10-02 22:00:38 +00:00
|
|
|
|
/* do we have a destructive cursor ? */
|
|
|
|
|
if (flags & CHAR_CURSOR) {
|
1997-06-30 13:31:49 +00:00
|
|
|
|
prev_image = scp->cursor_saveunder;
|
|
|
|
|
cursor_image = *ptr & 0x00ff;
|
|
|
|
|
if (cursor_image == DEAD_CHAR)
|
|
|
|
|
cursor_image = prev_image & 0x00ff;
|
|
|
|
|
cursor_image |= *(scp->cursor_pos) & 0xff00;
|
1996-10-02 22:00:38 +00:00
|
|
|
|
scp->cursor_saveunder = cursor_image;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
/* update the cursor bitmap if the char under the cursor has changed */
|
|
|
|
|
if (prev_image != cursor_image)
|
|
|
|
|
set_destructive_cursor(scp);
|
1996-10-02 22:00:38 +00:00
|
|
|
|
/* modify cursor_image */
|
|
|
|
|
if (!(flags & BLINK_CURSOR)||((flags & BLINK_CURSOR)&&(blinkrate & 4))){
|
1997-06-30 13:31:49 +00:00
|
|
|
|
/*
|
|
|
|
|
* When the mouse pointer is at the same position as the cursor,
|
|
|
|
|
* the cursor bitmap needs to be updated even if the char under
|
|
|
|
|
* the cursor hasn't changed, because the mouse pionter may
|
|
|
|
|
* have moved by a few dots within the cursor cel.
|
|
|
|
|
*/
|
|
|
|
|
if ((prev_image == cursor_image)
|
|
|
|
|
&& (cursor_image != *(scp->cursor_pos)))
|
|
|
|
|
set_destructive_cursor(scp);
|
1996-10-02 22:00:38 +00:00
|
|
|
|
cursor_image &= 0xff00;
|
|
|
|
|
cursor_image |= DEAD_CHAR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
cursor_image = (*(ptr) & 0x00ff) | *(scp->cursor_pos) & 0xff00;
|
|
|
|
|
scp->cursor_saveunder = cursor_image;
|
|
|
|
|
if (!(flags & BLINK_CURSOR)||((flags & BLINK_CURSOR)&&(blinkrate & 4))){
|
|
|
|
|
if ((cursor_image & 0x7000) == 0x7000) {
|
|
|
|
|
cursor_image &= 0x8fff;
|
|
|
|
|
if(!(cursor_image & 0x0700))
|
|
|
|
|
cursor_image |= 0x0700;
|
|
|
|
|
} else {
|
|
|
|
|
cursor_image |= 0x7000;
|
|
|
|
|
if ((cursor_image & 0x0700) == 0x0700)
|
|
|
|
|
cursor_image &= 0xf0ff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*ptr = cursor_image;
|
|
|
|
|
}
|
1995-11-28 00:17:32 +00:00
|
|
|
|
|
1996-10-02 22:00:38 +00:00
|
|
|
|
static inline void
|
|
|
|
|
remove_cursor_image(scr_stat *scp)
|
|
|
|
|
{
|
|
|
|
|
*(Crtat + (scp->cursor_oldpos - scp->scr_buf)) = scp->cursor_saveunder;
|
|
|
|
|
}
|
1995-11-28 00:17:32 +00:00
|
|
|
|
|
1996-10-02 22:00:38 +00:00
|
|
|
|
static inline void
|
|
|
|
|
move_crsr(scr_stat *scp, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
if (x < 0)
|
|
|
|
|
x = 0;
|
|
|
|
|
if (y < 0)
|
|
|
|
|
y = 0;
|
|
|
|
|
if (x >= scp->xsize)
|
|
|
|
|
x = scp->xsize-1;
|
|
|
|
|
if (y >= scp->ysize)
|
|
|
|
|
y = scp->ysize-1;
|
|
|
|
|
scp->xpos = x;
|
|
|
|
|
scp->ypos = y;
|
|
|
|
|
scp->cursor_pos = scp->scr_buf + scp->ypos * scp->xsize + scp->xpos;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-12-10 13:40:44 +00:00
|
|
|
|
static int
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scprobe(struct isa_device *dev)
|
1997-06-22 12:04:36 +00:00
|
|
|
|
{
|
|
|
|
|
if (!scvidprobe(dev->id_unit, dev->id_flags)) {
|
|
|
|
|
if (bootverbose)
|
|
|
|
|
printf("sc%d: no video adapter is found.\n", dev->id_unit);
|
|
|
|
|
return (0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sc_port = dev->id_iobase;
|
|
|
|
|
if (sckbdprobe(dev->id_unit, dev->id_flags))
|
|
|
|
|
return (IO_KBDSIZE);
|
|
|
|
|
else
|
|
|
|
|
return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* probe video adapters, return TRUE if found */
|
|
|
|
|
static int
|
|
|
|
|
scvidprobe(int unit, int flags)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* XXX don't try to `printf' anything here, the console may not have
|
|
|
|
|
* been configured yet.
|
|
|
|
|
*/
|
|
|
|
|
u_short volatile *cp;
|
|
|
|
|
u_short was;
|
|
|
|
|
u_long pa;
|
|
|
|
|
u_long segoff;
|
|
|
|
|
|
|
|
|
|
/* do this test only once */
|
|
|
|
|
if (init_done != COLD)
|
|
|
|
|
return (Crtat != 0);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Finish defaulting crtc variables for a mono screen. Crtat is a
|
|
|
|
|
* bogus common variable so that it can be shared with pcvt, so it
|
|
|
|
|
* can't be statically initialized. XXX.
|
|
|
|
|
*/
|
|
|
|
|
Crtat = (u_short *)MONO_BUF;
|
|
|
|
|
crtc_type = KD_MONO;
|
|
|
|
|
/* If CGA memory seems to work, switch to color. */
|
|
|
|
|
cp = (u_short *)CGA_BUF;
|
|
|
|
|
was = *cp;
|
|
|
|
|
*cp = (u_short) 0xA55A;
|
|
|
|
|
if (*cp == 0xA55A) {
|
|
|
|
|
Crtat = (u_short *)CGA_BUF;
|
|
|
|
|
crtc_addr = COLOR_BASE;
|
|
|
|
|
crtc_type = KD_CGA;
|
|
|
|
|
} else {
|
|
|
|
|
cp = Crtat;
|
|
|
|
|
was = *cp;
|
|
|
|
|
*cp = (u_short) 0xA55A;
|
|
|
|
|
if (*cp != 0xA55A) {
|
|
|
|
|
/* no screen at all, bail out */
|
|
|
|
|
Crtat = 0;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*cp = was;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Check rtc and BIOS date area.
|
|
|
|
|
* XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy
|
|
|
|
|
* of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are
|
|
|
|
|
* zeros for EGA and VGA. However, the EGA/VGA BIOS will set
|
|
|
|
|
* these bits in BIOSDATA_EQUIPMENT according to the monitor
|
|
|
|
|
* type detected.
|
|
|
|
|
*/
|
|
|
|
|
switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
|
|
|
|
|
case 0: /* EGA/VGA, or nothing */
|
|
|
|
|
crtc_type = KD_EGA;
|
|
|
|
|
/* the color adapter may be in the 40x25 mode... XXX */
|
|
|
|
|
break;
|
|
|
|
|
case 1: /* CGA 40x25 */
|
|
|
|
|
/* switch to the 80x25 mode? XXX */
|
|
|
|
|
/* FALL THROUGH */
|
|
|
|
|
case 2: /* CGA 80x25 */
|
|
|
|
|
/* `crtc_type' has already been set... */
|
|
|
|
|
/* crtc_type = KD_CGA; */
|
|
|
|
|
break;
|
|
|
|
|
case 3: /* MDA */
|
|
|
|
|
/* `crtc_type' has already been set... */
|
|
|
|
|
/* crtc_type = KD_MONO; */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* is this a VGA or higher ? */
|
|
|
|
|
outb(crtc_addr, 7);
|
|
|
|
|
if (inb(crtc_addr) == 7) {
|
|
|
|
|
|
|
|
|
|
crtc_type = KD_VGA;
|
|
|
|
|
crtc_vga = TRUE;
|
|
|
|
|
read_vgaregs(vgaregs);
|
|
|
|
|
|
|
|
|
|
/* Get the BIOS video mode pointer */
|
|
|
|
|
segoff = *(u_long *)pa_to_va(0x4a8);
|
|
|
|
|
pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
|
|
|
|
|
if (ISMAPPED(pa, sizeof(u_long))) {
|
|
|
|
|
segoff = *(u_long *)pa_to_va(pa);
|
|
|
|
|
pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
|
|
|
|
|
if (ISMAPPED(pa, 64))
|
|
|
|
|
video_mode_ptr = (char *)pa_to_va(pa);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* probe the keyboard, return TRUE if found */
|
|
|
|
|
static int
|
|
|
|
|
sckbdprobe(int unit, int flags)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1997-01-15 18:16:32 +00:00
|
|
|
|
int codeset;
|
|
|
|
|
int c = -1;
|
|
|
|
|
int m;
|
1994-08-17 08:51:59 +00:00
|
|
|
|
|
1997-01-15 18:16:32 +00:00
|
|
|
|
sc_kbdc = kbdc_open(sc_port);
|
|
|
|
|
|
|
|
|
|
if (!kbdc_lock(sc_kbdc, TRUE)) {
|
|
|
|
|
/* driver error? */
|
1997-06-22 12:04:36 +00:00
|
|
|
|
printf("sc%d: unable to lock the controller.\n", unit);
|
|
|
|
|
return ((flags & DETECT_KBD) ? FALSE : TRUE);
|
1997-01-15 18:16:32 +00:00
|
|
|
|
}
|
1996-11-14 22:19:17 +00:00
|
|
|
|
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
/* discard anything left after UserConfig */
|
1997-01-15 18:16:32 +00:00
|
|
|
|
empty_both_buffers(sc_kbdc, 10);
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
|
1996-11-14 22:19:17 +00:00
|
|
|
|
/* save the current keyboard controller command byte */
|
1997-01-15 18:16:32 +00:00
|
|
|
|
m = kbdc_get_device_mask(sc_kbdc) & ~KBD_KBD_CONTROL_BITS;
|
|
|
|
|
c = get_controller_command_byte(sc_kbdc);
|
1996-11-14 22:19:17 +00:00
|
|
|
|
if (c == -1) {
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
/* CONTROLLER ERROR */
|
1997-06-22 12:04:36 +00:00
|
|
|
|
printf("sc%d: unable to get the current command byte value.\n", unit);
|
1996-11-14 22:19:17 +00:00
|
|
|
|
goto fail;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1997-01-15 18:16:32 +00:00
|
|
|
|
if (bootverbose)
|
|
|
|
|
printf("sc%d: the current keyboard controller command byte %04x\n",
|
1997-06-22 12:04:36 +00:00
|
|
|
|
unit, c);
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
#if 0
|
|
|
|
|
/* override the keyboard lock switch */
|
|
|
|
|
c |= KBD_OVERRIDE_KBD_LOCK;
|
|
|
|
|
#endif
|
1996-11-14 22:19:17 +00:00
|
|
|
|
|
1997-06-22 12:04:36 +00:00
|
|
|
|
/*
|
|
|
|
|
* The keyboard may have been screwed up by the boot block.
|
|
|
|
|
* We may just be able to recover from error by testing the controller
|
|
|
|
|
* and the keyboard port. The controller command byte needs to be saved
|
|
|
|
|
* before this recovery operation, as some controllers seem to set
|
|
|
|
|
* the command byte to particular values.
|
|
|
|
|
*/
|
|
|
|
|
test_controller(sc_kbdc);
|
|
|
|
|
test_kbd_port(sc_kbdc);
|
|
|
|
|
|
1997-04-10 12:26:50 +00:00
|
|
|
|
/* enable the keyboard port, but disable the keyboard intr. */
|
1997-01-15 18:16:32 +00:00
|
|
|
|
if (!set_controller_command_byte(sc_kbdc,
|
1997-06-22 12:04:36 +00:00
|
|
|
|
KBD_KBD_CONTROL_BITS,
|
1997-04-10 12:26:50 +00:00
|
|
|
|
KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT)) {
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
/* CONTROLLER ERROR
|
|
|
|
|
* there is very little we can do...
|
|
|
|
|
*/
|
1997-06-22 12:04:36 +00:00
|
|
|
|
printf("sc%d: unable to set the command byte.\n", unit);
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
goto fail;
|
|
|
|
|
}
|
1997-01-15 18:16:32 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Check if we have an XT keyboard before we attempt to reset it.
|
|
|
|
|
* The procedure assumes that the keyboard and the controller have
|
|
|
|
|
* been set up properly by BIOS and have not been messed up
|
|
|
|
|
* during the boot process.
|
|
|
|
|
*/
|
|
|
|
|
codeset = -1;
|
1997-06-22 12:04:36 +00:00
|
|
|
|
if (flags & XT_KEYBD)
|
1997-01-15 18:16:32 +00:00
|
|
|
|
/* the user says there is a XT keyboard */
|
|
|
|
|
codeset = 1;
|
|
|
|
|
#ifdef DETECT_XT_KEYBOARD
|
|
|
|
|
else if ((c & KBD_TRANSLATION) == 0) {
|
|
|
|
|
/* SET_SCANCODE_SET is not always supported; ignore error */
|
|
|
|
|
if (send_kbd_command_and_data(sc_kbdc, KBDC_SET_SCANCODE_SET, 0)
|
|
|
|
|
== KBD_ACK)
|
|
|
|
|
codeset = read_kbd_data(sc_kbdc);
|
|
|
|
|
}
|
|
|
|
|
if (bootverbose)
|
1997-06-22 12:04:36 +00:00
|
|
|
|
printf("sc%d: keyboard scancode set %d\n", unit, codeset);
|
1997-01-15 18:16:32 +00:00
|
|
|
|
#endif /* DETECT_XT_KEYBOARD */
|
1996-11-14 22:19:17 +00:00
|
|
|
|
|
1997-06-29 22:23:32 +00:00
|
|
|
|
if (flags & KBD_NORESET) {
|
A fix/work-around for ThinkPad 535.
Add a new configuration flag, KBD_NORESET (0x20) to tell scprobe() not
to reset the keyboard.
IBM ThinkPad 535 has the `Fn' key with which the user can perform
certain functions in conjunction with other keys. For example, `Fn' +
PageUP/PageDOWN adjust speaker volume, `Fn' + Home/End change
brightness of LCD screen. It can also be used to suspend the system.
It appears that these functions are implemented at the keyboard level
or the keyboard controller level and totally independent from BIOS or
OS. But, if the keyboard is reset (as is done in scprobe()), they
become unavailable. (There are other laptops which have similar
functions associated with the `Fn' key. But, they aren't affected by
keyboard reset.)
ThinkPad 535 doesn't have switches or buttons to adjust brightness and
volume, or to put the system into the suspend mode. Therefore, it is
essential to preserve these `Fn' key functions in FreeBSD. The new
flag make scprobe() skip keyboard reset.
If this flag is not set, scprobe() behaves in the same say as before.
(If we only knew a way to detect ThinkPad 535, we could skip keyboard
reset automatically, but...)
1997-06-29 15:11:40 +00:00
|
|
|
|
write_kbd_command(sc_kbdc, KBDC_ECHO);
|
|
|
|
|
if (read_kbd_data(sc_kbdc) != KBD_ECHO) {
|
|
|
|
|
empty_both_buffers(sc_kbdc, 10);
|
|
|
|
|
test_controller(sc_kbdc);
|
|
|
|
|
test_kbd_port(sc_kbdc);
|
|
|
|
|
if (bootverbose)
|
|
|
|
|
printf("sc%d: failed to get response from the keyboard.\n",
|
|
|
|
|
unit);
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* reset keyboard hardware */
|
|
|
|
|
if (!reset_kbd(sc_kbdc)) {
|
|
|
|
|
/* KEYBOARD ERROR
|
|
|
|
|
* Keyboard reset may fail either because the keyboard doen't
|
|
|
|
|
* exist, or because the keyboard doesn't pass the self-test,
|
|
|
|
|
* or the keyboard controller on the motherboard and the keyboard
|
|
|
|
|
* somehow fail to shake hands. It is just possible, particularly
|
|
|
|
|
* in the last case, that the keyoard controller may be left
|
|
|
|
|
* in a hung state. test_controller() and test_kbd_port() appear
|
|
|
|
|
* to bring the keyboard controller back (I don't know why and
|
|
|
|
|
* how, though.)
|
|
|
|
|
*/
|
|
|
|
|
empty_both_buffers(sc_kbdc, 10);
|
|
|
|
|
test_controller(sc_kbdc);
|
|
|
|
|
test_kbd_port(sc_kbdc);
|
|
|
|
|
/* We could disable the keyboard port and interrupt... but,
|
|
|
|
|
* the keyboard may still exist (see above).
|
|
|
|
|
*/
|
|
|
|
|
if (bootverbose)
|
|
|
|
|
printf("sc%d: failed to reset the keyboard.\n", unit);
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
|
1996-11-10 16:44:13 +00:00
|
|
|
|
/*
|
|
|
|
|
* Allow us to set the XT_KEYBD flag in UserConfig so that keyboards
|
|
|
|
|
* such as those on the IBM ThinkPad laptop computers can be used
|
|
|
|
|
* with the standard console driver.
|
|
|
|
|
*/
|
1997-01-15 18:16:32 +00:00
|
|
|
|
if (codeset == 1) {
|
1996-11-14 22:19:17 +00:00
|
|
|
|
if (send_kbd_command_and_data(
|
1997-01-15 18:16:32 +00:00
|
|
|
|
sc_kbdc, KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) {
|
1996-11-14 22:19:17 +00:00
|
|
|
|
/* XT kbd doesn't need scan code translation */
|
|
|
|
|
c &= ~KBD_TRANSLATION;
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
} else {
|
|
|
|
|
/* KEYBOARD ERROR
|
|
|
|
|
* The XT kbd isn't usable unless the proper scan code set
|
|
|
|
|
* is selected.
|
|
|
|
|
*/
|
1997-06-22 12:04:36 +00:00
|
|
|
|
printf("sc%d: unable to set the XT keyboard mode.\n", unit);
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
goto fail;
|
|
|
|
|
}
|
1996-11-10 16:44:13 +00:00
|
|
|
|
}
|
1996-11-14 22:19:17 +00:00
|
|
|
|
/* enable the keyboard port and intr. */
|
1997-01-15 18:16:32 +00:00
|
|
|
|
if (!set_controller_command_byte(sc_kbdc,
|
1997-04-10 12:26:50 +00:00
|
|
|
|
KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK,
|
|
|
|
|
(c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK))
|
1997-01-15 18:16:32 +00:00
|
|
|
|
| KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
/* CONTROLLER ERROR
|
|
|
|
|
* This is serious; we are left with the disabled keyboard intr.
|
|
|
|
|
*/
|
1997-06-22 12:04:36 +00:00
|
|
|
|
printf("sc%d: unable to enable the keyboard port and intr.\n", unit);
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
goto fail;
|
|
|
|
|
}
|
1996-10-23 07:29:44 +00:00
|
|
|
|
|
1996-11-14 22:19:17 +00:00
|
|
|
|
succeed:
|
1997-01-15 18:16:32 +00:00
|
|
|
|
kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS),
|
|
|
|
|
kbdc_lock(sc_kbdc, FALSE);
|
1997-06-22 12:04:36 +00:00
|
|
|
|
return TRUE;
|
1996-10-23 07:29:44 +00:00
|
|
|
|
|
1996-11-14 22:19:17 +00:00
|
|
|
|
fail:
|
Alot of fixes from kazu:
1. All the suggestions earlier made by Bruce: renaming some symbols,
stricter error checking, removing redundant code, etc.
2. The `psm' driver preserves the default counter resolution and
report rate, whatever they are after reset. (Based on reports and
suggestion from Nate and Rob Bolin).
3. The `psm' driver now does not check the so-called sync. bit in the
first byte of the data packet by default, so that the tapping feature
of ALPUS GlidePoint works (based on reports from Louis Mamakos). I
tested the code with ALPUS Desktop GlidePoint (M/N GP101) and found
no problem; tapping worked. It appears ALPUS produces several models
of GlidePoint. I hope the other models are OK too.
The check code can still be activated by defining the PSM_CHECKSYNC
option in the config file. (The bit checking slightly reduces, if not
completely eliminates, weird mouse behavior cased by unsynchronized
mouse data packets. It also helps us to detect if the mouse interrupt
can ever be lost. But, well, if there are devices which cannot be
supported this way...)
4. The `psm' driver does not include the protocol emulation code by
default. The code can still be compiled in if the PSM_EMULATION option
is specified in the config file. Louis Mamakos suggests the emulation
code is putting too much in the kernel, and `moused' works well.
I will think about this later and decide if the entire emulation
code should be removed.
5. And, of course, the fix in `scprobe()' from Bruce to cure the
UserConfig problem. My code in `kbdio.c' is slightly different from
his patch, but has the same effect. There still is a possibility that
`scprobe()' gets confused, if, for whatever reasons, the user holds
down a key for very long time during the boot process. But we cannot
cope with everything, can we?
Submitted by: Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
1996-12-01 19:05:50 +00:00
|
|
|
|
if (c != -1)
|
1997-01-15 18:16:32 +00:00
|
|
|
|
/* try to restore the command byte as before, if possible */
|
|
|
|
|
set_controller_command_byte(sc_kbdc, 0xff, c);
|
|
|
|
|
kbdc_set_device_mask(sc_kbdc,
|
1997-06-22 12:04:36 +00:00
|
|
|
|
(flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS);
|
1997-01-15 18:16:32 +00:00
|
|
|
|
kbdc_lock(sc_kbdc, FALSE);
|
1997-06-22 12:04:36 +00:00
|
|
|
|
return FALSE;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-10-03 00:42:27 +00:00
|
|
|
|
#if NAPM > 0
|
|
|
|
|
static int
|
|
|
|
|
scresume(void *dummy)
|
|
|
|
|
{
|
|
|
|
|
shfts = ctls = alts = agrs = metas = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1995-12-10 13:40:44 +00:00
|
|
|
|
static int
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scattach(struct isa_device *dev)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1996-09-01 18:16:06 +00:00
|
|
|
|
scr_stat *scp;
|
|
|
|
|
dev_t cdev = makedev(CDEV_MAJOR, 0);
|
1996-03-27 19:11:41 +00:00
|
|
|
|
#ifdef DEVFS
|
1996-09-01 18:16:06 +00:00
|
|
|
|
int vc;
|
1996-03-27 19:11:41 +00:00
|
|
|
|
#endif
|
1995-01-28 22:18:05 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scinit();
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags = dev->id_flags;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
if (!crtc_vga)
|
|
|
|
|
flags &= ~CHAR_CURSOR;
|
1995-04-04 20:06:26 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp = console[0];
|
1995-04-04 20:06:26 +00:00
|
|
|
|
|
|
|
|
|
if (crtc_vga) {
|
1996-06-21 07:19:18 +00:00
|
|
|
|
cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT);
|
1995-04-04 20:06:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
|
|
|
|
|
M_DEVBUF, M_NOWAIT);
|
1996-10-26 20:16:58 +00:00
|
|
|
|
|
|
|
|
|
/* copy temporary buffer to final buffer */
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(sc_buffer, scp->scr_buf, scp->xsize * scp->ysize * sizeof(u_short));
|
1996-10-26 20:16:58 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
scp->cursor_pos = scp->cursor_oldpos =
|
|
|
|
|
scp->scr_buf + scp->xpos + scp->ypos * scp->xsize;
|
1996-10-18 18:51:37 +00:00
|
|
|
|
scp->mouse_pos = scp->mouse_oldpos =
|
|
|
|
|
scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
|
|
|
|
|
scp->mouse_xpos/8);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
|
|
|
|
/* initialize history buffer & pointers */
|
|
|
|
|
scp->history_head = scp->history_pos = scp->history =
|
|
|
|
|
(u_short *)malloc(scp->history_size*sizeof(u_short),
|
|
|
|
|
M_DEVBUF, M_NOWAIT);
|
|
|
|
|
bzero(scp->history_head, scp->history_size*sizeof(u_short));
|
|
|
|
|
|
1995-04-04 20:06:26 +00:00
|
|
|
|
/* initialize cursor stuff */
|
1997-06-30 13:31:49 +00:00
|
|
|
|
if (!(scp->status & UNKNOWN_MODE))
|
1996-10-01 23:24:09 +00:00
|
|
|
|
draw_cursor_image(scp);
|
1995-02-03 21:09:44 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* get screen update going */
|
1997-04-20 16:05:33 +00:00
|
|
|
|
scrn_timer(NULL);
|
1995-02-03 21:09:44 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
update_leds(scp->status);
|
1995-04-04 20:06:26 +00:00
|
|
|
|
|
1997-04-27 09:03:10 +00:00
|
|
|
|
if (bootverbose) {
|
|
|
|
|
printf("sc%d: BIOS video mode:%d\n",
|
|
|
|
|
dev->id_unit, *(u_char *)pa_to_va(0x449));
|
|
|
|
|
printf("sc%d: VGA registers upon power-up\n", dev->id_unit);
|
|
|
|
|
dump_vgaregs(vgaregs);
|
|
|
|
|
printf("sc%d: video mode:%d\n", dev->id_unit, scp->mode);
|
|
|
|
|
if (video_mode_ptr != NULL) {
|
|
|
|
|
printf("sc%d: VGA registers for mode:%d\n",
|
|
|
|
|
dev->id_unit, scp->mode);
|
|
|
|
|
dump_vgaregs(video_mode_ptr + (64*scp->mode));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-04-04 20:06:26 +00:00
|
|
|
|
printf("sc%d: ", dev->id_unit);
|
1997-06-22 12:04:36 +00:00
|
|
|
|
switch(crtc_type) {
|
|
|
|
|
case KD_VGA:
|
1995-04-04 20:06:26 +00:00
|
|
|
|
if (crtc_addr == MONO_BASE)
|
|
|
|
|
printf("VGA mono");
|
1995-05-30 08:16:23 +00:00
|
|
|
|
else
|
1995-04-04 20:06:26 +00:00
|
|
|
|
printf("VGA color");
|
1997-06-22 12:04:36 +00:00
|
|
|
|
break;
|
|
|
|
|
case KD_EGA:
|
1995-04-04 20:06:26 +00:00
|
|
|
|
if (crtc_addr == MONO_BASE)
|
1997-06-22 12:04:36 +00:00
|
|
|
|
printf("EGA mono");
|
1995-05-30 08:16:23 +00:00
|
|
|
|
else
|
1997-06-22 12:04:36 +00:00
|
|
|
|
printf("EGA color");
|
|
|
|
|
break;
|
|
|
|
|
case KD_CGA:
|
|
|
|
|
printf("CGA");
|
|
|
|
|
break;
|
|
|
|
|
case KD_MONO:
|
|
|
|
|
case KD_HERCULES:
|
|
|
|
|
default:
|
|
|
|
|
printf("MDA/hercules");
|
|
|
|
|
break;
|
|
|
|
|
}
|
1996-09-01 18:16:06 +00:00
|
|
|
|
printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags);
|
1995-04-04 20:06:26 +00:00
|
|
|
|
|
1995-02-17 02:22:57 +00:00
|
|
|
|
#if NAPM > 0
|
1995-02-25 20:09:44 +00:00
|
|
|
|
scp->r_hook.ah_fun = scresume;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->r_hook.ah_arg = NULL;
|
|
|
|
|
scp->r_hook.ah_name = "system keyboard";
|
|
|
|
|
scp->r_hook.ah_order = APM_MID_ORDER;
|
|
|
|
|
apm_hook_establish(APM_HOOK_RESUME , &scp->r_hook);
|
|
|
|
|
#endif
|
1995-09-10 21:36:12 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
cdevsw_add(&cdev, &scdevsw, NULL);
|
1995-12-14 22:03:12 +00:00
|
|
|
|
|
1996-03-27 19:11:41 +00:00
|
|
|
|
#ifdef DEVFS
|
|
|
|
|
for (vc = 0; vc < MAXCONS; vc++)
|
1996-09-01 18:16:06 +00:00
|
|
|
|
sc_devfs_token[vc] = devfs_add_devswf(&scdevsw, vc, DV_CHR, UID_ROOT,
|
|
|
|
|
GID_WHEEL, 0600, "ttyv%n", vc);
|
1996-03-27 19:11:41 +00:00
|
|
|
|
#endif
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
struct tty
|
1995-02-25 20:09:44 +00:00
|
|
|
|
*scdevtotty(dev_t dev)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
int unit = minor(dev);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
if (init_done == COLD)
|
1996-02-08 06:30:31 +00:00
|
|
|
|
return(NULL);
|
1996-09-08 21:31:56 +00:00
|
|
|
|
if (unit == SC_CONSOLE)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return CONSOLE_TTY;
|
1996-09-08 21:31:56 +00:00
|
|
|
|
if (unit == SC_MOUSE)
|
|
|
|
|
return MOUSE_TTY;
|
|
|
|
|
if (unit >= MAXCONS || unit < 0)
|
|
|
|
|
return(NULL);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return VIRTUAL_TTY(unit);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
int
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scopen(dev_t dev, int flag, int mode, struct proc *p)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-25 20:09:44 +00:00
|
|
|
|
struct tty *tp = scdevtotty(dev);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
|
|
|
|
if (!tp)
|
|
|
|
|
return(ENXIO);
|
|
|
|
|
|
1996-09-10 19:14:49 +00:00
|
|
|
|
tp->t_oproc = (minor(dev) == SC_MOUSE) ? scmousestart : scstart;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
tp->t_param = scparam;
|
|
|
|
|
tp->t_dev = dev;
|
|
|
|
|
if (!(tp->t_state & TS_ISOPEN)) {
|
|
|
|
|
ttychars(tp);
|
1997-04-03 21:42:42 +00:00
|
|
|
|
/* Use the current setting of the <-- key as default VERASE. */
|
|
|
|
|
/* If the Delete key is preferable, an stty is necessary */
|
|
|
|
|
tp->t_cc[VERASE] = key_map.key[0x0e].map[0];
|
1995-02-22 13:48:07 +00:00
|
|
|
|
tp->t_iflag = TTYDEF_IFLAG;
|
|
|
|
|
tp->t_oflag = TTYDEF_OFLAG;
|
|
|
|
|
tp->t_cflag = TTYDEF_CFLAG;
|
|
|
|
|
tp->t_lflag = TTYDEF_LFLAG;
|
|
|
|
|
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
|
|
|
|
|
scparam(tp, &tp->t_termios);
|
|
|
|
|
ttsetwater(tp);
|
1995-07-31 21:02:00 +00:00
|
|
|
|
(*linesw[tp->t_line].l_modem)(tp, 1);
|
1995-05-30 08:16:23 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
|
|
|
|
|
return(EBUSY);
|
1996-09-30 23:00:58 +00:00
|
|
|
|
if (minor(dev) < MAXCONS && !console[minor(dev)]) {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
console[minor(dev)] = alloc_scp();
|
1996-10-01 23:24:09 +00:00
|
|
|
|
}
|
1996-10-15 20:27:07 +00:00
|
|
|
|
if (minor(dev)<MAXCONS && !tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
|
|
|
|
|
tp->t_winsize.ws_col = console[minor(dev)]->xsize;
|
|
|
|
|
tp->t_winsize.ws_row = console[minor(dev)]->ysize;
|
|
|
|
|
}
|
1996-10-01 23:24:09 +00:00
|
|
|
|
return ((*linesw[tp->t_line].l_open)(dev, tp));
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
int
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scclose(dev_t dev, int flag, int mode, struct proc *p)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-25 20:09:44 +00:00
|
|
|
|
struct tty *tp = scdevtotty(dev);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
struct scr_stat *scp;
|
|
|
|
|
|
|
|
|
|
if (!tp)
|
|
|
|
|
return(ENXIO);
|
|
|
|
|
if (minor(dev) < MAXCONS) {
|
|
|
|
|
scp = get_scr_stat(tp->t_dev);
|
|
|
|
|
if (scp->status & SWITCH_WAIT_ACQ)
|
|
|
|
|
wakeup((caddr_t)&scp->smode);
|
1995-01-28 22:18:05 +00:00
|
|
|
|
#if not_yet_done
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (scp == &main_console) {
|
|
|
|
|
scp->pid = 0;
|
|
|
|
|
scp->proc = NULL;
|
|
|
|
|
scp->smode.mode = VT_AUTO;
|
|
|
|
|
}
|
|
|
|
|
else {
|
1995-05-30 08:16:23 +00:00
|
|
|
|
free(scp->scr_buf, M_DEVBUF);
|
1997-07-07 13:42:42 +00:00
|
|
|
|
if (scp->history != NULL)
|
|
|
|
|
free(scp->history, M_DEVBUF);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
free(scp, M_DEVBUF);
|
|
|
|
|
console[minor(dev)] = NULL;
|
|
|
|
|
}
|
1995-01-28 22:18:05 +00:00
|
|
|
|
#else
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->pid = 0;
|
|
|
|
|
scp->proc = NULL;
|
|
|
|
|
scp->smode.mode = VT_AUTO;
|
1995-01-20 08:35:32 +00:00
|
|
|
|
#endif
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1996-11-11 22:21:03 +00:00
|
|
|
|
spltty();
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(*linesw[tp->t_line].l_close)(tp, flag);
|
1995-05-30 08:16:23 +00:00
|
|
|
|
ttyclose(tp);
|
1996-11-11 22:21:03 +00:00
|
|
|
|
spl0();
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return(0);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
int
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scread(dev_t dev, struct uio *uio, int flag)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-25 20:09:44 +00:00
|
|
|
|
struct tty *tp = scdevtotty(dev);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (!tp)
|
|
|
|
|
return(ENXIO);
|
|
|
|
|
return((*linesw[tp->t_line].l_read)(tp, uio, flag));
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
int
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scwrite(dev_t dev, struct uio *uio, int flag)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-25 20:09:44 +00:00
|
|
|
|
struct tty *tp = scdevtotty(dev);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (!tp)
|
|
|
|
|
return(ENXIO);
|
|
|
|
|
return((*linesw[tp->t_line].l_write)(tp, uio, flag));
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
void
|
1994-08-17 08:51:59 +00:00
|
|
|
|
scintr(int unit)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
static struct tty *cur_tty;
|
|
|
|
|
int c, len;
|
|
|
|
|
u_char *cp;
|
|
|
|
|
|
|
|
|
|
/* make screensaver happy */
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
scrn_time_stamp = mono_time.tv_sec;
|
1993-10-28 05:27:36 +00:00
|
|
|
|
|
1996-11-04 21:01:08 +00:00
|
|
|
|
/*
|
|
|
|
|
* Loop while there is still input to get from the keyboard.
|
|
|
|
|
* I don't think this is nessesary, and it doesn't fix
|
|
|
|
|
* the Xaccel-2.1 keyboard hang, but it can't hurt. XXX
|
|
|
|
|
*/
|
|
|
|
|
while ((c = scgetc(SCGETC_NONBLOCK)) != NOKEY) {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
1996-11-04 21:01:08 +00:00
|
|
|
|
cur_tty = VIRTUAL_TTY(get_scr_num());
|
|
|
|
|
if (!(cur_tty->t_state & TS_ISOPEN))
|
|
|
|
|
if (!((cur_tty = CONSOLE_TTY)->t_state & TS_ISOPEN))
|
1996-11-11 22:21:03 +00:00
|
|
|
|
continue;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
1996-11-04 21:01:08 +00:00
|
|
|
|
switch (c & 0xff00) {
|
|
|
|
|
case 0x0000: /* normal key */
|
|
|
|
|
(*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty);
|
|
|
|
|
break;
|
|
|
|
|
case FKEY: /* function key, return string */
|
|
|
|
|
if (cp = get_fstr((u_int)c, (u_int *)&len)) {
|
|
|
|
|
while (len-- > 0)
|
|
|
|
|
(*linesw[cur_tty->t_line].l_rint)(*cp++ & 0xFF, cur_tty);
|
|
|
|
|
}
|
1996-11-11 22:21:03 +00:00
|
|
|
|
break;
|
1996-11-04 21:01:08 +00:00
|
|
|
|
case MKEY: /* meta is active, prepend ESC */
|
|
|
|
|
(*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty);
|
|
|
|
|
(*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty);
|
|
|
|
|
break;
|
|
|
|
|
case BKEY: /* backtab fixed sequence (esc [ Z) */
|
|
|
|
|
(*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty);
|
|
|
|
|
(*linesw[cur_tty->t_line].l_rint)('[', cur_tty);
|
|
|
|
|
(*linesw[cur_tty->t_line].l_rint)('Z', cur_tty);
|
|
|
|
|
break;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
}
|
1996-11-04 21:01:08 +00:00
|
|
|
|
|
1996-10-18 18:51:37 +00:00
|
|
|
|
if (cur_console->status & MOUSE_ENABLED) {
|
|
|
|
|
cur_console->status &= ~MOUSE_VISIBLE;
|
|
|
|
|
remove_mouse_image(cur_console);
|
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-12-10 13:40:44 +00:00
|
|
|
|
static int
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scparam(struct tty *tp, struct termios *t)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
tp->t_ispeed = t->c_ispeed;
|
|
|
|
|
tp->t_ospeed = t->c_ospeed;
|
|
|
|
|
tp->t_cflag = t->c_cflag;
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
int
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1996-10-15 20:27:07 +00:00
|
|
|
|
int error;
|
|
|
|
|
u_int i;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
struct tty *tp;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
scr_stat *scp;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-25 20:09:44 +00:00
|
|
|
|
tp = scdevtotty(dev);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (!tp)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
scp = get_scr_stat(tp->t_dev);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1996-10-18 18:51:37 +00:00
|
|
|
|
/* If there is a user_ioctl function call that first */
|
|
|
|
|
if (sc_user_ioctl) {
|
|
|
|
|
if (error = (*sc_user_ioctl)(dev, cmd, data, flag, p))
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
switch (cmd) { /* process console hardware related ioctl's */
|
1994-10-17 22:12:06 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case GIO_ATTR: /* get current attributes */
|
1996-07-30 15:20:08 +00:00
|
|
|
|
*(int*)data = (scp->term.cur_attr >> 8) & 0xFF;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
1994-10-17 22:12:06 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case GIO_COLOR: /* is this a color console ? */
|
|
|
|
|
if (crtc_addr == COLOR_BASE)
|
|
|
|
|
*(int*)data = 1;
|
|
|
|
|
else
|
|
|
|
|
*(int*)data = 0;
|
|
|
|
|
return 0;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case CONS_CURRENT: /* get current adapter type */
|
1997-06-22 12:04:36 +00:00
|
|
|
|
*(int *)data = crtc_type;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
1994-10-17 22:12:06 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case CONS_GET: /* get current video mode */
|
|
|
|
|
*(int*)data = scp->mode;
|
|
|
|
|
return 0;
|
1994-09-15 07:26:40 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */
|
1997-05-15 05:43:59 +00:00
|
|
|
|
if (*(int *)data < 0)
|
|
|
|
|
return EINVAL;
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
scrn_blank_time = *(int *)data;
|
|
|
|
|
if (scrn_blank_time == 0)
|
|
|
|
|
scrn_time_stamp = mono_time.tv_sec;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
1994-09-15 07:26:40 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case CONS_CURSORTYPE: /* set cursor type blink/noblink */
|
|
|
|
|
if ((*(int*)data) & 0x01)
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags |= BLINK_CURSOR;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
else
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags &= ~BLINK_CURSOR;
|
1995-04-04 20:06:26 +00:00
|
|
|
|
if ((*(int*)data) & 0x02) {
|
1996-09-01 18:16:06 +00:00
|
|
|
|
if (!crtc_vga)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
flags |= CHAR_CURSOR;
|
1995-04-04 20:06:26 +00:00
|
|
|
|
} else
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags &= ~CHAR_CURSOR;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
/*
|
|
|
|
|
* The cursor shape is global property; all virtual consoles
|
|
|
|
|
* are affected. Update the cursor in the current console...
|
|
|
|
|
*/
|
|
|
|
|
if (!(cur_console->status & UNKNOWN_MODE)) {
|
|
|
|
|
remove_cursor_image(cur_console);
|
|
|
|
|
if (flags & CHAR_CURSOR)
|
|
|
|
|
set_destructive_cursor(cur_console);
|
|
|
|
|
draw_cursor_image(cur_console);
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
1994-09-15 07:26:40 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case CONS_BELLTYPE: /* set bell type sound/visual */
|
|
|
|
|
if (*data)
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags |= VISUAL_BELL;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
else
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags &= ~VISUAL_BELL;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
1995-01-12 11:47:05 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case CONS_HISTORY: /* set history size */
|
|
|
|
|
if (*data) {
|
1997-07-09 14:10:19 +00:00
|
|
|
|
if (cur_console->status & BUFFER_SAVED)
|
|
|
|
|
return EBUSY;
|
1997-07-07 13:42:42 +00:00
|
|
|
|
if (scp->history != NULL)
|
|
|
|
|
free(scp->history, M_DEVBUF);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->history_size = *(int*)data;
|
|
|
|
|
if (scp->history_size < scp->ysize)
|
|
|
|
|
scp->history = NULL;
|
|
|
|
|
else {
|
|
|
|
|
scp->history_size *= scp->xsize;
|
|
|
|
|
scp->history_head = scp->history_pos = scp->history =
|
|
|
|
|
(u_short *)malloc(scp->history_size*sizeof(u_short),
|
1995-08-08 05:14:40 +00:00
|
|
|
|
M_DEVBUF, M_WAITOK);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
bzero(scp->history_head, scp->history_size*sizeof(u_short));
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return EINVAL;
|
1995-01-12 11:47:05 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case CONS_MOUSECTL: /* control mouse arrow */
|
|
|
|
|
{
|
|
|
|
|
mouse_info_t *mouse = (mouse_info_t*)data;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
|
|
|
|
|
if (!crtc_vga)
|
|
|
|
|
return ENXIO;
|
1996-06-26 13:04:53 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
switch (mouse->operation) {
|
1996-06-25 08:54:57 +00:00
|
|
|
|
case MOUSE_MODE:
|
1997-03-01 23:53:46 +00:00
|
|
|
|
if (ISSIGVALID(mouse->u.mode.signal)) {
|
1996-06-25 08:54:57 +00:00
|
|
|
|
scp->mouse_signal = mouse->u.mode.signal;
|
|
|
|
|
scp->mouse_proc = p;
|
|
|
|
|
scp->mouse_pid = p->p_pid;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1996-06-25 08:54:57 +00:00
|
|
|
|
else {
|
|
|
|
|
scp->mouse_signal = 0;
|
|
|
|
|
scp->mouse_proc = NULL;
|
|
|
|
|
scp->mouse_pid = 0;
|
1996-06-21 07:19:18 +00:00
|
|
|
|
}
|
1996-09-08 21:31:56 +00:00
|
|
|
|
break;
|
1996-06-21 07:19:18 +00:00
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
case MOUSE_SHOW:
|
|
|
|
|
if (!(scp->status & MOUSE_ENABLED)) {
|
1996-10-18 18:51:37 +00:00
|
|
|
|
scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE);
|
1996-09-01 18:16:06 +00:00
|
|
|
|
scp->mouse_oldpos = scp->mouse_pos;
|
1996-06-25 08:54:57 +00:00
|
|
|
|
mark_all(scp);
|
1996-06-21 07:19:18 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return EINVAL;
|
|
|
|
|
break;
|
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
case MOUSE_HIDE:
|
|
|
|
|
if (scp->status & MOUSE_ENABLED) {
|
1996-10-18 18:51:37 +00:00
|
|
|
|
scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
mark_all(scp);
|
1996-06-21 07:19:18 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return EINVAL;
|
|
|
|
|
break;
|
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
case MOUSE_MOVEABS:
|
|
|
|
|
scp->mouse_xpos = mouse->u.data.x;
|
|
|
|
|
scp->mouse_ypos = mouse->u.data.y;
|
|
|
|
|
set_mouse_pos(scp);
|
1996-06-21 07:19:18 +00:00
|
|
|
|
break;
|
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
case MOUSE_MOVEREL:
|
|
|
|
|
scp->mouse_xpos += mouse->u.data.x;
|
|
|
|
|
scp->mouse_ypos += mouse->u.data.y;
|
|
|
|
|
set_mouse_pos(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
1994-10-17 22:12:06 +00:00
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
case MOUSE_GETINFO:
|
|
|
|
|
mouse->u.data.x = scp->mouse_xpos;
|
|
|
|
|
mouse->u.data.y = scp->mouse_ypos;
|
|
|
|
|
mouse->u.data.buttons = scp->mouse_buttons;
|
1996-09-08 21:31:56 +00:00
|
|
|
|
break;
|
1994-10-17 22:12:06 +00:00
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
case MOUSE_ACTION:
|
1996-09-30 23:00:58 +00:00
|
|
|
|
/* this should maybe only be settable from /dev/consolectl SOS */
|
|
|
|
|
/* send out mouse event on /dev/sysmouse */
|
1996-10-18 18:51:37 +00:00
|
|
|
|
if (cur_console->status & MOUSE_ENABLED)
|
|
|
|
|
cur_console->status |= MOUSE_VISIBLE;
|
1996-09-08 21:31:56 +00:00
|
|
|
|
if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
|
|
|
|
|
u_char buf[5];
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
buf[0] = 0x80 | ((~mouse->u.data.buttons) & 0x07);
|
|
|
|
|
buf[1] = (mouse->u.data.x & 0x1fe >> 1);
|
|
|
|
|
buf[3] = (mouse->u.data.x & 0x1ff) - buf[1];
|
|
|
|
|
buf[2] = -(mouse->u.data.y & 0x1fe >> 1);
|
|
|
|
|
buf[4] = -(mouse->u.data.y & 0x1ff) - buf[2];
|
|
|
|
|
for (i=0; i<5; i++)
|
|
|
|
|
(*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[i],MOUSE_TTY);
|
|
|
|
|
}
|
1996-06-26 13:04:53 +00:00
|
|
|
|
if (cur_console->mouse_signal) {
|
|
|
|
|
cur_console->mouse_buttons = mouse->u.data.buttons;
|
|
|
|
|
/* has controlling process died? */
|
|
|
|
|
if (cur_console->mouse_proc &&
|
|
|
|
|
(cur_console->mouse_proc != pfind(cur_console->mouse_pid))){
|
1996-06-25 08:54:57 +00:00
|
|
|
|
cur_console->mouse_signal = 0;
|
|
|
|
|
cur_console->mouse_proc = NULL;
|
|
|
|
|
cur_console->mouse_pid = 0;
|
|
|
|
|
}
|
1996-06-26 13:04:53 +00:00
|
|
|
|
else
|
|
|
|
|
psignal(cur_console->mouse_proc, cur_console->mouse_signal);
|
|
|
|
|
}
|
|
|
|
|
else {
|
1996-09-30 23:00:58 +00:00
|
|
|
|
/* process button presses */
|
1996-06-26 13:04:53 +00:00
|
|
|
|
if (cur_console->mouse_buttons != mouse->u.data.buttons) {
|
|
|
|
|
cur_console->mouse_buttons = mouse->u.data.buttons;
|
1997-02-13 11:58:49 +00:00
|
|
|
|
if (!(cur_console->status & UNKNOWN_MODE)) {
|
1996-06-25 08:54:57 +00:00
|
|
|
|
if (cur_console->mouse_buttons & LEFT_BUTTON)
|
|
|
|
|
mouse_cut_start(cur_console);
|
|
|
|
|
else
|
|
|
|
|
mouse_cut_end(cur_console);
|
1996-09-30 23:00:58 +00:00
|
|
|
|
if (cur_console->mouse_buttons & RIGHT_BUTTON ||
|
|
|
|
|
cur_console->mouse_buttons & MIDDLE_BUTTON)
|
1996-06-25 08:54:57 +00:00
|
|
|
|
mouse_paste(cur_console);
|
|
|
|
|
}
|
|
|
|
|
}
|
1996-06-21 07:19:18 +00:00
|
|
|
|
}
|
1997-08-09 19:24:03 +00:00
|
|
|
|
if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
|
|
|
|
|
cur_console->mouse_xpos += mouse->u.data.x;
|
|
|
|
|
cur_console->mouse_ypos += mouse->u.data.y;
|
1996-06-25 08:54:57 +00:00
|
|
|
|
set_mouse_pos(cur_console);
|
1997-08-09 19:24:03 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return EINVAL;
|
|
|
|
|
}
|
|
|
|
|
/* make screensaver happy */
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
scrn_time_stamp = mono_time.tv_sec;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case CONS_GETINFO: /* get current (virtual) console info */
|
|
|
|
|
{
|
|
|
|
|
vid_info_t *ptr = (vid_info_t*)data;
|
|
|
|
|
if (ptr->size == sizeof(struct vid_info)) {
|
|
|
|
|
ptr->m_num = get_scr_num();
|
|
|
|
|
ptr->mv_col = scp->xpos;
|
|
|
|
|
ptr->mv_row = scp->ypos;
|
|
|
|
|
ptr->mv_csz = scp->xsize;
|
|
|
|
|
ptr->mv_rsz = scp->ysize;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
ptr->mv_norm.fore = (scp->term.std_color & 0x0f00)>>8;
|
|
|
|
|
ptr->mv_norm.back = (scp->term.std_color & 0xf000)>>12;
|
|
|
|
|
ptr->mv_rev.fore = (scp->term.rev_color & 0x0f00)>>8;
|
|
|
|
|
ptr->mv_rev.back = (scp->term.rev_color & 0xf000)>>12;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
ptr->mv_grfc.fore = 0; /* not supported */
|
|
|
|
|
ptr->mv_grfc.back = 0; /* not supported */
|
|
|
|
|
ptr->mv_ovscan = scp->border;
|
|
|
|
|
ptr->mk_keylock = scp->status & LOCK_KEY_MASK;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return EINVAL;
|
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case CONS_GETVERS: /* get version number */
|
|
|
|
|
*(int*)data = 0x200; /* version 2.0 */
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* VGA TEXT MODES */
|
|
|
|
|
case SW_VGA_C40x25:
|
|
|
|
|
case SW_VGA_C80x25: case SW_VGA_M80x25:
|
|
|
|
|
case SW_VGA_C80x30: case SW_VGA_M80x30:
|
|
|
|
|
case SW_VGA_C80x50: case SW_VGA_M80x50:
|
|
|
|
|
case SW_VGA_C80x60: case SW_VGA_M80x60:
|
|
|
|
|
case SW_B40x25: case SW_C40x25:
|
|
|
|
|
case SW_B80x25: case SW_C80x25:
|
1995-05-30 08:16:23 +00:00
|
|
|
|
case SW_ENH_B40x25: case SW_ENH_C40x25:
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case SW_ENH_B80x25: case SW_ENH_C80x25:
|
|
|
|
|
case SW_ENH_B80x43: case SW_ENH_C80x43:
|
1997-05-15 05:43:59 +00:00
|
|
|
|
case SW_EGAMONO80x25:
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
|
|
|
|
if (!crtc_vga || video_mode_ptr == NULL)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
switch (cmd & 0xff) {
|
|
|
|
|
case M_VGA_C80x60: case M_VGA_M80x60:
|
|
|
|
|
if (!(fonts_loaded & FONT_8))
|
|
|
|
|
return EINVAL;
|
|
|
|
|
scp->xsize = 80;
|
|
|
|
|
scp->ysize = 60;
|
|
|
|
|
break;
|
|
|
|
|
case M_VGA_C80x50: case M_VGA_M80x50:
|
|
|
|
|
if (!(fonts_loaded & FONT_8))
|
1995-02-01 21:56:32 +00:00
|
|
|
|
return EINVAL;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize = 80;
|
|
|
|
|
scp->ysize = 50;
|
|
|
|
|
break;
|
|
|
|
|
case M_ENH_B80x43: case M_ENH_C80x43:
|
|
|
|
|
if (!(fonts_loaded & FONT_8))
|
|
|
|
|
return EINVAL;
|
|
|
|
|
scp->xsize = 80;
|
|
|
|
|
scp->ysize = 43;
|
|
|
|
|
break;
|
|
|
|
|
case M_VGA_C80x30: case M_VGA_M80x30:
|
|
|
|
|
scp->xsize = 80;
|
|
|
|
|
scp->ysize = 30;
|
|
|
|
|
break;
|
1997-05-15 05:43:59 +00:00
|
|
|
|
case M_ENH_C40x25: case M_ENH_B40x25:
|
|
|
|
|
case M_ENH_C80x25: case M_ENH_B80x25:
|
|
|
|
|
case M_EGAMONO80x25:
|
|
|
|
|
if (!(fonts_loaded & FONT_14))
|
|
|
|
|
return EINVAL;
|
|
|
|
|
/* FALL THROUGH */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
default:
|
|
|
|
|
if ((cmd & 0xff) > M_VGA_CG320)
|
|
|
|
|
return EINVAL;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
else
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize = *(video_mode_ptr+((cmd&0xff)*64));
|
|
|
|
|
scp->ysize = *(video_mode_ptr+((cmd&0xff)*64)+1)+1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
scp->mode = cmd & 0xff;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
free(scp->scr_buf, M_DEVBUF);
|
1996-09-30 23:00:58 +00:00
|
|
|
|
scp->scr_buf = (u_short *)
|
|
|
|
|
malloc(scp->xsize*scp->ysize*sizeof(u_short), M_DEVBUF, M_WAITOK);
|
|
|
|
|
scp->cursor_pos = scp->cursor_oldpos =
|
|
|
|
|
scp->scr_buf + scp->xpos + scp->ypos * scp->xsize;
|
|
|
|
|
scp->mouse_pos = scp->mouse_oldpos =
|
|
|
|
|
scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
|
|
|
|
|
scp->mouse_xpos/8);
|
1996-06-21 07:19:18 +00:00
|
|
|
|
free(cut_buffer, M_DEVBUF);
|
|
|
|
|
cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT);
|
|
|
|
|
cut_buffer[0] = 0x00;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (scp == cur_console)
|
|
|
|
|
set_mode(scp);
|
1996-10-02 22:00:38 +00:00
|
|
|
|
scp->status &= ~UNKNOWN_MODE;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
clear_screen(scp);
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if (tp->t_winsize.ws_col != scp->xsize
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|| tp->t_winsize.ws_row != scp->ysize) {
|
|
|
|
|
tp->t_winsize.ws_col = scp->xsize;
|
|
|
|
|
tp->t_winsize.ws_row = scp->ysize;
|
|
|
|
|
pgsignal(tp->t_pgrp, SIGWINCH, 1);
|
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
return 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
|
|
|
|
/* GRAPHICS MODES */
|
|
|
|
|
case SW_BG320: case SW_BG640:
|
|
|
|
|
case SW_CG320: case SW_CG320_D: case SW_CG640_E:
|
|
|
|
|
case SW_CG640x350: case SW_ENH_CG640:
|
|
|
|
|
case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
|
|
|
|
|
|
|
|
|
|
if (!crtc_vga || video_mode_ptr == NULL)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
scp->mode = cmd & 0xFF;
|
1996-09-30 23:00:58 +00:00
|
|
|
|
scp->xpixel = (*(video_mode_ptr + (scp->mode*64))) * 8;
|
|
|
|
|
scp->ypixel = (*(video_mode_ptr + (scp->mode*64) + 1) + 1) *
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(*(video_mode_ptr + (scp->mode*64) + 2));
|
1996-10-02 22:00:38 +00:00
|
|
|
|
if (scp == cur_console)
|
|
|
|
|
set_mode(scp);
|
|
|
|
|
scp->status |= UNKNOWN_MODE; /* graphics mode */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* clear_graphics();*/
|
|
|
|
|
|
1996-09-30 23:00:58 +00:00
|
|
|
|
if (tp->t_winsize.ws_xpixel != scp->xpixel
|
|
|
|
|
|| tp->t_winsize.ws_ypixel != scp->ypixel) {
|
|
|
|
|
tp->t_winsize.ws_xpixel = scp->xpixel;
|
|
|
|
|
tp->t_winsize.ws_ypixel = scp->ypixel;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
pgsignal(tp->t_pgrp, SIGWINCH, 1);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1997-08-08 22:52:30 +00:00
|
|
|
|
case SW_VGA_MODEX:
|
|
|
|
|
if (!crtc_vga || video_mode_ptr == NULL)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
scp->mode = cmd & 0xFF;
|
|
|
|
|
if (scp == cur_console)
|
|
|
|
|
set_mode(scp);
|
|
|
|
|
scp->status |= UNKNOWN_MODE; /* graphics mode */
|
|
|
|
|
/* clear_graphics();*/
|
|
|
|
|
scp->xpixel = 320;
|
|
|
|
|
scp->ypixel = 240;
|
|
|
|
|
if (tp->t_winsize.ws_xpixel != scp->xpixel
|
|
|
|
|
|| tp->t_winsize.ws_ypixel != scp->ypixel) {
|
|
|
|
|
tp->t_winsize.ws_xpixel = scp->xpixel;
|
|
|
|
|
tp->t_winsize.ws_ypixel = scp->ypixel;
|
|
|
|
|
pgsignal(tp->t_pgrp, SIGWINCH, 1);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case VT_SETMODE: /* set screen switcher mode */
|
1997-03-01 23:53:46 +00:00
|
|
|
|
{
|
|
|
|
|
struct vt_mode *mode;
|
|
|
|
|
|
|
|
|
|
mode = (struct vt_mode *)data;
|
|
|
|
|
if (ISSIGVALID(mode->relsig) && ISSIGVALID(mode->acqsig) &&
|
|
|
|
|
ISSIGVALID(mode->frsig)) {
|
|
|
|
|
bcopy(data, &scp->smode, sizeof(struct vt_mode));
|
|
|
|
|
if (scp->smode.mode == VT_PROCESS) {
|
|
|
|
|
scp->proc = p;
|
|
|
|
|
scp->pid = scp->proc->p_pid;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
} else
|
|
|
|
|
return EINVAL;
|
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case VT_GETMODE: /* get screen switcher mode */
|
|
|
|
|
bcopy(&scp->smode, data, sizeof(struct vt_mode));
|
|
|
|
|
return 0;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case VT_RELDISP: /* screen switcher ioctl */
|
|
|
|
|
switch(*data) {
|
|
|
|
|
case VT_FALSE: /* user refuses to release screen, abort */
|
|
|
|
|
if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) {
|
|
|
|
|
old_scp->status &= ~SWITCH_WAIT_REL;
|
|
|
|
|
switch_in_progress = FALSE;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
|
|
case VT_TRUE: /* user has released screen, go on */
|
|
|
|
|
if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) {
|
|
|
|
|
scp->status &= ~SWITCH_WAIT_REL;
|
|
|
|
|
exchange_scr();
|
|
|
|
|
if (new_scp->smode.mode == VT_PROCESS) {
|
|
|
|
|
new_scp->status |= SWITCH_WAIT_ACQ;
|
|
|
|
|
psignal(new_scp->proc, new_scp->smode.acqsig);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
else
|
1995-02-22 13:48:07 +00:00
|
|
|
|
switch_in_progress = FALSE;
|
1993-10-28 05:27:36 +00:00
|
|
|
|
return 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
return EINVAL;
|
1993-10-28 05:27:36 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case VT_ACKACQ: /* acquire acknowledged, switch completed */
|
|
|
|
|
if (scp == new_scp && (scp->status & SWITCH_WAIT_ACQ)) {
|
|
|
|
|
scp->status &= ~SWITCH_WAIT_ACQ;
|
|
|
|
|
switch_in_progress = FALSE;
|
1995-02-01 21:56:32 +00:00
|
|
|
|
return 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
return EINVAL;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
default:
|
|
|
|
|
return EINVAL;
|
|
|
|
|
}
|
|
|
|
|
/* NOT REACHED */
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case VT_OPENQRY: /* return free virtual console */
|
|
|
|
|
for (i = 0; i < MAXCONS; i++) {
|
|
|
|
|
tp = VIRTUAL_TTY(i);
|
|
|
|
|
if (!(tp->t_state & TS_ISOPEN)) {
|
|
|
|
|
*data = i + 1;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
return 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
|
|
case VT_ACTIVATE: /* switch to screen *data */
|
|
|
|
|
return switch_scr(scp, (*data) - 1);
|
|
|
|
|
|
|
|
|
|
case VT_WAITACTIVE: /* wait for switch to occur */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if (*data > MAXCONS || *data < 0)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return EINVAL;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if (minor(dev) == (*data) - 1)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
|
|
|
|
if (*data == 0) {
|
|
|
|
|
if (scp == cur_console)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
return 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
else
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp = console[(*data) - 1];
|
1995-05-30 08:16:23 +00:00
|
|
|
|
while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
"waitvt", 0)) == ERESTART) ;
|
|
|
|
|
return error;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case VT_GETACTIVE:
|
|
|
|
|
*data = get_scr_num()+1;
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDENABIO: /* allow io operations */
|
1995-10-14 07:08:09 +00:00
|
|
|
|
error = suser(p->p_ucred, &p->p_acflag);
|
|
|
|
|
if (error != 0)
|
|
|
|
|
return error;
|
1996-11-11 22:21:03 +00:00
|
|
|
|
if (securelevel > 0)
|
|
|
|
|
return EPERM;
|
1997-05-07 20:02:38 +00:00
|
|
|
|
p->p_md.md_regs->tf_eflags |= PSL_IOPL;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDDISABIO: /* disallow io operations (default) */
|
1997-05-07 20:02:38 +00:00
|
|
|
|
p->p_md.md_regs->tf_eflags &= ~PSL_IOPL;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDSETMODE: /* set current mode of this (virtual) console */
|
|
|
|
|
switch (*data) {
|
|
|
|
|
case KD_TEXT: /* switch to TEXT (known) mode */
|
|
|
|
|
/* restore fonts & palette ! */
|
|
|
|
|
if (crtc_vga) {
|
|
|
|
|
if (fonts_loaded & FONT_8)
|
|
|
|
|
copy_font(LOAD, FONT_8, font_8);
|
|
|
|
|
if (fonts_loaded & FONT_14)
|
|
|
|
|
copy_font(LOAD, FONT_14, font_14);
|
|
|
|
|
if (fonts_loaded & FONT_16)
|
|
|
|
|
copy_font(LOAD, FONT_16, font_16);
|
1997-01-15 18:16:32 +00:00
|
|
|
|
load_palette(palette);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
/* FALL THROUGH */
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KD_TEXT1: /* switch to TEXT (known) mode */
|
|
|
|
|
/* no restore fonts & palette */
|
|
|
|
|
if (crtc_vga && video_mode_ptr)
|
|
|
|
|
set_mode(scp);
|
1996-09-30 23:00:58 +00:00
|
|
|
|
scp->status &= ~UNKNOWN_MODE;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
clear_screen(scp);
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
|
|
|
|
|
scp->status |= UNKNOWN_MODE;
|
|
|
|
|
return 0;
|
|
|
|
|
default:
|
|
|
|
|
return EINVAL;
|
|
|
|
|
}
|
|
|
|
|
/* NOT REACHED */
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDGETMODE: /* get current mode of this (virtual) console */
|
|
|
|
|
*data = (scp->status & UNKNOWN_MODE) ? KD_GRAPHICS : KD_TEXT;
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDSBORDER: /* set border color of this (virtual) console */
|
|
|
|
|
scp->border = *data;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if (scp == cur_console)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
set_border(scp->border);
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDSKBSTATE: /* set keyboard state (locks) */
|
|
|
|
|
if (*data >= 0 && *data <= LOCK_KEY_MASK) {
|
|
|
|
|
scp->status &= ~LOCK_KEY_MASK;
|
|
|
|
|
scp->status |= *data;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if (scp == cur_console)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
update_leds(scp->status);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return EINVAL;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDGKBSTATE: /* get keyboard state (locks) */
|
|
|
|
|
*data = scp->status & LOCK_KEY_MASK;
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDSETRAD: /* set keyboard repeat & delay rates */
|
|
|
|
|
if (*data & 0x80)
|
|
|
|
|
return EINVAL;
|
1997-01-15 18:16:32 +00:00
|
|
|
|
if (sc_kbdc != NULL)
|
|
|
|
|
set_keyboard(KBDC_SET_TYPEMATIC, *data);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDSKBMODE: /* set keyboard mode */
|
|
|
|
|
switch (*data) {
|
|
|
|
|
case K_RAW: /* switch to RAW scancode mode */
|
|
|
|
|
scp->status |= KBD_RAW_MODE;
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case K_XLATE: /* switch to XLT ascii mode */
|
1997-01-20 08:05:15 +00:00
|
|
|
|
if (scp == cur_console && scp->status & KBD_RAW_MODE)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
shfts = ctls = alts = agrs = metas = 0;
|
|
|
|
|
scp->status &= ~KBD_RAW_MODE;
|
|
|
|
|
return 0;
|
|
|
|
|
default:
|
|
|
|
|
return EINVAL;
|
|
|
|
|
}
|
|
|
|
|
/* NOT REACHED */
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDGKBMODE: /* get keyboard mode */
|
|
|
|
|
*data = (scp->status & KBD_RAW_MODE) ? K_RAW : K_XLATE;
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KDMKTONE: /* sound the bell */
|
|
|
|
|
if (*(int*)data)
|
|
|
|
|
do_bell(scp, (*(int*)data)&0xffff,
|
|
|
|
|
(((*(int*)data)>>16)&0xffff)*hz/1000);
|
|
|
|
|
else
|
|
|
|
|
do_bell(scp, scp->bell_pitch, scp->bell_duration);
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case KIOCSOUND: /* make tone (*data) hz */
|
|
|
|
|
if (scp == cur_console) {
|
|
|
|
|
if (*(int*)data) {
|
1996-10-26 20:16:58 +00:00
|
|
|
|
int pitch = timer_freq / *(int*)data;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* set command for counter 2, 2 byte write */
|
|
|
|
|
if (acquire_timer2(TIMER_16BIT|TIMER_SQWAVE))
|
|
|
|
|
return EBUSY;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* set pitch */
|
|
|
|
|
outb(TIMER_CNTR2, pitch);
|
|
|
|
|
outb(TIMER_CNTR2, (pitch>>8));
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* enable counter 2 output to speaker */
|
|
|
|
|
outb(IO_PPI, inb(IO_PPI) | 3);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* disable counter 2 output to speaker */
|
|
|
|
|
outb(IO_PPI, inb(IO_PPI) & 0xFC);
|
|
|
|
|
release_timer2();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case KDGKBTYPE: /* get keyboard type */
|
|
|
|
|
*data = 0; /* type not known (yet) */
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case KDSETLED: /* set keyboard LED status */
|
|
|
|
|
if (*data >= 0 && *data <= LED_MASK) {
|
|
|
|
|
scp->status &= ~LED_MASK;
|
|
|
|
|
scp->status |= *data;
|
|
|
|
|
if (scp == cur_console)
|
|
|
|
|
update_leds(scp->status);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
|
|
case KDGETLED: /* get keyboard LED status */
|
|
|
|
|
*data = scp->status & LED_MASK;
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case GETFKEY: /* get functionkey string */
|
|
|
|
|
if (*(u_short*)data < n_fkey_tab) {
|
|
|
|
|
fkeyarg_t *ptr = (fkeyarg_t*)data;
|
|
|
|
|
bcopy(&fkey_tab[ptr->keynum].str, ptr->keydef,
|
|
|
|
|
fkey_tab[ptr->keynum].len);
|
|
|
|
|
ptr->flen = fkey_tab[ptr->keynum].len;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
|
|
case SETFKEY: /* set functionkey string */
|
|
|
|
|
if (*(u_short*)data < n_fkey_tab) {
|
|
|
|
|
fkeyarg_t *ptr = (fkeyarg_t*)data;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
bcopy(ptr->keydef, &fkey_tab[ptr->keynum].str,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
min(ptr->flen, MAXFK));
|
|
|
|
|
fkey_tab[ptr->keynum].len = min(ptr->flen, MAXFK);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
|
|
case GIO_SCRNMAP: /* get output translation table */
|
|
|
|
|
bcopy(&scr_map, data, sizeof(scr_map));
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case PIO_SCRNMAP: /* set output translation table */
|
|
|
|
|
bcopy(data, &scr_map, sizeof(scr_map));
|
1996-09-01 18:16:06 +00:00
|
|
|
|
for (i=0; i<sizeof(scr_map); i++)
|
|
|
|
|
scr_rmap[scr_map[i]] = i;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case GIO_KEYMAP: /* get keyboard translation table */
|
|
|
|
|
bcopy(&key_map, data, sizeof(key_map));
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case PIO_KEYMAP: /* set keyboard translation table */
|
|
|
|
|
bcopy(data, &key_map, sizeof(key_map));
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case PIO_FONT8x8: /* set 8x8 dot font */
|
|
|
|
|
if (!crtc_vga)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
bcopy(data, font_8, 8*256);
|
|
|
|
|
fonts_loaded |= FONT_8;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
if (!(cur_console->status & UNKNOWN_MODE)) {
|
|
|
|
|
copy_font(LOAD, FONT_8, font_8);
|
|
|
|
|
if (flags & CHAR_CURSOR)
|
|
|
|
|
set_destructive_cursor(cur_console);
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case GIO_FONT8x8: /* get 8x8 dot font */
|
|
|
|
|
if (!crtc_vga)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
if (fonts_loaded & FONT_8) {
|
|
|
|
|
bcopy(font_8, data, 8*256);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return ENXIO;
|
|
|
|
|
|
|
|
|
|
case PIO_FONT8x14: /* set 8x14 dot font */
|
|
|
|
|
if (!crtc_vga)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
bcopy(data, font_14, 14*256);
|
|
|
|
|
fonts_loaded |= FONT_14;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
if (!(cur_console->status & UNKNOWN_MODE)) {
|
|
|
|
|
copy_font(LOAD, FONT_14, font_14);
|
|
|
|
|
if (flags & CHAR_CURSOR)
|
|
|
|
|
set_destructive_cursor(cur_console);
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case GIO_FONT8x14: /* get 8x14 dot font */
|
|
|
|
|
if (!crtc_vga)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
if (fonts_loaded & FONT_14) {
|
|
|
|
|
bcopy(font_14, data, 14*256);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return ENXIO;
|
|
|
|
|
|
|
|
|
|
case PIO_FONT8x16: /* set 8x16 dot font */
|
|
|
|
|
if (!crtc_vga)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
bcopy(data, font_16, 16*256);
|
|
|
|
|
fonts_loaded |= FONT_16;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
if (!(cur_console->status & UNKNOWN_MODE)) {
|
|
|
|
|
copy_font(LOAD, FONT_16, font_16);
|
|
|
|
|
if (flags & CHAR_CURSOR)
|
|
|
|
|
set_destructive_cursor(cur_console);
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case GIO_FONT8x16: /* get 8x16 dot font */
|
|
|
|
|
if (!crtc_vga)
|
|
|
|
|
return ENXIO;
|
|
|
|
|
if (fonts_loaded & FONT_16) {
|
|
|
|
|
bcopy(font_16, data, 16*256);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return ENXIO;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
|
|
|
|
|
if (error >= 0)
|
|
|
|
|
return(error);
|
|
|
|
|
error = ttioctl(tp, cmd, data, flag);
|
|
|
|
|
if (error >= 0)
|
|
|
|
|
return(error);
|
|
|
|
|
return(ENOTTY);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-12-10 13:40:44 +00:00
|
|
|
|
static void
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scstart(struct tty *tp)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
struct clist *rbp;
|
1995-11-20 12:13:32 +00:00
|
|
|
|
int s, len;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
u_char buf[PCBURST];
|
|
|
|
|
scr_stat *scp = get_scr_stat(tp->t_dev);
|
1993-10-28 05:27:36 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (scp->status & SLKED || blink_in_progress)
|
1996-09-08 21:31:56 +00:00
|
|
|
|
return; /* XXX who repeats the call when the above flags are cleared? */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
s = spltty();
|
1995-07-11 18:34:30 +00:00
|
|
|
|
if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
tp->t_state |= TS_BUSY;
|
|
|
|
|
rbp = &tp->t_outq;
|
|
|
|
|
while (rbp->c_cc) {
|
|
|
|
|
len = q_to_b(rbp, buf, PCBURST);
|
1995-07-11 18:34:30 +00:00
|
|
|
|
splx(s);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
ansi_put(scp, buf, len);
|
1995-07-11 18:34:30 +00:00
|
|
|
|
s = spltty();
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
tp->t_state &= ~TS_BUSY;
|
1995-07-22 01:30:45 +00:00
|
|
|
|
ttwwakeup(tp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
splx(s);
|
|
|
|
|
}
|
|
|
|
|
|
1996-09-10 19:14:49 +00:00
|
|
|
|
static void
|
|
|
|
|
scmousestart(struct tty *tp)
|
|
|
|
|
{
|
|
|
|
|
struct clist *rbp;
|
|
|
|
|
int s;
|
|
|
|
|
u_char buf[PCBURST];
|
|
|
|
|
|
|
|
|
|
s = spltty();
|
|
|
|
|
if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
|
|
|
|
|
tp->t_state |= TS_BUSY;
|
|
|
|
|
rbp = &tp->t_outq;
|
|
|
|
|
while (rbp->c_cc) {
|
|
|
|
|
q_to_b(rbp, buf, PCBURST);
|
|
|
|
|
}
|
|
|
|
|
tp->t_state &= ~TS_BUSY;
|
|
|
|
|
ttwwakeup(tp);
|
|
|
|
|
}
|
|
|
|
|
splx(s);
|
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
void
|
1995-09-10 21:36:12 +00:00
|
|
|
|
sccnprobe(struct consdev *cp)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-09-10 21:36:12 +00:00
|
|
|
|
struct isa_device *dvp;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-09-10 21:36:12 +00:00
|
|
|
|
/*
|
|
|
|
|
* Take control if we are the highest priority enabled display device.
|
|
|
|
|
*/
|
|
|
|
|
dvp = find_display();
|
1996-10-09 15:24:21 +00:00
|
|
|
|
if (dvp == NULL || dvp->id_driver != &scdriver) {
|
1995-09-10 21:36:12 +00:00
|
|
|
|
cp->cn_pri = CN_DEAD;
|
|
|
|
|
return;
|
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1997-06-22 12:04:36 +00:00
|
|
|
|
if (!scvidprobe(dvp->id_unit, dvp->id_flags)) {
|
|
|
|
|
cp->cn_pri = CN_DEAD;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* initialize required fields */
|
1996-09-08 21:31:56 +00:00
|
|
|
|
cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
cp->cn_pri = CN_INTERNAL;
|
1997-01-15 18:16:32 +00:00
|
|
|
|
|
|
|
|
|
sc_kbdc = kbdc_open(sc_port);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
void
|
1995-09-10 21:36:12 +00:00
|
|
|
|
sccninit(struct consdev *cp)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scinit();
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
void
|
1995-09-10 21:36:12 +00:00
|
|
|
|
sccnputc(dev_t dev, int c)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-04-23 10:15:42 +00:00
|
|
|
|
u_char buf[1];
|
1996-05-01 03:58:21 +00:00
|
|
|
|
int s;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scr_stat *scp = console[0];
|
|
|
|
|
term_stat save = scp->term;
|
|
|
|
|
|
|
|
|
|
scp->term = kernel_console;
|
|
|
|
|
current_default = &kernel_default;
|
1996-11-11 22:21:03 +00:00
|
|
|
|
if (scp == cur_console && !(scp->status & UNKNOWN_MODE))
|
1996-09-01 18:16:06 +00:00
|
|
|
|
remove_cursor_image(scp);
|
1995-06-14 05:16:12 +00:00
|
|
|
|
buf[0] = c;
|
|
|
|
|
ansi_put(scp, buf, 1);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
kernel_console = scp->term;
|
|
|
|
|
current_default = &user_default;
|
|
|
|
|
scp->term = save;
|
1996-06-21 07:19:18 +00:00
|
|
|
|
s = splclock();
|
1996-09-30 23:00:58 +00:00
|
|
|
|
if (scp == cur_console && !(scp->status & UNKNOWN_MODE)) {
|
1996-10-02 22:00:38 +00:00
|
|
|
|
if (/* timer not running && */ (scp->start <= scp->end)) {
|
1997-04-27 09:03:10 +00:00
|
|
|
|
sc_bcopy(scp->scr_buf + scp->start, Crtat + scp->start,
|
1995-03-29 20:55:03 +00:00
|
|
|
|
(1 + scp->end - scp->start) * sizeof(u_short));
|
|
|
|
|
scp->start = scp->xsize * scp->ysize;
|
|
|
|
|
scp->end = 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1996-09-01 18:16:06 +00:00
|
|
|
|
scp->cursor_oldpos = scp->cursor_pos;
|
|
|
|
|
draw_cursor_image(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1996-05-01 03:58:21 +00:00
|
|
|
|
splx(s);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
int
|
1995-09-10 21:36:12 +00:00
|
|
|
|
sccngetc(dev_t dev)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
int s = spltty(); /* block scintr and scrn_timer while we poll */
|
|
|
|
|
int c;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Stop the screen saver if necessary.
|
|
|
|
|
* What if we have been running in the screen saver code... XXX
|
|
|
|
|
*/
|
|
|
|
|
if (scrn_blanked > 0)
|
|
|
|
|
stop_scrn_saver(current_saver);
|
|
|
|
|
|
|
|
|
|
c = scgetc(SCGETC_CN);
|
|
|
|
|
|
|
|
|
|
/* make sure the screen saver won't be activated soon */
|
|
|
|
|
scrn_time_stamp = mono_time.tv_sec;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
splx(s);
|
|
|
|
|
return(c);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
int
|
1995-09-10 21:36:12 +00:00
|
|
|
|
sccncheckc(dev_t dev)
|
1994-10-20 00:08:31 +00:00
|
|
|
|
{
|
1996-09-14 04:27:46 +00:00
|
|
|
|
int c, s;
|
|
|
|
|
|
|
|
|
|
s = spltty();
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
if (scrn_blanked > 0)
|
|
|
|
|
stop_scrn_saver(current_saver);
|
1996-10-26 20:16:58 +00:00
|
|
|
|
c = scgetc(SCGETC_CN | SCGETC_NONBLOCK);
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
if (c != NOKEY)
|
|
|
|
|
scrn_time_stamp = mono_time.tv_sec;
|
1996-09-14 04:27:46 +00:00
|
|
|
|
splx(s);
|
|
|
|
|
return(c == NOKEY ? -1 : c); /* c == -1 can't happen */
|
1994-02-01 10:43:02 +00:00
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1996-10-02 22:00:38 +00:00
|
|
|
|
static scr_stat
|
|
|
|
|
*get_scr_stat(dev_t dev)
|
|
|
|
|
{
|
|
|
|
|
int unit = minor(dev);
|
|
|
|
|
|
|
|
|
|
if (unit == SC_CONSOLE)
|
|
|
|
|
return console[0];
|
|
|
|
|
if (unit >= MAXCONS || unit < 0)
|
|
|
|
|
return(NULL);
|
|
|
|
|
return console[unit];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
get_scr_num()
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
while ((i < MAXCONS) && (cur_console != console[i]))
|
|
|
|
|
i++;
|
|
|
|
|
return i < MAXCONS ? i : 0;
|
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static void
|
1997-04-20 16:05:33 +00:00
|
|
|
|
scrn_timer(void *arg)
|
o Restore removed hardware cursor support and make it _default_
case, software cursor now optional case. Driver must provide
raw things (what hardware do for us, exactly) as default case,
all driver features must be _optional_. Modern VGAs have internal
configuration utilities to set cursor shape/blinking which stored
into cards ROM, and syscons nuke out such features completely
by forcing software cursor. Moreover, software cursor is hard
to distinguish on standouted (or near standouted) fields and
tends to disappearse from the screen.
Set "flags 0x4" to enable software cursor now.
o Cleanup screen savers.
o Don't draw cursor if saver or blinker is active.
o Duplicated code moved to functons.
o Add more checks for blinker in progress, character lost otherwise
when blinker restore old contents.
o Reduce blinking counter to 3, too slow in old variant.
o Fix timeout code in scrn_timer(), old variant can reenter iself,
if action takes too long time.
o Disable visual bell for scroll lock mode, saved screen
becomes overwritted otherwise.
1995-01-26 04:56:25 +00:00
|
|
|
|
{
|
1995-02-01 21:56:32 +00:00
|
|
|
|
scr_stat *scp = cur_console;
|
1996-10-01 23:24:09 +00:00
|
|
|
|
int s = spltty();
|
o Restore removed hardware cursor support and make it _default_
case, software cursor now optional case. Driver must provide
raw things (what hardware do for us, exactly) as default case,
all driver features must be _optional_. Modern VGAs have internal
configuration utilities to set cursor shape/blinking which stored
into cards ROM, and syscons nuke out such features completely
by forcing software cursor. Moreover, software cursor is hard
to distinguish on standouted (or near standouted) fields and
tends to disappearse from the screen.
Set "flags 0x4" to enable software cursor now.
o Cleanup screen savers.
o Don't draw cursor if saver or blinker is active.
o Duplicated code moved to functons.
o Add more checks for blinker in progress, character lost otherwise
when blinker restore old contents.
o Reduce blinking counter to 3, too slow in old variant.
o Fix timeout code in scrn_timer(), old variant can reenter iself,
if action takes too long time.
o Disable visual bell for scroll lock mode, saved screen
becomes overwritted otherwise.
1995-01-26 04:56:25 +00:00
|
|
|
|
|
1996-11-04 21:01:08 +00:00
|
|
|
|
/*
|
|
|
|
|
* With release 2.1 of the Xaccel server, the keyboard is left
|
1996-11-15 08:45:24 +00:00
|
|
|
|
* hanging pretty often. Apparently an interrupt from the
|
1996-11-04 21:01:08 +00:00
|
|
|
|
* keyboard is lost, and I don't know why (yet).
|
1996-11-15 08:45:24 +00:00
|
|
|
|
* This ugly hack calls scintr if input is ready for the keyboard
|
|
|
|
|
* and conveniently hides the problem. XXX
|
1996-11-04 21:01:08 +00:00
|
|
|
|
*/
|
1997-01-15 18:16:32 +00:00
|
|
|
|
/* Try removing anything stuck in the keyboard controller; whether
|
|
|
|
|
* it's a keyboard scan code or mouse data. `scintr()' doesn't
|
|
|
|
|
* read the mouse data directly, but `kbdio' routines will, as a
|
|
|
|
|
* side effect.
|
|
|
|
|
*/
|
|
|
|
|
if (kbdc_lock(sc_kbdc, TRUE)) {
|
|
|
|
|
/*
|
|
|
|
|
* We have seen the lock flag is not set. Let's reset the flag early;
|
|
|
|
|
* otherwise `update_led()' failes which may want the lock
|
|
|
|
|
* during `scintr()'.
|
|
|
|
|
*/
|
|
|
|
|
kbdc_lock(sc_kbdc, FALSE);
|
|
|
|
|
if (kbdc_data_ready(sc_kbdc))
|
|
|
|
|
scintr(0);
|
|
|
|
|
}
|
1996-11-04 21:01:08 +00:00
|
|
|
|
|
1995-02-01 21:56:32 +00:00
|
|
|
|
/* should we just return ? */
|
1995-02-05 23:44:25 +00:00
|
|
|
|
if ((scp->status&UNKNOWN_MODE) || blink_in_progress || switch_in_progress) {
|
1997-04-20 16:05:33 +00:00
|
|
|
|
timeout(scrn_timer, NULL, hz / 10);
|
1996-10-26 20:16:58 +00:00
|
|
|
|
splx(s);
|
1995-02-01 21:56:32 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
/* should we stop the screen saver? */
|
|
|
|
|
if (mono_time.tv_sec <= scrn_time_stamp + scrn_blank_time)
|
|
|
|
|
if (scrn_blanked > 0)
|
|
|
|
|
stop_scrn_saver(current_saver);
|
|
|
|
|
|
|
|
|
|
if (scrn_blanked <= 0) {
|
1995-03-29 20:55:03 +00:00
|
|
|
|
/* update screen image */
|
|
|
|
|
if (scp->start <= scp->end) {
|
1997-04-27 09:03:10 +00:00
|
|
|
|
sc_bcopy(scp->scr_buf + scp->start, Crtat + scp->start,
|
1995-03-29 20:55:03 +00:00
|
|
|
|
(1 + scp->end - scp->start) * sizeof(u_short));
|
1996-06-21 11:31:09 +00:00
|
|
|
|
}
|
1995-02-05 23:44:25 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
/* update "pseudo" mouse pointer image */
|
1996-10-18 18:51:37 +00:00
|
|
|
|
if ((scp->status & MOUSE_VISIBLE) && crtc_vga) {
|
1996-09-01 18:16:06 +00:00
|
|
|
|
/* did mouse move since last time ? */
|
|
|
|
|
if (scp->status & MOUSE_MOVED) {
|
|
|
|
|
/* do we need to remove old mouse pointer image ? */
|
|
|
|
|
if (scp->mouse_cut_start != NULL ||
|
|
|
|
|
(scp->mouse_pos-scp->scr_buf) <= scp->start ||
|
|
|
|
|
(scp->mouse_pos+scp->xsize+1-scp->scr_buf) >= scp->end) {
|
|
|
|
|
remove_mouse_image(scp);
|
|
|
|
|
}
|
|
|
|
|
scp->status &= ~MOUSE_MOVED;
|
|
|
|
|
draw_mouse_image(scp);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* mouse didn't move, has it been overwritten ? */
|
|
|
|
|
if ((scp->mouse_pos+scp->xsize+1-scp->scr_buf) >= scp->start &&
|
|
|
|
|
(scp->mouse_pos - scp->scr_buf) <= scp->end) {
|
|
|
|
|
draw_mouse_image(scp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-02-01 21:56:32 +00:00
|
|
|
|
/* update cursor image */
|
1996-09-01 18:16:06 +00:00
|
|
|
|
if (scp->status & CURSOR_ENABLED) {
|
|
|
|
|
/* did cursor move since last time ? */
|
|
|
|
|
if (scp->cursor_pos != scp->cursor_oldpos) {
|
|
|
|
|
/* do we need to remove old cursor image ? */
|
1996-10-02 22:00:38 +00:00
|
|
|
|
if ((scp->cursor_oldpos - scp->scr_buf) < scp->start ||
|
|
|
|
|
((scp->cursor_oldpos - scp->scr_buf) > scp->end)) {
|
1996-09-01 18:16:06 +00:00
|
|
|
|
remove_cursor_image(scp);
|
|
|
|
|
}
|
|
|
|
|
scp->cursor_oldpos = scp->cursor_pos;
|
|
|
|
|
draw_cursor_image(scp);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* cursor didn't move, has it been overwritten ? */
|
1996-10-02 22:00:38 +00:00
|
|
|
|
if (scp->cursor_pos - scp->scr_buf >= scp->start &&
|
|
|
|
|
scp->cursor_pos - scp->scr_buf <= scp->end) {
|
1996-09-01 18:16:06 +00:00
|
|
|
|
draw_cursor_image(scp);
|
|
|
|
|
} else {
|
|
|
|
|
/* if its a blinking cursor, we may have to update it */
|
|
|
|
|
if (flags & BLINK_CURSOR)
|
|
|
|
|
draw_cursor_image(scp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
blinkrate++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (scp->mouse_cut_start != NULL)
|
|
|
|
|
draw_cutmarking(scp);
|
|
|
|
|
|
|
|
|
|
scp->end = 0;
|
|
|
|
|
scp->start = scp->xsize*scp->ysize;
|
1995-02-01 21:56:32 +00:00
|
|
|
|
}
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
|
|
|
|
|
/* should we activate the screen saver? */
|
|
|
|
|
if ((scrn_blank_time != 0)
|
|
|
|
|
&& (mono_time.tv_sec > scrn_time_stamp + scrn_blank_time))
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(*current_saver)(TRUE);
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
|
1997-04-20 16:05:33 +00:00
|
|
|
|
timeout(scrn_timer, NULL, hz / 25);
|
1996-10-01 23:24:09 +00:00
|
|
|
|
splx(s);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
int
|
|
|
|
|
add_scrn_saver(void (*this_saver)(int))
|
|
|
|
|
{
|
|
|
|
|
if (current_saver != none_saver)
|
|
|
|
|
return EBUSY;
|
|
|
|
|
current_saver = this_saver;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
remove_scrn_saver(void (*this_saver)(int))
|
|
|
|
|
{
|
|
|
|
|
if (current_saver != this_saver)
|
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* In order to prevent `current_saver' from being called by
|
|
|
|
|
* the timeout routine `scrn_timer()' while we manipulate
|
|
|
|
|
* the saver list, we shall set `current_saver' to `none_saver'
|
|
|
|
|
* before stopping the current saver, rather than blocking by `splXX()'.
|
|
|
|
|
*/
|
|
|
|
|
current_saver = none_saver;
|
|
|
|
|
if (scrn_blanked > 0)
|
|
|
|
|
stop_scrn_saver(this_saver);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
stop_scrn_saver(void (*saver)(int))
|
|
|
|
|
{
|
|
|
|
|
(*saver)(FALSE);
|
|
|
|
|
scrn_time_stamp = mono_time.tv_sec;
|
|
|
|
|
mark_all(cur_console);
|
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static void
|
1994-08-17 08:51:59 +00:00
|
|
|
|
clear_screen(scr_stat *scp)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
move_crsr(scp, 0, 0);
|
1996-09-04 22:24:19 +00:00
|
|
|
|
scp->cursor_oldpos = scp->cursor_pos;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20], scp->scr_buf,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize * scp->ysize);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_all(scp);
|
1996-09-01 18:16:06 +00:00
|
|
|
|
remove_cutmarking(scp);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static int
|
1995-01-12 11:47:05 +00:00
|
|
|
|
switch_scr(scr_stat *scp, u_int next_scr)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (switch_in_progress && (cur_console->proc != pfind(cur_console->pid)))
|
|
|
|
|
switch_in_progress = FALSE;
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if (next_scr >= MAXCONS || switch_in_progress ||
|
|
|
|
|
(cur_console->smode.mode == VT_AUTO
|
1995-02-22 13:48:07 +00:00
|
|
|
|
&& cur_console->status & UNKNOWN_MODE)) {
|
|
|
|
|
do_bell(scp, BELL_PITCH, BELL_DURATION);
|
|
|
|
|
return EINVAL;
|
|
|
|
|
}
|
1994-02-01 06:22:29 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* is the wanted virtual console open ? */
|
|
|
|
|
if (next_scr) {
|
|
|
|
|
struct tty *tp = VIRTUAL_TTY(next_scr);
|
|
|
|
|
if (!(tp->t_state & TS_ISOPEN)) {
|
|
|
|
|
do_bell(scp, BELL_PITCH, BELL_DURATION);
|
|
|
|
|
return EINVAL;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
/* delay switch if actively updating screen */
|
|
|
|
|
if (write_in_progress || blink_in_progress) {
|
|
|
|
|
delayed_next_scr = next_scr+1;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
return 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
switch_in_progress = TRUE;
|
|
|
|
|
old_scp = cur_console;
|
|
|
|
|
new_scp = console[next_scr];
|
|
|
|
|
wakeup((caddr_t)&new_scp->smode);
|
|
|
|
|
if (new_scp == old_scp) {
|
|
|
|
|
switch_in_progress = FALSE;
|
|
|
|
|
delayed_next_scr = FALSE;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* has controlling process died? */
|
|
|
|
|
if (old_scp->proc && (old_scp->proc != pfind(old_scp->pid)))
|
|
|
|
|
old_scp->smode.mode = VT_AUTO;
|
|
|
|
|
if (new_scp->proc && (new_scp->proc != pfind(new_scp->pid)))
|
|
|
|
|
new_scp->smode.mode = VT_AUTO;
|
|
|
|
|
|
1996-12-19 00:26:22 +00:00
|
|
|
|
/* check the modes and switch appropriately */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (old_scp->smode.mode == VT_PROCESS) {
|
|
|
|
|
old_scp->status |= SWITCH_WAIT_REL;
|
|
|
|
|
psignal(old_scp->proc, old_scp->smode.relsig);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
exchange_scr();
|
|
|
|
|
if (new_scp->smode.mode == VT_PROCESS) {
|
|
|
|
|
new_scp->status |= SWITCH_WAIT_ACQ;
|
|
|
|
|
psignal(new_scp->proc, new_scp->smode.acqsig);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
switch_in_progress = FALSE;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static void
|
|
|
|
|
exchange_scr(void)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
move_crsr(old_scp, old_scp->xpos, old_scp->ypos);
|
|
|
|
|
cur_console = new_scp;
|
|
|
|
|
if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){
|
|
|
|
|
if (crtc_vga && video_mode_ptr)
|
|
|
|
|
set_mode(new_scp);
|
|
|
|
|
}
|
|
|
|
|
move_crsr(new_scp, new_scp->xpos, new_scp->ypos);
|
1997-06-30 13:31:49 +00:00
|
|
|
|
if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR))
|
|
|
|
|
set_destructive_cursor(new_scp);
|
|
|
|
|
if ((old_scp->status & UNKNOWN_MODE) && crtc_vga)
|
1997-01-15 18:16:32 +00:00
|
|
|
|
load_palette(palette);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE)
|
|
|
|
|
shfts = ctls = alts = agrs = metas = 0;
|
|
|
|
|
update_leds(new_scp->status);
|
|
|
|
|
delayed_next_scr = FALSE;
|
1996-06-21 07:19:18 +00:00
|
|
|
|
mark_all(new_scp);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static void
|
1994-08-17 08:51:59 +00:00
|
|
|
|
scan_esc(scr_stat *scp, u_char c)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static u_char ansi_col[16] =
|
1995-02-22 13:48:07 +00:00
|
|
|
|
{0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15};
|
|
|
|
|
int i, n;
|
|
|
|
|
u_short *src, *dst, count;
|
|
|
|
|
|
|
|
|
|
if (scp->term.esc == 1) {
|
|
|
|
|
switch (c) {
|
|
|
|
|
|
1997-01-23 20:00:45 +00:00
|
|
|
|
case '7': /* Save cursor position */
|
|
|
|
|
scp->saved_xpos = scp->xpos;
|
|
|
|
|
scp->saved_ypos = scp->ypos;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '8': /* Restore saved cursor position */
|
|
|
|
|
if (scp->saved_xpos >= 0 && scp->saved_ypos >= 0)
|
|
|
|
|
move_crsr(scp, scp->saved_xpos, scp->saved_ypos);
|
|
|
|
|
break;
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case '[': /* Start ESC [ sequence */
|
|
|
|
|
scp->term.esc = 2;
|
|
|
|
|
scp->term.last_param = -1;
|
|
|
|
|
for (i = scp->term.num_param; i < MAX_ESC_PAR; i++)
|
|
|
|
|
scp->term.param[i] = 1;
|
|
|
|
|
scp->term.num_param = 0;
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case 'M': /* Move cursor up 1 line, scroll if at top */
|
|
|
|
|
if (scp->ypos > 0)
|
|
|
|
|
move_crsr(scp, scp->xpos, scp->ypos - 1);
|
|
|
|
|
else {
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(scp->scr_buf, scp->scr_buf + scp->xsize,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(scp->ysize - 1) * scp->xsize * sizeof(u_short));
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->scr_buf, scp->xsize);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_all(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
#if notyet
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case 'Q':
|
|
|
|
|
scp->term.esc = 4;
|
|
|
|
|
break;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
#endif
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case 'c': /* Clear screen & home */
|
|
|
|
|
clear_screen(scp);
|
|
|
|
|
break;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
else if (scp->term.esc == 2) {
|
|
|
|
|
if (c >= '0' && c <= '9') {
|
|
|
|
|
if (scp->term.num_param < MAX_ESC_PAR) {
|
|
|
|
|
if (scp->term.last_param != scp->term.num_param) {
|
|
|
|
|
scp->term.last_param = scp->term.num_param;
|
|
|
|
|
scp->term.param[scp->term.num_param] = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
scp->term.param[scp->term.num_param] *= 10;
|
|
|
|
|
scp->term.param[scp->term.num_param] += c - '0';
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
scp->term.num_param = scp->term.last_param + 1;
|
|
|
|
|
switch (c) {
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case ';':
|
|
|
|
|
if (scp->term.num_param < MAX_ESC_PAR)
|
|
|
|
|
return;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '=':
|
|
|
|
|
scp->term.esc = 3;
|
|
|
|
|
scp->term.last_param = -1;
|
|
|
|
|
for (i = scp->term.num_param; i < MAX_ESC_PAR; i++)
|
|
|
|
|
scp->term.param[i] = 1;
|
|
|
|
|
scp->term.num_param = 0;
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case 'A': /* up n rows */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, scp->xpos, scp->ypos - n);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'B': /* down n rows */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, scp->xpos, scp->ypos + n);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'C': /* right n columns */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, scp->xpos + n, scp->ypos);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'D': /* left n columns */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, scp->xpos - n, scp->ypos);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'E': /* cursor to start of line n lines down */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, 0, scp->ypos + n);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'F': /* cursor to start of line n lines up */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, 0, scp->ypos - n);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'f': /* Cursor move */
|
|
|
|
|
case 'H':
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if (scp->term.num_param == 0)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
move_crsr(scp, 0, 0);
|
|
|
|
|
else if (scp->term.num_param == 2)
|
|
|
|
|
move_crsr(scp, scp->term.param[1] - 1, scp->term.param[0] - 1);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'J': /* Clear all or part of display */
|
|
|
|
|
if (scp->term.num_param == 0)
|
|
|
|
|
n = 0;
|
|
|
|
|
else
|
|
|
|
|
n = scp->term.param[0];
|
|
|
|
|
switch (n) {
|
|
|
|
|
case 0: /* clear form cursor to end of display */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1995-05-30 08:16:23 +00:00
|
|
|
|
scp->cursor_pos,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->scr_buf + scp->xsize * scp->ysize - scp->cursor_pos);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
|
|
|
|
mark_for_update(scp, scp->xsize * scp->ysize);
|
1997-01-23 20:00:45 +00:00
|
|
|
|
remove_cutmarking(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 1: /* clear from beginning of display to cursor */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1995-05-30 08:16:23 +00:00
|
|
|
|
scp->scr_buf,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->cursor_pos - scp->scr_buf);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, 0);
|
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1997-01-23 20:00:45 +00:00
|
|
|
|
remove_cutmarking(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 2: /* clear entire display */
|
1997-01-23 20:00:45 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20], scp->scr_buf,
|
|
|
|
|
scp->xsize * scp->ysize);
|
|
|
|
|
mark_all(scp);
|
|
|
|
|
remove_cutmarking(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'K': /* Clear all or part of line */
|
|
|
|
|
if (scp->term.num_param == 0)
|
|
|
|
|
n = 0;
|
|
|
|
|
else
|
|
|
|
|
n = scp->term.param[0];
|
|
|
|
|
switch (n) {
|
|
|
|
|
case 0: /* clear form cursor to end of line */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1995-05-30 08:16:23 +00:00
|
|
|
|
scp->cursor_pos,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize - scp->xpos);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf +
|
|
|
|
|
scp->xsize - scp->xpos);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 1: /* clear from beginning of line to cursor */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1996-05-02 21:47:50 +00:00
|
|
|
|
scp->cursor_pos - scp->xpos,
|
|
|
|
|
scp->xpos + 1);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->ypos * scp->xsize);
|
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 2: /* clear entire line */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1996-05-02 21:47:50 +00:00
|
|
|
|
scp->cursor_pos - scp->xpos,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->ypos * scp->xsize);
|
|
|
|
|
mark_for_update(scp, (scp->ypos + 1) * scp->xsize);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'L': /* Insert n lines */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
if (n > scp->ysize - scp->ypos)
|
|
|
|
|
n = scp->ysize - scp->ypos;
|
|
|
|
|
src = scp->scr_buf + scp->ypos * scp->xsize;
|
|
|
|
|
dst = src + n * scp->xsize;
|
|
|
|
|
count = scp->ysize - (scp->ypos + n);
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(src, dst, count * scp->xsize * sizeof(u_short));
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20], src,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
n * scp->xsize);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->ypos * scp->xsize);
|
|
|
|
|
mark_for_update(scp, scp->xsize * scp->ysize);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'M': /* Delete n lines */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
if (n > scp->ysize - scp->ypos)
|
|
|
|
|
n = scp->ysize - scp->ypos;
|
|
|
|
|
dst = scp->scr_buf + scp->ypos * scp->xsize;
|
|
|
|
|
src = dst + n * scp->xsize;
|
|
|
|
|
count = scp->ysize - (scp->ypos + n);
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(src, dst, count * scp->xsize * sizeof(u_short));
|
1995-02-22 13:48:07 +00:00
|
|
|
|
src = dst + count * scp->xsize;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20], src,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
n * scp->xsize);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->ypos * scp->xsize);
|
|
|
|
|
mark_for_update(scp, scp->xsize * scp->ysize);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'P': /* Delete n chars */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
if (n > scp->xsize - scp->xpos)
|
|
|
|
|
n = scp->xsize - scp->xpos;
|
|
|
|
|
dst = scp->cursor_pos;
|
|
|
|
|
src = dst + n;
|
|
|
|
|
count = scp->xsize - (scp->xpos + n);
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(src, dst, count * sizeof(u_short));
|
1995-02-22 13:48:07 +00:00
|
|
|
|
src = dst + count;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20], src, n);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1995-04-04 20:06:26 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '@': /* Insert n chars */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
if (n > scp->xsize - scp->xpos)
|
|
|
|
|
n = scp->xsize - scp->xpos;
|
|
|
|
|
src = scp->cursor_pos;
|
|
|
|
|
dst = src + n;
|
|
|
|
|
count = scp->xsize - (scp->xpos + n);
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(src, dst, count * sizeof(u_short));
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20], src, n);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1995-04-04 20:06:26 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'S': /* scroll up n lines */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
if (n > scp->ysize)
|
|
|
|
|
n = scp->ysize;
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(scp->scr_buf + (scp->xsize * n),
|
1995-05-30 08:16:23 +00:00
|
|
|
|
scp->scr_buf,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize * (scp->ysize - n) * sizeof(u_short));
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1995-05-30 08:16:23 +00:00
|
|
|
|
scp->scr_buf + scp->xsize * (scp->ysize - n),
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize * n);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_all(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'T': /* scroll down n lines */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
if (n > scp->ysize)
|
|
|
|
|
n = scp->ysize;
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(scp->scr_buf,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->scr_buf + (scp->xsize * n),
|
1995-05-30 08:16:23 +00:00
|
|
|
|
scp->xsize * (scp->ysize - n) *
|
1995-02-22 13:48:07 +00:00
|
|
|
|
sizeof(u_short));
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->scr_buf, scp->xsize * n);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_all(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
1995-04-01 19:57:36 +00:00
|
|
|
|
case 'X': /* erase n characters in line */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
if (n > scp->xsize - scp->xpos)
|
|
|
|
|
n = scp->xsize - scp->xpos;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1996-06-21 07:19:18 +00:00
|
|
|
|
scp->cursor_pos, n);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Z': /* move n tabs backwards */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
if ((i = scp->xpos & 0xf8) == scp->xpos)
|
|
|
|
|
i -= 8*n;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
else
|
|
|
|
|
i -= 8*(n-1);
|
|
|
|
|
if (i < 0)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
i = 0;
|
|
|
|
|
move_crsr(scp, i, scp->ypos);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '`': /* move cursor to column n */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, n - 1, scp->ypos);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'a': /* move cursor n columns to the right */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, scp->xpos + n, scp->ypos);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'd': /* move cursor to row n */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, scp->xpos, n - 1);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'e': /* move cursor n rows down */
|
|
|
|
|
n = scp->term.param[0]; if (n < 1) n = 1;
|
|
|
|
|
move_crsr(scp, scp->xpos, scp->ypos + n);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'm': /* change attribute */
|
|
|
|
|
if (scp->term.num_param == 0) {
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask = NORMAL_ATTR;
|
|
|
|
|
scp->term.cur_attr =
|
|
|
|
|
scp->term.cur_color = scp->term.std_color;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; i < scp->term.num_param; i++) {
|
|
|
|
|
switch (n = scp->term.param[i]) {
|
|
|
|
|
case 0: /* back to normal */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask = NORMAL_ATTR;
|
|
|
|
|
scp->term.cur_attr =
|
|
|
|
|
scp->term.cur_color = scp->term.std_color;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
case 1: /* bold */
|
|
|
|
|
scp->term.attr_mask |= BOLD_ATTR;
|
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
case 4: /* underline */
|
|
|
|
|
scp->term.attr_mask |= UNDERLINE_ATTR;
|
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 5: /* blink */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask |= BLINK_ATTR;
|
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 7: /* reverse video */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask |= REVERSE_ATTR;
|
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 30: case 31: /* set fg color */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
case 32: case 33: case 34:
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case 35: case 36: case 37:
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask |= FOREGROUND_CHANGED;
|
|
|
|
|
scp->term.cur_color =
|
|
|
|
|
(scp->term.cur_color&0xF000) | (ansi_col[(n-30)&7]<<8);
|
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 40: case 41: /* set bg color */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
case 42: case 43: case 44:
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case 45: case 46: case 47:
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask |= BACKGROUND_CHANGED;
|
|
|
|
|
scp->term.cur_color =
|
|
|
|
|
(scp->term.cur_color&0x0F00) | (ansi_col[(n-40)&7]<<12);
|
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
1997-01-23 20:00:45 +00:00
|
|
|
|
case 's': /* Save cursor position */
|
|
|
|
|
scp->saved_xpos = scp->xpos;
|
|
|
|
|
scp->saved_ypos = scp->ypos;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'u': /* Restore saved cursor position */
|
|
|
|
|
if (scp->saved_xpos >= 0 && scp->saved_ypos >= 0)
|
|
|
|
|
move_crsr(scp, scp->saved_xpos, scp->saved_ypos);
|
|
|
|
|
break;
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case 'x':
|
|
|
|
|
if (scp->term.num_param == 0)
|
|
|
|
|
n = 0;
|
|
|
|
|
else
|
|
|
|
|
n = scp->term.param[0];
|
|
|
|
|
switch (n) {
|
|
|
|
|
case 0: /* reset attributes */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask = NORMAL_ATTR;
|
|
|
|
|
scp->term.cur_attr =
|
|
|
|
|
scp->term.cur_color = scp->term.std_color =
|
|
|
|
|
current_default->std_color;
|
|
|
|
|
scp->term.rev_color = current_default->rev_color;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 1: /* set ansi background */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask &= ~BACKGROUND_CHANGED;
|
|
|
|
|
scp->term.cur_color = scp->term.std_color =
|
|
|
|
|
(scp->term.std_color & 0x0F00) |
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(ansi_col[(scp->term.param[1])&0x0F]<<12);
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 2: /* set ansi foreground */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask &= ~FOREGROUND_CHANGED;
|
|
|
|
|
scp->term.cur_color = scp->term.std_color =
|
|
|
|
|
(scp->term.std_color & 0xF000) |
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(ansi_col[(scp->term.param[1])&0x0F]<<8);
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 3: /* set ansi attribute directly */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask &= ~(FOREGROUND_CHANGED|BACKGROUND_CHANGED);
|
|
|
|
|
scp->term.cur_color = scp->term.std_color =
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(scp->term.param[1]&0xFF)<<8;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 5: /* set ansi reverse video background */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.rev_color =
|
|
|
|
|
(scp->term.rev_color & 0x0F00) |
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(ansi_col[(scp->term.param[1])&0x0F]<<12);
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 6: /* set ansi reverse video foreground */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.rev_color =
|
|
|
|
|
(scp->term.rev_color & 0xF000) |
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(ansi_col[(scp->term.param[1])&0x0F]<<8);
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case 7: /* set ansi reverse video directly */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.rev_color =
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(scp->term.param[1]&0xFF)<<8;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'z': /* switch to (virtual) console n */
|
|
|
|
|
if (scp->term.num_param == 1)
|
|
|
|
|
switch_scr(scp, scp->term.param[0]);
|
|
|
|
|
break;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
else if (scp->term.esc == 3) {
|
|
|
|
|
if (c >= '0' && c <= '9') {
|
|
|
|
|
if (scp->term.num_param < MAX_ESC_PAR) {
|
|
|
|
|
if (scp->term.last_param != scp->term.num_param) {
|
|
|
|
|
scp->term.last_param = scp->term.num_param;
|
|
|
|
|
scp->term.param[scp->term.num_param] = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
scp->term.param[scp->term.num_param] *= 10;
|
|
|
|
|
scp->term.param[scp->term.num_param] += c - '0';
|
|
|
|
|
return;
|
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->term.num_param = scp->term.last_param + 1;
|
|
|
|
|
switch (c) {
|
|
|
|
|
|
|
|
|
|
case ';':
|
|
|
|
|
if (scp->term.num_param < MAX_ESC_PAR)
|
|
|
|
|
return;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'A': /* set display border color */
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
if (scp->term.num_param == 1) {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->border=scp->term.param[0] & 0xff;
|
|
|
|
|
if (scp == cur_console)
|
|
|
|
|
set_border(scp->border);
|
1997-05-15 05:43:59 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'B': /* set bell pitch and duration */
|
|
|
|
|
if (scp->term.num_param == 2) {
|
|
|
|
|
scp->bell_pitch = scp->term.param[0];
|
|
|
|
|
scp->bell_duration = scp->term.param[1]*10;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'C': /* set cursor type & shape */
|
|
|
|
|
if (scp->term.num_param == 1) {
|
|
|
|
|
if (scp->term.param[0] & 0x01)
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags |= BLINK_CURSOR;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
else
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags &= ~BLINK_CURSOR;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
if ((scp->term.param[0] & 0x02) && crtc_vga)
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags |= CHAR_CURSOR;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
else
|
1996-09-01 18:16:06 +00:00
|
|
|
|
flags &= ~CHAR_CURSOR;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
else if (scp->term.num_param == 2) {
|
1995-05-30 08:16:23 +00:00
|
|
|
|
scp->cursor_start = scp->term.param[0] & 0x1F;
|
|
|
|
|
scp->cursor_end = scp->term.param[1] & 0x1F;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* The cursor shape is global property; all virtual consoles
|
|
|
|
|
* are affected. Update the cursor in the current console...
|
|
|
|
|
*/
|
|
|
|
|
if (!(cur_console->status & UNKNOWN_MODE)) {
|
|
|
|
|
remove_cursor_image(cur_console);
|
|
|
|
|
if (crtc_vga && (flags & CHAR_CURSOR))
|
|
|
|
|
set_destructive_cursor(cur_console);
|
|
|
|
|
draw_cursor_image(cur_console);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'F': /* set ansi foreground */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
if (scp->term.num_param == 1) {
|
|
|
|
|
scp->term.attr_mask &= ~FOREGROUND_CHANGED;
|
|
|
|
|
scp->term.cur_color = scp->term.std_color =
|
|
|
|
|
(scp->term.std_color & 0xF000)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
| ((scp->term.param[0] & 0x0F) << 8);
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'G': /* set ansi background */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
if (scp->term.num_param == 1) {
|
|
|
|
|
scp->term.attr_mask &= ~BACKGROUND_CHANGED;
|
|
|
|
|
scp->term.cur_color = scp->term.std_color =
|
|
|
|
|
(scp->term.std_color & 0x0F00)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
| ((scp->term.param[0] & 0x0F) << 12);
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'H': /* set ansi reverse video foreground */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
if (scp->term.num_param == 1) {
|
|
|
|
|
scp->term.rev_color =
|
|
|
|
|
(scp->term.rev_color & 0xF000)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
| ((scp->term.param[0] & 0x0F) << 8);
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'I': /* set ansi reverse video background */
|
1995-11-28 00:17:32 +00:00
|
|
|
|
if (scp->term.num_param == 1) {
|
|
|
|
|
scp->term.rev_color =
|
|
|
|
|
(scp->term.rev_color & 0x0F00)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
| ((scp->term.param[0] & 0x0F) << 12);
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.cur_attr = mask2attr(&scp->term);
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
scp->term.esc = 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static void
|
1995-01-20 08:35:32 +00:00
|
|
|
|
ansi_put(scr_stat *scp, u_char *buf, int len)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
u_char *ptr = buf;
|
1995-01-20 08:35:32 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* make screensaver happy */
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
if (scp == cur_console)
|
|
|
|
|
scrn_time_stamp = mono_time.tv_sec;
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
write_in_progress++;
|
1995-01-20 08:35:32 +00:00
|
|
|
|
outloop:
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (scp->term.esc) {
|
|
|
|
|
scan_esc(scp, *ptr++);
|
|
|
|
|
len--;
|
|
|
|
|
}
|
|
|
|
|
else if (PRINTABLE(*ptr)) { /* Print only printables */
|
1995-03-03 08:37:52 +00:00
|
|
|
|
int cnt = len <= (scp->xsize-scp->xpos) ? len : (scp->xsize-scp->xpos);
|
|
|
|
|
u_short cur_attr = scp->term.cur_attr;
|
|
|
|
|
u_short *cursor_pos = scp->cursor_pos;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
do {
|
1995-07-11 17:59:22 +00:00
|
|
|
|
/*
|
|
|
|
|
* gcc-2.6.3 generates poor (un)sign extension code. Casting the
|
|
|
|
|
* pointers in the following to volatile should have no effect,
|
|
|
|
|
* but in fact speeds up this inner loop from 26 to 18 cycles
|
|
|
|
|
* (+ cache misses) on i486's.
|
|
|
|
|
*/
|
|
|
|
|
#define UCVP(ucp) ((u_char volatile *)(ucp))
|
|
|
|
|
*cursor_pos++ = UCVP(scr_map)[*UCVP(ptr)] | cur_attr;
|
|
|
|
|
ptr++;
|
1995-03-03 08:37:52 +00:00
|
|
|
|
cnt--;
|
|
|
|
|
} while (cnt && PRINTABLE(*ptr));
|
|
|
|
|
len -= (cursor_pos - scp->cursor_pos);
|
|
|
|
|
scp->xpos += (cursor_pos - scp->cursor_pos);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
|
|
|
|
mark_for_update(scp, cursor_pos - scp->scr_buf);
|
1995-03-03 08:37:52 +00:00
|
|
|
|
scp->cursor_pos = cursor_pos;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (scp->xpos >= scp->xsize) {
|
|
|
|
|
scp->xpos = 0;
|
|
|
|
|
scp->ypos++;
|
1995-01-20 08:35:32 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
switch(*ptr) {
|
|
|
|
|
case 0x07:
|
|
|
|
|
do_bell(scp, scp->bell_pitch, scp->bell_duration);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x08: /* non-destructive backspace */
|
|
|
|
|
if (scp->cursor_pos > scp->scr_buf) {
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->cursor_pos--;
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (scp->xpos > 0)
|
|
|
|
|
scp->xpos--;
|
|
|
|
|
else {
|
|
|
|
|
scp->xpos += scp->xsize - 1;
|
|
|
|
|
scp->ypos--;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x09: /* non-destructive tab */
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
|
|
|
|
scp->cursor_pos += (8 - scp->xpos % 8u);
|
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
|
|
|
|
if ((scp->xpos += (8 - scp->xpos % 8u)) >= scp->xsize) {
|
|
|
|
|
scp->xpos = 0;
|
|
|
|
|
scp->ypos++;
|
1995-01-20 08:35:32 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x0a: /* newline, same pos */
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->cursor_pos += scp->xsize;
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->ypos++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x0c: /* form feed, clears screen */
|
|
|
|
|
clear_screen(scp);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x0d: /* return, return to pos 0 */
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->cursor_pos -= scp->xpos;
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xpos = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 0x1b: /* start escape sequence */
|
|
|
|
|
scp->term.esc = 1;
|
|
|
|
|
scp->term.num_param = 0;
|
|
|
|
|
break;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
ptr++; len--;
|
|
|
|
|
}
|
|
|
|
|
/* do we have to scroll ?? */
|
|
|
|
|
if (scp->cursor_pos >= scp->scr_buf + scp->ysize * scp->xsize) {
|
1996-09-01 18:16:06 +00:00
|
|
|
|
remove_cutmarking(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (scp->history) {
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(scp->scr_buf, scp->history_head,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize * sizeof(u_short));
|
|
|
|
|
scp->history_head += scp->xsize;
|
|
|
|
|
if (scp->history_head + scp->xsize >
|
|
|
|
|
scp->history + scp->history_size)
|
|
|
|
|
scp->history_head = scp->history;
|
|
|
|
|
}
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(scp->scr_buf + scp->xsize, scp->scr_buf,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize * (scp->ysize - 1) * sizeof(u_short));
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(scp->term.cur_color | scr_map[0x20],
|
1995-05-30 08:16:23 +00:00
|
|
|
|
scp->scr_buf + scp->xsize * (scp->ysize - 1),
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize);
|
|
|
|
|
scp->cursor_pos -= scp->xsize;
|
|
|
|
|
scp->ypos--;
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_all(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
if (len)
|
|
|
|
|
goto outloop;
|
|
|
|
|
write_in_progress--;
|
|
|
|
|
if (delayed_next_scr)
|
|
|
|
|
switch_scr(scp, delayed_next_scr - 1);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static void
|
1994-08-17 08:51:59 +00:00
|
|
|
|
scinit(void)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1996-10-15 20:27:07 +00:00
|
|
|
|
u_int hw_cursor;
|
|
|
|
|
u_int i;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
if (init_done != COLD)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
init_done = WARM;
|
1995-09-10 21:36:12 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Ensure a zero start address. This is mainly to recover after
|
1995-11-24 14:56:00 +00:00
|
|
|
|
* switching from pcvt using userconfig(). The registers are w/o
|
1995-09-10 21:36:12 +00:00
|
|
|
|
* for old hardware so it's too hard to relocate the active screen
|
|
|
|
|
* memory.
|
|
|
|
|
*/
|
|
|
|
|
outb(crtc_addr, 12);
|
|
|
|
|
outb(crtc_addr + 1, 0);
|
|
|
|
|
outb(crtc_addr, 13);
|
|
|
|
|
outb(crtc_addr + 1, 0);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
|
|
|
|
/* extract cursor location */
|
1995-03-29 20:55:03 +00:00
|
|
|
|
outb(crtc_addr, 14);
|
|
|
|
|
hw_cursor = inb(crtc_addr + 1) << 8;
|
|
|
|
|
outb(crtc_addr, 15);
|
|
|
|
|
hw_cursor |= inb(crtc_addr + 1);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
1996-11-11 22:21:03 +00:00
|
|
|
|
/*
|
|
|
|
|
* Validate cursor location. It may be off the screen. Then we must
|
|
|
|
|
* not use it for the initial buffer offset.
|
|
|
|
|
*/
|
|
|
|
|
if (hw_cursor >= ROW * COL)
|
|
|
|
|
hw_cursor = (ROW - 1) * COL;
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* move hardware cursor out of the way */
|
1995-03-29 20:55:03 +00:00
|
|
|
|
outb(crtc_addr, 14);
|
|
|
|
|
outb(crtc_addr + 1, 0xff);
|
|
|
|
|
outb(crtc_addr, 15);
|
|
|
|
|
outb(crtc_addr + 1, 0xff);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
1997-06-22 12:04:36 +00:00
|
|
|
|
/* set up the first console */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
current_default = &user_default;
|
|
|
|
|
console[0] = &main_console;
|
|
|
|
|
init_scp(console[0]);
|
1997-01-17 15:49:13 +00:00
|
|
|
|
cur_console = console[0];
|
1996-10-26 20:16:58 +00:00
|
|
|
|
|
1997-04-27 09:03:10 +00:00
|
|
|
|
/* discard the video mode table if we are not familiar with it... */
|
|
|
|
|
if (video_mode_ptr) {
|
|
|
|
|
if (comp_vgaregs(vgaregs, video_mode_ptr + 64*console[0]->mode))
|
|
|
|
|
video_mode_ptr = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
1996-10-26 20:16:58 +00:00
|
|
|
|
/* copy screen to temporary buffer */
|
1997-04-27 09:03:10 +00:00
|
|
|
|
sc_bcopy(Crtat, sc_buffer,
|
1996-10-26 20:16:58 +00:00
|
|
|
|
console[0]->xsize * console[0]->ysize * sizeof(u_short));
|
|
|
|
|
|
|
|
|
|
console[0]->scr_buf = console[0]->mouse_pos = sc_buffer;
|
|
|
|
|
console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor;
|
1997-06-30 13:31:49 +00:00
|
|
|
|
console[0]->cursor_saveunder = *console[0]->cursor_pos;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
console[0]->xpos = hw_cursor % COL;
|
|
|
|
|
console[0]->ypos = hw_cursor / COL;
|
|
|
|
|
for (i=1; i<MAXCONS; i++)
|
|
|
|
|
console[i] = NULL;
|
|
|
|
|
kernel_console.esc = 0;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
kernel_console.attr_mask = NORMAL_ATTR;
|
|
|
|
|
kernel_console.cur_attr =
|
|
|
|
|
kernel_console.cur_color = kernel_console.std_color =
|
|
|
|
|
kernel_default.std_color;
|
|
|
|
|
kernel_console.rev_color = kernel_default.rev_color;
|
1997-01-15 18:16:32 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
/* initialize mapscrn arrays to a one to one map */
|
|
|
|
|
for (i=0; i<sizeof(scr_map); i++) {
|
|
|
|
|
scr_map[i] = scr_rmap[i] = i;
|
|
|
|
|
}
|
1996-10-01 23:24:09 +00:00
|
|
|
|
|
1997-01-19 17:34:14 +00:00
|
|
|
|
/* Save font and palette if VGA */
|
|
|
|
|
if (crtc_vga) {
|
1997-07-25 11:53:30 +00:00
|
|
|
|
if (fonts_loaded & FONT_16) {
|
|
|
|
|
copy_font(LOAD, FONT_16, font_16);
|
|
|
|
|
} else {
|
|
|
|
|
copy_font(SAVE, FONT_16, font_16);
|
|
|
|
|
fonts_loaded = FONT_16;
|
|
|
|
|
}
|
1997-01-19 17:34:14 +00:00
|
|
|
|
save_palette();
|
1997-06-30 13:31:49 +00:00
|
|
|
|
set_destructive_cursor(console[0]);
|
1997-01-19 17:34:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-10-01 23:24:09 +00:00
|
|
|
|
#ifdef SC_SPLASH_SCREEN
|
|
|
|
|
/*
|
|
|
|
|
* Now put up a graphics image, and maybe cycle a
|
|
|
|
|
* couble of palette entries for simple animation.
|
|
|
|
|
*/
|
|
|
|
|
toggle_splash_screen(cur_console);
|
|
|
|
|
#endif
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static scr_stat
|
1995-01-12 11:47:05 +00:00
|
|
|
|
*alloc_scp()
|
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scr_stat *scp;
|
|
|
|
|
|
1995-08-08 05:14:40 +00:00
|
|
|
|
scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
init_scp(scp);
|
1996-10-18 18:51:37 +00:00
|
|
|
|
scp->scr_buf = scp->cursor_pos = scp->cursor_oldpos =
|
1995-02-22 13:48:07 +00:00
|
|
|
|
(u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
|
1995-08-08 05:14:40 +00:00
|
|
|
|
M_DEVBUF, M_WAITOK);
|
1996-10-18 18:51:37 +00:00
|
|
|
|
scp->mouse_pos = scp->mouse_oldpos =
|
|
|
|
|
scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
|
|
|
|
|
scp->mouse_xpos/8);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->history_head = scp->history_pos = scp->history =
|
|
|
|
|
(u_short *)malloc(scp->history_size*sizeof(u_short),
|
1995-08-08 05:14:40 +00:00
|
|
|
|
M_DEVBUF, M_WAITOK);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
bzero(scp->history_head, scp->history_size*sizeof(u_short));
|
1996-10-02 22:00:38 +00:00
|
|
|
|
/* SOS
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (crtc_vga && video_mode_ptr)
|
|
|
|
|
set_mode(scp);
|
1996-10-02 22:00:38 +00:00
|
|
|
|
*/
|
1995-02-22 13:48:07 +00:00
|
|
|
|
clear_screen(scp);
|
1997-06-30 13:31:49 +00:00
|
|
|
|
scp->cursor_saveunder = *scp->cursor_pos;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
return scp;
|
1995-01-12 11:47:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_scp(scr_stat *scp)
|
|
|
|
|
{
|
1996-12-07 22:33:05 +00:00
|
|
|
|
if (crtc_vga)
|
|
|
|
|
if (crtc_addr == MONO_BASE)
|
|
|
|
|
scp->mode = M_VGA_M80x25;
|
|
|
|
|
else
|
1997-01-17 15:49:13 +00:00
|
|
|
|
scp->mode = M_VGA_C80x25;
|
1996-12-07 22:33:05 +00:00
|
|
|
|
else
|
|
|
|
|
if (crtc_addr == MONO_BASE)
|
|
|
|
|
scp->mode = M_B80x25;
|
|
|
|
|
else
|
|
|
|
|
scp->mode = M_C80x25;
|
|
|
|
|
|
1997-05-15 05:43:59 +00:00
|
|
|
|
scp->font_size = 16;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->xsize = COL;
|
|
|
|
|
scp->ysize = ROW;
|
1997-01-23 20:00:45 +00:00
|
|
|
|
scp->xpos = scp->ypos = 0;
|
|
|
|
|
scp->saved_xpos = scp->saved_ypos = -1;
|
1996-10-18 18:51:37 +00:00
|
|
|
|
scp->start = scp->xsize * scp->ysize;
|
1995-03-29 20:55:03 +00:00
|
|
|
|
scp->end = 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->term.esc = 0;
|
1995-11-28 00:17:32 +00:00
|
|
|
|
scp->term.attr_mask = NORMAL_ATTR;
|
|
|
|
|
scp->term.cur_attr =
|
|
|
|
|
scp->term.cur_color = scp->term.std_color =
|
|
|
|
|
current_default->std_color;
|
|
|
|
|
scp->term.rev_color = current_default->rev_color;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->border = BG_BLACK;
|
1995-03-30 14:32:31 +00:00
|
|
|
|
scp->cursor_start = *(char *)pa_to_va(0x461);
|
|
|
|
|
scp->cursor_end = *(char *)pa_to_va(0x460);
|
1996-10-18 18:51:37 +00:00
|
|
|
|
scp->mouse_xpos = scp->xsize*8/2;
|
|
|
|
|
scp->mouse_ypos = scp->ysize*scp->font_size/2;
|
1996-06-21 07:19:18 +00:00
|
|
|
|
scp->mouse_cut_start = scp->mouse_cut_end = NULL;
|
1996-06-25 08:54:57 +00:00
|
|
|
|
scp->mouse_signal = 0;
|
|
|
|
|
scp->mouse_pid = 0;
|
|
|
|
|
scp->mouse_proc = NULL;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->bell_pitch = BELL_PITCH;
|
|
|
|
|
scp->bell_duration = BELL_DURATION;
|
|
|
|
|
scp->status = (*(char *)pa_to_va(0x417) & 0x20) ? NLKED : 0;
|
|
|
|
|
scp->status |= CURSOR_ENABLED;
|
|
|
|
|
scp->pid = 0;
|
|
|
|
|
scp->proc = NULL;
|
|
|
|
|
scp->smode.mode = VT_AUTO;
|
|
|
|
|
scp->history_head = scp->history_pos = scp->history = NULL;
|
|
|
|
|
scp->history_size = HISTORY_SIZE;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static u_char
|
1994-08-17 08:51:59 +00:00
|
|
|
|
*get_fstr(u_int c, u_int *len)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
u_int i;
|
|
|
|
|
|
|
|
|
|
if (!(c & FKEY))
|
|
|
|
|
return(NULL);
|
|
|
|
|
i = (c & 0xFF) - F_FN;
|
|
|
|
|
if (i > n_fkey_tab)
|
|
|
|
|
return(NULL);
|
|
|
|
|
*len = fkey_tab[i].len;
|
|
|
|
|
return(fkey_tab[i].str);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-01-28 22:18:05 +00:00
|
|
|
|
static void
|
|
|
|
|
history_to_screen(scr_stat *scp)
|
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i=0; i<scp->ysize; i++)
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(scp->history + (((scp->history_pos - scp->history) +
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scp->history_size-((i+1)*scp->xsize))%scp->history_size),
|
|
|
|
|
scp->scr_buf + (scp->xsize * (scp->ysize-1 - i)),
|
|
|
|
|
scp->xsize * sizeof(u_short));
|
1995-03-29 20:55:03 +00:00
|
|
|
|
mark_all(scp);
|
1995-01-28 22:18:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
history_up_line(scr_stat *scp)
|
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (WRAPHIST(scp, scp->history_pos, -(scp->xsize*scp->ysize)) !=
|
|
|
|
|
scp->history_head) {
|
|
|
|
|
scp->history_pos = WRAPHIST(scp, scp->history_pos, -scp->xsize);
|
|
|
|
|
history_to_screen(scp);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
1995-01-28 22:18:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
history_down_line(scr_stat *scp)
|
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (scp->history_pos != scp->history_head) {
|
|
|
|
|
scp->history_pos = WRAPHIST(scp, scp->history_pos, scp->xsize);
|
|
|
|
|
history_to_screen(scp);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
1995-01-28 22:18:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
1993-07-26 21:21:11 +00:00
|
|
|
|
/*
|
1996-10-26 20:16:58 +00:00
|
|
|
|
* scgetc(flags) - get character from keyboard.
|
|
|
|
|
* If flags & SCGETC_CN, then avoid harmful side effects.
|
|
|
|
|
* If flags & SCGETC_NONBLOCK, then wait until a key is pressed, else
|
|
|
|
|
* return NOKEY if there is nothing there.
|
1993-07-26 21:21:11 +00:00
|
|
|
|
*/
|
1996-10-02 22:00:38 +00:00
|
|
|
|
static u_int
|
1996-10-26 20:16:58 +00:00
|
|
|
|
scgetc(u_int flags)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1996-11-14 22:19:17 +00:00
|
|
|
|
struct key_t *key;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
u_char scancode, keycode;
|
|
|
|
|
u_int state, action;
|
1996-11-14 22:19:17 +00:00
|
|
|
|
int c;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
static u_char esc_flag = 0, compose = 0;
|
|
|
|
|
static u_int chr = 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
|
|
|
|
next_code:
|
1996-11-14 22:19:17 +00:00
|
|
|
|
/* first see if there is something in the keyboard port */
|
|
|
|
|
if (flags & SCGETC_NONBLOCK) {
|
1997-01-15 18:16:32 +00:00
|
|
|
|
c = read_kbd_data_no_wait(sc_kbdc);
|
1996-11-14 22:19:17 +00:00
|
|
|
|
if (c == -1)
|
|
|
|
|
return(NOKEY);
|
|
|
|
|
} else {
|
|
|
|
|
do {
|
1997-01-15 18:16:32 +00:00
|
|
|
|
c = read_kbd_data(sc_kbdc);
|
1996-11-14 22:19:17 +00:00
|
|
|
|
} while(c == -1);
|
1996-11-04 21:01:08 +00:00
|
|
|
|
}
|
1996-11-14 22:19:17 +00:00
|
|
|
|
scancode = (u_char)c;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1996-09-30 23:00:58 +00:00
|
|
|
|
/* do the /dev/random device a favour */
|
1996-10-26 20:16:58 +00:00
|
|
|
|
if (!(flags & SCGETC_CN))
|
|
|
|
|
add_keyboard_randomness(scancode);
|
1995-10-28 16:58:05 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (cur_console->status & KBD_RAW_MODE)
|
|
|
|
|
return scancode;
|
1996-06-21 07:19:18 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
keycode = scancode & 0x7F;
|
|
|
|
|
switch (esc_flag) {
|
|
|
|
|
case 0x00: /* normal scancode */
|
|
|
|
|
switch(scancode) {
|
1996-09-30 23:00:58 +00:00
|
|
|
|
case 0xB8: /* left alt (compose key) */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (compose) {
|
1995-05-30 08:16:23 +00:00
|
|
|
|
compose = 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (chr > 255) {
|
1995-05-30 08:16:23 +00:00
|
|
|
|
do_bell(cur_console,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
BELL_PITCH, BELL_DURATION);
|
|
|
|
|
chr = 0;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0x38:
|
|
|
|
|
if (!compose) {
|
|
|
|
|
compose = 1;
|
|
|
|
|
chr = 0;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0xE0:
|
|
|
|
|
case 0xE1:
|
|
|
|
|
esc_flag = scancode;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
goto next_code;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0xE0: /* 0xE0 prefix */
|
|
|
|
|
esc_flag = 0;
|
|
|
|
|
switch (keycode) {
|
|
|
|
|
case 0x1C: /* right enter key */
|
|
|
|
|
keycode = 0x59;
|
|
|
|
|
break;
|
|
|
|
|
case 0x1D: /* right ctrl key */
|
|
|
|
|
keycode = 0x5A;
|
|
|
|
|
break;
|
|
|
|
|
case 0x35: /* keypad divide key */
|
|
|
|
|
keycode = 0x5B;
|
|
|
|
|
break;
|
|
|
|
|
case 0x37: /* print scrn key */
|
|
|
|
|
keycode = 0x5C;
|
|
|
|
|
break;
|
|
|
|
|
case 0x38: /* right alt key (alt gr) */
|
|
|
|
|
keycode = 0x5D;
|
|
|
|
|
break;
|
|
|
|
|
case 0x47: /* grey home key */
|
|
|
|
|
keycode = 0x5E;
|
|
|
|
|
break;
|
|
|
|
|
case 0x48: /* grey up arrow key */
|
|
|
|
|
keycode = 0x5F;
|
|
|
|
|
break;
|
|
|
|
|
case 0x49: /* grey page up key */
|
|
|
|
|
keycode = 0x60;
|
|
|
|
|
break;
|
|
|
|
|
case 0x4B: /* grey left arrow key */
|
|
|
|
|
keycode = 0x61;
|
|
|
|
|
break;
|
|
|
|
|
case 0x4D: /* grey right arrow key */
|
|
|
|
|
keycode = 0x62;
|
|
|
|
|
break;
|
|
|
|
|
case 0x4F: /* grey end key */
|
|
|
|
|
keycode = 0x63;
|
|
|
|
|
break;
|
|
|
|
|
case 0x50: /* grey down arrow key */
|
|
|
|
|
keycode = 0x64;
|
|
|
|
|
break;
|
|
|
|
|
case 0x51: /* grey page down key */
|
|
|
|
|
keycode = 0x65;
|
|
|
|
|
break;
|
|
|
|
|
case 0x52: /* grey insert key */
|
|
|
|
|
keycode = 0x66;
|
|
|
|
|
break;
|
|
|
|
|
case 0x53: /* grey delete key */
|
|
|
|
|
keycode = 0x67;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* the following 3 are only used on the MS "Natural" keyboard */
|
|
|
|
|
case 0x5b: /* left Window key */
|
|
|
|
|
keycode = 0x69;
|
|
|
|
|
break;
|
|
|
|
|
case 0x5c: /* right Window key */
|
|
|
|
|
keycode = 0x6a;
|
|
|
|
|
break;
|
|
|
|
|
case 0x5d: /* menu key */
|
|
|
|
|
keycode = 0x6b;
|
|
|
|
|
break;
|
|
|
|
|
default: /* ignore everything else */
|
|
|
|
|
goto next_code;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0xE1: /* 0xE1 prefix */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
esc_flag = 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (keycode == 0x1D)
|
|
|
|
|
esc_flag = 0x1D;
|
|
|
|
|
goto next_code;
|
|
|
|
|
/* NOT REACHED */
|
|
|
|
|
case 0x1D: /* pause / break */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
esc_flag = 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (keycode != 0x45)
|
|
|
|
|
goto next_code;
|
|
|
|
|
keycode = 0x68;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if scroll-lock pressed allow history browsing */
|
|
|
|
|
if (cur_console->history && cur_console->status & SLKED) {
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
cur_console->status &= ~CURSOR_ENABLED;
|
|
|
|
|
if (!(cur_console->status & BUFFER_SAVED)) {
|
|
|
|
|
cur_console->status |= BUFFER_SAVED;
|
|
|
|
|
cur_console->history_save = cur_console->history_head;
|
|
|
|
|
|
|
|
|
|
/* copy screen into top of history buffer */
|
|
|
|
|
for (i=0; i<cur_console->ysize; i++) {
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(cur_console->scr_buf + (cur_console->xsize * i),
|
1995-02-22 13:48:07 +00:00
|
|
|
|
cur_console->history_head,
|
|
|
|
|
cur_console->xsize * sizeof(u_short));
|
|
|
|
|
cur_console->history_head += cur_console->xsize;
|
|
|
|
|
if (cur_console->history_head + cur_console->xsize >
|
|
|
|
|
cur_console->history + cur_console->history_size)
|
|
|
|
|
cur_console->history_head=cur_console->history;
|
|
|
|
|
}
|
|
|
|
|
cur_console->history_pos = cur_console->history_head;
|
|
|
|
|
history_to_screen(cur_console);
|
|
|
|
|
}
|
|
|
|
|
switch (scancode) {
|
|
|
|
|
case 0x47: /* home key */
|
|
|
|
|
cur_console->history_pos = cur_console->history_head;
|
|
|
|
|
history_to_screen(cur_console);
|
|
|
|
|
goto next_code;
|
|
|
|
|
|
|
|
|
|
case 0x4F: /* end key */
|
|
|
|
|
cur_console->history_pos =
|
1995-05-30 08:16:23 +00:00
|
|
|
|
WRAPHIST(cur_console, cur_console->history_head,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
cur_console->xsize*cur_console->ysize);
|
|
|
|
|
history_to_screen(cur_console);
|
|
|
|
|
goto next_code;
|
|
|
|
|
|
|
|
|
|
case 0x48: /* up arrow key */
|
|
|
|
|
if (history_up_line(cur_console))
|
|
|
|
|
do_bell(cur_console, BELL_PITCH, BELL_DURATION);
|
|
|
|
|
goto next_code;
|
|
|
|
|
|
|
|
|
|
case 0x50: /* down arrow key */
|
|
|
|
|
if (history_down_line(cur_console))
|
|
|
|
|
do_bell(cur_console, BELL_PITCH, BELL_DURATION);
|
|
|
|
|
goto next_code;
|
|
|
|
|
|
|
|
|
|
case 0x49: /* page up key */
|
|
|
|
|
for (i=0; i<cur_console->ysize; i++)
|
|
|
|
|
if (history_up_line(cur_console)) {
|
|
|
|
|
do_bell(cur_console, BELL_PITCH, BELL_DURATION);
|
1993-07-30 02:20:26 +00:00
|
|
|
|
break;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
goto next_code;
|
|
|
|
|
|
|
|
|
|
case 0x51: /* page down key */
|
|
|
|
|
for (i=0; i<cur_console->ysize; i++)
|
|
|
|
|
if (history_down_line(cur_console)) {
|
|
|
|
|
do_bell(cur_console, BELL_PITCH, BELL_DURATION);
|
1993-07-30 02:20:26 +00:00
|
|
|
|
break;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
goto next_code;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (compose) {
|
|
|
|
|
switch (scancode) {
|
|
|
|
|
/* key pressed process it */
|
|
|
|
|
case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */
|
|
|
|
|
chr = (scancode - 0x40) + chr*10;
|
|
|
|
|
goto next_code;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
chr = (scancode - 0x47) + chr*10;
|
|
|
|
|
goto next_code;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
chr = (scancode - 0x4E) + chr*10;
|
|
|
|
|
goto next_code;
|
|
|
|
|
case 0x52: /* keypad 0 */
|
|
|
|
|
chr *= 10;
|
|
|
|
|
goto next_code;
|
|
|
|
|
|
|
|
|
|
/* key release, no interest here */
|
|
|
|
|
case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */
|
|
|
|
|
case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case 0xD2: /* keypad 0 */
|
|
|
|
|
goto next_code;
|
|
|
|
|
|
|
|
|
|
case 0x38: /* left alt key */
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (chr) {
|
|
|
|
|
compose = chr = 0;
|
|
|
|
|
do_bell(cur_console, BELL_PITCH, BELL_DURATION);
|
1995-05-30 08:16:23 +00:00
|
|
|
|
goto next_code;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
1995-01-12 11:47:05 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
state = (shfts ? 1 : 0 ) | (2 * (ctls ? 1 : 0)) | (4 * (alts ? 1 : 0));
|
|
|
|
|
if ((!agrs && (cur_console->status & ALKED))
|
|
|
|
|
|| (agrs && !(cur_console->status & ALKED)))
|
|
|
|
|
keycode += ALTGR_OFFSET;
|
|
|
|
|
key = &key_map.key[keycode];
|
|
|
|
|
if ( ((key->flgs & FLAG_LOCK_C) && (cur_console->status & CLKED))
|
|
|
|
|
|| ((key->flgs & FLAG_LOCK_N) && (cur_console->status & NLKED)) )
|
|
|
|
|
state ^= 1;
|
|
|
|
|
|
|
|
|
|
/* Check for make/break */
|
|
|
|
|
action = key->map[state];
|
|
|
|
|
if (scancode & 0x80) { /* key released */
|
1997-07-14 03:36:50 +00:00
|
|
|
|
if (key->spcl & (0x80>>state)) {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
switch (action) {
|
|
|
|
|
case LSH:
|
|
|
|
|
shfts &= ~1;
|
|
|
|
|
break;
|
|
|
|
|
case RSH:
|
|
|
|
|
shfts &= ~2;
|
|
|
|
|
break;
|
|
|
|
|
case LCTR:
|
|
|
|
|
ctls &= ~1;
|
|
|
|
|
break;
|
|
|
|
|
case RCTR:
|
|
|
|
|
ctls &= ~2;
|
|
|
|
|
break;
|
|
|
|
|
case LALT:
|
|
|
|
|
alts &= ~1;
|
|
|
|
|
break;
|
|
|
|
|
case RALT:
|
|
|
|
|
alts &= ~2;
|
|
|
|
|
break;
|
|
|
|
|
case NLK:
|
1995-05-30 08:16:23 +00:00
|
|
|
|
nlkcnt = 0;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case CLK:
|
|
|
|
|
clkcnt = 0;
|
|
|
|
|
break;
|
|
|
|
|
case SLK:
|
|
|
|
|
slkcnt = 0;
|
|
|
|
|
break;
|
|
|
|
|
case ASH:
|
|
|
|
|
agrs = 0;
|
|
|
|
|
break;
|
|
|
|
|
case ALK:
|
|
|
|
|
alkcnt = 0;
|
|
|
|
|
break;
|
|
|
|
|
case META:
|
|
|
|
|
metas = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
1993-07-30 02:20:26 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (chr && !compose) {
|
|
|
|
|
action = chr;
|
|
|
|
|
chr = 0;
|
|
|
|
|
return(action);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* key pressed */
|
|
|
|
|
if (key->spcl & (0x80>>state)) {
|
|
|
|
|
switch (action) {
|
|
|
|
|
/* LOCKING KEYS */
|
|
|
|
|
case NLK:
|
1996-10-01 07:38:14 +00:00
|
|
|
|
#ifdef SC_SPLASH_SCREEN
|
1996-09-30 23:00:58 +00:00
|
|
|
|
toggle_splash_screen(cur_console); /* SOS XXX */
|
1996-10-01 07:38:14 +00:00
|
|
|
|
#endif
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (!nlkcnt) {
|
|
|
|
|
nlkcnt++;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if (cur_console->status & NLKED)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
cur_console->status &= ~NLKED;
|
|
|
|
|
else
|
|
|
|
|
cur_console->status |= NLKED;
|
|
|
|
|
update_leds(cur_console->status);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case CLK:
|
|
|
|
|
if (!clkcnt) {
|
|
|
|
|
clkcnt++;
|
|
|
|
|
if (cur_console->status & CLKED)
|
|
|
|
|
cur_console->status &= ~CLKED;
|
|
|
|
|
else
|
|
|
|
|
cur_console->status |= CLKED;
|
|
|
|
|
update_leds(cur_console->status);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SLK:
|
|
|
|
|
if (!slkcnt) {
|
|
|
|
|
slkcnt++;
|
|
|
|
|
if (cur_console->status & SLKED) {
|
|
|
|
|
cur_console->status &= ~SLKED;
|
|
|
|
|
if (cur_console->status & BUFFER_SAVED){
|
|
|
|
|
int i;
|
|
|
|
|
u_short *ptr = cur_console->history_save;
|
|
|
|
|
|
|
|
|
|
for (i=0; i<cur_console->ysize; i++) {
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(ptr,
|
1995-02-22 13:48:07 +00:00
|
|
|
|
cur_console->scr_buf +
|
|
|
|
|
(cur_console->xsize*i),
|
|
|
|
|
cur_console->xsize * sizeof(u_short));
|
|
|
|
|
ptr += cur_console->xsize;
|
1997-07-08 13:38:58 +00:00
|
|
|
|
if (ptr + cur_console->xsize >
|
1995-02-22 13:48:07 +00:00
|
|
|
|
cur_console->history +
|
|
|
|
|
cur_console->history_size)
|
|
|
|
|
ptr = cur_console->history;
|
|
|
|
|
}
|
1995-03-29 20:55:03 +00:00
|
|
|
|
cur_console->status &= ~BUFFER_SAVED;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
cur_console->history_head=cur_console->history_save;
|
1995-03-29 20:55:03 +00:00
|
|
|
|
cur_console->status |= CURSOR_ENABLED;
|
1995-04-25 10:22:28 +00:00
|
|
|
|
mark_all(cur_console);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
scstart(VIRTUAL_TTY(get_scr_num()));
|
1995-05-30 08:16:23 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
1995-02-22 13:48:07 +00:00
|
|
|
|
cur_console->status |= SLKED;
|
|
|
|
|
update_leds(cur_console->status);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case ALK:
|
|
|
|
|
if (!alkcnt) {
|
|
|
|
|
alkcnt++;
|
|
|
|
|
if (cur_console->status & ALKED)
|
|
|
|
|
cur_console->status &= ~ALKED;
|
|
|
|
|
else
|
|
|
|
|
cur_console->status |= ALKED;
|
|
|
|
|
update_leds(cur_console->status);
|
1993-07-30 02:20:26 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* NON-LOCKING KEYS */
|
|
|
|
|
case NOP:
|
|
|
|
|
break;
|
1996-09-30 23:00:58 +00:00
|
|
|
|
case SPSC:
|
|
|
|
|
#ifdef SC_SPLASH_SCREEN
|
|
|
|
|
toggle_splash_screen(cur_console);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case RBT:
|
|
|
|
|
shutdown_nice();
|
1995-05-30 08:16:23 +00:00
|
|
|
|
break;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case SUSP:
|
1995-05-30 08:16:23 +00:00
|
|
|
|
#if NAPM > 0
|
1995-02-22 13:48:07 +00:00
|
|
|
|
apm_suspend();
|
1995-02-17 02:22:57 +00:00
|
|
|
|
#endif
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case DBG:
|
|
|
|
|
#ifdef DDB /* try to switch to console 0 */
|
|
|
|
|
if (cur_console->smode.mode == VT_AUTO &&
|
|
|
|
|
console[0]->smode.mode == VT_AUTO)
|
1995-05-30 08:16:23 +00:00
|
|
|
|
switch_scr(cur_console, 0);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
Debugger("manual escape to debugger");
|
1993-10-28 05:27:36 +00:00
|
|
|
|
#else
|
1995-02-22 13:48:07 +00:00
|
|
|
|
printf("No debugger in kernel\n");
|
1993-10-28 05:27:36 +00:00
|
|
|
|
#endif
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case LSH:
|
|
|
|
|
shfts |= 1;
|
|
|
|
|
break;
|
|
|
|
|
case RSH:
|
|
|
|
|
shfts |= 2;
|
|
|
|
|
break;
|
|
|
|
|
case LCTR:
|
|
|
|
|
ctls |= 1;
|
|
|
|
|
break;
|
|
|
|
|
case RCTR:
|
|
|
|
|
ctls |= 2;
|
|
|
|
|
break;
|
|
|
|
|
case LALT:
|
|
|
|
|
alts |= 1;
|
|
|
|
|
break;
|
|
|
|
|
case RALT:
|
|
|
|
|
alts |= 2;
|
|
|
|
|
break;
|
|
|
|
|
case ASH:
|
|
|
|
|
agrs = 1;
|
|
|
|
|
break;
|
|
|
|
|
case META:
|
|
|
|
|
metas = 1;
|
|
|
|
|
break;
|
|
|
|
|
case NEXT:
|
1997-01-30 15:12:17 +00:00
|
|
|
|
{
|
|
|
|
|
int next, this = get_scr_num();
|
|
|
|
|
for (next = this+1; next != this; next = (next+1)%MAXCONS) {
|
|
|
|
|
struct tty *tp = VIRTUAL_TTY(next);
|
|
|
|
|
if (tp->t_state & TS_ISOPEN) {
|
|
|
|
|
switch_scr(cur_console, next);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
|
|
|
|
case BTAB:
|
|
|
|
|
return(BKEY);
|
|
|
|
|
default:
|
|
|
|
|
if (action >= F_SCR && action <= L_SCR) {
|
|
|
|
|
switch_scr(cur_console, action - F_SCR);
|
|
|
|
|
break;
|
1993-10-28 05:27:36 +00:00
|
|
|
|
}
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if (action >= F_FN && action <= L_FN)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
action |= FKEY;
|
|
|
|
|
return(action);
|
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
1995-02-22 13:48:07 +00:00
|
|
|
|
else {
|
|
|
|
|
if (metas)
|
|
|
|
|
action |= MKEY;
|
|
|
|
|
return(action);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
goto next_code;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
int
|
1995-01-20 08:35:32 +00:00
|
|
|
|
scmmap(dev_t dev, int offset, int nprot)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (offset > 0x20000 - PAGE_SIZE)
|
|
|
|
|
return -1;
|
|
|
|
|
return i386_btop((VIDEOMEM + offset));
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-10-02 22:00:38 +00:00
|
|
|
|
/*
|
|
|
|
|
* Calculate hardware attributes word using logical attributes mask and
|
|
|
|
|
* hardware colors
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mask2attr(struct term_stat *term)
|
|
|
|
|
{
|
|
|
|
|
int attr, mask = term->attr_mask;
|
|
|
|
|
|
|
|
|
|
if (mask & REVERSE_ATTR) {
|
|
|
|
|
attr = ((mask & FOREGROUND_CHANGED) ?
|
|
|
|
|
((term->cur_color & 0xF000) >> 4) :
|
|
|
|
|
(term->rev_color & 0x0F00)) |
|
|
|
|
|
((mask & BACKGROUND_CHANGED) ?
|
|
|
|
|
((term->cur_color & 0x0F00) << 4) :
|
|
|
|
|
(term->rev_color & 0xF000));
|
|
|
|
|
} else
|
|
|
|
|
attr = term->cur_color;
|
|
|
|
|
|
|
|
|
|
/* XXX: underline mapping for Hercules adapter can be better */
|
|
|
|
|
if (mask & (BOLD_ATTR | UNDERLINE_ATTR))
|
|
|
|
|
attr ^= 0x0800;
|
|
|
|
|
if (mask & BLINK_ATTR)
|
|
|
|
|
attr ^= 0x8000;
|
|
|
|
|
|
|
|
|
|
return attr;
|
|
|
|
|
}
|
|
|
|
|
|
1996-09-30 23:00:58 +00:00
|
|
|
|
static void
|
1997-01-15 18:16:32 +00:00
|
|
|
|
set_keyboard(int command, int data)
|
1996-09-30 23:00:58 +00:00
|
|
|
|
{
|
|
|
|
|
int s;
|
1997-01-15 18:16:32 +00:00
|
|
|
|
int c;
|
|
|
|
|
|
|
|
|
|
if (sc_kbdc == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* prevent the timeout routine from polling the keyboard */
|
|
|
|
|
if (!kbdc_lock(sc_kbdc, TRUE))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* disable the keyboard and mouse interrupt */
|
|
|
|
|
s = spltty();
|
Interim patch/kludge for keyboard lock-up when `kbdcontrol' tries to
change typematic rate, or the X server (XFree86 or Accelerated X)
starts up.
So far, there have been two independent reports from Dell Latitude XPi
notebook/laptop owners. The Latitude seems to be the only system which
suffers from this problem. (I don't know the problem is with the
entire Latitude line or with only some Latitude models) No problem
report has been heard about other systems (I certainly cannot
reproduce the problem in my -current and 2.2 systems).
In 3.0-CURRENT, 2.2-RELEASE and 2.2-GAMMA-970310, when programming the
keyboard LED/repeat-rate, `set_keyboard()' in `syscons' tells the
keyboard controller not to generate keyboard interrupt (IRQ1) and then
enable tty interrupts, expecting the keyboard interrupt doesn't occur.
It appears that somehow Latitude's keyboard controller still generates
the keyboard interrupt thereafter, and `set_keyboard()' doesn't see
the return code from the keyboard because it is consumed by the
keyboard interrupt handler.
The patch entirely disables tty interrupts while setting LED and
typematic rate in `set_keyboard()', making the routine behave more
like the previous versions of `syscons' (versions in 2.1.X and
2.2-ALPHA, -BETA, and some -GAMMAs). The reporter said this patch
eliminated the problem.
(I also found another typo/bug, but the reporter and I found that it
wasn't the cause of the problem...)
This should go into RELENG_2_2.
1997-03-28 10:11:24 +00:00
|
|
|
|
#if 0
|
1997-01-15 18:16:32 +00:00
|
|
|
|
c = get_controller_command_byte(sc_kbdc);
|
|
|
|
|
if ((c == -1)
|
|
|
|
|
|| !set_controller_command_byte(sc_kbdc,
|
|
|
|
|
kbdc_get_device_mask(sc_kbdc),
|
Interim patch/kludge for keyboard lock-up when `kbdcontrol' tries to
change typematic rate, or the X server (XFree86 or Accelerated X)
starts up.
So far, there have been two independent reports from Dell Latitude XPi
notebook/laptop owners. The Latitude seems to be the only system which
suffers from this problem. (I don't know the problem is with the
entire Latitude line or with only some Latitude models) No problem
report has been heard about other systems (I certainly cannot
reproduce the problem in my -current and 2.2 systems).
In 3.0-CURRENT, 2.2-RELEASE and 2.2-GAMMA-970310, when programming the
keyboard LED/repeat-rate, `set_keyboard()' in `syscons' tells the
keyboard controller not to generate keyboard interrupt (IRQ1) and then
enable tty interrupts, expecting the keyboard interrupt doesn't occur.
It appears that somehow Latitude's keyboard controller still generates
the keyboard interrupt thereafter, and `set_keyboard()' doesn't see
the return code from the keyboard because it is consumed by the
keyboard interrupt handler.
The patch entirely disables tty interrupts while setting LED and
typematic rate in `set_keyboard()', making the routine behave more
like the previous versions of `syscons' (versions in 2.1.X and
2.2-ALPHA, -BETA, and some -GAMMAs). The reporter said this patch
eliminated the problem.
(I also found another typo/bug, but the reporter and I found that it
wasn't the cause of the problem...)
This should go into RELENG_2_2.
1997-03-28 10:11:24 +00:00
|
|
|
|
KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
|
1997-01-15 18:16:32 +00:00
|
|
|
|
| KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
|
|
|
|
|
/* CONTROLLER ERROR */
|
|
|
|
|
kbdc_lock(sc_kbdc, FALSE);
|
|
|
|
|
splx(s);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* Now that the keyboard controller is told not to generate
|
|
|
|
|
* the keyboard and mouse interrupts, call `splx()' to allow
|
|
|
|
|
* the other tty interrupts. The clock interrupt may also occur,
|
|
|
|
|
* but the timeout routine (`scrn_timer()') will be blocked
|
|
|
|
|
* by the lock flag set via `kbdc_lock()'
|
|
|
|
|
*/
|
|
|
|
|
splx(s);
|
Interim patch/kludge for keyboard lock-up when `kbdcontrol' tries to
change typematic rate, or the X server (XFree86 or Accelerated X)
starts up.
So far, there have been two independent reports from Dell Latitude XPi
notebook/laptop owners. The Latitude seems to be the only system which
suffers from this problem. (I don't know the problem is with the
entire Latitude line or with only some Latitude models) No problem
report has been heard about other systems (I certainly cannot
reproduce the problem in my -current and 2.2 systems).
In 3.0-CURRENT, 2.2-RELEASE and 2.2-GAMMA-970310, when programming the
keyboard LED/repeat-rate, `set_keyboard()' in `syscons' tells the
keyboard controller not to generate keyboard interrupt (IRQ1) and then
enable tty interrupts, expecting the keyboard interrupt doesn't occur.
It appears that somehow Latitude's keyboard controller still generates
the keyboard interrupt thereafter, and `set_keyboard()' doesn't see
the return code from the keyboard because it is consumed by the
keyboard interrupt handler.
The patch entirely disables tty interrupts while setting LED and
typematic rate in `set_keyboard()', making the routine behave more
like the previous versions of `syscons' (versions in 2.1.X and
2.2-ALPHA, -BETA, and some -GAMMAs). The reporter said this patch
eliminated the problem.
(I also found another typo/bug, but the reporter and I found that it
wasn't the cause of the problem...)
This should go into RELENG_2_2.
1997-03-28 10:11:24 +00:00
|
|
|
|
#endif
|
1997-01-15 18:16:32 +00:00
|
|
|
|
|
Interim patch/kludge for keyboard lock-up when `kbdcontrol' tries to
change typematic rate, or the X server (XFree86 or Accelerated X)
starts up.
So far, there have been two independent reports from Dell Latitude XPi
notebook/laptop owners. The Latitude seems to be the only system which
suffers from this problem. (I don't know the problem is with the
entire Latitude line or with only some Latitude models) No problem
report has been heard about other systems (I certainly cannot
reproduce the problem in my -current and 2.2 systems).
In 3.0-CURRENT, 2.2-RELEASE and 2.2-GAMMA-970310, when programming the
keyboard LED/repeat-rate, `set_keyboard()' in `syscons' tells the
keyboard controller not to generate keyboard interrupt (IRQ1) and then
enable tty interrupts, expecting the keyboard interrupt doesn't occur.
It appears that somehow Latitude's keyboard controller still generates
the keyboard interrupt thereafter, and `set_keyboard()' doesn't see
the return code from the keyboard because it is consumed by the
keyboard interrupt handler.
The patch entirely disables tty interrupts while setting LED and
typematic rate in `set_keyboard()', making the routine behave more
like the previous versions of `syscons' (versions in 2.1.X and
2.2-ALPHA, -BETA, and some -GAMMAs). The reporter said this patch
eliminated the problem.
(I also found another typo/bug, but the reporter and I found that it
wasn't the cause of the problem...)
This should go into RELENG_2_2.
1997-03-28 10:11:24 +00:00
|
|
|
|
if (send_kbd_command_and_data(sc_kbdc, command, data) != KBD_ACK)
|
|
|
|
|
send_kbd_command(sc_kbdc, KBDC_ENABLE_KBD);
|
1997-01-15 18:16:32 +00:00
|
|
|
|
|
Interim patch/kludge for keyboard lock-up when `kbdcontrol' tries to
change typematic rate, or the X server (XFree86 or Accelerated X)
starts up.
So far, there have been two independent reports from Dell Latitude XPi
notebook/laptop owners. The Latitude seems to be the only system which
suffers from this problem. (I don't know the problem is with the
entire Latitude line or with only some Latitude models) No problem
report has been heard about other systems (I certainly cannot
reproduce the problem in my -current and 2.2 systems).
In 3.0-CURRENT, 2.2-RELEASE and 2.2-GAMMA-970310, when programming the
keyboard LED/repeat-rate, `set_keyboard()' in `syscons' tells the
keyboard controller not to generate keyboard interrupt (IRQ1) and then
enable tty interrupts, expecting the keyboard interrupt doesn't occur.
It appears that somehow Latitude's keyboard controller still generates
the keyboard interrupt thereafter, and `set_keyboard()' doesn't see
the return code from the keyboard because it is consumed by the
keyboard interrupt handler.
The patch entirely disables tty interrupts while setting LED and
typematic rate in `set_keyboard()', making the routine behave more
like the previous versions of `syscons' (versions in 2.1.X and
2.2-ALPHA, -BETA, and some -GAMMAs). The reporter said this patch
eliminated the problem.
(I also found another typo/bug, but the reporter and I found that it
wasn't the cause of the problem...)
This should go into RELENG_2_2.
1997-03-28 10:11:24 +00:00
|
|
|
|
#if 0
|
1997-01-15 18:16:32 +00:00
|
|
|
|
/* restore the interrupts */
|
|
|
|
|
if (!set_controller_command_byte(sc_kbdc,
|
|
|
|
|
kbdc_get_device_mask(sc_kbdc),
|
|
|
|
|
c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) {
|
|
|
|
|
/* CONTROLLER ERROR */
|
|
|
|
|
}
|
Interim patch/kludge for keyboard lock-up when `kbdcontrol' tries to
change typematic rate, or the X server (XFree86 or Accelerated X)
starts up.
So far, there have been two independent reports from Dell Latitude XPi
notebook/laptop owners. The Latitude seems to be the only system which
suffers from this problem. (I don't know the problem is with the
entire Latitude line or with only some Latitude models) No problem
report has been heard about other systems (I certainly cannot
reproduce the problem in my -current and 2.2 systems).
In 3.0-CURRENT, 2.2-RELEASE and 2.2-GAMMA-970310, when programming the
keyboard LED/repeat-rate, `set_keyboard()' in `syscons' tells the
keyboard controller not to generate keyboard interrupt (IRQ1) and then
enable tty interrupts, expecting the keyboard interrupt doesn't occur.
It appears that somehow Latitude's keyboard controller still generates
the keyboard interrupt thereafter, and `set_keyboard()' doesn't see
the return code from the keyboard because it is consumed by the
keyboard interrupt handler.
The patch entirely disables tty interrupts while setting LED and
typematic rate in `set_keyboard()', making the routine behave more
like the previous versions of `syscons' (versions in 2.1.X and
2.2-ALPHA, -BETA, and some -GAMMAs). The reporter said this patch
eliminated the problem.
(I also found another typo/bug, but the reporter and I found that it
wasn't the cause of the problem...)
This should go into RELENG_2_2.
1997-03-28 10:11:24 +00:00
|
|
|
|
#else
|
|
|
|
|
splx(s);
|
|
|
|
|
#endif
|
1997-01-15 18:16:32 +00:00
|
|
|
|
kbdc_lock(sc_kbdc, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
update_leds(int which)
|
|
|
|
|
{
|
1996-09-30 23:00:58 +00:00
|
|
|
|
static u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
|
|
|
|
|
|
|
|
|
|
/* replace CAPS led with ALTGR led for ALTGR keyboards */
|
|
|
|
|
if (key_map.n_keys > ALTGR_OFFSET) {
|
|
|
|
|
if (which & ALKED)
|
|
|
|
|
which |= CLKED;
|
|
|
|
|
else
|
|
|
|
|
which &= ~CLKED;
|
|
|
|
|
}
|
1996-11-14 22:19:17 +00:00
|
|
|
|
|
1997-01-15 18:16:32 +00:00
|
|
|
|
set_keyboard(KBDC_SET_LEDS, xlate_leds[which & LED_MASK]);
|
1996-09-30 23:00:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
void
|
1994-08-17 08:51:59 +00:00
|
|
|
|
set_mode(scr_stat *scp)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
char *modetable;
|
|
|
|
|
char special_modetable[64];
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (scp != cur_console)
|
|
|
|
|
return;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* setup video hardware for the given mode */
|
|
|
|
|
switch (scp->mode) {
|
1995-05-30 08:16:23 +00:00
|
|
|
|
case M_VGA_M80x60:
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(video_mode_ptr+(64*M_VGA_M80x25), &special_modetable, 64);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
goto special_80x60;
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
case M_VGA_C80x60:
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(video_mode_ptr+(64*M_VGA_C80x25), &special_modetable, 64);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
special_80x60:
|
|
|
|
|
special_modetable[2] = 0x08;
|
|
|
|
|
special_modetable[19] = 0x47;
|
|
|
|
|
goto special_480l;
|
|
|
|
|
|
|
|
|
|
case M_VGA_M80x30:
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(video_mode_ptr+(64*M_VGA_M80x25), &special_modetable, 64);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
goto special_80x30;
|
|
|
|
|
|
|
|
|
|
case M_VGA_C80x30:
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(video_mode_ptr+(64*M_VGA_C80x25), &special_modetable, 64);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
special_80x30:
|
|
|
|
|
special_modetable[19] = 0x4f;
|
|
|
|
|
special_480l:
|
|
|
|
|
special_modetable[9] |= 0xc0;
|
|
|
|
|
special_modetable[16] = 0x08;
|
|
|
|
|
special_modetable[17] = 0x3e;
|
|
|
|
|
special_modetable[26] = 0xea;
|
1995-05-30 08:16:23 +00:00
|
|
|
|
special_modetable[28] = 0xdf;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
special_modetable[31] = 0xe7;
|
|
|
|
|
special_modetable[32] = 0x04;
|
|
|
|
|
modetable = special_modetable;
|
|
|
|
|
goto setup_mode;
|
|
|
|
|
|
|
|
|
|
case M_ENH_B80x43:
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(video_mode_ptr+(64*M_ENH_B80x25), &special_modetable, 64);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
goto special_80x43;
|
|
|
|
|
|
|
|
|
|
case M_ENH_C80x43:
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(video_mode_ptr+(64*M_ENH_C80x25), &special_modetable, 64);
|
1995-05-30 08:16:23 +00:00
|
|
|
|
special_80x43:
|
1995-02-22 13:48:07 +00:00
|
|
|
|
special_modetable[28] = 87;
|
|
|
|
|
goto special_80x50;
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
case M_VGA_M80x50:
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(video_mode_ptr+(64*M_VGA_M80x25), &special_modetable, 64);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
goto special_80x50;
|
|
|
|
|
|
|
|
|
|
case M_VGA_C80x50:
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(video_mode_ptr+(64*M_VGA_C80x25), &special_modetable, 64);
|
1995-05-30 08:16:23 +00:00
|
|
|
|
special_80x50:
|
1995-02-22 13:48:07 +00:00
|
|
|
|
special_modetable[2] = 8;
|
|
|
|
|
special_modetable[19] = 7;
|
|
|
|
|
modetable = special_modetable;
|
|
|
|
|
goto setup_mode;
|
|
|
|
|
|
|
|
|
|
case M_VGA_C40x25: case M_VGA_C80x25:
|
|
|
|
|
case M_VGA_M80x25:
|
|
|
|
|
case M_B40x25: case M_C40x25:
|
|
|
|
|
case M_B80x25: case M_C80x25:
|
|
|
|
|
case M_ENH_B40x25: case M_ENH_C40x25:
|
|
|
|
|
case M_ENH_B80x25: case M_ENH_C80x25:
|
1997-05-15 05:43:59 +00:00
|
|
|
|
case M_EGAMONO80x25:
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
|
|
|
|
modetable = video_mode_ptr + (scp->mode * 64);
|
1994-09-15 07:26:40 +00:00
|
|
|
|
setup_mode:
|
1995-02-22 13:48:07 +00:00
|
|
|
|
set_vgaregs(modetable);
|
1996-09-01 18:16:06 +00:00
|
|
|
|
scp->font_size = *(modetable + 2);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
|
|
|
|
/* set font type (size) */
|
1997-05-15 05:43:59 +00:00
|
|
|
|
if (scp->font_size < 14) {
|
1996-09-30 23:00:58 +00:00
|
|
|
|
if (fonts_loaded & FONT_8)
|
|
|
|
|
copy_font(LOAD, FONT_8, font_8);
|
1996-09-01 18:16:06 +00:00
|
|
|
|
outb(TSIDX, 0x03); outb(TSREG, 0x0A); /* font 2 */
|
1997-05-15 05:43:59 +00:00
|
|
|
|
} else if (scp->font_size >= 16) {
|
1996-09-30 23:00:58 +00:00
|
|
|
|
if (fonts_loaded & FONT_16)
|
|
|
|
|
copy_font(LOAD, FONT_16, font_16);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
outb(TSIDX, 0x03); outb(TSREG, 0x00); /* font 0 */
|
1996-09-01 18:16:06 +00:00
|
|
|
|
} else {
|
1996-09-30 23:00:58 +00:00
|
|
|
|
if (fonts_loaded & FONT_14)
|
|
|
|
|
copy_font(LOAD, FONT_14, font_14);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
outb(TSIDX, 0x03); outb(TSREG, 0x05); /* font 1 */
|
|
|
|
|
}
|
1996-09-01 18:16:06 +00:00
|
|
|
|
if (flags & CHAR_CURSOR)
|
|
|
|
|
set_destructive_cursor(scp);
|
1996-09-30 23:00:58 +00:00
|
|
|
|
mark_all(scp);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
1994-09-15 07:26:40 +00:00
|
|
|
|
|
1997-08-08 22:52:30 +00:00
|
|
|
|
case M_VGA_MODEX:
|
|
|
|
|
/* start out with std 320x200x256 mode */
|
|
|
|
|
bcopy(video_mode_ptr+(64*M_VGA_CG320), &special_modetable, 64);
|
|
|
|
|
/* "unchain" the VGA mode */
|
|
|
|
|
special_modetable[5-1+0x04] &= 0xf7;
|
|
|
|
|
special_modetable[5-1+0x04] |= 0x04;
|
|
|
|
|
/* turn off doubleword mode */
|
|
|
|
|
special_modetable[10+0x14] &= 0xbf;
|
|
|
|
|
/* turn off word adressing */
|
|
|
|
|
special_modetable[10+0x17] |= 0x40;
|
|
|
|
|
/* set logical screen width */
|
|
|
|
|
special_modetable[10+0x13] = 80;
|
|
|
|
|
/* set 240 lines */
|
|
|
|
|
special_modetable[10+0x11] = 0x2c;
|
|
|
|
|
special_modetable[10+0x06] = 0x0d;
|
|
|
|
|
special_modetable[10+0x07] = 0x3e;
|
|
|
|
|
special_modetable[10+0x10] = 0xea;
|
|
|
|
|
special_modetable[10+0x11] = 0xac;
|
|
|
|
|
special_modetable[10+0x12] = 0xdf;
|
|
|
|
|
special_modetable[10+0x15] = 0xe7;
|
|
|
|
|
special_modetable[10+0x16] = 0x06;
|
|
|
|
|
/* set vertical sync polarity to reflect aspect ratio */
|
|
|
|
|
special_modetable[9] = 0xe3;
|
|
|
|
|
|
|
|
|
|
modetable = special_modetable;
|
|
|
|
|
goto setup_grmode;
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
case M_BG320: case M_CG320: case M_BG640:
|
|
|
|
|
case M_CG320_D: case M_CG640_E:
|
|
|
|
|
case M_CG640x350: case M_ENH_CG640:
|
|
|
|
|
case M_BG640x480: case M_CG640x480: case M_VGA_CG320:
|
1997-08-08 22:52:30 +00:00
|
|
|
|
modetable = video_mode_ptr + (scp->mode * 64);
|
|
|
|
|
setup_grmode:
|
|
|
|
|
set_vgaregs(modetable);
|
1996-06-26 13:04:53 +00:00
|
|
|
|
scp->font_size = FONT_NONE;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
break;
|
1994-09-15 07:26:40 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
default:
|
|
|
|
|
/* call user defined function XXX */
|
|
|
|
|
break;
|
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* set border color for this (virtual) console */
|
|
|
|
|
set_border(scp->border);
|
|
|
|
|
return;
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
void
|
1996-09-01 18:16:06 +00:00
|
|
|
|
set_border(u_char color)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
Screen saver related fixes.
1. Add new interface, add_scrn_saver()/remove_scrn_saver(), to declare
loading/unloading of a screen saver. The screen saver calls these
functions to notify syscons of loading/unloading events.
It was possible to load multiple savers each of which will try to
remember the previous saver in a local variable (`old_saver'). The
scheme breaks easily if the user load two savers and unload them in a
wrong order; if the first saver is unloaded first, `old_saver' in the
second saver points to nowhere.
Now only one screen saver is allowed in memory at a time.
Soeren will be looking into this issue again later. syscons is
becoming too heavy. It's time to cut things down, rather than adding
more...
2. Make scrn_timer() to be the primary caller of the screen saver
(*current_saver)(). scintr(), scioctl() and ansi_put() update
`scrn_time_stamp' to indicate that they want to stop the screen saver.
There are three exceptions, however.
One is remove_scrn_saver() which need to stop the current screen saver
if it is running. To guard against scrn_timer() calling the saver during
this operation, `current_saver' is set to `none_saver' early.
The others are sccngetc() and sccncheckc(); they will unblank the
screen too. When the kernel enters DDB (via the hot key or a
break point), the screen saver will be stopped by sccngetc().
However, we have a reentrancy problem here. If the system has been in
the middle of the screen saver...
(The screen saver reentrancy problem has always been with sccnputc()
and sccngetc() in the -current source. So, the new code is doing no
worse, I reckon.)
3. Use `mono_time' rather than `time'.
4. Make set_border() work for EGA and CGA in addition to VGA. Do
nothing for MDA.
Changes to the LKM screen saver modules will follow shortly. YOU NEED
TO RECOMPILE BOTH SCREEN SAVERS AND KERNEL AS OF THESE CHANGES.
Reviewed by: sos and bde
1997-07-15 14:43:27 +00:00
|
|
|
|
switch (crtc_type) {
|
|
|
|
|
case KD_EGA:
|
|
|
|
|
case KD_VGA:
|
|
|
|
|
inb(crtc_addr + 6); /* reset flip-flop */
|
|
|
|
|
outb(ATC, 0x11); outb(ATC, color);
|
|
|
|
|
inb(crtc_addr + 6); /* reset flip-flop */
|
|
|
|
|
outb(ATC, 0x20); /* enable Palette */
|
|
|
|
|
break;
|
|
|
|
|
case KD_CGA:
|
|
|
|
|
outb(crtc_addr + 5, color & 0x0f); /* color select register */
|
|
|
|
|
break;
|
|
|
|
|
case KD_MONO:
|
|
|
|
|
case KD_HERCULES:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1994-09-15 07:26:40 +00:00
|
|
|
|
static void
|
|
|
|
|
set_vgaregs(char *modetable)
|
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
int i, s = splhigh();
|
1994-09-15 07:26:40 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
|
|
|
|
|
outb(TSIDX, 0x07); outb(TSREG, 0x00); /* unlock registers */
|
|
|
|
|
for (i=0; i<4; i++) { /* program sequencer */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
outb(TSIDX, i+1);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
outb(TSREG, modetable[i+5]);
|
|
|
|
|
}
|
|
|
|
|
outb(MISC, modetable[9]); /* set dot-clock */
|
|
|
|
|
outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
|
|
|
|
|
outb(crtc_addr, 0x11);
|
|
|
|
|
outb(crtc_addr+1, inb(crtc_addr+1) & 0x7F);
|
|
|
|
|
for (i=0; i<25; i++) { /* program crtc */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
outb(crtc_addr, i);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (i == 14 || i == 15) /* no hardware cursor */
|
|
|
|
|
outb(crtc_addr+1, 0xff);
|
|
|
|
|
else
|
|
|
|
|
outb(crtc_addr+1, modetable[i+10]);
|
|
|
|
|
}
|
|
|
|
|
inb(crtc_addr+6); /* reset flip-flop */
|
|
|
|
|
for (i=0; i<20; i++) { /* program attribute ctrl */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
outb(ATC, i);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
outb(ATC, modetable[i+35]);
|
|
|
|
|
}
|
|
|
|
|
for (i=0; i<9; i++) { /* program graph data ctrl */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
outb(GDCIDX, i);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
outb(GDCREG, modetable[i+55]);
|
|
|
|
|
}
|
|
|
|
|
inb(crtc_addr+6); /* reset flip-flop */
|
1996-09-30 23:00:58 +00:00
|
|
|
|
outb(ATC, 0x20); /* enable palette */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
splx(s);
|
1994-09-15 07:26:40 +00:00
|
|
|
|
}
|
1994-08-17 08:51:59 +00:00
|
|
|
|
|
1997-04-27 09:03:10 +00:00
|
|
|
|
static void
|
|
|
|
|
read_vgaregs(char *buf)
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
int s;
|
|
|
|
|
|
|
|
|
|
bzero(buf, 64);
|
|
|
|
|
|
|
|
|
|
s = splhigh();
|
|
|
|
|
|
|
|
|
|
outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
|
|
|
|
|
outb(TSIDX, 0x07); outb(TSREG, 0x00); /* unlock registers */
|
|
|
|
|
for (i=0, j=5; i<4; i++) {
|
|
|
|
|
outb(TSIDX, i+1);
|
|
|
|
|
buf[j++] = inb(TSREG);
|
|
|
|
|
}
|
|
|
|
|
buf[9] = inb(MISC + 10); /* dot-clock */
|
|
|
|
|
outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
|
|
|
|
|
|
|
|
|
|
for (i=0, j=10; i<25; i++) { /* crtc */
|
|
|
|
|
outb(crtc_addr, i);
|
|
|
|
|
buf[j++] = inb(crtc_addr+1);
|
|
|
|
|
}
|
|
|
|
|
for (i=0, j=35; i<20; i++) { /* attribute ctrl */
|
|
|
|
|
inb(crtc_addr+6); /* reset flip-flop */
|
|
|
|
|
outb(ATC, i);
|
|
|
|
|
buf[j++] = inb(ATC + 1);
|
|
|
|
|
}
|
|
|
|
|
for (i=0, j=55; i<9; i++) { /* graph data ctrl */
|
|
|
|
|
outb(GDCIDX, i);
|
|
|
|
|
buf[j++] = inb(GDCREG);
|
|
|
|
|
}
|
|
|
|
|
inb(crtc_addr+6); /* reset flip-flop */
|
|
|
|
|
outb(ATC, 0x20); /* enable palette */
|
|
|
|
|
|
|
|
|
|
buf[0] = *(char *)pa_to_va(0x44a); /* COLS */
|
|
|
|
|
buf[1] = *(char *)pa_to_va(0x484); /* ROWS */
|
|
|
|
|
buf[2] = *(char *)pa_to_va(0x485); /* POINTS */
|
|
|
|
|
buf[3] = *(char *)pa_to_va(0x44c);
|
|
|
|
|
buf[4] = *(char *)pa_to_va(0x44d);
|
|
|
|
|
|
|
|
|
|
splx(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
comp_vgaregs(u_char *buf1, u_char *buf2)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
1997-04-30 01:19:21 +00:00
|
|
|
|
for(i = 0; i < 20; ++i) {
|
1997-04-27 09:03:10 +00:00
|
|
|
|
if (*buf1++ != *buf2++)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
1997-04-30 15:31:22 +00:00
|
|
|
|
buf1 += 2; /* skip the cursor shape */
|
|
|
|
|
buf2 += 2;
|
|
|
|
|
for(i = 22; i < 24; ++i) {
|
|
|
|
|
if (*buf1++ != *buf2++)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
buf1 += 2; /* skip the cursor position */
|
|
|
|
|
buf2 += 2;
|
1997-04-27 09:03:10 +00:00
|
|
|
|
for(i = 26; i < 64; ++i) {
|
|
|
|
|
if (*buf1++ != *buf2++)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dump_vgaregs(u_char *buf)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < 64;) {
|
|
|
|
|
printf("%02x ", buf[i]);
|
|
|
|
|
if ((++i % 16) == 0)
|
|
|
|
|
printf("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-01-20 08:35:32 +00:00
|
|
|
|
static void
|
|
|
|
|
set_font_mode()
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1997-01-17 15:49:13 +00:00
|
|
|
|
int s = splhigh();
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* setup vga for loading fonts (graphics plane mode) */
|
1996-09-30 23:00:58 +00:00
|
|
|
|
inb(crtc_addr+6); /* reset flip-flop */
|
|
|
|
|
outb(ATC, 0x10); outb(ATC, 0x01);
|
|
|
|
|
inb(crtc_addr+6); /* reset flip-flop */
|
|
|
|
|
outb(ATC, 0x20); /* enable palette */
|
1997-01-17 15:49:13 +00:00
|
|
|
|
|
1995-01-28 22:18:05 +00:00
|
|
|
|
#if SLOW_VGA
|
1995-02-22 13:48:07 +00:00
|
|
|
|
outb(TSIDX, 0x02); outb(TSREG, 0x04);
|
|
|
|
|
outb(TSIDX, 0x04); outb(TSREG, 0x06);
|
|
|
|
|
outb(GDCIDX, 0x04); outb(GDCREG, 0x02);
|
|
|
|
|
outb(GDCIDX, 0x05); outb(GDCREG, 0x00);
|
1995-05-30 08:16:23 +00:00
|
|
|
|
outb(GDCIDX, 0x06); outb(GDCREG, 0x05);
|
1995-01-20 08:35:32 +00:00
|
|
|
|
#else
|
1995-02-22 13:48:07 +00:00
|
|
|
|
outw(TSIDX, 0x0402);
|
|
|
|
|
outw(TSIDX, 0x0604);
|
|
|
|
|
outw(GDCIDX, 0x0204);
|
|
|
|
|
outw(GDCIDX, 0x0005);
|
|
|
|
|
outw(GDCIDX, 0x0506); /* addr = a0000, 64kb */
|
1995-01-20 08:35:32 +00:00
|
|
|
|
#endif
|
1997-01-17 15:49:13 +00:00
|
|
|
|
splx(s);
|
1995-01-20 08:35:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
set_normal_mode()
|
|
|
|
|
{
|
1996-09-30 23:00:58 +00:00
|
|
|
|
char *modetable;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
int s = splhigh();
|
1995-01-20 08:35:32 +00:00
|
|
|
|
|
1996-09-30 23:00:58 +00:00
|
|
|
|
switch (cur_console->mode) {
|
|
|
|
|
case M_VGA_M80x60:
|
|
|
|
|
case M_VGA_M80x50:
|
|
|
|
|
case M_VGA_M80x30:
|
|
|
|
|
modetable = video_mode_ptr + (64*M_VGA_M80x25);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case M_VGA_C80x60:
|
|
|
|
|
case M_VGA_C80x50:
|
|
|
|
|
case M_VGA_C80x30:
|
|
|
|
|
modetable = video_mode_ptr + (64*M_VGA_C80x25);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case M_ENH_B80x43:
|
|
|
|
|
modetable = video_mode_ptr + (64*M_ENH_B80x25);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case M_ENH_C80x43:
|
|
|
|
|
modetable = video_mode_ptr + (64*M_ENH_C80x25);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case M_VGA_C40x25: case M_VGA_C80x25:
|
|
|
|
|
case M_VGA_M80x25:
|
|
|
|
|
case M_B40x25: case M_C40x25:
|
|
|
|
|
case M_B80x25: case M_C80x25:
|
|
|
|
|
case M_ENH_B40x25: case M_ENH_C40x25:
|
|
|
|
|
case M_ENH_B80x25: case M_ENH_C80x25:
|
1997-05-15 05:43:59 +00:00
|
|
|
|
case M_EGAMONO80x25:
|
1996-09-30 23:00:58 +00:00
|
|
|
|
|
|
|
|
|
case M_BG320: case M_CG320: case M_BG640:
|
|
|
|
|
case M_CG320_D: case M_CG640_E:
|
|
|
|
|
case M_CG640x350: case M_ENH_CG640:
|
|
|
|
|
case M_BG640x480: case M_CG640x480: case M_VGA_CG320:
|
|
|
|
|
modetable = video_mode_ptr + (cur_console->mode * 64);
|
1997-02-28 08:42:35 +00:00
|
|
|
|
break;
|
1996-09-30 23:00:58 +00:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
modetable = video_mode_ptr + (64*M_VGA_C80x25);
|
|
|
|
|
}
|
|
|
|
|
|
1997-04-27 09:03:10 +00:00
|
|
|
|
if (video_mode_ptr == NULL)
|
|
|
|
|
modetable = vgaregs;
|
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
/* setup vga for normal operation mode again */
|
1996-09-30 23:00:58 +00:00
|
|
|
|
inb(crtc_addr+6); /* reset flip-flop */
|
|
|
|
|
outb(ATC, 0x10); outb(ATC, modetable[0x10+35]);
|
|
|
|
|
inb(crtc_addr+6); /* reset flip-flop */
|
|
|
|
|
outb(ATC, 0x20); /* enable palette */
|
1995-01-28 22:18:05 +00:00
|
|
|
|
#if SLOW_VGA
|
1996-09-30 23:00:58 +00:00
|
|
|
|
outb(TSIDX, 0x02); outb(TSREG, modetable[0x02+4]);
|
|
|
|
|
outb(TSIDX, 0x04); outb(TSREG, modetable[0x04+4]);
|
|
|
|
|
outb(GDCIDX, 0x04); outb(GDCREG, modetable[0x04+55]);
|
|
|
|
|
outb(GDCIDX, 0x05); outb(GDCREG, modetable[0x05+55]);
|
|
|
|
|
outb(GDCIDX, 0x06); outb(GDCREG, modetable[0x06+55]);
|
1996-12-07 22:33:05 +00:00
|
|
|
|
if (crtc_addr == MONO_BASE) {
|
|
|
|
|
outb(GDCIDX, 0x06); outb(GDCREG,(modetable[0x06+55] & 0x03) | 0x08);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
outb(GDCIDX, 0x06); outb(GDCREG,(modetable[0x06+55] & 0x03) | 0x0c);
|
|
|
|
|
}
|
1995-01-20 08:35:32 +00:00
|
|
|
|
#else
|
1996-09-30 23:00:58 +00:00
|
|
|
|
outw(TSIDX, 0x0002 | (modetable[0x02+4]<<8));
|
|
|
|
|
outw(TSIDX, 0x0004 | (modetable[0x04+4]<<8));
|
|
|
|
|
outw(GDCIDX, 0x0004 | (modetable[0x04+55]<<8));
|
|
|
|
|
outw(GDCIDX, 0x0005 | (modetable[0x05+55]<<8));
|
1996-12-07 22:33:05 +00:00
|
|
|
|
if (crtc_addr == MONO_BASE)
|
|
|
|
|
outw(GDCIDX, 0x0006 | (((modetable[0x06+55] & 0x03) | 0x08)<<8));
|
|
|
|
|
else
|
|
|
|
|
outw(GDCIDX, 0x0006 | (((modetable[0x06+55] & 0x03) | 0x0c)<<8));
|
1995-01-20 08:35:32 +00:00
|
|
|
|
#endif
|
1995-02-22 13:48:07 +00:00
|
|
|
|
splx(s);
|
1995-01-20 08:35:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
void
|
1995-01-20 08:35:32 +00:00
|
|
|
|
copy_font(int operation, int font_type, char* font_image)
|
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
int ch, line, segment, fontsize;
|
|
|
|
|
u_char val;
|
|
|
|
|
|
1996-09-30 23:00:58 +00:00
|
|
|
|
/* dont mess with console we dont know video mode on */
|
|
|
|
|
if (cur_console->status & UNKNOWN_MODE)
|
|
|
|
|
return;
|
1996-10-02 22:00:38 +00:00
|
|
|
|
|
1995-02-22 13:48:07 +00:00
|
|
|
|
switch (font_type) {
|
|
|
|
|
default:
|
|
|
|
|
case FONT_8:
|
|
|
|
|
segment = 0x8000;
|
|
|
|
|
fontsize = 8;
|
|
|
|
|
break;
|
|
|
|
|
case FONT_14:
|
|
|
|
|
segment = 0x4000;
|
|
|
|
|
fontsize = 14;
|
|
|
|
|
break;
|
|
|
|
|
case FONT_16:
|
|
|
|
|
segment = 0x0000;
|
|
|
|
|
fontsize = 16;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */
|
|
|
|
|
outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
|
|
|
|
|
set_font_mode();
|
1995-05-30 08:16:23 +00:00
|
|
|
|
for (ch=0; ch < 256; ch++)
|
|
|
|
|
for (line=0; line < fontsize; line++)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (operation)
|
|
|
|
|
*(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line) =
|
1995-05-30 08:16:23 +00:00
|
|
|
|
font_image[(ch*fontsize)+line];
|
1995-02-22 13:48:07 +00:00
|
|
|
|
else
|
|
|
|
|
font_image[(ch*fontsize)+line] =
|
|
|
|
|
*(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line);
|
|
|
|
|
set_normal_mode();
|
|
|
|
|
outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); /* enable screen */
|
1995-01-20 08:35:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static void
|
1996-09-01 18:16:06 +00:00
|
|
|
|
set_destructive_cursor(scr_stat *scp)
|
1995-03-29 20:55:03 +00:00
|
|
|
|
{
|
|
|
|
|
u_char cursor[32];
|
|
|
|
|
caddr_t address;
|
1996-06-26 13:04:53 +00:00
|
|
|
|
int i;
|
1995-03-30 14:32:31 +00:00
|
|
|
|
char *font_buffer;
|
1995-03-29 20:55:03 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
|
1997-05-15 05:43:59 +00:00
|
|
|
|
if (scp->font_size < 14) {
|
1995-03-30 14:32:31 +00:00
|
|
|
|
font_buffer = font_8;
|
|
|
|
|
address = (caddr_t)VIDEOMEM + 0x8000;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
}
|
1997-05-15 05:43:59 +00:00
|
|
|
|
else if (scp->font_size >= 16) {
|
1995-03-30 14:32:31 +00:00
|
|
|
|
font_buffer = font_16;
|
1995-03-29 20:55:03 +00:00
|
|
|
|
address = (caddr_t)VIDEOMEM;
|
|
|
|
|
}
|
1996-09-01 18:16:06 +00:00
|
|
|
|
else {
|
|
|
|
|
font_buffer = font_14;
|
|
|
|
|
address = (caddr_t)VIDEOMEM + 0x4000;
|
|
|
|
|
}
|
|
|
|
|
|
1996-10-18 18:51:37 +00:00
|
|
|
|
if (scp->status & MOUSE_VISIBLE) {
|
1996-06-25 08:54:57 +00:00
|
|
|
|
if ((scp->cursor_saveunder & 0xff) == 0xd0)
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(&scp->mouse_cursor[0], cursor, scp->font_size);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
else if ((scp->cursor_saveunder & 0xff) == 0xd1)
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(&scp->mouse_cursor[32], cursor, scp->font_size);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
else if ((scp->cursor_saveunder & 0xff) == 0xd2)
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(&scp->mouse_cursor[64], cursor, scp->font_size);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
else if ((scp->cursor_saveunder & 0xff) == 0xd3)
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(&scp->mouse_cursor[96], cursor, scp->font_size);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
else
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(font_buffer+((scp->cursor_saveunder & 0xff)*scp->font_size),
|
1996-06-26 13:04:53 +00:00
|
|
|
|
cursor, scp->font_size);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(font_buffer + ((scp->cursor_saveunder & 0xff) * scp->font_size),
|
1996-06-26 13:04:53 +00:00
|
|
|
|
cursor, scp->font_size);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
for (i=0; i<32; i++)
|
1995-05-30 08:16:23 +00:00
|
|
|
|
if ((i >= scp->cursor_start && i <= scp->cursor_end) ||
|
1996-06-26 13:04:53 +00:00
|
|
|
|
(scp->cursor_start >= scp->font_size && i == scp->font_size - 1))
|
1995-03-30 14:32:31 +00:00
|
|
|
|
cursor[i] |= 0xff;
|
1997-01-19 17:34:14 +00:00
|
|
|
|
#if 1
|
|
|
|
|
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
|
|
|
|
|
#endif
|
1995-03-29 20:55:03 +00:00
|
|
|
|
set_font_mode();
|
1997-04-27 09:03:10 +00:00
|
|
|
|
sc_bcopy(cursor, (char *)pa_to_va(address) + DEAD_CHAR * 32, 32);
|
1995-03-29 20:55:03 +00:00
|
|
|
|
set_normal_mode();
|
|
|
|
|
}
|
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
static void
|
|
|
|
|
set_mouse_pos(scr_stat *scp)
|
|
|
|
|
{
|
1996-09-01 18:16:06 +00:00
|
|
|
|
static int last_xpos = -1, last_ypos = -1;
|
1997-08-09 19:24:03 +00:00
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
if (scp->mouse_xpos < 0)
|
|
|
|
|
scp->mouse_xpos = 0;
|
|
|
|
|
if (scp->mouse_ypos < 0)
|
|
|
|
|
scp->mouse_ypos = 0;
|
1997-08-08 22:52:30 +00:00
|
|
|
|
if (scp->status & UNKNOWN_MODE) {
|
1997-08-09 19:24:03 +00:00
|
|
|
|
if (scp->mouse_xpos > scp->xpixel-1)
|
1997-08-08 22:52:30 +00:00
|
|
|
|
scp->mouse_xpos = scp->xpixel-1;
|
1997-08-09 19:24:03 +00:00
|
|
|
|
if (scp->mouse_ypos > scp->ypixel-1)
|
1997-08-08 22:52:30 +00:00
|
|
|
|
scp->mouse_ypos = scp->ypixel-1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
1997-08-09 19:24:03 +00:00
|
|
|
|
if (scp->mouse_xpos > (scp->xsize*8)-1)
|
|
|
|
|
scp->mouse_xpos = (scp->xsize*8)-1;
|
|
|
|
|
if (scp->mouse_ypos > (scp->ysize*scp->font_size)-1)
|
|
|
|
|
scp->mouse_ypos = (scp->ysize*scp->font_size)-1;
|
1996-06-26 13:04:53 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
if (scp->mouse_xpos != last_xpos || scp->mouse_ypos != last_ypos) {
|
|
|
|
|
scp->status |= MOUSE_MOVED;
|
1996-06-25 08:54:57 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
scp->mouse_pos = scp->scr_buf +
|
|
|
|
|
((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
|
1996-10-18 18:51:37 +00:00
|
|
|
|
if ((scp->status & MOUSE_VISIBLE) && (scp->status & MOUSE_CUTTING)) {
|
1996-09-01 18:16:06 +00:00
|
|
|
|
u_short *ptr;
|
|
|
|
|
int i = 0;
|
1996-06-21 07:19:18 +00:00
|
|
|
|
|
1996-09-01 18:16:06 +00:00
|
|
|
|
mark_for_update(scp, scp->mouse_cut_start - scp->scr_buf);
|
|
|
|
|
mark_for_update(scp, scp->mouse_cut_end - scp->scr_buf);
|
|
|
|
|
scp->mouse_cut_end = scp->mouse_pos;
|
|
|
|
|
for (ptr = (scp->mouse_cut_start > scp->mouse_cut_end
|
|
|
|
|
? scp->mouse_cut_end : scp->mouse_cut_start);
|
|
|
|
|
ptr <= (scp->mouse_cut_start > scp->mouse_cut_end
|
|
|
|
|
? scp->mouse_cut_start : scp->mouse_cut_end);
|
|
|
|
|
ptr++) {
|
|
|
|
|
cut_buffer[i++] = *ptr & 0xff;
|
|
|
|
|
if (((ptr - scp->scr_buf) % scp->xsize) == (scp->xsize - 1)) {
|
1996-06-26 13:04:53 +00:00
|
|
|
|
cut_buffer[i++] = '\n';
|
1996-09-01 18:16:06 +00:00
|
|
|
|
}
|
1996-06-26 13:04:53 +00:00
|
|
|
|
}
|
1996-06-21 07:19:18 +00:00
|
|
|
|
cut_buffer[i] = 0x00;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
}
|
1996-06-21 07:19:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1996-06-25 08:54:57 +00:00
|
|
|
|
static void
|
|
|
|
|
mouse_cut_start(scr_stat *scp)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
1996-10-18 18:51:37 +00:00
|
|
|
|
if (scp->status & MOUSE_VISIBLE) {
|
1996-06-25 08:54:57 +00:00
|
|
|
|
if (scp->mouse_pos == scp->mouse_cut_start &&
|
|
|
|
|
scp->mouse_cut_start == scp->mouse_cut_end) {
|
1996-06-26 13:04:53 +00:00
|
|
|
|
cut_buffer[0] = 0x00;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
remove_cutmarking(scp);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
scp->mouse_cut_start = scp->mouse_cut_end = scp->mouse_pos;
|
|
|
|
|
cut_buffer[0] = *scp->mouse_cut_start & 0xff;
|
1996-06-26 13:04:53 +00:00
|
|
|
|
cut_buffer[1] = 0x00;
|
1996-06-25 08:54:57 +00:00
|
|
|
|
scp->status |= MOUSE_CUTTING;
|
|
|
|
|
}
|
1996-09-01 18:16:06 +00:00
|
|
|
|
mark_all(scp);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
/* delete all other screens cut markings */
|
|
|
|
|
for (i=0; i<MAXCONS; i++) {
|
|
|
|
|
if (console[i] == NULL || console[i] == scp)
|
|
|
|
|
continue;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
remove_cutmarking(console[i]);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mouse_cut_end(scr_stat *scp)
|
|
|
|
|
{
|
1996-10-18 18:51:37 +00:00
|
|
|
|
if (scp->status & MOUSE_VISIBLE) {
|
1996-06-25 08:54:57 +00:00
|
|
|
|
scp->status &= ~MOUSE_CUTTING;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mouse_paste(scr_stat *scp)
|
|
|
|
|
{
|
1996-10-18 18:51:37 +00:00
|
|
|
|
if (scp->status & MOUSE_VISIBLE) {
|
1996-06-25 08:54:57 +00:00
|
|
|
|
struct tty *tp;
|
1996-06-26 13:04:53 +00:00
|
|
|
|
u_char *ptr = cut_buffer;
|
1996-06-25 08:54:57 +00:00
|
|
|
|
|
|
|
|
|
tp = VIRTUAL_TTY(get_scr_num());
|
|
|
|
|
while (*ptr)
|
1996-09-01 18:16:06 +00:00
|
|
|
|
(*linesw[tp->t_line].l_rint)(scr_rmap[*ptr++], tp);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-01-20 08:35:32 +00:00
|
|
|
|
static void
|
|
|
|
|
draw_mouse_image(scr_stat *scp)
|
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
caddr_t address;
|
1996-06-26 13:04:53 +00:00
|
|
|
|
int i;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
char *font_buffer;
|
|
|
|
|
u_short buffer[32];
|
|
|
|
|
u_short xoffset, yoffset;
|
|
|
|
|
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
|
1996-06-26 13:04:53 +00:00
|
|
|
|
int font_size = scp->font_size;
|
1995-02-22 13:48:07 +00:00
|
|
|
|
|
1997-05-15 05:43:59 +00:00
|
|
|
|
if (font_size < 14) {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
font_buffer = font_8;
|
1995-03-30 14:32:31 +00:00
|
|
|
|
address = (caddr_t)VIDEOMEM + 0x8000;
|
1996-09-01 18:16:06 +00:00
|
|
|
|
}
|
1997-05-15 05:43:59 +00:00
|
|
|
|
else if (font_size >= 16) {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
font_buffer = font_16;
|
|
|
|
|
address = (caddr_t)VIDEOMEM;
|
|
|
|
|
}
|
1996-09-01 18:16:06 +00:00
|
|
|
|
else {
|
|
|
|
|
font_buffer = font_14;
|
|
|
|
|
address = (caddr_t)VIDEOMEM + 0x4000;
|
|
|
|
|
}
|
|
|
|
|
xoffset = scp->mouse_xpos % 8;
|
|
|
|
|
yoffset = scp->mouse_ypos % font_size;
|
|
|
|
|
|
|
|
|
|
/* prepare mousepointer char's bitmaps */
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size),
|
1995-02-22 13:48:07 +00:00
|
|
|
|
&scp->mouse_cursor[0], font_size);
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(font_buffer + ((*(scp->mouse_pos+1) & 0xff) * font_size),
|
1995-02-22 13:48:07 +00:00
|
|
|
|
&scp->mouse_cursor[32], font_size);
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(font_buffer + ((*(scp->mouse_pos+scp->xsize) & 0xff) * font_size),
|
1995-02-22 13:48:07 +00:00
|
|
|
|
&scp->mouse_cursor[64], font_size);
|
1997-05-07 10:42:06 +00:00
|
|
|
|
bcopy(font_buffer + ((*(scp->mouse_pos+scp->xsize+1) & 0xff) * font_size),
|
1995-02-22 13:48:07 +00:00
|
|
|
|
&scp->mouse_cursor[96], font_size);
|
|
|
|
|
for (i=0; i<font_size; i++) {
|
|
|
|
|
buffer[i] = scp->mouse_cursor[i]<<8 | scp->mouse_cursor[i+32];
|
|
|
|
|
buffer[i+font_size]=scp->mouse_cursor[i+64]<<8|scp->mouse_cursor[i+96];
|
|
|
|
|
}
|
1996-09-01 18:16:06 +00:00
|
|
|
|
|
|
|
|
|
/* now and-or in the mousepointer image */
|
1995-02-22 13:48:07 +00:00
|
|
|
|
for (i=0; i<16; i++) {
|
|
|
|
|
buffer[i+yoffset] =
|
|
|
|
|
( buffer[i+yoffset] & ~(mouse_and_mask[i] >> xoffset))
|
|
|
|
|
| (mouse_or_mask[i] >> xoffset);
|
|
|
|
|
}
|
|
|
|
|
for (i=0; i<font_size; i++) {
|
|
|
|
|
scp->mouse_cursor[i] = (buffer[i] & 0xff00) >> 8;
|
|
|
|
|
scp->mouse_cursor[i+32] = buffer[i] & 0xff;
|
|
|
|
|
scp->mouse_cursor[i+64] = (buffer[i+font_size] & 0xff00) >> 8;
|
|
|
|
|
scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff;
|
|
|
|
|
}
|
1996-09-01 18:16:06 +00:00
|
|
|
|
|
|
|
|
|
scp->mouse_oldpos = scp->mouse_pos;
|
|
|
|
|
|
|
|
|
|
/* wait for vertical retrace to avoid jitter on some videocards */
|
1997-01-19 17:34:14 +00:00
|
|
|
|
#if 1
|
1996-09-01 18:16:06 +00:00
|
|
|
|
while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ;
|
1997-01-19 17:34:14 +00:00
|
|
|
|
#endif
|
1996-06-25 08:54:57 +00:00
|
|
|
|
set_font_mode();
|
1997-04-27 09:03:10 +00:00
|
|
|
|
sc_bcopy(scp->mouse_cursor, (char *)pa_to_va(address) + 0xd0 * 32, 128);
|
1996-06-25 08:54:57 +00:00
|
|
|
|
set_normal_mode();
|
1995-11-20 12:13:32 +00:00
|
|
|
|
*(crt_pos) = (*(scp->mouse_pos)&0xff00)|0xd0;
|
|
|
|
|
*(crt_pos+scp->xsize) = (*(scp->mouse_pos+scp->xsize)&0xff00)|0xd2;
|
1996-06-21 07:19:18 +00:00
|
|
|
|
if (scp->mouse_xpos < (scp->xsize-1)*8) {
|
|
|
|
|
*(crt_pos+1) = (*(scp->mouse_pos+1)&0xff00)|0xd1;
|
|
|
|
|
*(crt_pos+scp->xsize+1) = (*(scp->mouse_pos+scp->xsize+1)&0xff00)|0xd3;
|
|
|
|
|
}
|
1996-10-02 22:00:38 +00:00
|
|
|
|
mark_for_update(scp, scp->mouse_pos - scp->scr_buf);
|
|
|
|
|
mark_for_update(scp, scp->mouse_pos + scp->xsize + 1 - scp->scr_buf);
|
1996-09-01 18:16:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
remove_mouse_image(scr_stat *scp)
|
|
|
|
|
{
|
|
|
|
|
u_short *crt_pos = Crtat + (scp->mouse_oldpos - scp->scr_buf);
|
|
|
|
|
|
|
|
|
|
*(crt_pos) = *(scp->mouse_oldpos);
|
|
|
|
|
*(crt_pos+1) = *(scp->mouse_oldpos+1);
|
|
|
|
|
*(crt_pos+scp->xsize) = *(scp->mouse_oldpos+scp->xsize);
|
|
|
|
|
*(crt_pos+scp->xsize+1) = *(scp->mouse_oldpos+scp->xsize+1);
|
1996-10-02 22:00:38 +00:00
|
|
|
|
mark_for_update(scp, scp->mouse_oldpos - scp->scr_buf);
|
|
|
|
|
mark_for_update(scp, scp->mouse_oldpos + scp->xsize + 1 - scp->scr_buf);
|
1996-09-01 18:16:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
draw_cutmarking(scr_stat *scp)
|
|
|
|
|
{
|
|
|
|
|
u_short *ptr;
|
|
|
|
|
u_short och, nch;
|
|
|
|
|
|
|
|
|
|
for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) {
|
|
|
|
|
nch = och = *(Crtat + (ptr - scp->scr_buf));
|
|
|
|
|
/* are we outside the selected area ? */
|
|
|
|
|
if ( ptr < (scp->mouse_cut_start > scp->mouse_cut_end ?
|
|
|
|
|
scp->mouse_cut_end : scp->mouse_cut_start) ||
|
|
|
|
|
ptr > (scp->mouse_cut_start > scp->mouse_cut_end ?
|
|
|
|
|
scp->mouse_cut_start : scp->mouse_cut_end)) {
|
|
|
|
|
if (ptr != scp->cursor_pos)
|
|
|
|
|
nch = (och & 0xff) | (*ptr & 0xff00);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* are we clear of the cursor image ? */
|
|
|
|
|
if (ptr != scp->cursor_pos)
|
|
|
|
|
nch = (och & 0x88ff) | (*ptr & 0x7000)>>4 | (*ptr & 0x0700)<<4;
|
|
|
|
|
else {
|
|
|
|
|
if (flags & CHAR_CURSOR)
|
|
|
|
|
nch = (och & 0x88ff)|(*ptr & 0x7000)>>4|(*ptr & 0x0700)<<4;
|
|
|
|
|
else
|
|
|
|
|
if (!(flags & BLINK_CURSOR))
|
|
|
|
|
nch = (och & 0xff) | (*ptr & 0xff00);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (nch != och)
|
|
|
|
|
*(Crtat + (ptr - scp->scr_buf)) = nch;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
remove_cutmarking(scr_stat *scp)
|
|
|
|
|
{
|
|
|
|
|
scp->mouse_cut_start = scp->mouse_cut_end = NULL;
|
|
|
|
|
scp->status &= ~MOUSE_CUTTING;
|
|
|
|
|
mark_all(scp);
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
static void
|
1995-01-12 11:47:05 +00:00
|
|
|
|
save_palette(void)
|
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
int i;
|
1995-01-12 11:47:05 +00:00
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
outb(PALRADR, 0x00);
|
|
|
|
|
for (i=0x00; i<0x300; i++)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
palette[i] = inb(PALDATA);
|
|
|
|
|
inb(crtc_addr+6); /* reset flip/flop */
|
1995-01-12 11:47:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-05-30 08:16:23 +00:00
|
|
|
|
void
|
1997-01-15 18:16:32 +00:00
|
|
|
|
load_palette(char *palette)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1995-02-22 13:48:07 +00:00
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
outb(PIXMASK, 0xFF); /* no pixelmask */
|
1995-05-30 08:16:23 +00:00
|
|
|
|
outb(PALWADR, 0x00);
|
|
|
|
|
for (i=0x00; i<0x300; i++)
|
1995-02-22 13:48:07 +00:00
|
|
|
|
outb(PALDATA, palette[i]);
|
|
|
|
|
inb(crtc_addr+6); /* reset flip/flop */
|
|
|
|
|
outb(ATC, 0x20); /* enable palette */
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-01-12 11:47:05 +00:00
|
|
|
|
static void
|
|
|
|
|
do_bell(scr_stat *scp, int pitch, int duration)
|
1993-07-26 21:21:11 +00:00
|
|
|
|
{
|
1996-09-01 18:16:06 +00:00
|
|
|
|
if (flags & VISUAL_BELL) {
|
1996-02-05 14:08:39 +00:00
|
|
|
|
if (blink_in_progress)
|
|
|
|
|
return;
|
|
|
|
|
blink_in_progress = 4;
|
|
|
|
|
if (scp != cur_console)
|
|
|
|
|
blink_in_progress += 2;
|
|
|
|
|
blink_screen(cur_console);
|
|
|
|
|
} else {
|
|
|
|
|
if (scp != cur_console)
|
|
|
|
|
pitch *= 2;
|
|
|
|
|
sysbeep(pitch, duration);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1995-01-12 11:47:05 +00:00
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
|
1995-01-12 11:47:05 +00:00
|
|
|
|
static void
|
1997-04-20 16:05:33 +00:00
|
|
|
|
blink_screen(void *arg)
|
1995-01-12 11:47:05 +00:00
|
|
|
|
{
|
1997-04-20 16:05:33 +00:00
|
|
|
|
scr_stat *scp = arg;
|
|
|
|
|
|
1997-05-15 05:43:59 +00:00
|
|
|
|
if ((scp->status & UNKNOWN_MODE) || (blink_in_progress <= 1)) {
|
|
|
|
|
blink_in_progress = FALSE;
|
|
|
|
|
mark_all(scp);
|
|
|
|
|
if (delayed_next_scr)
|
|
|
|
|
switch_scr(scp, delayed_next_scr - 1);
|
|
|
|
|
}
|
|
|
|
|
else {
|
1995-02-22 13:48:07 +00:00
|
|
|
|
if (blink_in_progress & 1)
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(kernel_default.std_color | scr_map[0x20],
|
1995-02-22 13:48:07 +00:00
|
|
|
|
Crtat, scp->xsize * scp->ysize);
|
|
|
|
|
else
|
1995-11-28 00:17:32 +00:00
|
|
|
|
fillw(kernel_default.rev_color | scr_map[0x20],
|
1995-02-22 13:48:07 +00:00
|
|
|
|
Crtat, scp->xsize * scp->ysize);
|
|
|
|
|
blink_in_progress--;
|
1997-04-20 16:05:33 +00:00
|
|
|
|
timeout(blink_screen, scp, hz / 10);
|
1995-02-22 13:48:07 +00:00
|
|
|
|
}
|
1993-07-26 21:21:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-09-30 23:00:58 +00:00
|
|
|
|
#ifdef SC_SPLASH_SCREEN
|
|
|
|
|
static void
|
|
|
|
|
toggle_splash_screen(scr_stat *scp)
|
|
|
|
|
{
|
|
|
|
|
static int toggle = 0;
|
|
|
|
|
static u_char save_mode;
|
1997-04-27 09:03:10 +00:00
|
|
|
|
int s;
|
|
|
|
|
|
|
|
|
|
if (video_mode_ptr == NULL)
|
|
|
|
|
return;
|
1996-09-30 23:00:58 +00:00
|
|
|
|
|
1997-04-27 09:03:10 +00:00
|
|
|
|
s = splhigh();
|
1996-09-30 23:00:58 +00:00
|
|
|
|
if (toggle) {
|
|
|
|
|
scp->mode = save_mode;
|
|
|
|
|
scp->status &= ~UNKNOWN_MODE;
|
|
|
|
|
set_mode(scp);
|
1997-01-15 18:16:32 +00:00
|
|
|
|
load_palette(palette);
|
1996-09-30 23:00:58 +00:00
|
|
|
|
toggle = 0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
save_mode = scp->mode;
|
|
|
|
|
scp->mode = M_VGA_CG320;
|
|
|
|
|
scp->status |= UNKNOWN_MODE;
|
|
|
|
|
set_mode(scp);
|
|
|
|
|
/* load image */
|
|
|
|
|
toggle = 1;
|
|
|
|
|
}
|
|
|
|
|
splx(s);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
1993-07-26 21:21:11 +00:00
|
|
|
|
#endif /* NSC */
|