#ifndef lint static char sccsid[] = "@(#)pr_open.c 9.2 88/01/19 SMI"; #endif /* * Copyright 1986 by Sun Microsystems, Inc. * * pr_open() function from libpixrect. */ /* * Pixrect device opening routine. */ #include #include #include #include #include #include /* * pixrect create function vector * (defined in pr_makefun.c) */ extern Pixrect *(*(pr_makefun[FBTYPE_LASTPLUSONE]))(); #define IS_VALID_FBTYPE(type) \ ((unsigned) (type) < FBTYPE_LASTPLUSONE && pr_makefun[(type)] != 0) #define CAN_SATTR(attr) \ ((attr).owner == 0) Pixrect * pr_open(fbname) char *fbname; { register int fd; register char *errstr; struct pr_size fbsize; Pixrect *pr; struct fbgattr attr; if ((fd = open(fbname, O_RDWR, 0)) < 0) { errstr = "open failed for"; goto bad; } /* force FBIOGTYPE if FBIOGATTR fails */ attr.fbtype.fb_type = -1; /* get frame buffer attributes */ if (ioctl(fd, FBIOGATTR, &attr) != -1 && CAN_SATTR(attr)) { /* * If we can't use the native mode, pick a suitable * emulation mode and turn auto-initialization on. */ if (!IS_VALID_FBTYPE(attr.fbtype.fb_type)) { register int bestemu, *ep; fprintf(stderr, "!IS_VALID_FBTYPE %d\n", attr.fbtype.fb_type); bestemu = -1; for (ep = attr.emu_types; ep < &attr.emu_types[FB_ATTR_NEMUTYPES]; ep++) { if (*ep == -1) break; if (IS_VALID_FBTYPE(*ep) && *ep > bestemu) bestemu = *ep; } /* skip the ioctl if it wouldn't change anything */ if (bestemu > 0 && (bestemu != attr.sattr.emu_type || !(attr.sattr.flags & FB_ATTR_AUTOINIT))) { attr.sattr.flags |= FB_ATTR_AUTOINIT; attr.sattr.emu_type = bestemu; (void) ioctl(fd, FBIOSATTR, &attr.sattr); } } } /* * If using an emulation mode, get the type information for it. */ if (!IS_VALID_FBTYPE(attr.fbtype.fb_type) && ioctl(fd, FBIOGTYPE, &attr.fbtype) == -1) { errstr = "FBIOGTYPE ioctl failed for"; goto bad; } if (!IS_VALID_FBTYPE(attr.fbtype.fb_type)) { errstr = "no pixrect implemented for"; goto bad; } fbsize.x = attr.fbtype.fb_width; fbsize.y = attr.fbtype.fb_height; if ((pr = (*pr_makefun[attr.fbtype.fb_type])(fd, fbsize, attr.fbtype.fb_depth)) == 0) { errstr = "pixrect create failed for"; goto bad; } close(fd); return pr; bad: if (fd >= 0) close(fd); fprintf(stderr, "pr_open: %s %s\n", errstr, fbname); return (Pixrect *) 0; } #ifdef REF struct pixrect * osi_create_screen_device(name_str) char *name_str; { register struct pixrect *pr; /* Always open a screen pixrect */ if ((pr = pr_open(name_str)) == 0) return (struct pixrect *)0; return pr; } #endif