{ 0004, 0261, 0007, 0007, 0007, 0007, 0370, 0361, 0007, 0007, 0331, 0277, 0332, 0300, 0305, 0304,
0304, 0304, 0137, 0137, 0303, 0264, 0301, 0302, 0263, 0363, 0362, 0343, 0330, 0234, 0007, 00 };
+/* Reference counter to the screen, to keep track of if we need reinitialization. */
+static int ansicon_counter = 0;
+
/* Common setup */
-static void __constructor ansicon_init(void)
+int __ansicon_open(struct file_info *fp)
{
static com32sys_t ireg; /* Auto-initalized to all zero */
com32sys_t oreg;
- /* Initial state */
- memcpy(&st, &default_state, sizeof st);
-
- /* Are we disabled? */
- ireg.eax.w[0] = 0x000b;
- __intcall(0x22, &ireg, &oreg);
+ (void)fp;
- if ( (signed char)oreg.ebx.b[1] < 0 ) {
- st.disabled = 1;
- return;
+ if (!ansicon_counter) {
+ /* Initial state */
+ memcpy(&st, &default_state, sizeof st);
+
+ /* Are we disabled? */
+ ireg.eax.w[0] = 0x000b;
+ __intcall(0x22, &ireg, &oreg);
+
+ if ( (signed char)oreg.ebx.b[1] < 0 ) {
+ st.disabled = 1;
+ } else {
+ /* Force text mode */
+ ireg.eax.w[0] = 0x0005;
+ __intcall(0x22, &ireg, NULL);
+
+ /* Get cursor shape */
+ ireg.eax.b[1] = 0x03;
+ ireg.ebx.b[1] = BIOS_PAGE;
+ __intcall(0x10, &ireg, &oreg);
+ st.cursor_type = oreg.ecx.w[0];
+ }
}
- /* Force text mode */
- ireg.eax.w[0] = 0x0005;
- __intcall(0x22, &ireg, NULL);
+ ansicon_counter++;
+ return 0;
+}
+
+int __ansicon_close(struct file_info *fp)
+{
+ (void)fp;
- /* Get cursor shape */
- ireg.eax.b[1] = 0x03;
- ireg.ebx.b[1] = BIOS_PAGE;
- __intcall(0x10, &ireg, &oreg);
- st.cursor_type = oreg.ecx.w[0];
+ ansicon_counter--;
+ return 0;
}
/* Erase a region of the screen */
.flags = __DEV_TTY | __DEV_OUTPUT,
.fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
.write = __ansicon_write,
- .close = NULL,
+ .close = __ansicon_close,
+ .open = __ansicon_open,
};
#include <minmax.h>
#include "file.h"
+extern int __ansicon_open(void);
+extern int __ansicon_close(struct file_info *);
extern ssize_t __ansicon_write(struct file_info *, const void *, size_t);
extern ssize_t __serial_write(struct file_info *, const void *, size_t);
.flags = __DEV_TTY | __DEV_OUTPUT,
.fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
.write = __ansiserial_write,
- .close = NULL,
+ .close = __ansicon_close,
+ .open = __ansicon_open,
};
int fileflags; /* Permitted file flags */
ssize_t (*read)(struct file_info *, void *, size_t);
int (*close)(struct file_info *);
+ int (*open)(struct file_info *);
};
+
struct output_dev {
uint16_t dev_magic; /* Magic number */
uint16_t flags; /* Flags */
int fileflags;
ssize_t (*write)(struct file_info *, const void *, size_t);
int (*close)(struct file_info *);
+ int (*open)(struct file_info *);
};
/* File structure */
#include <errno.h>
#include <com32.h>
#include <string.h>
+#include <unistd.h>
#include "file.h"
/*
* Open a special device
*/
-int opendev(const struct input_dev *idev, const struct output_dev *odev, int flags)
+int opendev(const struct input_dev *idev,
+ const struct output_dev *odev, int flags)
{
int fd;
struct file_info *fp;
int okflags;
+ int e;
okflags = (idev ? idev->fileflags : 0) | (odev ? odev->fileflags : 0);
return -1;
}
- fp->iop = idev ? idev : &dev_error_r;
- fp->oop = odev ? odev : &dev_error_w;
+ fp->iop = &dev_error_r;
+ fp->oop = &dev_error_w;
fp->i.offset = 0;
fp->i.nbytes = 0;
fp->i.datap = fp->i.buf;
+ if (idev) {
+ if (idev->open && (e = idev->open(fp))) {
+ errno = e;
+ goto puke;
+ }
+ fp->iop = idev;
+ }
+
+ if (odev) {
+ if (odev->open && (e = odev->open(fp))) {
+ errno = e;
+ goto puke;
+ }
+ fp->oop = odev;
+ }
+
return fd;
+
+ puke:
+ close(fd);
+ return -1;
}
0304, 0304, 0137, 0137, 0303, 0264, 0301, 0302, 0263, 0363, 0362, 0343, 0330, 0234, 0007, 00 };
/* Common setup */
-static void __constructor vesacon_init(void)
+static void vesacon_init(void)
{
static com32sys_t ireg; /* Auto-initalized to all zero */
com32sys_t oreg;
.fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
.write = __vesacon_write,
.close = NULL,
+ .init = vesacon_init,
};