OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [drivers/] [vtswitch.c] - Blame information for rev 674

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
#include <unistd.h>
2
#include <fcntl.h>
3
#include <signal.h>
4
#include <sys/ioctl.h>
5
#include <sys/time.h>
6
#include <linux/vt.h>
7
#include "device.h"
8
#include "fb.h"
9
/*
10
 * VT switch handling code for Linux
11
 */
12
 
13
/* signal to use when VT swithing*/
14
#ifndef SIGUNUSED
15
#define SIGUNUSED       SIGUSR1         /* some systems lack SIGUNUSED*/
16
#endif
17
 
18
#define SIGVTSWITCH     SIGUNUSED       /* SIGUSR2 is used by pthreads...*/
19
 
20
int     mwvterm;                /* the VT we were started on */
21
volatile int mwdrawing;         /* nonzero when drawing is happening*/
22
static int mwcvt, mwocvt;
23
static int ttyfd = -1;          /* /dev/tty0*/
24
static int visible = 1;         /* VT visible flag*/
25
static struct vt_mode mode;     /* terminal mode*/
26
static SUBDRIVER save;          /* saved subdriver when VT switched*/
27
 
28
extern SCREENDEVICE     scrdev; /* FIXME */
29
 
30
/* entry points*/
31
int     MwInitVt(void);
32
int     MwCurrentVt(void);
33
int     MwCheckVtChange(void);
34
void    MwRedrawVt(int t);
35
 
36
/* local routines*/
37
static void     draw_enable(void);
38
static void     draw_disable(void);
39
static void     vt_switch(int sig);
40
 
41
/* null subdriver for drawing when switched out*/
42
static void     null_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c) {}
43
static MWPIXELVAL null_readpixel(PSD psd,MWCOORD x, MWCOORD y) { return 0;}
44
static void     null_drawhorzline(PSD psd,MWCOORD x1,MWCOORD x2,MWCOORD y,
45
                        MWPIXELVAL c) {}
46
static void     null_drawvertline(PSD psd,MWCOORD x,MWCOORD y1,MWCOORD y2,
47
                        MWPIXELVAL c) {}
48
static void     null_fillrect(PSD psd,MWCOORD x1,MWCOORD y1,MWCOORD x2,
49
                        MWCOORD y2,MWPIXELVAL c) {}
50
static void     null_blit(PSD dstpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,
51
                        MWCOORD h,PSD srcpsd,MWCOORD srcx,MWCOORD srcy,
52
                        long op) {}
53
static void     null_drawarea(PSD psd, driver_gc_t *gc, int op) {}
54
static SUBDRIVER nulldriver = {
55
        NULL,
56
        null_drawpixel,
57
        null_readpixel,
58
        null_drawhorzline,
59
        null_drawvertline,
60
        null_fillrect,
61
        null_blit,
62
        null_drawarea
63
};
64
 
65
static void
66
draw_enable(void)
67
{
68
        if(visible)
69
                return;
70
        visible = 1;
71
 
72
        /* restore screen drawing functions*/
73
        set_subdriver(&scrdev, &save, FALSE);
74
}
75
 
76
static void
77
draw_disable(void)
78
{
79
        if(!visible)
80
                return;
81
        visible = 0;
82
 
83
        /* save screen drawing functions and reroute drawing*/
84
        get_subdriver(&scrdev, &save);
85
 
86
        /* set null driver*/
87
        set_subdriver(&scrdev, &nulldriver, FALSE);
88
}
89
 
