Просмотр исходного кода

* src/caca.c src/graphics.c src/io.c src/time.c:

+ Native win32 port.
tags/v0.99.beta14
Sam Hocevar sam 21 лет назад
Родитель
Сommit
85511793bf
7 измененных файлов: 300 добавлений и 13 удалений
  1. +2
    -1
      NOTES
  2. +8
    -0
      examples/cacaview.c
  3. +24
    -3
      src/caca.c
  4. +5
    -0
      src/caca_internals.h
  5. +193
    -3
      src/graphics.c
  6. +63
    -1
      src/io.c
  7. +5
    -5
      src/time.c

+ 2
- 1
NOTES Просмотреть файл

@@ -193,5 +193,6 @@ $Id$
o MS-DOS: all bright colours, bright backgrounds, and bright combinations
work using <conio.h>. No need to kludge anything.

o Win32: we use GetConsoleScreenBufferInfo etc.
o Win32: we use GetConsoleScreenBufferInfo etc. There is an interesting
tutorial here: http://www.adrianxw.dk/SoftwareSite/index.html


+ 8
- 0
examples/cacaview.c Просмотреть файл

@@ -34,6 +34,10 @@
# include <stdio.h>
#endif

#if defined(HAVE_SLEEP)
# include <windows.h>
#endif

#include "caca.h"

/* Local macros */
@@ -256,7 +260,11 @@ int main(int argc, char **argv)

if(!update)
{
#if defined(HAVE_USLEEP)
usleep(10000);
#elif defined(HAVE_SLEEP)
Sleep(10);
#endif
continue;
}



+ 24
- 3
src/caca.c Просмотреть файл

@@ -70,6 +70,10 @@ enum caca_driver _caca_driver;
static mmask_t oldmask;
#endif

#if defined(USE_WIN32)
static CONSOLE_CURSOR_INFO cci;
#endif

/** \brief Initialise \e libcaca.
*
* This function initialises internal \e libcaca structures and the backend
@@ -168,8 +172,19 @@ int caca_init(void)
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
{
/* Nothing to do */
printf("initialising win32 driver\n");
win32_hin = GetStdHandle(STD_INPUT_HANDLE);
win32_hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if(win32_hout == INVALID_HANDLE_VALUE)
return -1;

GetConsoleCursorInfo(win32_hout, &cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(win32_hout, &cci);

SetConsoleMode(win32_hout, ENABLE_MOUSE_INPUT);
}
else
#endif
@@ -391,7 +406,13 @@ void caca_end(void)
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
{
/* Nothing to do */
SetConsoleTextAttribute(win32_hout, FOREGROUND_INTENSITY
| FOREGROUND_RED
| FOREGROUND_GREEN
| FOREGROUND_BLUE);
cci.bVisible = TRUE;
SetConsoleCursorInfo(win32_hout, &cci);
CloseHandle(win32_hout);
}
else
#endif


+ 5
- 0
src/caca_internals.h Просмотреть файл

@@ -86,4 +86,9 @@ extern Window x11_window;
extern int x11_font_width, x11_font_height;
#endif

#if defined(USE_WIN32)
#include <windows.h>
extern HANDLE win32_hin, win32_hout;
#endif

#endif /* __CACA_INTERNALS_H__ */

+ 193
- 3
src/graphics.c Просмотреть файл

@@ -51,6 +51,9 @@
# include <X11/XKBlib.h>
# endif
#endif
#if defined(USE_WIN32)
# include <windows.h>
#endif

#if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME)
# include <inttypes.h>
@@ -61,6 +64,7 @@ typedef unsigned char uint8_t;
#include <stdio.h> /* BUFSIZ */
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>

#include "caca.h"
@@ -161,6 +165,53 @@ static Bool x11_detect_autorepeat;
#endif
#endif

#if defined(USE_WIN32)
static uint8_t *win32_char, *win32_attr;
HANDLE win32_hin, win32_hout;
static HANDLE win32_front, win32_back;
static CHAR_INFO *win32_buffer;

static int const win32_fg_palette[] =
{
0,
FOREGROUND_BLUE,
FOREGROUND_GREEN,
FOREGROUND_GREEN | FOREGROUND_BLUE,
FOREGROUND_RED,
FOREGROUND_RED | FOREGROUND_BLUE,
FOREGROUND_RED | FOREGROUND_GREEN,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
FOREGROUND_INTENSITY,
FOREGROUND_INTENSITY | FOREGROUND_BLUE,
FOREGROUND_INTENSITY | FOREGROUND_GREEN,
FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE,
FOREGROUND_INTENSITY | FOREGROUND_RED,
FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE,
FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN,
FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
};

static int const win32_bg_palette[] =
{
0,
BACKGROUND_BLUE,
BACKGROUND_GREEN,
BACKGROUND_GREEN | BACKGROUND_BLUE,
BACKGROUND_RED,
BACKGROUND_RED | BACKGROUND_BLUE,
BACKGROUND_RED | BACKGROUND_GREEN,
BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE,
BACKGROUND_INTENSITY,
BACKGROUND_INTENSITY | BACKGROUND_BLUE,
BACKGROUND_INTENSITY | BACKGROUND_GREEN,
BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_BLUE,
BACKGROUND_INTENSITY | BACKGROUND_RED,
BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BLUE,
BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN,
BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
};
#endif

