139287Ssos/*- 239643Syokota * Copyright (c) 1998 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 339287Ssos * All rights reserved. 439287Ssos * 5146736Sdelphij * This code is derived from software contributed to The DragonFly Project 6146736Sdelphij * by Sascha Wildner <saw@online.de> 7146736Sdelphij * 839287Ssos * Redistribution and use in source and binary forms, with or without 939287Ssos * modification, are permitted provided that the following conditions 1039287Ssos * are met: 1139287Ssos * 1. Redistributions of source code must retain the above copyright 1239643Syokota * notice, this list of conditions and the following disclaimer as 1339643Syokota * the first lines of this file unmodified. 1439287Ssos * 2. Redistributions in binary form must reproduce the above copyright 1539287Ssos * notice, this list of conditions and the following disclaimer in the 1639287Ssos * documentation and/or other materials provided with the distribution. 1739287Ssos * 1839643Syokota * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1939643Syokota * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2039643Syokota * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2139643Syokota * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2239643Syokota * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2339643Syokota * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2439643Syokota * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2539643Syokota * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2639643Syokota * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2739643Syokota * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2839287Ssos */ 2939287Ssos 30119420Sobrien#include <sys/cdefs.h> 31119420Sobrien__FBSDID("$FreeBSD$"); 32119420Sobrien 33162711Sru#include "opt_compat.h" 3439287Ssos#include "opt_syscons.h" 3539287Ssos 3639287Ssos#include <sys/param.h> 3739287Ssos#include <sys/systm.h> 3851404Syokota#include <sys/conf.h> 3939287Ssos#include <sys/signalvar.h> 4039287Ssos#include <sys/tty.h> 4139287Ssos#include <sys/kernel.h> 4266834Sphk#include <sys/fbio.h> 4366834Sphk#include <sys/consio.h> 4491140Stanimura#include <sys/filedesc.h> 4591140Stanimura#include <sys/lock.h> 4691140Stanimura#include <sys/sx.h> 4791140Stanimura#include <sys/mutex.h> 4891140Stanimura#include <sys/proc.h> 4939287Ssos 5042504Syokota#include <dev/fb/fbreg.h> 5142504Syokota#include <dev/syscons/syscons.h> 5239287Ssos 5378161SpeterSET_DECLARE(scrndr_set, const sc_renderer_t); 5478161Speter 5542504Syokota/* for compatibility with previous versions */ 5648104Syokota/* 3.0-RELEASE used the following structure */ 5742504Syokotatypedef struct old_video_adapter { 5842504Syokota int va_index; 5942504Syokota int va_type; 6042504Syokota int va_flags; 6148104Syokota/* flag bits are the same as the -CURRENT 6242504Syokota#define V_ADP_COLOR (1<<0) 6342504Syokota#define V_ADP_MODECHANGE (1<<1) 6442504Syokota#define V_ADP_STATESAVE (1<<2) 6542504Syokota#define V_ADP_STATELOAD (1<<3) 6642504Syokota#define V_ADP_FONT (1<<4) 6742504Syokota#define V_ADP_PALETTE (1<<5) 6842504Syokota#define V_ADP_BORDER (1<<6) 6942504Syokota#define V_ADP_VESA (1<<7) 7048104Syokota*/ 7142504Syokota int va_crtc_addr; 7242504Syokota u_int va_window; /* virtual address */ 7342504Syokota size_t va_window_size; 7442504Syokota size_t va_window_gran; 7542504Syokota u_int va_buffer; /* virtual address */ 7642504Syokota size_t va_buffer_size; 7742504Syokota int va_initial_mode; 7842504Syokota int va_initial_bios_mode; 7942504Syokota int va_mode; 8042504Syokota} old_video_adapter_t; 8139287Ssos 8242504Syokota#define OLD_CONS_ADPINFO _IOWR('c', 101, old_video_adapter_t) 8342504Syokota 8448104Syokota/* 3.1-RELEASE used the following structure */ 8548104Syokotatypedef struct old_video_adapter_info { 8648104Syokota int va_index; 8748104Syokota int va_type; 8848104Syokota char va_name[16]; 8948104Syokota int va_unit; 9048104Syokota int va_flags; 9148104Syokota int va_io_base; 9248104Syokota int va_io_size; 9348104Syokota int va_crtc_addr; 9448104Syokota int va_mem_base; 9548104Syokota int va_mem_size; 9648104Syokota u_int va_window; /* virtual address */ 9748104Syokota size_t va_window_size; 9848104Syokota size_t va_window_gran; 99132107Sstefanf u_int va_buffer; 10048104Syokota size_t va_buffer_size; 10148104Syokota int va_initial_mode; 10248104Syokota int va_initial_bios_mode; 10348104Syokota int va_mode; 10448104Syokota int va_line_width; 10548104Syokota} old_video_adapter_info_t; 10639287Ssos 10748104Syokota#define OLD_CONS_ADPINFO2 _IOWR('c', 101, old_video_adapter_info_t) 10848104Syokota 10948104Syokota/* 3.0-RELEASE and 3.1-RELEASE used the following structure */ 11048104Syokotatypedef struct old_video_info { 11148104Syokota int vi_mode; 11248104Syokota int vi_flags; 11348104Syokota/* flag bits are the same as the -CURRENT 11448104Syokota#define V_INFO_COLOR (1<<0) 11548104Syokota#define V_INFO_GRAPHICS (1<<1) 11648104Syokota#define V_INFO_LINEAR (1<<2) 11748104Syokota#define V_INFO_VESA (1<<3) 11848104Syokota*/ 11948104Syokota int vi_width; 12048104Syokota int vi_height; 12148104Syokota int vi_cwidth; 12248104Syokota int vi_cheight; 12348104Syokota int vi_depth; 12448104Syokota int vi_planes; 12548104Syokota u_int vi_window; /* physical address */ 12648104Syokota size_t vi_window_size; 12748104Syokota size_t vi_window_gran; 12848104Syokota u_int vi_buffer; /* physical address */ 12948104Syokota size_t vi_buffer_size; 13048104Syokota} old_video_info_t; 13148104Syokota 13248104Syokota#define OLD_CONS_MODEINFO _IOWR('c', 102, old_video_info_t) 13348104Syokota#define OLD_CONS_FINDMODE _IOWR('c', 103, old_video_info_t) 13448104Syokota 13539287Ssosint 13639287Ssossc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, 137149640Srodrigc int fontsize, int fontwidth) 13839287Ssos{ 13939287Ssos video_info_t info; 140242529Sed struct winsize wsz; 14148104Syokota u_char *font; 14248667Syokota int prev_ysize; 14339287Ssos int error; 14439287Ssos int s; 14539287Ssos 146174985Swkoszek if (vidd_get_info(scp->sc->adp, mode, &info)) 14739287Ssos return ENODEV; 14848104Syokota 14939287Ssos /* adjust argument values */ 150149828Srodrigc if (fontwidth <= 0) 151149828Srodrigc fontwidth = info.vi_cwidth; 15239287Ssos if (fontsize <= 0) 15339287Ssos fontsize = info.vi_cheight; 154216079Sjkim if (fontsize < 14) 15539287Ssos fontsize = 8; 156216079Sjkim else if (fontsize >= 16) 15739287Ssos fontsize = 16; 158216079Sjkim else 15939287Ssos fontsize = 14; 16048104Syokota#ifndef SC_NO_FONT_LOADING 161216079Sjkim switch (fontsize) { 162216079Sjkim case 8: 163216079Sjkim if ((scp->sc->fonts_loaded & FONT_8) == 0) 164216079Sjkim return (EINVAL); 165216079Sjkim font = scp->sc->font_8; 166216079Sjkim break; 167216079Sjkim case 14: 168216079Sjkim if ((scp->sc->fonts_loaded & FONT_14) == 0) 169216079Sjkim return (EINVAL); 17048104Syokota font = scp->sc->font_14; 171216079Sjkim break; 172216079Sjkim case 16: 173216079Sjkim if ((scp->sc->fonts_loaded & FONT_16) == 0) 174216079Sjkim return (EINVAL); 175216079Sjkim font = scp->sc->font_16; 176216079Sjkim break; 177216079Sjkim } 17848104Syokota#else 179216079Sjkim font = NULL; 18048104Syokota#endif 18139287Ssos if ((xsize <= 0) || (xsize > info.vi_width)) 18239287Ssos xsize = info.vi_width; 18339287Ssos if ((ysize <= 0) || (ysize > info.vi_height)) 18439287Ssos ysize = info.vi_height; 18539287Ssos 18639287Ssos /* stop screen saver, etc */ 18739287Ssos s = spltty(); 18839287Ssos if ((error = sc_clean_up(scp))) { 18939287Ssos splx(s); 19039287Ssos return error; 19139287Ssos } 19239287Ssos 19356043Syokota if (sc_render_match(scp, scp->sc->adp->va_name, 0) == NULL) { 19448104Syokota splx(s); 19548104Syokota return ENODEV; 19648104Syokota } 19748104Syokota 19839287Ssos /* set up scp */ 19951394Syokota#ifndef SC_NO_HISTORY 20051394Syokota if (scp->history != NULL) 20151394Syokota sc_hist_save(scp); 20251394Syokota#endif 20348667Syokota prev_ysize = scp->ysize; 20439287Ssos /* 20539287Ssos * This is a kludge to fend off scrn_update() while we 20639287Ssos * muck around with scp. XXX 20739287Ssos */ 20858872Syokota scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 20958872Syokota scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE | MOUSE_VISIBLE); 21039287Ssos scp->mode = mode; 21139287Ssos scp->xsize = xsize; 21239287Ssos scp->ysize = ysize; 21342504Syokota scp->xoff = 0; 21442504Syokota scp->yoff = 0; 21539287Ssos scp->xpixel = scp->xsize*8; 21639287Ssos scp->ypixel = scp->ysize*fontsize; 21748104Syokota scp->font = font; 21848104Syokota scp->font_size = fontsize; 219149640Srodrigc scp->font_width = fontwidth; 22039287Ssos 22139287Ssos /* allocate buffers */ 22239287Ssos sc_alloc_scr_buffer(scp, TRUE, TRUE); 22356043Syokota sc_init_emulator(scp, NULL); 22448104Syokota#ifndef SC_NO_CUTPASTE 22548104Syokota sc_alloc_cut_buffer(scp, FALSE); 22648104Syokota#endif 22748104Syokota#ifndef SC_NO_HISTORY 22848667Syokota sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE); 22948104Syokota#endif 23039287Ssos splx(s); 23139287Ssos 23248104Syokota if (scp == scp->sc->cur_scp) 23339287Ssos set_mode(scp); 23439287Ssos scp->status &= ~UNKNOWN_MODE; 23539287Ssos 23639287Ssos if (tp == NULL) 23739287Ssos return 0; 238242529Sed wsz.ws_col = scp->xsize; 239242529Sed wsz.ws_row = scp->ysize; 240242529Sed tty_set_winsize(tp, &wsz); 24139287Ssos return 0; 24239287Ssos} 24339287Ssos 24439287Ssosint 24539287Ssossc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) 24639287Ssos{ 24748104Syokota#ifdef SC_NO_MODE_CHANGE 24848104Syokota return ENODEV; 24948104Syokota#else 25039287Ssos video_info_t info; 251242529Sed struct winsize wsz; 25239287Ssos int error; 25339287Ssos int s; 25439287Ssos 255174985Swkoszek if (vidd_get_info(scp->sc->adp, mode, &info)) 25639287Ssos return ENODEV; 25739287Ssos 25839287Ssos /* stop screen saver, etc */ 25939287Ssos s = spltty(); 26039287Ssos if ((error = sc_clean_up(scp))) { 26139287Ssos splx(s); 26239287Ssos return error; 26339287Ssos } 26439287Ssos 26556043Syokota if (sc_render_match(scp, scp->sc->adp->va_name, GRAPHICS_MODE) == NULL) { 26648104Syokota splx(s); 26748104Syokota return ENODEV; 26848104Syokota } 26948104Syokota 27039287Ssos /* set up scp */ 27158872Syokota scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE | MOUSE_HIDDEN); 27258872Syokota scp->status &= ~(PIXEL_MODE | MOUSE_VISIBLE); 27339287Ssos scp->mode = mode; 27450447Syokota /* 27550447Syokota * Don't change xsize and ysize; preserve the previous vty 27650447Syokota * and history buffers. 27750447Syokota */ 27842504Syokota scp->xoff = 0; 27942504Syokota scp->yoff = 0; 28039287Ssos scp->xpixel = info.vi_width; 28139287Ssos scp->ypixel = info.vi_height; 28248104Syokota scp->font = NULL; 28356328Syokota scp->font_size = 0; 28448104Syokota#ifndef SC_NO_SYSMOUSE 28539287Ssos /* move the mouse cursor at the center of the screen */ 28648104Syokota sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2); 28748104Syokota#endif 28856043Syokota sc_init_emulator(scp, NULL); 28939287Ssos splx(s); 29039287Ssos 29148104Syokota if (scp == scp->sc->cur_scp) 29239287Ssos set_mode(scp); 29339287Ssos /* clear_graphics();*/ 29439287Ssos scp->status &= ~UNKNOWN_MODE; 29539287Ssos 29639287Ssos if (tp == NULL) 29739287Ssos return 0; 298242529Sed wsz.ws_col = scp->xsize; 299242529Sed wsz.ws_row = scp->ysize; 300242529Sed tty_set_winsize(tp, &wsz); 30139287Ssos return 0; 30248104Syokota#endif /* SC_NO_MODE_CHANGE */ 30339287Ssos} 30439287Ssos 30539287Ssosint 30639287Ssossc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, 307149640Srodrigc int fontsize, int fontwidth) 30839287Ssos{ 30948104Syokota#ifndef SC_PIXEL_MODE 31048104Syokota return ENODEV; 31148104Syokota#else 31239287Ssos video_info_t info; 313242529Sed struct winsize wsz; 31448104Syokota u_char *font; 31548667Syokota int prev_ysize; 31639287Ssos int error; 31739287Ssos int s; 31839287Ssos 319174985Swkoszek if (vidd_get_info(scp->sc->adp, scp->mode, &info)) 32039287Ssos return ENODEV; /* this shouldn't happen */ 32139287Ssos 32239287Ssos /* adjust argument values */ 32356328Syokota if (fontsize <= 0) 32439287Ssos fontsize = info.vi_cheight; 325216079Sjkim if (fontsize < 14) 32639287Ssos fontsize = 8; 327216079Sjkim else if (fontsize >= 16) 32839287Ssos fontsize = 16; 329216079Sjkim else 33039287Ssos fontsize = 14; 33148104Syokota#ifndef SC_NO_FONT_LOADING 332216079Sjkim switch (fontsize) { 333216079Sjkim case 8: 334216079Sjkim if ((scp->sc->fonts_loaded & FONT_8) == 0) 335216079Sjkim return (EINVAL); 336216079Sjkim font = scp->sc->font_8; 337216079Sjkim break; 338216079Sjkim case 14: 339216079Sjkim if ((scp->sc->fonts_loaded & FONT_14) == 0) 340216079Sjkim return (EINVAL); 34148104Syokota font = scp->sc->font_14; 342216079Sjkim break; 343216079Sjkim case 16: 344216079Sjkim if ((scp->sc->fonts_loaded & FONT_16) == 0) 345216079Sjkim return (EINVAL); 346216079Sjkim font = scp->sc->font_16; 347216079Sjkim break; 348216079Sjkim } 34948104Syokota#else 350216079Sjkim font = NULL; 35148104Syokota#endif 35239287Ssos if (xsize <= 0) 35339287Ssos xsize = info.vi_width/8; 35439287Ssos if (ysize <= 0) 35539287Ssos ysize = info.vi_height/fontsize; 35639287Ssos 35739591Syokota if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize)) 35839591Syokota return EINVAL; 35939591Syokota 360204281Sjkim if (!sc_support_pixel_mode(&info)) 36139591Syokota return ENODEV; 36239591Syokota 36339287Ssos /* stop screen saver, etc */ 36439287Ssos s = spltty(); 36539287Ssos if ((error = sc_clean_up(scp))) { 36639287Ssos splx(s); 36739287Ssos return error; 36839287Ssos } 36939287Ssos 37056043Syokota if (sc_render_match(scp, scp->sc->adp->va_name, PIXEL_MODE) == NULL) { 37148104Syokota splx(s); 37248104Syokota return ENODEV; 37348104Syokota } 37448104Syokota 37556043Syokota#if 0 37656043Syokota if (scp->tsw) 37756043Syokota (*scp->tsw->te_term)(scp, scp->ts); 37856043Syokota scp->tsw = NULL; 37956043Syokota scp->ts = NULL; 38056043Syokota#endif 38156043Syokota 38239287Ssos /* set up scp */ 38351394Syokota#ifndef SC_NO_HISTORY 38451394Syokota if (scp->history != NULL) 38551394Syokota sc_hist_save(scp); 38651394Syokota#endif 38748667Syokota prev_ysize = scp->ysize; 38858872Syokota scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN); 38958872Syokota scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE); 39039287Ssos scp->xsize = xsize; 39139287Ssos scp->ysize = ysize; 39239287Ssos scp->xoff = (scp->xpixel/8 - xsize)/2; 39339287Ssos scp->yoff = (scp->ypixel/fontsize - ysize)/2; 39448104Syokota scp->font = font; 39548104Syokota scp->font_size = fontsize; 396149640Srodrigc scp->font_width = fontwidth; 39739287Ssos 39839287Ssos /* allocate buffers */ 39939287Ssos sc_alloc_scr_buffer(scp, TRUE, TRUE); 40056043Syokota sc_init_emulator(scp, NULL); 40148104Syokota#ifndef SC_NO_CUTPASTE 40248104Syokota sc_alloc_cut_buffer(scp, FALSE); 40348104Syokota#endif 40448104Syokota#ifndef SC_NO_HISTORY 40548667Syokota sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE); 40648104Syokota#endif 40739287Ssos splx(s); 40839287Ssos 40948104Syokota if (scp == scp->sc->cur_scp) { 41056043Syokota sc_set_border(scp, scp->border); 41148104Syokota sc_set_cursor_image(scp); 41248104Syokota } 41339287Ssos 41439287Ssos scp->status &= ~UNKNOWN_MODE; 41539287Ssos 41639287Ssos if (tp == NULL) 41739287Ssos return 0; 418242529Sed wsz.ws_col = scp->xsize; 419242529Sed wsz.ws_row = scp->ysize; 420242529Sed tty_set_winsize(tp, &wsz); 42139287Ssos return 0; 42248104Syokota#endif /* SC_PIXEL_MODE */ 42339287Ssos} 42439287Ssos 425204281Sjkimint 426204281Sjkimsc_support_pixel_mode(void *arg) 427204281Sjkim{ 428204281Sjkim#ifdef SC_PIXEL_MODE 429204281Sjkim video_info_t *info = arg; 430204281Sjkim 431204281Sjkim if ((info->vi_flags & V_INFO_GRAPHICS) == 0) 432204281Sjkim return (0); 433204281Sjkim 434204281Sjkim /* 435204281Sjkim * We currently support the following graphic modes: 436204281Sjkim * 437204281Sjkim * - 4 bpp planar modes whose memory size does not exceed 64K 438204281Sjkim * - 15, 16, 24 and 32 bpp linear modes 439204281Sjkim */ 440204281Sjkim switch (info->vi_mem_model) { 441204281Sjkim case V_INFO_MM_PLANAR: 442204281Sjkim if (info->vi_planes != 4) 443204281Sjkim break; 444204281Sjkim /* 445204281Sjkim * A memory size >64K requires bank switching to access 446204281Sjkim * the entire screen. XXX 447204281Sjkim */ 448204281Sjkim if (info->vi_width * info->vi_height / 8 > info->vi_window_size) 449204281Sjkim break; 450204281Sjkim return (1); 451204281Sjkim case V_INFO_MM_DIRECT: 452204281Sjkim if ((info->vi_flags & V_INFO_LINEAR) == 0 && 453204281Sjkim info->vi_depth != 15 && info->vi_depth != 16 && 454204281Sjkim info->vi_depth != 24 && info->vi_depth != 32) 455204281Sjkim break; 456204281Sjkim return (1); 457204281Sjkim case V_INFO_MM_PACKED: 458204281Sjkim if ((info->vi_flags & V_INFO_LINEAR) == 0 && 459204281Sjkim info->vi_depth != 8) 460204281Sjkim break; 461204281Sjkim return (1); 462204281Sjkim } 463204281Sjkim#endif 464204281Sjkim return (0); 465204281Sjkim} 466204281Sjkim 46748104Syokota#define fb_ioctl(a, c, d) \ 46848104Syokota (((a) == NULL) ? ENODEV : \ 469174985Swkoszek vidd_ioctl((a), (c), (caddr_t)(d))) 47048104Syokota 47139287Ssosint 472181905Sedsc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) 47339287Ssos{ 47439287Ssos scr_stat *scp; 47548104Syokota video_adapter_t *adp; 47648104Syokota video_info_t info; 47748104Syokota video_adapter_info_t adp_info; 47839287Ssos int error; 47939287Ssos int s; 480162711Sru#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ 481162711Sru defined(COMPAT_FREEBSD4) || defined(COMPAT_43) 482162711Sru int ival; 483162711Sru#endif 48439287Ssos 485181905Sed scp = SC_STAT(tp); 48648104Syokota if (scp == NULL) /* tp == SC_MOUSE */ 48748104Syokota return ENOIOCTL; 48848104Syokota adp = scp->sc->adp; 48948104Syokota if (adp == NULL) /* shouldn't happen??? */ 49048104Syokota return ENODEV; 49139287Ssos 49239287Ssos switch (cmd) { 49339287Ssos 49448104Syokota case CONS_CURRENTADP: /* get current adapter index */ 49548104Syokota case FBIO_ADAPTER: 49648104Syokota return fb_ioctl(adp, FBIO_ADAPTER, data); 49748104Syokota 49839287Ssos case CONS_CURRENT: /* get current adapter type */ 49948104Syokota case FBIO_ADPTYPE: 50048104Syokota return fb_ioctl(adp, FBIO_ADPTYPE, data); 50139287Ssos 50248104Syokota case OLD_CONS_ADPINFO: /* adapter information (old interface) */ 50348104Syokota if (((old_video_adapter_t *)data)->va_index >= 0) { 50448104Syokota adp = vid_get_adapter(((old_video_adapter_t *)data)->va_index); 50548104Syokota if (adp == NULL) 50648104Syokota return ENODEV; 50748104Syokota } 50848104Syokota ((old_video_adapter_t *)data)->va_index = adp->va_index; 50948104Syokota ((old_video_adapter_t *)data)->va_type = adp->va_type; 51048104Syokota ((old_video_adapter_t *)data)->va_flags = adp->va_flags; 51148104Syokota ((old_video_adapter_t *)data)->va_crtc_addr = adp->va_crtc_addr; 51248104Syokota ((old_video_adapter_t *)data)->va_window = adp->va_window; 51348104Syokota ((old_video_adapter_t *)data)->va_window_size = adp->va_window_size; 51448104Syokota ((old_video_adapter_t *)data)->va_window_gran = adp->va_window_gran; 51548104Syokota ((old_video_adapter_t *)data)->va_buffer = adp->va_buffer; 51648104Syokota ((old_video_adapter_t *)data)->va_buffer_size = adp->va_buffer_size; 51748104Syokota ((old_video_adapter_t *)data)->va_mode = adp->va_mode; 51848104Syokota ((old_video_adapter_t *)data)->va_initial_mode = adp->va_initial_mode; 51942504Syokota ((old_video_adapter_t *)data)->va_initial_bios_mode 52048104Syokota = adp->va_initial_bios_mode; 52142504Syokota return 0; 52242504Syokota 52348104Syokota case OLD_CONS_ADPINFO2: /* adapter information (yet another old I/F) */ 52448104Syokota adp_info.va_index = ((old_video_adapter_info_t *)data)->va_index; 52548104Syokota if (adp_info.va_index >= 0) { 52648104Syokota adp = vid_get_adapter(adp_info.va_index); 52748104Syokota if (adp == NULL) 52848104Syokota return ENODEV; 52948104Syokota } 53048104Syokota error = fb_ioctl(adp, FBIO_ADPINFO, &adp_info); 53148104Syokota if (error == 0) 53248104Syokota bcopy(&adp_info, data, sizeof(old_video_adapter_info_t)); 53348104Syokota return error; 53448104Syokota 53539287Ssos case CONS_ADPINFO: /* adapter information */ 53648104Syokota case FBIO_ADPINFO: 53748104Syokota if (((video_adapter_info_t *)data)->va_index >= 0) { 53848104Syokota adp = vid_get_adapter(((video_adapter_info_t *)data)->va_index); 53948104Syokota if (adp == NULL) 54048104Syokota return ENODEV; 54148104Syokota } 54248104Syokota return fb_ioctl(adp, FBIO_ADPINFO, data); 54339287Ssos 54439287Ssos case CONS_GET: /* get current video mode */ 54548104Syokota case FBIO_GETMODE: 54639287Ssos *(int *)data = scp->mode; 54739287Ssos return 0; 54839287Ssos 54948104Syokota#ifndef SC_NO_MODE_CHANGE 55048104Syokota case FBIO_SETMODE: /* set video mode */ 55148104Syokota if (!(adp->va_flags & V_ADP_MODECHANGE)) 55248104Syokota return ENODEV; 55348104Syokota info.vi_mode = *(int *)data; 55448104Syokota error = fb_ioctl(adp, FBIO_MODEINFO, &info); 55548104Syokota if (error) 55648104Syokota return error; 55748104Syokota if (info.vi_flags & V_INFO_GRAPHICS) 55848104Syokota return sc_set_graphics_mode(scp, tp, *(int *)data); 55948104Syokota else 560149640Srodrigc return sc_set_text_mode(scp, tp, *(int *)data, 0, 0, 0, 0); 56148104Syokota#endif /* SC_NO_MODE_CHANGE */ 56248104Syokota 56348104Syokota case OLD_CONS_MODEINFO: /* get mode information (old infterface) */ 56448104Syokota info.vi_mode = ((old_video_info_t *)data)->vi_mode; 56548104Syokota error = fb_ioctl(adp, FBIO_MODEINFO, &info); 56648104Syokota if (error == 0) 56748104Syokota bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t)); 56848104Syokota return error; 56948104Syokota 57039287Ssos case CONS_MODEINFO: /* get mode information */ 57148104Syokota case FBIO_MODEINFO: 57248104Syokota return fb_ioctl(adp, FBIO_MODEINFO, data); 57339287Ssos 57448104Syokota case OLD_CONS_FINDMODE: /* find a matching video mode (old interface) */ 57548104Syokota bzero(&info, sizeof(info)); 57648104Syokota bcopy((old_video_info_t *)data, &info, sizeof(old_video_info_t)); 57748104Syokota error = fb_ioctl(adp, FBIO_FINDMODE, &info); 57848104Syokota if (error == 0) 57948104Syokota bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t)); 58048104Syokota return error; 58148104Syokota 58239287Ssos case CONS_FINDMODE: /* find a matching video mode */ 58348104Syokota case FBIO_FINDMODE: 58448104Syokota return fb_ioctl(adp, FBIO_FINDMODE, data); 58539287Ssos 586162711Sru#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ 587162711Sru defined(COMPAT_FREEBSD4) || defined(COMPAT_43) 588162711Sru case _IO('c', 104): 589162711Sru ival = IOCPARM_IVAL(data); 590162711Sru data = (caddr_t)&ival; 591162711Sru /* FALLTHROUGH */ 592162711Sru#endif 59348104Syokota case CONS_SETWINORG: /* set frame buffer window origin */ 59448104Syokota case FBIO_SETWINORG: 59548104Syokota if (scp != scp->sc->cur_scp) 59648104Syokota return ENODEV; /* XXX */ 59748104Syokota return fb_ioctl(adp, FBIO_SETWINORG, data); 59839287Ssos 59948104Syokota case FBIO_GETWINORG: /* get frame buffer window origin */ 60048104Syokota if (scp != scp->sc->cur_scp) 60148104Syokota return ENODEV; /* XXX */ 60248104Syokota return fb_ioctl(adp, FBIO_GETWINORG, data); 60348104Syokota 60448104Syokota case FBIO_GETDISPSTART: 60548104Syokota case FBIO_SETDISPSTART: 60648104Syokota case FBIO_GETLINEWIDTH: 60748104Syokota case FBIO_SETLINEWIDTH: 60848104Syokota if (scp != scp->sc->cur_scp) 60948104Syokota return ENODEV; /* XXX */ 61048104Syokota return fb_ioctl(adp, cmd, data); 61148104Syokota 61248104Syokota case FBIO_GETPALETTE: 61348104Syokota case FBIO_SETPALETTE: 61448104Syokota case FBIOPUTCMAP: 61548104Syokota case FBIOGETCMAP: 61648104Syokota case FBIOGTYPE: 61748104Syokota case FBIOGATTR: 61848104Syokota case FBIOSVIDEO: 61948104Syokota case FBIOGVIDEO: 62048104Syokota case FBIOSCURSOR: 62148104Syokota case FBIOGCURSOR: 62248104Syokota case FBIOSCURPOS: 62348104Syokota case FBIOGCURPOS: 62448104Syokota case FBIOGCURMAX: 62548104Syokota if (scp != scp->sc->cur_scp) 62648104Syokota return ENODEV; /* XXX */ 62748104Syokota return fb_ioctl(adp, cmd, data); 62848104Syokota 62981039Syokota case FBIO_BLANK: 63081039Syokota if (scp != scp->sc->cur_scp) 63181039Syokota return ENODEV; /* XXX */ 63281039Syokota return fb_ioctl(adp, cmd, data); 63381039Syokota 63448104Syokota#ifndef SC_NO_MODE_CHANGE 63539591Syokota /* generic text modes */ 63639591Syokota case SW_TEXT_80x25: case SW_TEXT_80x30: 63739591Syokota case SW_TEXT_80x43: case SW_TEXT_80x50: 63839591Syokota case SW_TEXT_80x60: 639102412Scharnier /* FALLTHROUGH */ 64039591Syokota 64139287Ssos /* VGA TEXT MODES */ 64239287Ssos case SW_VGA_C40x25: 64339287Ssos case SW_VGA_C80x25: case SW_VGA_M80x25: 64439287Ssos case SW_VGA_C80x30: case SW_VGA_M80x30: 64539287Ssos case SW_VGA_C80x50: case SW_VGA_M80x50: 64639287Ssos case SW_VGA_C80x60: case SW_VGA_M80x60: 64748104Syokota case SW_VGA_C90x25: case SW_VGA_M90x25: 64848104Syokota case SW_VGA_C90x30: case SW_VGA_M90x30: 64948104Syokota case SW_VGA_C90x43: case SW_VGA_M90x43: 65048104Syokota case SW_VGA_C90x50: case SW_VGA_M90x50: 65148104Syokota case SW_VGA_C90x60: case SW_VGA_M90x60: 65239287Ssos case SW_B40x25: case SW_C40x25: 65339287Ssos case SW_B80x25: case SW_C80x25: 65439287Ssos case SW_ENH_B40x25: case SW_ENH_C40x25: 65539287Ssos case SW_ENH_B80x25: case SW_ENH_C80x25: 65639287Ssos case SW_ENH_B80x43: case SW_ENH_C80x43: 65739287Ssos case SW_EGAMONO80x25: 65842504Syokota 65942504Syokota#ifdef PC98 66042504Syokota /* PC98 TEXT MODES */ 66142504Syokota case SW_PC98_80x25: 66242504Syokota case SW_PC98_80x30: 66342504Syokota#endif 66448104Syokota if (!(adp->va_flags & V_ADP_MODECHANGE)) 66539287Ssos return ENODEV; 666149640Srodrigc return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0, 0); 66739287Ssos 66839287Ssos /* GRAPHICS MODES */ 66939287Ssos case SW_BG320: case SW_BG640: 67039287Ssos case SW_CG320: case SW_CG320_D: case SW_CG640_E: 67139287Ssos case SW_CG640x350: case SW_ENH_CG640: 67239287Ssos case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: 67339287Ssos case SW_VGA_MODEX: 67459689Snyan#ifdef PC98 67559689Snyan /* PC98 GRAPHICS MODES */ 67659689Snyan case SW_PC98_EGC640x400: case SW_PC98_PEGC640x400: 67759689Snyan case SW_PC98_PEGC640x480: 67859689Snyan#endif 67948104Syokota if (!(adp->va_flags & V_ADP_MODECHANGE)) 68039287Ssos return ENODEV; 68139287Ssos return sc_set_graphics_mode(scp, tp, cmd & 0xff); 68248104Syokota#endif /* SC_NO_MODE_CHANGE */ 68339287Ssos 684162711Sru#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ 685162711Sru defined(COMPAT_FREEBSD4) || defined(COMPAT_43) 686162711Sru case _IO('K', 10): 687162711Sru ival = IOCPARM_IVAL(data); 688162711Sru data = (caddr_t)&ival; 689162711Sru /* FALLTHROUGH */ 690162711Sru#endif 69139287Ssos case KDSETMODE: /* set current mode of this (virtual) console */ 692162711Sru switch (*(int *)data) { 69339287Ssos case KD_TEXT: /* switch to TEXT (known) mode */ 69439287Ssos /* 69539287Ssos * If scp->mode is of graphics modes, we don't know which 69639287Ssos * text mode to switch back to... 69739287Ssos */ 69839287Ssos if (scp->status & GRAPHICS_MODE) 69939287Ssos return EINVAL; 70039287Ssos /* restore fonts & palette ! */ 70139287Ssos#if 0 70248104Syokota#ifndef SC_NO_FONT_LOADING 70348104Syokota if (ISFONTAVAIL(adp->va_flags) 70439287Ssos && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) 70539287Ssos /* 70639287Ssos * FONT KLUDGE 70739287Ssos * Don't load fonts for now... XXX 70839287Ssos */ 70948104Syokota if (scp->sc->fonts_loaded & FONT_8) 710150686Smarius sc_load_font(scp, 0, 8, 8, scp->sc->font_8, 0, 256); 71148104Syokota if (scp->sc->fonts_loaded & FONT_14) 712150686Smarius sc_load_font(scp, 0, 14, 8, scp->sc->font_14, 0, 256); 71348104Syokota if (scp->sc->fonts_loaded & FONT_16) 714150686Smarius sc_load_font(scp, 0, 16, 8, scp->sc->font_16, 0, 256); 71539287Ssos } 71648104Syokota#endif /* SC_NO_FONT_LOADING */ 71739287Ssos#endif 71839287Ssos 71948104Syokota#ifndef SC_NO_PALETTE_LOADING 720204265Sjkim#ifdef SC_PIXEL_MODE 721205865Sjkim if (adp->va_info.vi_mem_model == V_INFO_MM_DIRECT) 722204265Sjkim vidd_load_palette(adp, scp->sc->palette2); 723204265Sjkim else 724204265Sjkim#endif 725174985Swkoszek vidd_load_palette(adp, scp->sc->palette); 72648104Syokota#endif 72748104Syokota 72848104Syokota#ifndef PC98 72939287Ssos /* move hardware cursor out of the way */ 730174985Swkoszek vidd_set_hw_cursor(adp, -1, -1); 73148104Syokota#endif 73239287Ssos 733102412Scharnier /* FALLTHROUGH */ 73439287Ssos 73539287Ssos case KD_TEXT1: /* switch to TEXT (known) mode */ 73639287Ssos /* 73739287Ssos * If scp->mode is of graphics modes, we don't know which 73839287Ssos * text/pixel mode to switch back to... 73939287Ssos */ 74039287Ssos if (scp->status & GRAPHICS_MODE) 74139287Ssos return EINVAL; 74239287Ssos s = spltty(); 74339287Ssos if ((error = sc_clean_up(scp))) { 74439287Ssos splx(s); 74539287Ssos return error; 74639287Ssos } 74742504Syokota#ifndef PC98 74858872Syokota scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 74939287Ssos splx(s); 75039287Ssos /* no restore fonts & palette */ 75148104Syokota if (scp == scp->sc->cur_scp) 75239287Ssos set_mode(scp); 75339287Ssos sc_clear_screen(scp); 75439287Ssos scp->status &= ~UNKNOWN_MODE; 75542504Syokota#else /* PC98 */ 75642504Syokota scp->status &= ~UNKNOWN_MODE; 75742504Syokota /* no restore fonts & palette */ 75848104Syokota if (scp == scp->sc->cur_scp) 75942504Syokota set_mode(scp); 76042504Syokota sc_clear_screen(scp); 76142504Syokota splx(s); 76242504Syokota#endif /* PC98 */ 76339287Ssos return 0; 76439287Ssos 76548104Syokota#ifdef SC_PIXEL_MODE 76639287Ssos case KD_PIXEL: /* pixel (raster) display */ 76739287Ssos if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE))) 76839287Ssos return EINVAL; 76939591Syokota if (scp->status & GRAPHICS_MODE) 77039287Ssos return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize, 771149640Srodrigc scp->font_size, scp->font_width); 77239287Ssos s = spltty(); 77339287Ssos if ((error = sc_clean_up(scp))) { 77439287Ssos splx(s); 77539287Ssos return error; 77639287Ssos } 77758872Syokota scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN); 77839287Ssos splx(s); 77948104Syokota if (scp == scp->sc->cur_scp) { 78039287Ssos set_mode(scp); 78148104Syokota#ifndef SC_NO_PALETTE_LOADING 782205865Sjkim if (adp->va_info.vi_mem_model == V_INFO_MM_DIRECT) 783204265Sjkim vidd_load_palette(adp, scp->sc->palette2); 784204265Sjkim else 785204265Sjkim vidd_load_palette(adp, scp->sc->palette); 78648104Syokota#endif 78739287Ssos } 78839287Ssos sc_clear_screen(scp); 78939287Ssos scp->status &= ~UNKNOWN_MODE; 79039287Ssos return 0; 79148104Syokota#endif /* SC_PIXEL_MODE */ 79239287Ssos 79339287Ssos case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */ 79439287Ssos s = spltty(); 79539287Ssos if ((error = sc_clean_up(scp))) { 79639287Ssos splx(s); 79739287Ssos return error; 79839287Ssos } 79958872Syokota scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN; 80039287Ssos splx(s); 80142504Syokota#ifdef PC98 80248104Syokota if (scp == scp->sc->cur_scp) 80342504Syokota set_mode(scp); 80442504Syokota#endif 80539287Ssos return 0; 80639287Ssos 80739287Ssos default: 80839287Ssos return EINVAL; 80939287Ssos } 81039287Ssos /* NOT REACHED */ 81139287Ssos 81248104Syokota#ifdef SC_PIXEL_MODE 81339287Ssos case KDRASTER: /* set pixel (raster) display mode */ 81439287Ssos if (ISUNKNOWNSC(scp) || ISTEXTSC(scp)) 81539287Ssos return ENODEV; 81639287Ssos return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1], 817149640Srodrigc ((int *)data)[2], 8); 81848104Syokota#endif /* SC_PIXEL_MODE */ 81939287Ssos 82039287Ssos case KDGETMODE: /* get current mode of this (virtual) console */ 82139287Ssos /* 82239287Ssos * From the user program's point of view, KD_PIXEL is the same 82339287Ssos * as KD_TEXT... 82439287Ssos */ 82539287Ssos *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT; 82639287Ssos return 0; 82739287Ssos 828162711Sru#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ 829162711Sru defined(COMPAT_FREEBSD4) || defined(COMPAT_43) 830162711Sru case _IO('K', 13): 831162711Sru ival = IOCPARM_IVAL(data); 832162711Sru data = (caddr_t)&ival; 833162711Sru /* FALLTHROUGH */ 834162711Sru#endif 83539287Ssos case KDSBORDER: /* set border color of this (virtual) console */ 836162711Sru scp->border = *(int *)data; 83748104Syokota if (scp == scp->sc->cur_scp) 83856043Syokota sc_set_border(scp, scp->border); 83939287Ssos return 0; 84039287Ssos } 84139287Ssos 84239287Ssos return ENOIOCTL; 84339287Ssos} 84439287Ssos 84560938Sjakestatic LIST_HEAD(, sc_renderer) sc_rndr_list = 84656043Syokota LIST_HEAD_INITIALIZER(sc_rndr_list); 84756043Syokota 84856043Syokotaint 84956043Syokotasc_render_add(sc_renderer_t *rndr) 85056043Syokota{ 85156043Syokota LIST_INSERT_HEAD(&sc_rndr_list, rndr, link); 85256043Syokota return 0; 85356043Syokota} 85456043Syokota 85556043Syokotaint 85656043Syokotasc_render_remove(sc_renderer_t *rndr) 85756043Syokota{ 85856043Syokota /* 85956043Syokota LIST_REMOVE(rndr, link); 86056043Syokota */ 86156043Syokota return EBUSY; /* XXX */ 86256043Syokota} 86356043Syokota 86456043Syokotasc_rndr_sw_t 86556043Syokota*sc_render_match(scr_stat *scp, char *name, int mode) 86656043Syokota{ 86756043Syokota const sc_renderer_t **list; 86856043Syokota const sc_renderer_t *p; 86956043Syokota 87056043Syokota if (!LIST_EMPTY(&sc_rndr_list)) { 87156043Syokota LIST_FOREACH(p, &sc_rndr_list, link) { 87256043Syokota if ((strcmp(p->name, name) == 0) 87356043Syokota && (mode == p->mode)) { 87456043Syokota scp->status &= 87556043Syokota ~(VR_CURSOR_ON | VR_CURSOR_BLINK); 87656043Syokota return p->rndrsw; 87756043Syokota } 87856043Syokota } 87956043Syokota } else { 88078161Speter SET_FOREACH(list, scrndr_set) { 88178161Speter p = *list; 88256043Syokota if ((strcmp(p->name, name) == 0) 88356043Syokota && (mode == p->mode)) { 88456043Syokota scp->status &= 88556043Syokota ~(VR_CURSOR_ON | VR_CURSOR_BLINK); 88656043Syokota return p->rndrsw; 88756043Syokota } 88856043Syokota } 88956043Syokota } 89056043Syokota 89156043Syokota return NULL; 89256043Syokota} 893