source: libcaca/trunk/caca/driver_win32.c @ 539

Last change on this file since 539 was 539, checked in by Sam Hocevar, 15 years ago
  • Split caca/graphics.c into driver-specific files. Resize is currently broken, and event handling is not yet in the driver-specific files, but I will of course fix that later.
  • Property svn:keywords set to Id
File size: 7.2 KB
Line 
1/*
2 *  libcaca       ASCII-Art library
3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the Do What The Fuck You Want To
8 *  Public License, Version 2, as published by Sam Hocevar. See
9 *  http://sam.zoy.org/wtfpl/COPYING for more details.
10 */
11
12/** \file graphics.c
13 *  \version \$Id: driver_win32.c 539 2006-03-06 23:01:59Z sam $
14 *  \author Sam Hocevar <sam@zoy.org>
15 *  \brief Character drawing
16 *
17 *  This file contains character and string drawing functions.
18 */
19
20#include "config.h"
21
22#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
23#   include <inttypes.h>
24#else
25typedef unsigned int uint32_t;
26typedef unsigned char uint8_t;
27#endif
28
29#if defined(USE_WIN32)
30
31#include <windows.h>
32
33#include <stdio.h> /* BUFSIZ */
34#include <string.h>
35#include <stdlib.h>
36#if defined(HAVE_UNISTD_H)
37#   include <unistd.h>
38#endif
39#include <stdarg.h>
40
41#include "caca.h"
42#include "caca_internals.h"
43#include "cucul.h"
44#include "cucul_internals.h"
45
46/*
47 * Global variables
48 */
49
50static int const win32_fg_palette[] =
51{
52    0,
53    FOREGROUND_BLUE,
54    FOREGROUND_GREEN,
55    FOREGROUND_GREEN | FOREGROUND_BLUE,
56    FOREGROUND_RED,
57    FOREGROUND_RED | FOREGROUND_BLUE,
58    FOREGROUND_RED | FOREGROUND_GREEN,
59    FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
60    FOREGROUND_INTENSITY,
61    FOREGROUND_INTENSITY | FOREGROUND_BLUE,
62    FOREGROUND_INTENSITY | FOREGROUND_GREEN,
63    FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE,
64    FOREGROUND_INTENSITY | FOREGROUND_RED,
65    FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE,
66    FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN,
67    FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
68};
69
70static int const win32_bg_palette[] =
71{
72    0,
73    BACKGROUND_BLUE,
74    BACKGROUND_GREEN,
75    BACKGROUND_GREEN | BACKGROUND_BLUE,
76    BACKGROUND_RED,
77    BACKGROUND_RED | BACKGROUND_BLUE,
78    BACKGROUND_RED | BACKGROUND_GREEN,
79    BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE,
80    BACKGROUND_INTENSITY,
81    BACKGROUND_INTENSITY | BACKGROUND_BLUE,
82    BACKGROUND_INTENSITY | BACKGROUND_GREEN,
83    BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_BLUE,
84    BACKGROUND_INTENSITY | BACKGROUND_RED,
85    BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BLUE,
86    BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN,
87    BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
88};
89
90int win32_init_graphics(caca_t *);
91int win32_end_graphics(caca_t *);
92int win32_set_window_title(caca_t *, char const *);
93unsigned int win32_get_window_width(caca_t *);
94unsigned int win32_get_window_height(caca_t *);
95void win32_display(caca_t *);
96void win32_handle_resize(caca_t *);
97
98int win32_init_graphics(caca_t *kk)
99{
100    CONSOLE_CURSOR_INFO cci;
101    CONSOLE_SCREEN_BUFFER_INFO csbi;
102    COORD size;
103
104    /* This call is allowed to fail in case we already have a console */
105    AllocConsole();
106
107    kk->win32.hin = GetStdHandle(STD_INPUT_HANDLE);
108    kk->win32.hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
109                                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
110                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
111    if(kk->win32.hout == INVALID_HANDLE_VALUE)
112        return -1;
113
114    GetConsoleCursorInfo(kk->win32.hout, &cci);
115    cci.bVisible = FALSE;
116    SetConsoleCursorInfo(kk->win32.hout, &cci);
117
118    SetConsoleMode(kk->win32.hout, ENABLE_MOUSE_INPUT);
119
120    kk->win32.front =
121        CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
122                                  0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
123    if(!kk->win32.front || kk->win32.front == INVALID_HANDLE_VALUE)
124        return -1;
125
126    kk->win32.back =
127        CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
128                                  0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
129    if(!kk->win32.back || kk->win32.back == INVALID_HANDLE_VALUE)
130        return -1;
131
132    if(!GetConsoleScreenBufferInfo(kk->win32.hout, &csbi))
133        return -1;
134
135    /* Sample code to get the biggest possible window */
136    //size = GetLargestConsoleWindowSize(kk->win32.hout);
137    cucul_set_size(kk->qq, csbi.srWindow.Right - csbi.srWindow.Left + 1,
138                           csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
139    size.X = kk->qq->width;
140    size.Y = kk->qq->height;
141    SetConsoleScreenBufferSize(kk->win32.front, size);
142    SetConsoleScreenBufferSize(kk->win32.back, size);
143
144    SetConsoleMode(kk->win32.front, 0);
145    SetConsoleMode(kk->win32.back, 0);
146
147    GetConsoleCursorInfo(kk->win32.front, &cci);
148    cci.dwSize = 0;
149    cci.bVisible = FALSE;
150    SetConsoleCursorInfo(kk->win32.front, &cci);
151    SetConsoleCursorInfo(kk->win32.back, &cci);
152
153    SetConsoleActiveScreenBuffer(kk->win32.front);
154
155    kk->win32.buffer = malloc(kk->qq->width * kk->qq->height
156                               * sizeof(CHAR_INFO));
157    if(kk->win32.buffer == NULL)
158        return -1;
159
160    return 0;
161}
162
163int win32_end_graphics(caca_t *kk)
164{
165    SetConsoleActiveScreenBuffer(kk->win32.hout);
166    CloseHandle(kk->win32.back);
167    CloseHandle(kk->win32.front);
168
169    SetConsoleTextAttribute(kk->win32.hout, FOREGROUND_INTENSITY
170                                             | FOREGROUND_RED
171                                             | FOREGROUND_GREEN
172                                             | FOREGROUND_BLUE);
173    cci.bVisible = TRUE;
174    SetConsoleCursorInfo(kk->win32.hout, &cci);
175    CloseHandle(kk->win32.hout);
176
177    return 0;
178}
179
180int win32_set_window_title(caca_t *kk, char const *title)
181{
182    SetConsoleTitle(title);
183    return 0;
184}
185
186unsigned int win32_get_window_width(caca_t *kk)
187{
188    /* FIXME */
189
190    /* Fallback to a 6x10 font */
191    return kk->qq->width * 6;
192}
193
194unsigned int win32_get_window_height(caca_t *kk)
195{
196    /* FIXME */
197
198    /* Fallback to a 6x10 font */
199    return kk->qq->height * 10;
200}
201
202void win32_display(caca_t *kk)
203{
204    COORD size, pos;
205    SMALL_RECT rect;
206    unsigned int i;
207
208    /* Render everything to our back buffer */
209    for(i = 0; i < kk->qq->width * kk->qq->height; i++)
210    {
211        kk->win32.buffer[i].Char.AsciiChar = kk->qq->chars[i] & 0x7f;
212        kk->win32.buffer[i].Attributes =
213                win32_fg_palette[kk->qq->attr[i] & 0xf]
214                 | win32_bg_palette[kk->qq->attr[i] >> 4];
215    }
216
217    /* Blit the back buffer to the front buffer */
218    size.X = kk->qq->width;
219    size.Y = kk->qq->height;
220    pos.X = pos.Y = 0;
221    rect.Left = rect.Top = 0;
222    rect.Right = kk->qq->width - 1;
223    rect.Bottom = kk->qq->height - 1;
224    WriteConsoleOutput(kk->win32.front, kk->win32.buffer, size, pos, &rect);
225}
226
227void win32_handle_resize(caca_t *kk)
228{
229    unsigned int new_width, new_height;
230
231    new_width = kk->qq->width;
232    new_height = kk->qq->height;
233
234    /* Nothing to do here. */
235}
236
237/*
238 * Driver initialisation
239 */
240
241void win32_init_driver(caca_t *kk)
242{
243    kk->driver.driver = CACA_DRIVER_WIN32;
244
245    kk->driver.init_graphics = win32_init_graphics;
246    kk->driver.end_graphics = win32_end_graphics;
247    kk->driver.set_window_title = win32_set_window_title;
248    kk->driver.get_window_width = win32_get_window_width;
249    kk->driver.get_window_height = win32_get_window_height;
250    kk->driver.display = win32_display;
251    kk->driver.handle_resize = win32_handle_resize;
252}
253
254#endif /* USE_WIN32 */
255
Note: See TracBrowser for help on using the repository browser.