static char *_caca_empty_line;
static char *_caca_scratch_line;

@@ -244,7 +295,12 @@ void caca_set_color(enum caca_color fgcolor, enum caca_color bgcolor)
#endif
#if defined(USE_X11)
case CACA_DRIVER_X11:
/* FIXME */
/* Nothing to do */
break;
#endif
#if defined(USE_WIN32)
case CACA_DRIVER_WIN32:
/* Nothing to do */
break;
#endif
default:
@@ -326,6 +382,12 @@ void caca_putchar(int x, int y, char c)
x11_char[x + y * _caca_width] = c;
x11_attr[x + y * _caca_width] = (_caca_bgcolor << 4) | _caca_fgcolor;
break;
#endif
#if defined(USE_WIN32)
case CACA_DRIVER_WIN32:
win32_char[x + y * _caca_width] = c;
win32_attr[x + y * _caca_width] = (_caca_bgcolor << 4) | _caca_fgcolor;
break;
#endif
default:
break;
@@ -345,10 +407,10 @@ void caca_putchar(int x, int y, char c)
*/
void caca_putstr(int x, int y, char const *s)
{
#if defined(USE_CONIO) | defined(USE_X11)
#if defined(USE_CONIO) | defined(USE_X11) | defined(USE_WIN32)
char *charbuf;
#endif
#if defined(USE_X11)
#if defined(USE_X11) | defined(USE_WIN32)
char *attrbuf;
#endif
unsigned int len;
@@ -414,6 +476,17 @@ void caca_putstr(int x, int y, char const *s)
*attrbuf++ = (_caca_bgcolor << 4) | _caca_fgcolor;
}
break;
#endif
#if defined(USE_WIN32)
case CACA_DRIVER_WIN32:
charbuf = win32_char + x + y * _caca_width;
attrbuf = win32_attr + x + y * _caca_width;
while(*s)
{
*charbuf++ = *s++;
*attrbuf++ = (_caca_bgcolor << 4) | _caca_fgcolor;
}
break;
#endif
default:
break;
@@ -734,6 +807,64 @@ int _caca_init_graphics(void)
DefaultScreen(x11_dpy)));
}
else
#endif
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
{
CONSOLE_CURSOR_INFO cci;
CONSOLE_SCREEN_BUFFER_INFO csbi;
COORD size;

win32_front = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
0, NULL,
CONSOLE_TEXTMODE_BUFFER, NULL);
if(!win32_front)
return -1;

win32_back = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
0, NULL,
CONSOLE_TEXTMODE_BUFFER, NULL);
if(!win32_back)
return -1;

if(!GetConsoleScreenBufferInfo(win32_hout, &csbi))
return -1;

_caca_width = csbi.srWindow.Right - csbi.srWindow.Left + 1;
_caca_height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;

size.X = _caca_width;
size.Y = _caca_height;
SetConsoleScreenBufferSize(win32_front, size);
SetConsoleScreenBufferSize(win32_back, size);

SetConsoleMode(win32_front, 0);
SetConsoleMode(win32_back, 0);

GetConsoleCursorInfo(win32_front, &cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(win32_front, &cci);
SetConsoleCursorInfo(win32_back, &cci);

SetConsoleActiveScreenBuffer(win32_front);

win32_char = malloc(_caca_width * _caca_height * sizeof(int));
if(win32_char == NULL)
return -1;

win32_attr = malloc(_caca_width * _caca_height * sizeof(int));
if(win32_attr == NULL)
{
free(win32_char);
return -1;
}

win32_buffer = malloc(sizeof(CHAR_INFO) * _caca_width * _caca_height);

memset(win32_char, 0, _caca_width * _caca_height * sizeof(int));
memset(win32_attr, 0, _caca_width * _caca_height * sizeof(int));
}
else
#endif
{
/* Dummy */
@@ -784,6 +915,17 @@ int _caca_end_graphics(void)
free(x11_attr);
}
else
#endif
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
{
SetConsoleActiveScreenBuffer(win32_hout);
CloseHandle(win32_back);
CloseHandle(win32_front);
free(win32_char);
free(win32_attr);
}
else
#endif
{
/* Dummy */
@@ -926,7 +1068,55 @@ void caca_refresh(void)
0, 0);
XFlush(x11_dpy);
}
else
#endif
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
{
COORD size, pos;
SMALL_RECT rect;
DWORD dummy;
unsigned int x, y, len;

/* Render everything to our back buffer */
for(y = 0; y < _caca_height; y++)
{
pos.X = 0;
pos.Y = y;
SetConsoleCursorPosition(win32_back, pos);

for(x = 0; x < _caca_width; x += len)
{
unsigned char *attr = win32_attr + x + y * _caca_width;

len = 1;
while(x + len < _caca_width && attr[len] == attr[0])
len++;

SetConsoleTextAttribute(win32_back,
win32_fg_palette[attr[0] & 0xf]
| win32_bg_palette[attr[0] >> 4]);

WriteConsole(win32_back, win32_char + x + y * _caca_width,
len, &dummy, NULL);
}
}

/* Blit the back buffer to the front buffer */
size.X = _caca_width;
size.Y = _caca_height;
pos.X = pos.Y = 0;
rect.Left = rect.Top = 0;
rect.Right = _caca_width - 1;
rect.Bottom = _caca_height - 1;
ReadConsoleOutput(win32_back, win32_buffer, size, pos, &rect);
WriteConsoleOutput(win32_front, win32_buffer, size, pos, &rect);
}
else
#endif
{
/* Dummy */
}

