1 /* $NetBSD: view.c,v 1.30 2009/03/18 17:06:43 cegger Exp $ */
4 * Copyright (c) 1994 Christian E. Hopps
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christian E. Hopps.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 /* The view major device is a placeholder device. It serves
34 * simply to map the semantics of a graphics dipslay to
35 * the semantics of a character block device. In other
36 * words the graphics system as currently built does not like to be
37 * refered to by open/close/ioctl. This device serves as
38 * a interface to graphics. */
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: view.c,v 1.30 2009/03/18 17:06:43 cegger Exp $");
43 #include <sys/param.h>
44 #include <sys/systm.h>
46 #include <sys/ioctl.h>
48 #include <sys/device.h>
49 #include <sys/malloc.h>
50 #include <sys/queue.h>
52 #include <machine/cpu.h>
53 #include <atari/dev/grfabs_reg.h>
54 #include <atari/dev/viewioctl.h>
55 #include <atari/dev/viewvar.h>
58 static void view_display(struct view_softc
*);
59 static void view_remove(struct view_softc
*);
60 static int view_setsize(struct view_softc
*, struct view_size
*);
61 static int view_get_colormap(struct view_softc
*, colormap_t
*);
62 static int view_set_colormap(struct view_softc
*, colormap_t
*);
64 struct view_softc views
[NVIEW
];
65 static int view_inited
;
69 int view_default_width
= 640;
70 int view_default_height
= 400;
71 int view_default_depth
= 1;
73 dev_type_open(viewopen
);
74 dev_type_close(viewclose
);
75 dev_type_ioctl(viewioctl
);
76 dev_type_mmap(viewmmap
);
78 const struct cdevsw view_cdevsw
= {
79 viewopen
, viewclose
, nullread
, nullwrite
, viewioctl
,
80 nostop
, notty
, nopoll
, viewmmap
, nokqfilter
,
84 * functions for probeing.
92 printf("%d view%s configured\n", NVIEW
, NVIEW
> 1 ? "s" : "");
95 /* this function is called early to set up a display. */
106 for(i
=0; i
<NVIEW
; i
++) {
107 views
[i
].view
= NULL
;
115 * Internal functions.
119 view_display (struct view_softc
*vu
)
129 * mark views that share this monitor as not displaying
131 for (i
= 0; i
< NVIEW
; i
++) {
132 if(views
[i
].flags
& VUF_DISPLAY
) {
133 if (vu
->view
&& (vu
->view
== views
[i
].view
)) {
138 grf_save_view(views
[i
].view
);
139 views
[i
].view
->flags
&= ~VF_DISPLAY
;
141 views
[i
].flags
&= ~VUF_DISPLAY
;
145 vu
->flags
|= VUF_ADDED
;
147 vu
->view
->display
.x
= vu
->size
.x
;
148 vu
->view
->display
.y
= vu
->size
.y
;
150 grf_display_view(vu
->view
);
151 vu
->view
->flags
|= VF_DISPLAY
;
153 vu
->size
.x
= vu
->view
->display
.x
;
154 vu
->size
.y
= vu
->view
->display
.y
;
155 vu
->flags
|= VUF_DISPLAY
;
161 * remove a view from our added list if it is marked as displaying
162 * switch to a new display.
165 view_remove(struct view_softc
*vu
)
169 if ((vu
->flags
& VUF_ADDED
) == 0)
172 vu
->flags
&= ~VUF_ADDED
;
173 if (vu
->flags
& VUF_DISPLAY
) {
174 for (i
= 0; i
< NVIEW
; i
++) {
175 if((views
[i
].flags
& VUF_ADDED
) && &views
[i
] != vu
) {
176 view_display(&views
[i
]);
181 vu
->flags
&= ~VUF_DISPLAY
;
182 grf_remove_view(vu
->view
);
186 view_setsize(struct view_softc
*vu
, struct view_size
*vs
)
195 if (vs
->x
!= vu
->size
.x
|| vs
->y
!= vu
->size
.y
)
198 if (vs
->width
!= vu
->size
.width
|| vs
->height
!= vu
->size
.height
||
199 vs
->depth
!= vu
->size
.depth
)
202 if (cs
== 0 && co
== 0)
205 ns
.width
= vs
->width
;
206 ns
.height
= vs
->height
;
208 if((dmode
= grf_get_best_mode(&ns
, vs
->depth
)) != NULL
) {
210 * If we can't do better, leave it
212 if(dmode
== vu
->view
->mode
)
215 new = grf_alloc_view(dmode
, &ns
, vs
->depth
);
221 vu
->size
.x
= new->display
.x
;
222 vu
->size
.y
= new->display
.y
;
223 vu
->size
.width
= new->display
.width
;
224 vu
->size
.height
= new->display
.height
;
225 vu
->size
.depth
= new->bitmap
->depth
;
228 * we need a custom remove here to avoid letting
229 * another view display mark as not added or displayed
231 if (vu
->flags
& VUF_DISPLAY
) {
232 vu
->flags
&= ~(VUF_ADDED
|VUF_DISPLAY
);
240 view_get_colormap (struct view_softc
*vu
, colormap_t
*ucm
)
246 if(ucm
->size
> MAX_CENTRIES
)
249 /* add one incase of zero, ick. */
250 cme
= malloc(sizeof(ucm
->entry
[0])*(ucm
->size
+1), M_TEMP
,M_WAITOK
);
256 ucm
->entry
= cme
; /* set entry to out alloc. */
257 if(vu
->view
== NULL
|| grf_get_colormap(vu
->view
, ucm
))
259 else error
= copyout(cme
, uep
, sizeof(ucm
->entry
[0]) * ucm
->size
);
260 ucm
->entry
= uep
; /* set entry back to users. */
266 view_set_colormap(struct view_softc
*vu
, colormap_t
*ucm
)
271 if(ucm
->size
> MAX_CENTRIES
)
274 cm
= malloc(sizeof(ucm
->entry
[0])*ucm
->size
+ sizeof(*cm
), M_TEMP
,
279 memcpy(cm
, ucm
, sizeof(colormap_t
));
280 cm
->entry
= (long *)&cm
[1]; /* table directly after. */
282 copyin(ucm
->entry
,cm
->entry
,sizeof(ucm
->entry
[0])*ucm
->size
)) == 0)
283 && (vu
->view
== NULL
|| grf_use_colormap(vu
->view
, cm
)))
290 * functions made available by conf.c
295 viewopen(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
298 struct view_softc
*vu
;
300 vu
= &views
[minor(dev
)];
302 if(minor(dev
) >= NVIEW
)
304 if(vu
->flags
& VUF_OPEN
)
307 vu
->size
.x
= view_default_x
;
308 vu
->size
.y
= view_default_y
;
309 size
.width
= vu
->size
.width
= view_default_width
;
310 size
.height
= vu
->size
.height
= view_default_height
;
311 vu
->size
.depth
= view_default_depth
;
312 vu
->view
= grf_alloc_view(NULL
, &size
, vu
->size
.depth
);
313 if (vu
->view
== NULL
)
316 vu
->size
.x
= vu
->view
->display
.x
;
317 vu
->size
.y
= vu
->view
->display
.y
;
318 vu
->size
.width
= vu
->view
->display
.width
;
319 vu
->size
.height
= vu
->view
->display
.height
;
320 vu
->size
.depth
= vu
->view
->bitmap
->depth
;
321 vu
->flags
|= VUF_OPEN
;
327 viewclose (dev_t dev
, int flags
, int mode
, struct lwp
*l
)
329 struct view_softc
*vu
;
331 vu
= &views
[minor(dev
)];
333 if ((vu
->flags
& VUF_OPEN
) == 0)
334 return (0); /* XXX not open? */
336 grf_free_view (vu
->view
);
345 viewioctl (dev_t dev
, u_long cmd
, void * data
, int flag
, struct lwp
*l
)
347 struct view_softc
*vu
;
351 vu
= &views
[minor(dev
)];
362 memcpy(data
, &vu
->size
, sizeof (struct view_size
));
365 error
= view_setsize(vu
, (struct view_size
*)data
);
369 memcpy(bm
, vu
->view
->bitmap
, sizeof(bmap_t
));
372 bm
->hw_address
= NULL
;
378 error
= view_get_colormap(vu
, (colormap_t
*)data
);
381 error
= view_set_colormap(vu
, (colormap_t
*)data
);
384 error
= EPASSTHROUGH
;
392 viewmmap(dev_t dev
, off_t off
, int prot
)
394 struct view_softc
*vu
;
397 u_long bmd_lin
, bmd_vga
;
399 vu
= &views
[minor(dev
)];
400 bm
= vu
->view
->bitmap
;
401 bmd_start
= bm
->hw_address
;
402 bmd_lin
= bm
->lin_base
;
403 bmd_vga
= bm
->vga_base
;
408 if (off
>= 0 && off
< bm
->reg_size
)
409 return(((paddr_t
)bm
->hw_regs
+ off
) >> PGSHIFT
);
414 if (off
>= bmd_vga
&& off
< (bmd_vga
+ bm
->vga_mappable
))
415 return(((paddr_t
)bm
->vga_address
- bmd_vga
+ off
) >> PGSHIFT
);
420 if (off
>= bmd_lin
&& off
< (bmd_lin
+ bm
->phys_mappable
))
421 return(((paddr_t
)bmd_start
- bmd_lin
+ off
) >> PGSHIFT
);
429 return(views
[minor(dev
)].view
);