1/* 2 * Copyright 2011 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23/** \file spiceqxl_driver.c 24 * \author Alon Levy <alevy@redhat.com> 25 * 26 * most of the code is still in qxl_driver.c, but for clarity parts are moved 27 * here, and only used / compiled if XSPICE is defined 28 */ 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include "qxl.h" 34#include "spiceqxl_driver.h" 35 36#define SPICE_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 37 38#define QXL_MODE_EX(x_res, y_res) \ 39 QXL_MODE_16_32(x_res, y_res, 0), \ 40 QXL_MODE_16_32(y_res, x_res, 1), \ 41 QXL_MODE_16_32(x_res, y_res, 2), \ 42 QXL_MODE_16_32(y_res, x_res, 3) 43 44#define QXL_MODE_16_32(x_res, y_res, orientation) \ 45 QXL_MODE(x_res, y_res, 16, orientation), \ 46 QXL_MODE(x_res, y_res, 32, orientation) 47 48#define QXL_MODE(_x, _y, _b, _o) \ 49 { .x_res = _x, \ 50 .y_res = _y, \ 51 .bits = _b, \ 52 .stride = (_x) * (_b) / 8, \ 53 .x_mili = PIXEL_SIZE * (_x), \ 54 .y_mili = PIXEL_SIZE * (_y), \ 55 .orientation = _o, \ 56 } 57 58#define PIXEL_SIZE 0.2936875 //1280x1024 is 14.8" x 11.9" 59 60#define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1)) 61 62static QXLMode qxl_modes[] = { 63 QXL_MODE_EX(640, 480), 64 QXL_MODE_EX(800, 480), 65 QXL_MODE_EX(800, 600), 66 QXL_MODE_EX(832, 624), 67 QXL_MODE_EX(960, 640), 68 QXL_MODE_EX(1024, 600), 69 QXL_MODE_EX(1024, 768), 70 QXL_MODE_EX(1152, 864), 71 QXL_MODE_EX(1152, 870), 72 QXL_MODE_EX(1280, 720), 73 QXL_MODE_EX(1280, 760), 74 QXL_MODE_EX(1280, 768), 75 QXL_MODE_EX(1280, 800), 76 QXL_MODE_EX(1280, 960), 77 QXL_MODE_EX(1280, 1024), 78 QXL_MODE_EX(1360, 768), 79 QXL_MODE_EX(1366, 768), 80 QXL_MODE_EX(1400, 1050), 81 QXL_MODE_EX(1440, 900), 82 QXL_MODE_EX(1600, 900), 83 QXL_MODE_EX(1600, 1200), 84 QXL_MODE_EX(1680, 1050), 85 QXL_MODE_EX(1920, 1080), 86 QXL_MODE_EX(1920, 1200), 87 QXL_MODE_EX(1920, 1440), 88 QXL_MODE_EX(2048, 1536), 89 QXL_MODE_EX(2560, 1440), 90 QXL_MODE_EX(2560, 1600), 91 QXL_MODE_EX(3840, 1080), 92 QXL_MODE_EX(2560, 2048), 93 QXL_MODE_EX(2800, 2100), 94 QXL_MODE_EX(3200, 2400), 95 QXL_MODE_EX(5760, 1080), 96 QXL_MODE_EX(7680, 1080), 97 98}; 99 100 101// TODO - reuse code from qxl.c? 102void init_qxl_rom(qxl_screen_t* qxl, uint32_t rom_size) 103{ 104 QXLRom *rom = qxl->rom; 105 struct QXLModes *modes = (struct QXLModes *)(rom + 1); 106 uint32_t ram_header_size; 107 uint32_t num_pages; 108 uint32_t fb; 109 int i, m; 110 111 memset(rom, 0, rom_size); 112 113 rom->magic = QXL_ROM_MAGIC; 114 rom->id = 0; // TODO - multihead? 115 rom->log_level = 3; 116 rom->modes_offset = (sizeof(QXLRom)); 117 118 rom->slot_gen_bits = MEMSLOT_GENERATION_BITS; 119 rom->slot_id_bits = MEMSLOT_SLOT_BITS; 120 rom->slots_start = 0; 121 rom->slots_end = 1; 122 rom->n_surfaces = (NUM_SURFACES); 123 124 for (i = 0, m = 0; i < (SPICE_ARRAY_SIZE(qxl_modes)); i++) { 125 fb = qxl_modes[i].y_res * qxl_modes[i].stride; 126 if (fb > qxl->surface0_size) 127 continue; 128 129 modes->modes[m].id = m; 130 modes->modes[m].x_res = qxl_modes[i].x_res; 131 modes->modes[m].y_res = qxl_modes[i].y_res; 132 modes->modes[m].bits = qxl_modes[i].bits; 133 modes->modes[m].stride = qxl_modes[i].stride; 134 modes->modes[m].x_mili = qxl_modes[i].x_mili; 135 modes->modes[m].y_mili = qxl_modes[i].y_mili; 136 modes->modes[m].orientation = qxl_modes[i].orientation; 137 138 m++; 139 } 140 modes->n_modes = m; 141 142 ram_header_size = ALIGN(sizeof(struct QXLRam), 4096); 143 num_pages = qxl->vram_size; 144 num_pages -= ram_header_size; 145 num_pages -= qxl->surface0_size; 146 num_pages = num_pages / TARGET_PAGE_SIZE; 147 148 rom->draw_area_offset = 0; 149 rom->surface0_area_size = qxl->surface0_size; 150 rom->pages_offset = rom->surface0_area_size; 151 rom->num_pages = num_pages; 152 rom->ram_header_offset = qxl->vram_size - ram_header_size; 153 154 qxl->shadow_rom = *qxl->rom; // TODO - do we need this? 155} 156