/* Wait until _caca_delay + time of last call */
ticks += _caca_getticks(&timer);


+ 63
- 1
src/io.c Просмотреть файл

@@ -56,14 +56,18 @@

static unsigned int _get_next_event(void);
static unsigned int _lowlevel_event(void);
#if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
static void _push_event(unsigned int);
static unsigned int _pop_event(void);
#endif

#if !defined(_DOXYGEN_SKIP_ME)
#define EVENTBUF_LEN 10
#endif
#if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
static unsigned int eventbuf[EVENTBUF_LEN];
static int events = 0;
#endif

#if !defined(_DOXYGEN_SKIP_ME)
/* If no new key was pressed after AUTOREPEAT_THRESHOLD usec, assume the
@@ -198,10 +202,14 @@ static unsigned int _get_next_event(void)

static unsigned int _lowlevel_event(void)
{
unsigned int event = _pop_event();
unsigned int event;

#if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
event = _pop_event();

if(event)
return event;
#endif

#if defined(USE_X11)
/* The X11 event check routine */
@@ -540,6 +548,58 @@ static unsigned int _lowlevel_event(void)
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
{
INPUT_RECORD rec;
DWORD num;

GetNumberOfConsoleInputEvents(win32_hin, &num);
if(num == 0)
return CACA_EVENT_NONE;

ReadConsoleInput(win32_hin, &rec, 1, &num);
if(rec.EventType == KEY_EVENT)
{
if(rec.Event.KeyEvent.bKeyDown)
event = CACA_EVENT_KEY_PRESS;
else
event = CACA_EVENT_KEY_RELEASE;

if(rec.Event.KeyEvent.uChar.AsciiChar)
return event | rec.Event.KeyEvent.uChar.AsciiChar;
}
else if(rec.EventType == MOUSE_EVENT)
{
if(rec.Event.MouseEvent.dwEventFlags == 0)
{
if(rec.Event.MouseEvent.dwButtonState & 0x01)
return CACA_EVENT_MOUSE_PRESS | 0x000001;

if(rec.Event.MouseEvent.dwButtonState & 0x02)
return CACA_EVENT_MOUSE_PRESS | 0x000002;
}
else if(rec.Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
{
return CACA_EVENT_MOUSE_MOTION
| (rec.Event.MouseEvent.dwMousePosition.X << 12)
| (rec.Event.MouseEvent.dwMousePosition.Y);
}
#if 0
else if(rec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)
{
cout << rec.Event.MouseEvent.dwMousePosition.X << "," <<
rec.Event.MouseEvent.dwMousePosition.Y << " " << flush;
}
else if(rec.Event.MouseEvent.dwEventFlags == MOUSE_WHEELED)
{
SetConsoleCursorPosition(hOut,
WheelWhere);
if(rec.Event.MouseEvent.dwButtonState & 0xFF000000)
cout << "Down" << flush;
else
cout << "Up " << flush;
}
#endif
}

return CACA_EVENT_NONE;
}
else
@@ -551,6 +611,7 @@ static unsigned int _lowlevel_event(void)
return CACA_EVENT_NONE;
}

#if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
static void _push_event(unsigned int event)
{
if(events == EVENTBUF_LEN)
@@ -574,4 +635,5 @@ static unsigned int _pop_event(void)

return event;
}
#endif


+ 5
- 5
src/time.c Просмотреть файл

@@ -58,8 +58,8 @@ unsigned int _caca_getticks(struct caca_timer *timer)
#if defined(HAVE_GETTIMEOFDAY)
struct timeval tv;
#elif defined(USE_WIN32)
static long long int freq = -1LL;
long long int usec;
static long long int freq = -1;
unsigned long long int usec;
#endif
unsigned int ticks = 0;
int new_sec, new_usec;
@@ -69,15 +69,15 @@ unsigned int _caca_getticks(struct caca_timer *timer)
new_sec = tv.tv_sec;
new_usec = tv.tv_usec;
#elif defined(USE_WIN32)
if(freq == -1LL)
if(freq == -1)
{
if(!QueryPerformanceFrequency((LARGE_INTEGER *)&freq))
freq = 0;
}

QueryPerformanceCounter((LARGE_INTEGER *)&usec);
new_sec = usec / freq;
new_usec = usec % freq;
new_sec = usec * 1000000 / freq / 1000000;
new_usec = (usec * 1000000 / freq) % 1000000;
#endif

if(timer->last_sec != 0)


Загрузка…
Отмена
Сохранить