90
/* Timer handler used to do the VT switch at a time when not drawing */
91
static void
92
vt_do_switch(void *arg)
93
{
94
    static unsigned short r[16], g[16], b[16];
95
 
96
    /*
97
     * If a drawing function is in progress then we cannot mode
98
     * switch right now because the drawing function would continue to
99
     * scribble on the screen after the switch.  So disable further
100
     * drawing and schedule an alarm to try again in .1 second.
101
     */
102
    if(mwdrawing) {
103
        draw_disable ();
104
        GdAddTimer(100, vt_do_switch, NULL);
105
        return;
106
    }
107
 
108
    if(visible) {
109
        draw_disable ();
110
        ioctl_getpalette(0, 16, r, g, b);
111
 
112
        if(ioctl (ttyfd, VT_RELDISP, 1) == -1)
113
            EPRINTF("Error can't switch away from VT: %m\n");
114
    } else {
115
        ioctl_setpalette(0, 16, r, g, b);
116
        draw_enable ();
117
 
118
        if(ioctl (ttyfd, VT_RELDISP, VT_ACKACQ) == -1)
119
                EPRINTF("Error can't acknowledge VT switch: %m\n");
120
    }
121
}
122
 
123
/* Signal handler called when kernel switches to or from our tty*/
124
static void
125
vt_switch(int sig)
126
{
127
        signal(SIGVTSWITCH, vt_switch);
128
        vt_do_switch(NULL);
129
}
130
 
131
/*
132
 * Init VT switch catching code
133
 *      return 0 on success, -1 on error
134
 */
135
int
136
MwInitVt(void)
137
{
138
        ttyfd = open("/dev/tty0", O_RDONLY);
139
        if(ttyfd == -1)
140
                return EPRINTF("Error can't open tty0: %m\n");
141
 
142
        /* setup new tty mode*/
143
        if(ioctl (ttyfd, VT_GETMODE, &mode) == -1)
144
                return EPRINTF("Error can't get VT mode: %m\n");
145
 
146
        mode.mode = VT_PROCESS;
147
        mode.relsig = SIGVTSWITCH;
148
        mode.acqsig = SIGVTSWITCH;
149
        signal (SIGVTSWITCH, vt_switch);
150
        if(ioctl (ttyfd, VT_SETMODE, &mode) == -1)
151
                return EPRINTF("Error can't set VT mode: %m\n");
152
 
153
        mwcvt = mwocvt = mwvterm = MwCurrentVt();
154
        /*
155
         * Note: this hack is required to get Linux
156
         * to orient virtual 0,0 with physical 0,0
157
         * I have no idea why this kluge is required...
158
         */
159
        MwRedrawVt(mwvterm);
160
 
161
        return 0;
162
}
163
 
164
/*
165
 * This function is used to find out what the current active VT is.
166
 */
167
int
168
MwCurrentVt(void)
169
{
170
        struct vt_stat stat;
171
 
172
        ioctl(ttyfd, VT_GETSTATE, &stat);
173
        return stat.v_active;
174
}
175
 
176
/*
177
 * Check if our VT has changed.  Return 1 if so.
178
 */
179
int
180
MwCheckVtChange(void)
181
{
182
        mwcvt = MwCurrentVt();
183
        if(mwcvt != mwocvt && mwcvt == mwvterm) {
184
                mwocvt = mwcvt;
185
                return 1;
186
        }
187
        mwocvt = mwcvt;
188
        return 0;
189
}
190
 
191
/*
192
 * This function is used to cause a redraw of the text console.
193
 * FIXME: Switching to another console and
194
 * back works, but that's a really dirty hack
195
 */
196
void
197
MwRedrawVt(int t)
198
{
199
        if(MwCurrentVt() == mwvterm) {
200
                ioctl(ttyfd, VT_ACTIVATE, t == 1 ? 2 : 1); /* Awful hack!!*/
201
                ioctl(ttyfd, VT_ACTIVATE, t);
202
        }
203
}
204
 
205
void
206
MwExitVt(void)
207
{
208
        signal(SIGVTSWITCH, SIG_DFL);
209
        mode.mode = VT_AUTO;
210
        mode.relsig = 0;
211
        mode.acqsig = 0;
212
        ioctl(ttyfd, VT_SETMODE, &mode);
213
 
214
        if(ttyfd != -1)
215
                close(ttyfd);
216
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.