19decb2cdStsutsui/* $NetBSD: x68kConfig.c,v 1.8 2025/06/22 22:32:14 tsutsui Exp $ */ 2ba64b02eStsutsui/*------------------------------------------------------------------------- 3ba64b02eStsutsui * Copyright (c) 1996 Yasushi Yamasaki 4ba64b02eStsutsui * All rights reserved. 5ba64b02eStsutsui * 6ba64b02eStsutsui * Redistribution and use in source and binary forms, with or without 7ba64b02eStsutsui * modification, are permitted provided that the following conditions 8ba64b02eStsutsui * are met: 9ba64b02eStsutsui * 1. Redistributions of source code must retain the above copyright 10ba64b02eStsutsui * notice, this list of conditions and the following disclaimer. 11ba64b02eStsutsui * 2. Redistributions in binary form must reproduce the above copyright 12ba64b02eStsutsui * notice, this list of conditions and the following disclaimer in the 13ba64b02eStsutsui * documentation and/or other materials provided with the distribution. 14ba64b02eStsutsui * 15ba64b02eStsutsui * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16ba64b02eStsutsui * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17ba64b02eStsutsui * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18ba64b02eStsutsui * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19ba64b02eStsutsui * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20ba64b02eStsutsui * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21ba64b02eStsutsui * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22ba64b02eStsutsui * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23ba64b02eStsutsui * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24ba64b02eStsutsui * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25ba64b02eStsutsui *-----------------------------------------------------------------------*/ 26ba64b02eStsutsui 27ba64b02eStsutsui#include <stdarg.h> 28ba64b02eStsutsui#include "x68k.h" 29ba64b02eStsutsui#include "opaque.h" 30ba64b02eStsutsui 31ba64b02eStsutsuistatic PixmapFormatRec *x68kFormat = NULL; 32ba64b02eStsutsuistatic PixmapFormatRec defaultFormat = { 33ba64b02eStsutsui 1, 34ba64b02eStsutsui 1, 35ba64b02eStsutsui BITMAP_SCANLINE_PAD 36ba64b02eStsutsui}; 37ba64b02eStsutsuistatic X68kScreenRec x68kScreen[X68K_FB_TYPES]; 38ba64b02eStsutsuistatic X68kFbProcRec x68kFbProc[X68K_FB_TYPES]; 39ba64b02eStsutsui 409decb2cdStsutsuistatic int x68kKbdType = X68K_KB_STANDARD; 419decb2cdStsutsui 42ba64b02eStsutsui/*------------------------------------------------------------------------- 43ba64b02eStsutsui * function "x68kGetScreenRec" 44ba64b02eStsutsui * 45ba64b02eStsutsui * purpose: get corresponding screen record 46ba64b02eStsutsui * argument: (int)sindex : screen index 47ba64b02eStsutsui * returns: (X68kScreenRec *) : X68k dependent screen record 48ba64b02eStsutsui *-----------------------------------------------------------------------*/ 49ba64b02eStsutsuiX68kScreenRec * 50ba64b02eStsutsuix68kGetScreenRec(int sindex) 51ba64b02eStsutsui{ 52ba64b02eStsutsui return &x68kScreen[sindex]; 53ba64b02eStsutsui} 54ba64b02eStsutsui 55ba64b02eStsutsui/*------------------------------------------------------------------------- 56ba64b02eStsutsui * function "x68kGetScreenRecByType" 57ba64b02eStsutsui * 58ba64b02eStsutsui * purpose: search screen record by type 59ba64b02eStsutsui * argument: (int)type : screen type 60ba64b02eStsutsui * returns: (X68kScreenRec *) : X68k dependent screen record 61ba64b02eStsutsui *-----------------------------------------------------------------------*/ 62ba64b02eStsutsuiX68kScreenRec * 63ba64b02eStsutsuix68kGetScreenRecByType(int type) 64ba64b02eStsutsui{ 65ba64b02eStsutsui int i; 66ab290810Stsutsui 67ba64b02eStsutsui for (i = 0; i < X68K_FB_TYPES; i++) { 68ba64b02eStsutsui if (x68kScreen[i].type == type) 69ba64b02eStsutsui return &x68kScreen[i]; 70ba64b02eStsutsui } 71ba64b02eStsutsui return NULL; 72ba64b02eStsutsui} 73ba64b02eStsutsui 74ba64b02eStsutsui/*------------------------------------------------------------------------- 75ba64b02eStsutsui * function "x68kGetFbProcRec" 76ba64b02eStsutsui * 77ba64b02eStsutsui * purpose: get corresponding frame buffer procedure record 78ba64b02eStsutsui * argument: (int)sindex : screen index 79ba64b02eStsutsui * returns: (X68kFbProcRec *) : frame buffer procedure record 80ba64b02eStsutsui *-----------------------------------------------------------------------*/ 81ba64b02eStsutsuiX68kFbProcRec * 82ba64b02eStsutsuix68kGetFbProcRec(int sindex) 83ba64b02eStsutsui{ 84ba64b02eStsutsui return &x68kFbProc[sindex]; 85ba64b02eStsutsui} 86ba64b02eStsutsui 87ba64b02eStsutsui/*------------------------------------------------------------------------- 88ba64b02eStsutsui * function "x68kRegisterPixmapFormats" 89ba64b02eStsutsui * 90ba64b02eStsutsui * purpose: register pixmap formats into ScreenInfo struct 91ba64b02eStsutsui * argument: (ScreenInfo *)pScreenInfo 92ba64b02eStsutsui * returns: nothing 93ba64b02eStsutsui *-----------------------------------------------------------------------*/ 94ba64b02eStsutsuivoid 95ba64b02eStsutsuix68kRegisterPixmapFormats(ScreenInfo *pScreenInfo) 96ba64b02eStsutsui{ 97ba64b02eStsutsui /* supports only one pixmap format for each screen type */ 98ba64b02eStsutsui pScreenInfo->numPixmapFormats = 1; 99ba64b02eStsutsui pScreenInfo->formats[0] = defaultFormat; 100ba64b02eStsutsui 101ba64b02eStsutsui if (x68kFormat) 102ba64b02eStsutsui pScreenInfo->formats[pScreenInfo->numPixmapFormats++] = *x68kFormat; 103ba64b02eStsutsui} 104ba64b02eStsutsui 1059decb2cdStsutsui/*------------------------------------------------------------------------- 1069decb2cdStsutsui * function "x68kGetKbdType" 1079decb2cdStsutsui * 1089decb2cdStsutsui * purpose: get keyboard map type specified in the config file 1099decb2cdStsutsui * argument: none 1109decb2cdStsutsui * returns: (int) : keyboard type 1119decb2cdStsutsui *-----------------------------------------------------------------------*/ 1129decb2cdStsutsuiint 1139decb2cdStsutsuix68kGetKbdType(void) 1149decb2cdStsutsui{ 1159decb2cdStsutsui return x68kKbdType; 1169decb2cdStsutsui} 1179decb2cdStsutsui 118ba64b02eStsutsui/*------------------------------------------------------------------------- 119ba64b02eStsutsui * function "x68kConfig" 120ba64b02eStsutsui * 121ba64b02eStsutsui * purpose: process general configuration by reading "X68kConfig" file 122b65a0881Stsutsui * <X11_LIBDIR> is the default location of this file 123ba64b02eStsutsui * argument: nothing 124ba64b02eStsutsui * returns: the number of screens 125ba64b02eStsutsui *-----------------------------------------------------------------------*/ 126ba64b02eStsutsuiconst char *hostConfigFilename = "/etc/X68kConfig"; 127ba64b02eStsutsuiconst char *siteConfigFilename = X11_LIBDIR "/X68kConfig"; 128ba64b02eStsutsuiconst char *configFilename = NULL; 129ba64b02eStsutsuistatic FILE *config; 13015b0c026Stsutsuistatic char modeSet = FALSE; 131ba64b02eStsutsui 132ba64b02eStsutsuistatic int parseCommand(void); 13315b0c026Stsutsuistatic void logConfig(void); 134ba64b02eStsutsui 135ba64b02eStsutsuiint 136ba64b02eStsutsuix68kConfig(void) 137ba64b02eStsutsui{ 13815b0c026Stsutsui MessageType filefrom = X_DEFAULT; 13915b0c026Stsutsui 14015b0c026Stsutsui if (configFilename) { 141ba64b02eStsutsui config = fopen(configFilename, "r"); 14215b0c026Stsutsui filefrom = X_CMDLINE; 14315b0c026Stsutsui } else { 144ba64b02eStsutsui configFilename = hostConfigFilename; 145ba64b02eStsutsui config = fopen(configFilename, "r"); 146ba64b02eStsutsui if (config == NULL) { 147ba64b02eStsutsui configFilename = siteConfigFilename; 148ba64b02eStsutsui config = fopen(configFilename, "r"); 149ba64b02eStsutsui } 150ba64b02eStsutsui } 151ba64b02eStsutsui if (config == NULL) 152ba64b02eStsutsui FatalError("Can't open X68kConfig file"); 15315b0c026Stsutsui 15415b0c026Stsutsui LogMessage(filefrom, "Using config file: \"%s\"\n", configFilename); 15515b0c026Stsutsui 156ba64b02eStsutsui while (parseCommand()) 157ba64b02eStsutsui ; 158ba64b02eStsutsui fclose(config); 159ba64b02eStsutsui if (!modeSet) 160ba64b02eStsutsui FatalError("No mode set."); 16115b0c026Stsutsui logConfig(); 162ba64b02eStsutsui return 1; 163ba64b02eStsutsui} 164ba64b02eStsutsui 165ba64b02eStsutsui 166ba64b02eStsutsui/*------------------------------------------------------------------------- 167ba64b02eStsutsui * X68KConfig parsing part 168ba64b02eStsutsui *-----------------------------------------------------------------------*/ 16915b0c026Stsutsuistatic void parseError(int line, const char *str, ...); 170ba64b02eStsutsui 171ba64b02eStsutsuienum TokenType { 172ba64b02eStsutsui TOKEN_EOF, 173ba64b02eStsutsui TOKEN_SYMBOL, 174ba64b02eStsutsui TOKEN_LITERAL, 175ba64b02eStsutsui TOKEN_OPEN_PARENTHESIS, 176ba64b02eStsutsui TOKEN_CLOSE_PARENTHESIS 177ba64b02eStsutsui}; 178ba64b02eStsutsui 179ba64b02eStsutsuitypedef struct { 180ba64b02eStsutsui enum TokenType type; 181ba64b02eStsutsui int line; 182ba64b02eStsutsui union { 183ba64b02eStsutsui char *symbol; 184ba64b02eStsutsui int literal; 185ba64b02eStsutsui } content; 186ba64b02eStsutsui} Token; 187ba64b02eStsutsui 188ba64b02eStsutsui/*------------------------------------------------------------------------- 189ba64b02eStsutsui * function "getToken" 190ba64b02eStsutsui * 191ba64b02eStsutsui * purpose: cut out a token from configration file stream 192ba64b02eStsutsui * argument: nothing 193ba64b02eStsutsui * returns: (Token *) : cut token 194ba64b02eStsutsui *-----------------------------------------------------------------------*/ 195ba64b02eStsutsuistatic Token * 196ba64b02eStsutsuigetToken(void) 197ba64b02eStsutsui{ 198ba64b02eStsutsui int c; 199ba64b02eStsutsui static int line = 1; 200ba64b02eStsutsui Token *ret; 201ab290810Stsutsui 202d998ab55Stsutsui ret = malloc(sizeof(Token)); 203ba64b02eStsutsui if (ret == NULL) 204ba64b02eStsutsui FatalError("Out of memory"); 205ba64b02eStsutsui while (TRUE) { 206ba64b02eStsutsui /* slip white spaces */ 207ba64b02eStsutsui do { 208ba64b02eStsutsui c = fgetc(config); 209ba64b02eStsutsui if (c == '\n') 210ba64b02eStsutsui line++; 211ba64b02eStsutsui } while (isspace(c)); 212ba64b02eStsutsui if (c != ';') 213ba64b02eStsutsui break; 214ba64b02eStsutsui /* skip a comment */ 215ba64b02eStsutsui do { 216ba64b02eStsutsui c = fgetc(config); 217ba64b02eStsutsui } while (c != '\n'); 218ba64b02eStsutsui line++; 219ba64b02eStsutsui } 220ba64b02eStsutsui ret->line = line; 221ba64b02eStsutsui if (c == EOF) { 222ba64b02eStsutsui ret->type = TOKEN_EOF; 223ba64b02eStsutsui return ret; 224ba64b02eStsutsui } 225ba64b02eStsutsui /* is a symbol? */ 226ba64b02eStsutsui if (isalpha(c)) { 227ba64b02eStsutsui int i = 0; 228d998ab55Stsutsui ret->content.symbol = malloc(32 * sizeof(char)); 229ba64b02eStsutsui if (ret->content.symbol == NULL) 230ba64b02eStsutsui FatalError("Out of memory"); 231ba64b02eStsutsui do { 232ba64b02eStsutsui if (i < 31) 233ba64b02eStsutsui ret->content.symbol[i++] = c; 234ba64b02eStsutsui c = fgetc(config); 235ba64b02eStsutsui } while (isalnum(c) || c == '_'); 236ba64b02eStsutsui ungetc(c, config); 237ba64b02eStsutsui ret->content.symbol[i] = '\0'; 238ba64b02eStsutsui ret->type = TOKEN_SYMBOL; 239ba64b02eStsutsui return ret; 240ba64b02eStsutsui } 241ba64b02eStsutsui /* is a literal number? */ 242ba64b02eStsutsui if (isdigit(c)) { 243ba64b02eStsutsui char tmp[32]; 244ba64b02eStsutsui int i = 0; 245ba64b02eStsutsui do { 246ba64b02eStsutsui if (i < 31) 247ba64b02eStsutsui tmp[i++] = c; 248ba64b02eStsutsui c = fgetc(config); 249ba64b02eStsutsui } while (isdigit(c)); 250ba64b02eStsutsui ungetc(c, config); 251ba64b02eStsutsui tmp[i] = '\0'; 252ba64b02eStsutsui if (sscanf(tmp, "%d", &ret->content.literal) != 1) 253ba64b02eStsutsui parseError(line, "illegal literal value"); 254ba64b02eStsutsui ret->type = TOKEN_LITERAL; 255ba64b02eStsutsui return ret; 256ba64b02eStsutsui } 257ba64b02eStsutsui /* others */ 258ba64b02eStsutsui switch(c) { 259ba64b02eStsutsui case '(': 260ba64b02eStsutsui ret->type = TOKEN_OPEN_PARENTHESIS; 261ba64b02eStsutsui break; 262ba64b02eStsutsui case ')': 263ba64b02eStsutsui ret->type = TOKEN_CLOSE_PARENTHESIS; 264ba64b02eStsutsui break; 265ba64b02eStsutsui default: 266ba64b02eStsutsui parseError(line, NULL); 267ba64b02eStsutsui } 268ba64b02eStsutsui return ret; 269ba64b02eStsutsui} 270ba64b02eStsutsui 271ba64b02eStsutsuitypedef struct { 272ba64b02eStsutsui const char *symbol; 273ba64b02eStsutsui void (*proc)(int argc, Token **argv); 274ba64b02eStsutsui} Command; 275ba64b02eStsutsui 276ba64b02eStsutsuistatic void parseModeDef(int argc, Token **argv); 277ba64b02eStsutsuistatic void parseMouse(int argc, Token **argv); 278ba64b02eStsutsuistatic void parseKeyboard(int argc, Token **argv); 279ba64b02eStsutsuistatic void parseMode(int argc, Token **argv); 280ba64b02eStsutsui 28115b0c026Stsutsuistatic const Command command[] = { 282ba64b02eStsutsui { "ModeDef", parseModeDef }, 283ba64b02eStsutsui { "Mouse", parseMouse }, 284ba64b02eStsutsui { "Keyboard", parseKeyboard }, 285ba64b02eStsutsui { "Mode", parseMode }, 286ba64b02eStsutsui}; 287ab290810Stsutsui#define NCOMMANDS (sizeof(command)/sizeof(command[0])) 288ba64b02eStsutsui 28915b0c026Stsutsuistatic const char *x68kTypeStr[] = { 29015b0c026Stsutsui [X68K_FB_NULL] = NULL, 29115b0c026Stsutsui [X68K_FB_TEXT] = "Text", 29215b0c026Stsutsui [X68K_FB_GRAPHIC] = "Graphic", 29315b0c026Stsutsui}; 29415b0c026Stsutsui#define NTYPES (sizeof(x68kTypeStr) / sizeof(x68kTypeStr[0])) 29515b0c026Stsutsui 29615b0c026Stsutsuistatic const char *x68kClassStr[] = { 29715b0c026Stsutsui [StaticGray] = "StaticGray", 29815b0c026Stsutsui [GrayScale] = "GrayScale", 29915b0c026Stsutsui [StaticColor] = "StaticColor", 30015b0c026Stsutsui [PseudoColor] = "PseudoColor", 30115b0c026Stsutsui [TrueColor] = "TrueColor", 30215b0c026Stsutsui [DirectColor] = "DirectColor", 30315b0c026Stsutsui}; 30415b0c026Stsutsui#define NCLASSES (sizeof(x68kClassStr) / sizeof(x68kClassStr[0])) 30515b0c026Stsutsui#define ClassInvalid (-1) 30615b0c026Stsutsui 307ba64b02eStsutsui/*------------------------------------------------------------------------- 308ba64b02eStsutsui * function "parseCommand" 309ba64b02eStsutsui * 310ba64b02eStsutsui * purpose: parse generic command. every command parsing departs here. 311ba64b02eStsutsui * argument: nothing 312ba64b02eStsutsui * returns: (int) : FALSE if there's no rest 313ba64b02eStsutsui * TRUE otherwise 314ba64b02eStsutsui *-----------------------------------------------------------------------*/ 315ba64b02eStsutsuistatic int 316ba64b02eStsutsuiparseCommand(void) 317ba64b02eStsutsui{ 318ba64b02eStsutsui Token **argv = 0, *token; 319ba64b02eStsutsui int argc = 0; 320ba64b02eStsutsui int i; 321ab290810Stsutsui 322ba64b02eStsutsui token = getToken(); 323ba64b02eStsutsui if (token->type == TOKEN_EOF) 324ba64b02eStsutsui return FALSE; 325ba64b02eStsutsui if (token->type != TOKEN_OPEN_PARENTHESIS) 326ba64b02eStsutsui parseError(token->line, "missing parenthesis"); 327a2ab6c90Stsutsui free(token); 328ba64b02eStsutsui 329ba64b02eStsutsui /* get command name and arguments */ 330ba64b02eStsutsui while (TRUE) { 331ba64b02eStsutsui token = getToken(); 332ba64b02eStsutsui if (token->type == TOKEN_EOF) 333ba64b02eStsutsui parseError(token->line, "reached EOF"); 334ba64b02eStsutsui if (token->type == TOKEN_CLOSE_PARENTHESIS) { 335a2ab6c90Stsutsui free(token); 336ba64b02eStsutsui break; 337ba64b02eStsutsui } 338ba64b02eStsutsui argc++; 339d998ab55Stsutsui argv = realloc(argv, sizeof(Token *) * argc); 340ba64b02eStsutsui if (argv == NULL) 341ba64b02eStsutsui FatalError("Out of memory"); 342ba64b02eStsutsui argv[argc-1] = token; 343ba64b02eStsutsui } 344ba64b02eStsutsui if (argc == 0) 345ba64b02eStsutsui return TRUE; 346ba64b02eStsutsui 347ba64b02eStsutsui /* call corresponding command procedure */ 348ba64b02eStsutsui if (argv[0]->type != TOKEN_SYMBOL) 349ba64b02eStsutsui parseError(argv[0]->line, "command name required"); 350ba64b02eStsutsui for (i = 0; i < NCOMMANDS; i++) { 351ba64b02eStsutsui if (strcasecmp(command[i].symbol, argv[0]->content.symbol) == 0) { 352ba64b02eStsutsui /* parse command */ 353ab290810Stsutsui command[i].proc(argc, argv); 354ba64b02eStsutsui break; 355ba64b02eStsutsui } 356ba64b02eStsutsui } 357ba64b02eStsutsui if (i == NCOMMANDS) 358ba64b02eStsutsui parseError(argv[0]->line, "unknown command `%s'", 359ba64b02eStsutsui argv[0]->content.symbol); 360ba64b02eStsutsui 361ba64b02eStsutsui /* free arguments */ 362ba64b02eStsutsui for (i = 0; i < argc; i++) { 363ba64b02eStsutsui if (argv[i]->type == TOKEN_SYMBOL) 364a2ab6c90Stsutsui free(argv[i]->content.symbol); 365a2ab6c90Stsutsui free(argv[i]); 366ba64b02eStsutsui } 367a2ab6c90Stsutsui free(argv); 368ba64b02eStsutsui return TRUE; 369ba64b02eStsutsui} 370ba64b02eStsutsui 371ba64b02eStsutsui/*------------------------------------------------------------------------- 372ba64b02eStsutsui * function "checkArguments" 373ba64b02eStsutsui * 374ba64b02eStsutsui * purpose: examine the number of arguments and the type of each 375ba64b02eStsutsui * argument. 376ba64b02eStsutsui * argument: (int)n : correct number of arguments 37715b0c026Stsutsui * (const enum TokenType *)type : table of types 378ba64b02eStsutsui * (int)argc_m1 : actual number of arguments 379ba64b02eStsutsui * (Token **)argv : command and arguments 380ba64b02eStsutsui * returns: nothing 381ba64b02eStsutsui *-----------------------------------------------------------------------*/ 382ba64b02eStsutsuistatic void 38315b0c026StsutsuicheckArguments(int n, const enum TokenType *type, int argc_m1, Token **argv) 384ba64b02eStsutsui{ 385ba64b02eStsutsui int i; 386ab290810Stsutsui 387ba64b02eStsutsui if (argc_m1 < n) 388ba64b02eStsutsui parseError(argv[0]->line, "too few arguments to command `%s'", 389ba64b02eStsutsui argv[0]->content.symbol); 390ba64b02eStsutsui if (argc_m1 > n) 391ba64b02eStsutsui parseError(argv[0]->line, "too many arguments to command `%s'", 392ba64b02eStsutsui argv[0]->content.symbol); 393ba64b02eStsutsui for (i = 0; i < n; i++) { 394ba64b02eStsutsui if (argv[i+1]->type != type[i]) 395ba64b02eStsutsui parseError(argv[i+1]->line, 396ba64b02eStsutsui "type mismatch. argument %d to command `%s'", 397ba64b02eStsutsui i+1, argv[0]->content.symbol); 398ba64b02eStsutsui } 399ba64b02eStsutsui} 400ba64b02eStsutsui 401ba64b02eStsutsuitypedef struct _Mode { 402ba64b02eStsutsui struct _Mode *next; 40315b0c026Stsutsui const char *name; 404ba64b02eStsutsui int type; 405ba64b02eStsutsui int depth; 406ba64b02eStsutsui int class; 407ba64b02eStsutsui int width, height; 408ba64b02eStsutsui X68kFbReg reg; 409ba64b02eStsutsui} Mode; 410ba64b02eStsutsui 41115b0c026Stsutsuistatic Mode *modeList = NULL; 41215b0c026Stsutsuistatic Mode *modeChosen; 413ba64b02eStsutsui 414ba64b02eStsutsui/*------------------------------------------------------------------------- 415ba64b02eStsutsui * function "parseModeDef" 416ba64b02eStsutsui * 417ba64b02eStsutsui * purpose: define a mode 418ba64b02eStsutsui * argument: (int)argc, (Token **)argv : command and arguments 419ba64b02eStsutsui * returns: nothing 420ba64b02eStsutsui *-----------------------------------------------------------------------*/ 421ba64b02eStsutsuistatic void 422ba64b02eStsutsuiparseModeDef(int argc, Token **argv) 423ba64b02eStsutsui{ 42415b0c026Stsutsui const enum TokenType argtype[] = { 425ba64b02eStsutsui /* name type depth class */ 426ba64b02eStsutsui TOKEN_SYMBOL, TOKEN_SYMBOL, TOKEN_LITERAL, TOKEN_SYMBOL, 427ba64b02eStsutsui /* width height */ 428ba64b02eStsutsui TOKEN_LITERAL, TOKEN_LITERAL, 429ba64b02eStsutsui /* register values */ 430ba64b02eStsutsui TOKEN_LITERAL, TOKEN_LITERAL, TOKEN_LITERAL, TOKEN_LITERAL, 431ba64b02eStsutsui TOKEN_LITERAL, TOKEN_LITERAL, TOKEN_LITERAL, TOKEN_LITERAL, 432ba64b02eStsutsui TOKEN_LITERAL, TOKEN_LITERAL, TOKEN_LITERAL, TOKEN_LITERAL 433ba64b02eStsutsui }; 434ba64b02eStsutsui Mode *mode; 435ba64b02eStsutsui char *symbol; 43615b0c026Stsutsui int type, class, width, height; 437ab290810Stsutsui 438ba64b02eStsutsui checkArguments(18, argtype, argc-1, argv); 439ba64b02eStsutsui 440d998ab55Stsutsui mode = malloc(sizeof(Mode)); 441ba64b02eStsutsui if (mode == NULL) 442ba64b02eStsutsui FatalError("Out of memory"); 443ba64b02eStsutsui mode->name = strdup(argv[1]->content.symbol); 444ab290810Stsutsui 445ba64b02eStsutsui /* parse frame buffer type */ 446ba64b02eStsutsui symbol = argv[2]->content.symbol; 44715b0c026Stsutsui mode->type = X68K_FB_NULL; 44815b0c026Stsutsui for (type = 1; type < NTYPES; type++) { 44915b0c026Stsutsui if (strcasecmp(x68kTypeStr[type], symbol) == 0) { 45015b0c026Stsutsui mode->type = type; 45115b0c026Stsutsui break; 45215b0c026Stsutsui } 45315b0c026Stsutsui } 45415b0c026Stsutsui if (mode->type == X68K_FB_NULL) 45515b0c026Stsutsui parseError(argv[2]->line, "unknown frame buffer type `%s'", symbol); 45615b0c026Stsutsui 457ba64b02eStsutsui mode->depth = argv[3]->content.literal; 458ab290810Stsutsui 459ba64b02eStsutsui /* parse frame buffer class */ 460ba64b02eStsutsui symbol = argv[4]->content.symbol; 46115b0c026Stsutsui mode->class = ClassInvalid; 46215b0c026Stsutsui for (class = 0; class < NCLASSES; class++) { 46315b0c026Stsutsui if (strcasecmp(x68kClassStr[class], symbol) == 0) { 46415b0c026Stsutsui mode->class = class; 46515b0c026Stsutsui break; 46615b0c026Stsutsui } 46715b0c026Stsutsui } 46815b0c026Stsutsui if (mode->class == ClassInvalid) 46915b0c026Stsutsui parseError(argv[4]->line, "unknown frame buffer class `%s'", symbol); 47015b0c026Stsutsui 471ba64b02eStsutsui width = mode->width = argv[5]->content.literal; 472ba64b02eStsutsui height = mode->height = argv[6]->content.literal; 473ab290810Stsutsui 474ba64b02eStsutsui /* examine whether type, depth, class, width, and height are 475ba64b02eStsutsui a legal combination or not, and then set mode registers */ 47615b0c026Stsutsui switch (type) { 477ba64b02eStsutsui case X68K_FB_TEXT: 478ba64b02eStsutsui if (mode->depth == 1 && class == StaticGray && 479ba64b02eStsutsui width <= 1024 && height <= 1024) { 480ba64b02eStsutsui mode->reg.videoc.r1 = 0x21e4; 481ba64b02eStsutsui mode->reg.videoc.r2 = 0x0020; 482ba64b02eStsutsui goto legal; 483ba64b02eStsutsui } 484ba64b02eStsutsui break; 485ba64b02eStsutsui case X68K_FB_GRAPHIC: 486ba64b02eStsutsui switch (mode->depth) { 487ba64b02eStsutsui case 4: 488ba64b02eStsutsui if ( (class == StaticGray || class == PseudoColor) && 489ba64b02eStsutsui width <= 1024 && height <= 1024 ) { 490ba64b02eStsutsui mode->reg.videoc.r1 = 0x21e4; 491ba64b02eStsutsui mode->reg.videoc.r2 = 0x0010; 492ba64b02eStsutsui goto legal; 493ba64b02eStsutsui } 494ba64b02eStsutsui break; 495ba64b02eStsutsui case 8: 496ba64b02eStsutsui if (class == PseudoColor && 497ba64b02eStsutsui width <= 512 && height <= 512) { 498ba64b02eStsutsui mode->reg.videoc.r1 = 0x21e4; 499ba64b02eStsutsui mode->reg.videoc.r2 = 0x0003; 500ba64b02eStsutsui goto legal; 501ba64b02eStsutsui } 502ba64b02eStsutsui break; 503ba64b02eStsutsui case 15: 504ba64b02eStsutsui if (class == TrueColor && 505ba64b02eStsutsui width <= 512 && height <= 512) { 506ba64b02eStsutsui mode->reg.videoc.r1 = 0x21e4; 507ba64b02eStsutsui mode->reg.videoc.r2 = 0x000f; 508ba64b02eStsutsui goto legal; 509ba64b02eStsutsui } 510ba64b02eStsutsui break; 511ba64b02eStsutsui } 512ba64b02eStsutsui break; 513ba64b02eStsutsui } 514ba64b02eStsutsui parseError(argv[0]->line, "illegal combination of mode parameters"); 515ba64b02eStsutsui legal: 516ba64b02eStsutsui 517ba64b02eStsutsui /* store register values */ 518ba64b02eStsutsui mode->reg.crtc.r00 = argv[7]->content.literal; 519ba64b02eStsutsui mode->reg.crtc.r01 = argv[8]->content.literal; 520ba64b02eStsutsui mode->reg.crtc.r02 = argv[9]->content.literal; 521ba64b02eStsutsui mode->reg.crtc.r03 = argv[10]->content.literal; 522ba64b02eStsutsui mode->reg.crtc.r04 = argv[11]->content.literal; 523ba64b02eStsutsui mode->reg.crtc.r05 = argv[12]->content.literal; 524ba64b02eStsutsui mode->reg.crtc.r06 = argv[13]->content.literal; 525ba64b02eStsutsui mode->reg.crtc.r07 = argv[14]->content.literal; 526ba64b02eStsutsui mode->reg.crtc.r08 = argv[15]->content.literal; 527ba64b02eStsutsui mode->reg.crtc.r20 = argv[16]->content.literal; 528ba64b02eStsutsui mode->reg.videoc.r0 = argv[17]->content.literal; 529ba64b02eStsutsui mode->reg.dotClock = argv[18]->content.literal; 530ba64b02eStsutsui 531ba64b02eStsutsui /* set scroll registers to zero */ 532ba64b02eStsutsui mode->reg.crtc.r12 = 0; mode->reg.crtc.r13 = 0; 533ba64b02eStsutsui mode->reg.crtc.r14 = 0; mode->reg.crtc.r15 = 0; 534ba64b02eStsutsui mode->reg.crtc.r16 = 0; mode->reg.crtc.r17 = 0; 535ba64b02eStsutsui mode->reg.crtc.r18 = 0; mode->reg.crtc.r19 = 0; 536ab290810Stsutsui 537ba64b02eStsutsui /* add new mode to linked mode list */ 538ba64b02eStsutsui mode->next = modeList; 539ba64b02eStsutsui modeList = mode; 540ba64b02eStsutsui} 541ba64b02eStsutsui 542ba64b02eStsutsui/*------------------------------------------------------------------------- 543ba64b02eStsutsui * function "parseMode" 544ba64b02eStsutsui * 545ba64b02eStsutsui * purpose: choose a mode from predefined modes 546ba64b02eStsutsui * argument: (int)argc, (Token **)argv : command and arguments 547ba64b02eStsutsui * returns: nothing 548ba64b02eStsutsui *-----------------------------------------------------------------------*/ 549ba64b02eStsutsuistatic void 550ba64b02eStsutsuiparseMode(int argc, Token **argv) 551ba64b02eStsutsui{ 55215b0c026Stsutsui const enum TokenType argtype[]= { TOKEN_SYMBOL }; 553ba64b02eStsutsui Mode *mode; 554ba64b02eStsutsui 555ba64b02eStsutsui checkArguments(1, argtype, argc-1, argv); 556ba64b02eStsutsui 557ba64b02eStsutsui /* search mode to set from mode list */ 558ba64b02eStsutsui for (mode = modeList; mode != NULL; mode = mode->next) { 559ba64b02eStsutsui if (strcmp(mode->name, argv[1]->content.symbol) == 0) 560ba64b02eStsutsui break; 561ba64b02eStsutsui } 562ba64b02eStsutsui if (mode == NULL) 563ba64b02eStsutsui parseError(argv[1]->line, "undefined mode `%s'", 564ba64b02eStsutsui argv[1]->content.symbol); 565ba64b02eStsutsui 566ba64b02eStsutsui x68kScreen[0].type = mode->type; 567ba64b02eStsutsui x68kScreen[0].depth = mode->depth; 568ba64b02eStsutsui x68kScreen[0].class = mode->class; 569ba64b02eStsutsui x68kScreen[0].dpi = 75; 570ba64b02eStsutsui x68kScreen[0].x68kreg = mode->reg; 571ba64b02eStsutsui x68kScreen[0].scr_width = mode->width; 572ba64b02eStsutsui x68kScreen[0].scr_height = mode->height; 573ab290810Stsutsui 574ba64b02eStsutsui switch (mode->type) { 575ba64b02eStsutsui /* for TVRAM frame buffer */ 576ba64b02eStsutsui case X68K_FB_TEXT: 577ba64b02eStsutsui x68kFbProc[0].open = x68kTextOpen; 578ba64b02eStsutsui x68kFbProc[0].init = x68kTextInit; 579ba64b02eStsutsui x68kFbProc[0].close = x68kTextClose; 580ba64b02eStsutsui x68kScreen[0].fb_width = 1024; 581ba64b02eStsutsui x68kScreen[0].fb_height = 1024; 582ba64b02eStsutsui break; 583ba64b02eStsutsui /* for GVRAM frame buffer */ 584ba64b02eStsutsui case X68K_FB_GRAPHIC: 585ba64b02eStsutsui x68kFbProc[0].open = x68kGraphOpen; 586ba64b02eStsutsui x68kFbProc[0].init = x68kGraphInit; 587ba64b02eStsutsui x68kFbProc[0].close = x68kGraphClose; 588d998ab55Stsutsui x68kFormat = malloc (sizeof(PixmapFormatRec)); 589ba64b02eStsutsui x68kFormat->scanlinePad = BITMAP_SCANLINE_PAD; 590ba64b02eStsutsui x68kFormat->bitsPerPixel = 16; 591ba64b02eStsutsui switch (mode->depth) { 592ba64b02eStsutsui case 4: 593ba64b02eStsutsui x68kFormat->depth = 4; 594ba64b02eStsutsui x68kScreen[0].fb_width = 1024; 595ba64b02eStsutsui x68kScreen[0].fb_height = 1024; 596ba64b02eStsutsui break; 597ba64b02eStsutsui case 8: 598ba64b02eStsutsui x68kFormat->depth = 8; 599ba64b02eStsutsui x68kScreen[0].fb_width = 512; 600ba64b02eStsutsui x68kScreen[0].fb_height = 512; 601ba64b02eStsutsui break; 602ba64b02eStsutsui case 15: 603ba64b02eStsutsui x68kFormat->depth = 15; 604ba64b02eStsutsui x68kScreen[0].fb_width = 512; 605ba64b02eStsutsui x68kScreen[0].fb_height = 512; 606ba64b02eStsutsui } 607ba64b02eStsutsui } 608ba64b02eStsutsui modeSet = TRUE; 60915b0c026Stsutsui modeChosen = mode; 610ba64b02eStsutsui} 611ba64b02eStsutsui 612ba64b02eStsutsui/*------------------------------------------------------------------------- 613ba64b02eStsutsui * function "parseMouse" 614ba64b02eStsutsui * 615ba64b02eStsutsui * purpose: set mouse attribute. 616ba64b02eStsutsui * argument: (int)argc, (Token **)argv : command and arguments 617ba64b02eStsutsui * returns: nothing 618ba64b02eStsutsui *-----------------------------------------------------------------------*/ 619ba64b02eStsutsuistatic void 620ba64b02eStsutsuiparseMouse(int argc, Token **argv) 621ba64b02eStsutsui{ 62215b0c026Stsutsui const enum TokenType argtype[] = { TOKEN_SYMBOL }; 623ab290810Stsutsui 624ba64b02eStsutsui checkArguments(1, argtype, argc-1, argv); 625ba64b02eStsutsui /* only `standard' mouse allowed */ 626ba64b02eStsutsui if (strcasecmp("standard", argv[1]->content.symbol) != 0) 627ba64b02eStsutsui parseError(argv[1]->line, "unknown mouse type `%s'", 628ba64b02eStsutsui argv[1]->content.symbol); 629ba64b02eStsutsui} 630ba64b02eStsutsui 631ba64b02eStsutsui/*------------------------------------------------------------------------- 632ba64b02eStsutsui * function "parseKeyboard" 633ba64b02eStsutsui * 634ba64b02eStsutsui * purpose: select keyboard map 635ba64b02eStsutsui * argument: (int)argc, (Token **)argv : command and arguments 636ba64b02eStsutsui * returns: nothing 637ba64b02eStsutsui *-----------------------------------------------------------------------*/ 638ba64b02eStsutsuistatic void 639ba64b02eStsutsuiparseKeyboard(int argc, Token **argv) 640ba64b02eStsutsui{ 64115b0c026Stsutsui const enum TokenType argtype[] = { TOKEN_SYMBOL }; 642ab290810Stsutsui 643ba64b02eStsutsui checkArguments(1, argtype, argc-1, argv); 644ba64b02eStsutsui if (strcasecmp("standard", argv[1]->content.symbol) == 0) { 645ba64b02eStsutsui x68kKeySyms = &jisKeySyms; 6469decb2cdStsutsui x68kKbdType = X68K_KB_STANDARD; 647ba64b02eStsutsui } else if (strcasecmp("ascii", argv[1]->content.symbol) == 0) { 648ba64b02eStsutsui x68kKeySyms = &asciiKeySyms; 6499decb2cdStsutsui x68kKbdType = X68K_KB_ASCII; 650ab290810Stsutsui } else 651ba64b02eStsutsui parseError(argv[1]->line, "unknown keyboard type `%s'", 652ba64b02eStsutsui argv[1]->content.symbol); 653ba64b02eStsutsui} 654ba64b02eStsutsui 655ba64b02eStsutsui/*------------------------------------------------------------------------- 656ba64b02eStsutsui * function "parseError" 657ba64b02eStsutsui * 65815b0c026Stsutsui * purpose: print error message to log and stderr and abort Xserver. 65915b0c026Stsutsui * argument: (int)line : the line in which some error was detected 66015b0c026Stsutsui * (const char *)str : error message 661ba64b02eStsutsui * returns: nothing 662ba64b02eStsutsui *-----------------------------------------------------------------------*/ 66315b0c026Stsutsuistatic void 664ba64b02eStsutsuiparseError(int line, const char *str, ...) 665ba64b02eStsutsui{ 666ba64b02eStsutsui va_list arglist; 667ab290810Stsutsui 66815b0c026Stsutsui LogMessageVerb(X_ERROR, 0, "parse error in %s at line %d", 66915b0c026Stsutsui configFilename, line); 670ba64b02eStsutsui if (str != NULL) { 67115b0c026Stsutsui LogMessageVerb(X_NONE, 0, ":\n\t"); 672ba64b02eStsutsui va_start(arglist, str); 67315b0c026Stsutsui LogVMessageVerb(X_NONE, 0, str, arglist); 674ba64b02eStsutsui va_end(arglist); 67515b0c026Stsutsui } 67615b0c026Stsutsui LogMessageVerb(X_NONE, 0, "\n"); 67715b0c026Stsutsui FatalError("Error in X68k server config file. Exiting.\n"); 67815b0c026Stsutsui} 67915b0c026Stsutsui 68015b0c026Stsutsui/*------------------------------------------------------------------------- 68115b0c026Stsutsui * function "logConfig" 68215b0c026Stsutsui * 68315b0c026Stsutsui * purpose: print specified config settings to log. 68415b0c026Stsutsui * argument: nothing 68515b0c026Stsutsui * returns: nothing 68615b0c026Stsutsui *-----------------------------------------------------------------------*/ 68715b0c026Stsutsuistatic void 68815b0c026StsutsuilogConfig(void) 68915b0c026Stsutsui{ 69015b0c026Stsutsui 69115b0c026Stsutsui LogMessage(X_CONFIG, "Using specified mode: \"%s\"\n", modeChosen->name); 69215b0c026Stsutsui LogMessage(X_CONFIG, "Type: %s, Class: %s, Size: %dx%d, Depth: %d\n", 69315b0c026Stsutsui x68kTypeStr[modeChosen->type], x68kClassStr[modeChosen->class], 69415b0c026Stsutsui modeChosen->width, modeChosen->height, modeChosen->depth); 69515b0c026Stsutsui LogMessage(X_CONFIG, "Keyboard: %s\n", 6969decb2cdStsutsui x68kKbdType == X68K_KB_ASCII ? "ascii" : "standard"); 69715b0c026Stsutsui LogMessage(X_CONFIG, "Mouse: %s\n", "standard"); 698ba64b02eStsutsui} 699ba64b02eStsutsui 700ba64b02eStsutsui/* EOF x68kConfig.c */ 701