1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
14
/* $Id: gdevvglb.c 8250 2007-09-25 13:31:24Z giles $ */
16
* This is a driver for 386 PCs using vgalib for graphics on the console
17
* display. Note that this driver only works with 16-color modes.
19
* Written by Sigfrid Lundberg, siglun@euler.teorekol.lu.se.
20
* Modified by Erik Talvola, talvola@gnu.ai.mit.edu
21
* Updated 9/28/96 by L. Peter Deutsch, ghost@aladdin.com: allow setting
22
* the display mode as a device parameter.
23
* Updated 2/13/97 by ghost@aladdin.com: make the device identify itself
25
* Updated 5/2/97 by ghost@aladdin.com: copy_mono computed some parameters
26
* before doing fit_copy.
27
* Update 1997-06-28 by ghost@aladdin.com: get_bits wasn't implemented.
39
typedef struct gx_device_vgalib {
44
#define vga_dev ((gx_device_vgalib *)dev)
46
#define XDPI 60 /* to get a more-or-less square aspect ratio */
49
#ifndef A4 /*Letter size */
50
#define YSIZE (20.0 * YDPI / 2.5)
51
#define XSIZE (8.5 / 11)*YSIZE /* 8.5 x 11 inch page, by default */
57
static dev_proc_open_device(vgalib_open);
58
static dev_proc_close_device(vgalib_close);
59
static dev_proc_map_rgb_color(vgalib_map_rgb_color);
60
static dev_proc_map_color_rgb(vgalib_map_color_rgb);
61
static dev_proc_fill_rectangle(vgalib_fill_rectangle);
62
static dev_proc_tile_rectangle(vgalib_tile_rectangle);
63
static dev_proc_copy_mono(vgalib_copy_mono);
64
static dev_proc_copy_color(vgalib_copy_color);
65
static dev_proc_get_bits(vgalib_get_bits);
66
static dev_proc_get_params(vgalib_get_params);
67
static dev_proc_put_params(vgalib_put_params);
69
const gx_device_vgalib gs_vgalib_device =
71
std_device_std_body(gx_device_vgalib, 0, "vgalib",
74
NULL, /* get_initial_matrix */
75
NULL, /* sync_output */
76
NULL, /* output_page */
80
vgalib_fill_rectangle,
81
vgalib_tile_rectangle,
84
NULL, /* draw_line (obsolete) */
88
NULL, /* map_cmyk_color */
89
NULL, /* get_xfont_procs */
90
NULL, /* get_xfont_device */
91
NULL, /* map_rgb_alpha_color */
92
gx_page_device_get_page_device
98
vgalib_open(gx_device * dev)
100
int VGAMODE = vga_dev->display_mode;
101
int width = dev->width, height = dev->height;
104
VGAMODE = vga_getdefaultmode();
106
vga_setmode(G640x480x16);
108
vga_setmode(VGAMODE);
111
width = vga_getxdim() + 1;
113
height = vga_getydim() + 1;
115
/*vgalib provides no facilities for finding out aspect ratios */
116
if (dev->y_pixels_per_inch == 1) {
117
dev->y_pixels_per_inch = height / 11.0;
118
dev->x_pixels_per_inch = dev->y_pixels_per_inch;
120
gx_device_set_width_height(dev, width, height);
122
/* Find out if the device supports color */
123
/* (default initialization is monochrome). */
124
/* We only recognize 16-color devices right now. */
125
if (vga_getcolors() > 1) {
128
static const gx_device_color_info vgalib_16color = dci_pc_4bit;
130
dev->color_info = vgalib_16color;
132
for (index = 0; index < 16; ++index) {
133
gx_color_value rgb[3];
135
(*dev_proc(dev, map_color_rgb)) (dev, (gx_color_index) index, rgb);
136
#define cv2pv(cv) ((cv) >> (gx_color_value_bits - 8))
137
vga_setpalette(index, cv2pv(rgb[0]), cv2pv(rgb[1]), cv2pv(rgb[2]));
145
vgalib_close(gx_device * dev)
151
static gx_color_index
152
vgalib_map_rgb_color(gx_device * dev, gx_color_value red,
153
gx_color_value green, gx_color_value blue)
155
return pc_4bit_map_rgb_color(dev, red, green, blue);
159
vgalib_map_color_rgb(gx_device * dev, gx_color_index index,
160
unsigned short rgb[3])
162
return pc_4bit_map_color_rgb(dev, index, rgb);
166
vgalib_tile_rectangle(gx_device * dev, const gx_tile_bitmap * tile,
167
int x, int y, int w, int h, gx_color_index czero,
168
gx_color_index cone, int px, int py)
170
if (czero != gx_no_color_index && cone != gx_no_color_index) {
171
vgalib_fill_rectangle(dev, x, y, w, h, czero);
172
czero = gx_no_color_index;
174
return gx_default_tile_rectangle(dev, tile, x, y, w, h, czero, cone, px,
179
vgalib_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
180
gx_color_index color)
184
fit_fill(dev, x, y, w, h);
185
vga_setcolor((int)color);
186
if ((w | h) > 3) { /* Draw larger rectangles as lines. */
188
for (i = y; i < y + h; ++i)
189
vga_drawline(x, i, x + w - 1, i);
191
for (j = x; j < x + w; ++j)
192
vga_drawline(j, y, j, y + h - 1);
193
} else { /* Draw small rectangles point-by-point. */
194
for (i = y; i < y + h; i++)
195
for (j = x; j < x + w; j++)
202
vgalib_copy_mono(gx_device * dev, const byte * base, int sourcex,
203
int raster, gx_bitmap_id id, int x, int y, int width,
204
int height, gx_color_index zero, gx_color_index one)
206
const byte *ptr_line;
207
int left_bit, dest_y, end_x;
211
fit_copy(dev, base, sourcex, raster, id, x, y, width, height);
212
ptr_line = base + (sourcex >> 3);
213
left_bit = 0x80 >> (sourcex & 7);
214
dest_y = y, end_x = x + width;
216
if (zero == gx_no_color_index) {
217
if (one == gx_no_color_index)
221
if (one == gx_no_color_index) {
224
} else { /* Pre-clear the rectangle to zero */
225
vgalib_fill_rectangle(dev, x, y, width, height, zero);
231
while (height--) { /* for each line */
232
const byte *ptr_source = ptr_line;
233
register int dest_x = x;
234
register int bit = left_bit;
236
while (dest_x < end_x) { /* for each bit in the line */
237
if ((*ptr_source ^ invert) & bit)
238
vga_drawpixel(dest_x, dest_y);
240
if ((bit >>= 1) == 0)
241
bit = 0x80, ptr_source++;
251
/* Copy a color pixel map. This is just like a bitmap, except that */
252
/* each pixel takes 4 bits instead of 1 when device driver has color. */
254
vgalib_copy_color(gx_device * dev, const byte * base, int sourcex,
255
int raster, gx_bitmap_id id, int x, int y,
256
int width, int height)
259
fit_copy(dev, base, sourcex, raster, id, x, y, width, height);
261
if (gx_device_has_color(dev)) { /* color device, four bits per pixel */
262
const byte *line = base + (sourcex >> 1);
263
int dest_y = y, end_x = x + width;
267
while (height--) { /* for each line */
268
const byte *source = line;
269
register int dest_x = x;
271
if (sourcex & 1) { /* odd nibble first */
272
int color = *source++ & 0xf;
275
vga_drawpixel(dest_x, dest_y);
278
/* Now do full bytes */
279
while (dest_x < end_x) {
280
int color = *source >> 4;
283
vga_drawpixel(dest_x, dest_y);
286
if (dest_x < end_x) {
287
color = *source++ & 0xf;
289
vga_drawpixel(dest_x, dest_y);
297
} else { /* monochrome device: one bit per pixel */
298
/* bitmap is the same as bgi_copy_mono: one bit per pixel */
299
vgalib_copy_mono(dev, base, sourcex, raster, id, x, y, width, height,
300
(gx_color_index) 0, (gx_color_index) 7);
306
/* Read bits back from the device. */
308
vgalib_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
313
int depth = dev->color_info.depth; /* 1 or 4 */
314
int mask = (1 << depth) - 1;
319
for (x = 0; x < dev->width; ++x) {
320
int color = vga_getpixel(x, y);
322
if ((left -= depth) < 0)
323
*dest++ = b, b = 0, left += 8;
324
b += (color & mask) << left;
331
/* Get/put the display mode parameter. */
333
vgalib_get_params(gx_device * dev, gs_param_list * plist)
335
int code = gx_default_get_params(dev, plist);
339
return param_write_int(plist, "DisplayMode", &vga_dev->display_mode);
342
vgalib_put_params(gx_device * dev, gs_param_list * plist)
346
int imode = vga_dev->display_mode;
347
const char *param_name;
349
switch (code = param_read_int(plist, (param_name = "DisplayMode"), &imode)) {
352
param_signal_error(plist, param_name, ecode);
360
code = gx_default_put_params(dev, plist);
364
if (imode != vga_dev->display_mode) {
367
vga_dev->display_mode = imode;
372
#ifdef GS_DEVS_SHARED
373
extern void gs_lib_register_device(const gx_device *dev);
377
gs_lib_register_device(&gs_vgalib_device);