/* * Mach Operating System * Copyright (c) 1991,1990,1989 Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ /* * File: xcfb_misc.c * Author: Alessandro Forin, Carnegie Mellon University * Date: 1/92 * * Driver for the MAXine color framebuffer * */ #include #if (NXCFB > 0) /* * NOTE: This driver relies heavily on the pm one. */ #include #include #include #include typedef pm_softc_t xcfb_softc_t; #include #define ims332 cursor_registers /* * Initialize color map, for kernel use */ xcfb_init_colormap(sc) screen_softc_t sc; { xcfb_softc_t *xcfb = (xcfb_softc_t*)sc->hw_state; user_info_t *up = sc->up; color_map_t Bg_Fg[2]; register int i; ims332_init_colormap( xcfb->ims332 ); /* init bg/fg colors */ for (i = 0; i < 3; i++) { up->dev_dep_2.pm.Bg_color[i] = 0x00; up->dev_dep_2.pm.Fg_color[i] = 0xff; } Bg_Fg[0].red = Bg_Fg[0].green = Bg_Fg[0].blue = 0x00; Bg_Fg[1].red = Bg_Fg[1].green = Bg_Fg[1].blue = 0xff; ims332_cursor_color( xcfb->ims332, Bg_Fg); } /* * Large viz small cursor */ xcfb_small_cursor_to_large(up, cursor) user_info_t *up; cursor_sprite_t cursor; { unsigned short new_cursor[32]; unsigned char *cursor_bytes; char *sprite; register int i; /* Clear out old cursor */ bzero( up->dev_dep_2.pm.cursor_sprite, sizeof(up->dev_dep_2.pm.cursor_sprite)); /* small cursor is 32x2 bytes, fg first */ cursor_bytes = (unsigned char *) cursor; /* use the upper left corner of the large cursor * as a 64x1 cursor, fg&bg alternated */ for (i = 0; i < 32; i++) { register short nc = 0; register unsigned char fg, bg; register int j, k; fg = cursor_bytes[i]; bg = cursor_bytes[i + 32]; bg &= ~fg; for (j = 1, k = 0; j < 256; j <<= 1) { nc |= (bg & j) << (k++); nc |= (fg & j) << (k); } new_cursor[i] = nc; } /* Now stick it in the proper place */ cursor_bytes = (unsigned char *) new_cursor; sprite = up->dev_dep_2.pm.cursor_sprite; for (i = 0; i < 64; i += 4) { *sprite++ = cursor_bytes[i + 0]; *sprite++ = cursor_bytes[i + 1]; *sprite++ = cursor_bytes[i + 2]; *sprite++ = cursor_bytes[i + 3]; sprite += 12; /* skip rest of the line */ } } /* * Device-specific set status */ xcfb_set_status(sc, flavor, status, status_count) screen_softc_t sc; int flavor; dev_status_t status; unsigned int status_count; { xcfb_softc_t *xcfb = (xcfb_softc_t*) sc->hw_state; switch (flavor) { case SCREEN_ADJ_MAPPED_INFO: return pm_set_status(sc, flavor, status, status_count); case SCREEN_LOAD_CURSOR: if (status_count < sizeof(cursor_sprite_t)/sizeof(int)) return D_INVALID_SIZE; xcfb_small_cursor_to_large(sc->up, (cursor_sprite_t*) status); /* Fall through */ case SCREEN_LOAD_CURSOR_LONG: /* 3max only */ sc->flags |= SCREEN_BEING_UPDATED; ims332_cursor_sprite(xcfb->ims332, sc->up->dev_dep_2.pm.cursor_sprite); sc->flags &= ~SCREEN_BEING_UPDATED; break; case SCREEN_SET_CURSOR_COLOR: { color_map_t c[2]; register cursor_color_t *cc = (cursor_color_t*) status; c[0].red = cc->Bg_rgb[0]; c[0].green = cc->Bg_rgb[1]; c[0].blue = cc->Bg_rgb[2]; c[1].red = cc->Fg_rgb[0]; c[1].green = cc->Fg_rgb[1]; c[1].blue = cc->Fg_rgb[2]; sc->flags |= SCREEN_BEING_UPDATED; ims332_cursor_color (xcfb->ims332, c ); sc->flags &= ~SCREEN_BEING_UPDATED; break; } case SCREEN_SET_CMAP_ENTRY: { color_map_entry_t *e = (color_map_entry_t*) status; if (e->index < 256) { sc->flags |= SCREEN_BEING_UPDATED; ims332_load_colormap_entry( xcfb->ims332, e->index, &e->value); sc->flags &= ~SCREEN_BEING_UPDATED; } break; } default: return D_INVALID_OPERATION; } return D_SUCCESS; } /* * Hardware initialization */ xcfb_init_screen(xcfb) xcfb_softc_t *xcfb; { extern xcfb_monitor_type_t xcfb_get_monitor_type(); ims332_init( xcfb->ims332, xcfb->vdac_registers, xcfb_get_monitor_type()); } /* * Do what's needed when X exits */ xcfb_soft_reset(sc) screen_softc_t sc; { xcfb_softc_t *xcfb = (xcfb_softc_t*) sc->hw_state; user_info_t *up = sc->up; extern cursor_sprite_t dc503_default_cursor; /* * Restore params in mapped structure */ pm_init_screen_params(sc,up); up->row = up->max_row - 1; up->dev_dep_2.pm.x26 = 2; /* you do not want to know */ up->dev_dep_1.pm.x18 = (short*)2; /* * Restore RAMDAC chip to default state */ xcfb_init_screen(xcfb); /* * Load kernel's cursor sprite: just use the same pmax one */ xcfb_small_cursor_to_large(up, dc503_default_cursor); ims332_cursor_sprite(xcfb->ims332, up->dev_dep_2.pm.cursor_sprite); /* * Color map and cursor color */ xcfb_init_colormap(sc); } #endif (NXCFB > 0)