1 /* $NetBSD: view.c,v 1.1.1.1 1995/03/26 07:12:14 leo Exp $ */ 2 3 /* 4 * Copyright (c) 1994 Christian E. Hopps 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 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 20 * 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. 31 */ 32 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. */ 39 40 #include <sys/param.h> 41 #include <sys/proc.h> 42 #include <sys/ioctl.h> 43 #include <sys/file.h> 44 #include <sys/device.h> 45 #include <sys/malloc.h> 46 #include <sys/queue.h> 47 #include <machine/cpu.h> 48 #include <atari/dev/grfabs_reg.h> 49 #include <atari/dev/viewioctl.h> 50 #include <atari/dev/viewvar.h> 51 #include "view.h" 52 53 static void view_display __P((struct view_softc *)); 54 static void view_remove __P((struct view_softc *)); 55 static int view_setsize __P((struct view_softc *, struct view_size *)); 56 57 void viewclose __P((dev_t, int)); 58 int viewioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); 59 int viewopen __P((dev_t, int)); 60 int viewmap __P((dev_t, int, int)); 61 62 int view_get_colormap __P((struct view_softc *, colormap_t *)); 63 int view_set_colormap __P((struct view_softc *, colormap_t *)); 64 65 int viewprobe (); 66 67 struct view_softc views[NVIEW]; 68 static int view_inited; 69 70 int view_default_x; 71 int view_default_y; 72 int view_default_width = 640; 73 int view_default_height = 400; 74 int view_default_depth = 1; 75 76 /* 77 * functions for probeing. 78 */ 79 viewattach(cnt) 80 int cnt; 81 { 82 viewprobe(); 83 printf("%d view%s configured\n", NVIEW, NVIEW > 1 ? "s" : ""); 84 } 85 86 /* this function is called early to set up a display. */ 87 viewprobe() 88 { 89 int i; 90 91 if(view_inited) 92 return(1); 93 94 view_inited = 1; 95 96 for(i=0; i<NVIEW; i++) { 97 views[i].view = NULL; 98 views[i].flags = 0; 99 } 100 return(1); 101 } 102 103 104 /* 105 * Internal functions. 106 */ 107 108 static void 109 view_display (vu) 110 struct view_softc *vu; 111 { 112 int s, i; 113 114 if (vu == NULL) 115 return; 116 117 s = spltty (); 118 119 /* 120 * mark views that share this monitor as not displaying 121 */ 122 for (i=0; i<NVIEW; i++) { 123 if(views[i].flags & VUF_DISPLAY) 124 views[i].flags &= ~VUF_DISPLAY; 125 } 126 127 vu->flags |= VUF_ADDED; 128 if (vu->view) { 129 vu->view->display.x = vu->size.x; 130 vu->view->display.y = vu->size.y; 131 132 grf_display_view(vu->view); 133 134 vu->size.x = vu->view->display.x; 135 vu->size.y = vu->view->display.y; 136 vu->flags |= VUF_DISPLAY; 137 } 138 splx(s); 139 } 140 141 /* 142 * remove a view from our added list if it is marked as displaying 143 * switch to a new display. 144 */ 145 static void 146 view_remove(vu) 147 struct view_softc *vu; 148 { 149 int i; 150 151 if ((vu->flags & VUF_ADDED) == 0) 152 return; 153 154 vu->flags &= ~VUF_ADDED; 155 if (vu->flags & VUF_DISPLAY) { 156 for (i = 0; i < NVIEW; i++) { 157 if((views[i].flags & VUF_ADDED) && &views[i] != vu) { 158 view_display(&views[i]); 159 break; 160 } 161 } 162 } 163 vu->flags &= ~VUF_DISPLAY; 164 grf_remove_view(vu->view); 165 } 166 167 static int 168 view_setsize(vu, vs) 169 struct view_softc *vu; 170 struct view_size *vs; 171 { 172 view_t *new, *old; 173 dimen_t ns; 174 int co, cs; 175 176 co = 0; 177 cs = 0; 178 if (vs->x != vu->size.x || vs->y != vu->size.y) 179 co = 1; 180 181 if (vs->width != vu->size.width || vs->height != vu->size.height || 182 vs->depth != vu->size.depth) 183 cs = 1; 184 185 if (cs == 0 && co == 0) 186 return(0); 187 188 ns.width = vs->width; 189 ns.height = vs->height; 190 191 new = grf_alloc_view(NULL, &ns, vs->depth); 192 if (new == NULL) 193 return(ENOMEM); 194 195 old = vu->view; 196 vu->view = new; 197 vu->size.x = new->display.x; 198 vu->size.y = new->display.y; 199 vu->size.width = new->display.width; 200 vu->size.height = new->display.height; 201 vu->size.depth = new->bitmap->depth; 202 vu->size.x = vs->x; 203 vu->size.y = vs->y; 204 205 /* 206 * we need a custom remove here to avoid letting 207 * another view display mark as not added or displayed 208 */ 209 if (vu->flags & VUF_DISPLAY) { 210 vu->flags &= ~(VUF_ADDED|VUF_DISPLAY); 211 view_display(vu); 212 } 213 grf_free_view(old); 214 return(0); 215 } 216 217 /* 218 * functions made available by conf.c 219 */ 220 221 /*ARGSUSED*/ 222 int viewopen(dev, flags) 223 dev_t dev; 224 int flags; 225 { 226 dimen_t size; 227 struct view_softc *vu; 228 229 vu = &views[minor(dev)]; 230 231 if(minor(dev) >= NVIEW) 232 return(EXDEV); 233 if(vu->flags & VUF_OPEN) 234 return(EBUSY); 235 236 vu->size.x = view_default_x; 237 vu->size.y = view_default_y; 238 size.width = vu->size.width = view_default_width; 239 size.height = vu->size.height = view_default_height; 240 vu->size.depth = view_default_depth; 241 242 vu->view = grf_alloc_view(NULL, &size, vu->size.depth); 243 if (vu->view == NULL) 244 return(ENOMEM); 245 246 vu->size.x = vu->view->display.x; 247 vu->size.y = vu->view->display.y; 248 vu->size.width = vu->view->display.width; 249 vu->size.height = vu->view->display.height; 250 vu->size.depth = vu->view->bitmap->depth; 251 vu->flags |= VUF_OPEN; 252 return(0); 253 } 254 255 /*ARGSUSED*/ 256 void 257 viewclose (dev, flags) 258 dev_t dev; 259 int flags; 260 { 261 struct view_softc *vu; 262 263 vu = &views[minor(dev)]; 264 265 if ((vu->flags & VUF_OPEN) == 0) 266 return; 267 view_remove (vu); 268 grf_free_view (vu->view); 269 vu->flags = 0; 270 vu->view = NULL; 271 } 272 273 274 /*ARGSUSED*/ 275 int 276 viewioctl (dev, cmd, data, flag, p) 277 dev_t dev; 278 u_long cmd; 279 caddr_t data; 280 int flag; 281 struct proc *p; 282 { 283 struct view_softc *vu; 284 bmap_t *bm; 285 int error; 286 287 vu = &views[minor(dev)]; 288 error = 0; 289 290 switch (cmd) { 291 case VIOCDISPLAY: 292 view_display(vu); 293 break; 294 case VIOCREMOVE: 295 view_remove(vu); 296 break; 297 case VIOCGSIZE: 298 bcopy(&vu->size, data, sizeof (struct view_size)); 299 break; 300 case VIOCSSIZE: 301 error = view_setsize(vu, (struct view_size *)data); 302 break; 303 case VIOCGBMAP: 304 bm = (bmap_t *)data; 305 bcopy(vu->view->bitmap, bm, sizeof(bmap_t)); 306 if ((int)p != -1) { 307 bm->plane = NULL; 308 bm->hw_address = NULL; 309 } 310 break; 311 case VIOCGCMAP: 312 error = view_get_colormap(vu, (colormap_t *)data); 313 break; 314 case VIOCSCMAP: 315 error = view_set_colormap(vu, (colormap_t *)data); 316 break; 317 default: 318 error = EINVAL; 319 break; 320 } 321 return(error); 322 } 323 324 int view_get_colormap (vu, ucm) 325 struct view_softc *vu; 326 colormap_t *ucm; 327 { 328 int error; 329 u_short *cme; 330 u_short *uep; 331 332 if(ucm->nentries > MAX_CENTRIES) 333 return(EINVAL); 334 335 /* add one incase of zero, ick. */ 336 cme = malloc(sizeof(u_short) * (ucm->nentries+1),M_IOCTLOPS,M_WAITOK); 337 if (cme == NULL) 338 return(ENOMEM); 339 340 error = 0; 341 uep = ucm->centry; 342 ucm->centry = cme; /* set entry to out alloc. */ 343 if(vu->view == NULL || grf_get_colormap(vu->view, ucm)) 344 error = EINVAL; 345 else error = copyout(cme, uep, sizeof(u_short) * ucm->nentries); 346 ucm->centry = uep; /* set entry back to users. */ 347 free(cme, M_IOCTLOPS); 348 return(error); 349 } 350 351 int view_set_colormap(vu, ucm) 352 struct view_softc *vu; 353 colormap_t *ucm; 354 { 355 colormap_t *cm; 356 int error = 0; 357 358 if(ucm->nentries > MAX_CENTRIES) 359 return(EINVAL); 360 361 cm = malloc(sizeof(u_short) * ucm->nentries + sizeof(*cm), M_IOCTLOPS, 362 M_WAITOK); 363 if(cm == NULL) 364 return(ENOMEM); 365 366 bcopy(ucm, cm, sizeof(colormap_t)); 367 cm->centry = (u_short *)&cm[1]; /* table directly after. */ 368 if (((error = 369 copyin(ucm->centry,cm->centry,sizeof(u_short)*ucm->nentries)) == 0) 370 && (vu->view == NULL || grf_use_colormap(vu->view, cm))) 371 error = EINVAL; 372 free(cm, M_IOCTLOPS); 373 return(error); 374 } 375 376 /*ARGSUSED*/ 377 int 378 viewmap(dev, off, prot) 379 dev_t dev; 380 int off, prot; 381 { 382 struct view_softc *vu; 383 bmap_t *bm; 384 u_char *bmd_start; 385 u_long bmd_size; 386 387 vu = &views[minor(dev)]; 388 bm = vu->view->bitmap; 389 bmd_start = bm->hw_address; 390 bmd_size = bm->bytes_per_row*bm->rows*bm->depth; 391 392 if (off >= 0 && off < bmd_size) 393 return(((u_int)bmd_start + off) >> PGSHIFT); 394 395 return(-1); 396 } 397 398 /*ARGSUSED*/ 399 int 400 viewselect(dev, rw) 401 dev_t dev; 402 int rw; 403 { 404 if(rw == FREAD) 405 return(0); 406 return(1); 407 } 408