[SDL2] Add video subsystem

This commit is contained in:
Arnav Bhatt 2024-09-27 01:10:35 +05:30
parent 6fc6f9cc87
commit e32aec84d6
17 changed files with 965 additions and 6 deletions

View File

@ -20,7 +20,7 @@ audio_OBJS = src/audio/SDL_audio.o src/audio/SDL_audiocvt.o \
src/audio/SDL_mixer.o src/audio/SDL_wave.o \
src/audio/kolibri/SDL_kolibriaudio.o
cpuinfo_OBJS = zsrc/cpuinfo/SDL_cpuinfo.o
cpuinfo_OBJS = src/cpuinfo/SDL_cpuinfo.o
events_OBJS = src/events/imKStoUCS.o src/events/SDL_clipboardevents.o \
src/events/SDL_displayevents.o src/events/SDL_dropevents.o \
@ -83,8 +83,9 @@ video_OBJS = src/video/SDL_blit_0.o src/video/SDL_blit_1.o src/video/SDL_blit_A.
src/video/SDL_shape.o src/video/SDL_stretch.o src/video/SDL_surface.o \
src/video/SDL_video.o src/video/SDL_yuv.o src/video/yuv2rgb/yuv_rgb_lsx.o \
src/video/yuv2rgb/yuv_rgb_sse.o src/video/yuv2rgb/yuv_rgb_std.o \
src/video/dummy/SDL_nullevents.o src/video/dummy/SDL_nullframebuffer.o \
src/video/dummy/SDL_nullvideo.o
src/video/kolibri/SDL_kolibrievents.o src/video/kolibri/SDL_kolibriframebuffer.o \
src/video/kolibri/SDL_kolibrivideo.o src/video/kolibri/SDL_kolibriwindow.o \
src/video/kolibri/SDL_kolibrimouse.o src/video/kolibri/SDL_kolibriclipboard.o
curr_OBJS = src/SDL_assert.o src/SDL_dataqueue.o src/SDL_error.o src/SDL_guid.o \
src/SDL_hints.o src/SDL_list.o src/SDL_log.o src/SDL_utils.o src/SDL.o

View File

@ -113,8 +113,8 @@
/* Enable the Kolibri timer driver (src/timer/kolibri/\*.c) */
#define SDL_TIMER_KOLIBRI 1
/* Enable the dummy video driver (src/video/dummy/\*.c) */
#define SDL_VIDEO_DRIVER_DUMMY 1
/* Enable the Kolibri video driver (src/video/kolibri/\*.c) */
#define SDL_VIDEO_DRIVER_KOLIBRI 1
/* Enable the Kolibri filesystem driver (src/filesystem/kolibri/\*.c) */
#define SDL_FILESYSTEM_KOLIBRI 1

View File

@ -148,7 +148,8 @@ typedef enum
SDL_SYSWM_OS2,
SDL_SYSWM_HAIKU,
SDL_SYSWM_KMSDRM,
SDL_SYSWM_RISCOS
SDL_SYSWM_RISCOS,
SDL_SYSWM_KOLIBRI
} SDL_SYSWM_TYPE;
/**

View File

@ -484,6 +484,7 @@ extern VideoBootStrap OFFSCREEN_bootstrap;
extern VideoBootStrap NGAGE_bootstrap;
extern VideoBootStrap OS2DIVE_bootstrap;
extern VideoBootStrap OS2VMAN_bootstrap;
extern VideoBootStrap KOLIBRI_bootstrap;
/* Use SDL_OnVideoThread() sparingly, to avoid regressions in use cases that currently happen to work */
extern SDL_bool SDL_OnVideoThread(void);

View File

@ -144,6 +144,9 @@ static VideoBootStrap *bootstrap[] = {
#ifdef SDL_INPUT_LINUXEV
&DUMMY_evdev_bootstrap,
#endif
#endif
#ifdef SDL_VIDEO_DRIVER_KOLIBRI
&KOLIBRI_bootstrap,
#endif
NULL
};

View File

@ -0,0 +1,60 @@
#include "../../SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_KOLIBRI
#include <sys/ksys.h>
#define string_length(x) SDL_strlen(x) + 1
#include "../SDL_sysvideo.h"
char *KOLIBRI_GetClipboardText(_THIS)
{
int clip_num = _ksys_clip_num();
char *clip_buf, *result;
if (clip_num > 0) {
clip_buf = _ksys_clip_get(clip_num - 1);
if ((int)*clip_buf > 0 && (int)*(clip_buf + 4) == KSYS_CLIP_TEXT && ((int)*(clip_buf + 8) == KSYS_CLIP_CP866)) {
char *clip_text = clip_buf + 12;
result = SDL_calloc((int)*clip_buf, sizeof(char));
SDL_strlcpy(result, clip_text, (int)*clip_buf);
_ksys_free(clip_buf);
}
}
if (!result)
result = SDL_strdup("");
return result;
}
int KOLIBRI_SetClipboardText(_THIS, const char *text)
{
char *temp_buffer = SDL_calloc(string_length(text) + 12, sizeof(char));
*temp_buffer = string_length(text);
*(temp_buffer + 4) = KSYS_CLIP_TEXT;
*(temp_buffer + 8) = KSYS_CLIP_CP866;
SDL_strlcpy(temp_buffer + 12, text, string_length(text));
_ksys_clip_set(string_length(text) + 12, temp_buffer);
SDL_free(temp_buffer);
return 0;
}
SDL_bool KOLIBRI_HasClipboardText(_THIS)
{
SDL_bool result = SDL_FALSE;
char *text = KOLIBRI_GetClipboardText(_this);
if (text) {
result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE;
SDL_free(text);
}
return result;
}
#endif /* SDL_VIDEO_DRIVER_KOLIBRI */

View File

@ -0,0 +1,11 @@
#include "../../SDL_internal.h"
#ifndef SDL_kolibriclipboard_h_
#define SDL_kolibriclipboard_h_
char *KOLIBRI_GetClipboardText(_THIS);
int KOLIBRI_SetClipboardText(_THIS, const char *text);
SDL_bool KOLIBRI_HasClipboardText(_THIS);
#endif /* SDL_kolibriclipboard_h_ */

View File

@ -0,0 +1,277 @@
#include "../../SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_KOLIBRI
#include <sys/ksys.h>
#include "SDL.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../SDL_sysvideo.h"
#include "SDL_kolibrievents.h"
#include "SDL_kolibrivideo.h"
#include "SDL_kolibriwindow.h"
static SDL_Keycode sdlkeys[0x80] = {
// 0x0*
0, SDLK_ESCAPE, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6,
SDLK_7, SDLK_8, SDLK_9, SDLK_0, SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSPACE, SDLK_TAB,
// 0x1*
SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i,
SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, SDLK_RETURN, SDLK_LCTRL, SDLK_a, SDLK_s,
// 0x2*
SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_SEMICOLON,
SDLK_QUOTE, SDLK_BACKQUOTE, SDLK_LSHIFT, SDLK_BACKSLASH, SDLK_z, SDLK_x, SDLK_c, SDLK_v,
// 0x3*
SDLK_b, SDLK_n, SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_RSHIFT, SDLK_KP_MULTIPLY,
SDLK_LALT, SDLK_SPACE, SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5,
// 0x4*
SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCKCLEAR, SDLK_SCROLLLOCK, SDLK_KP_7,
SDLK_KP_8, SDLK_KP_9, SDLK_KP_MINUS, SDLK_KP_4, SDLK_KP_5, SDLK_KP_6, SDLK_KP_PLUS, SDLK_KP_1,
// 0x5*
SDLK_KP_2, SDLK_KP_3, SDLK_KP_0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11,
SDLK_F12, 0, 0, 0, 0, 0, 0, 0,
// 0x6*
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// 0x7*
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static SDL_Keycode sdlkeys_shift[0x80] = {
// 0x0*
0, SDLK_ESCAPE, SDLK_EXCLAIM, SDLK_AT, SDLK_HASH, SDLK_DOLLAR, '%', SDLK_CARET,
SDLK_AMPERSAND, SDLK_ASTERISK, SDLK_LEFTPAREN, SDLK_RIGHTPAREN, SDLK_UNDERSCORE, SDLK_PLUS, SDLK_BACKSPACE, SDLK_TAB,
// 0x1*
SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i,
SDLK_o, SDLK_p, '{', '}', SDLK_RETURN, SDLK_LCTRL, SDLK_a, SDLK_s,
// 0x2*
SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_COLON,
SDLK_QUOTEDBL, '~', SDLK_LSHIFT, '|', SDLK_z, SDLK_x, SDLK_c, SDLK_v,
// 0x3*
SDLK_b, SDLK_n, SDLK_m, SDLK_LESS, SDLK_GREATER, SDLK_QUESTION, SDLK_RSHIFT, SDLK_KP_MULTIPLY,
SDLK_LALT, SDLK_SPACE, SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5,
// 0x4*
SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCKCLEAR, SDLK_SCROLLLOCK, SDLK_KP_7,
SDLK_KP_8, SDLK_KP_9, SDLK_KP_MINUS, SDLK_KP_4, SDLK_KP_5, SDLK_KP_6, SDLK_KP_PLUS, SDLK_KP_1,
// 0x5*
SDLK_KP_2, SDLK_KP_3, SDLK_KP_0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11,
SDLK_F12, 0, 0, 0, 0, 0, 0, 0,
// 0x6*
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// 0x7*
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static SDL_Keycode sdlkeys_e0[0x80] = {
// 0x0*
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// 0x1*
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, SDLK_KP_ENTER, SDLK_RCTRL, 0, 0,
// 0x2*
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// 0x3*
0, 0, 0, 0, 0, SDLK_KP_DIVIDE, 0, SDLK_PRINTSCREEN,
SDLK_RALT, 0, 0, 0, 0, 0, 0, 0,
// 0x4*
0, 0, 0, 0, 0, 0, 0, SDLK_HOME,
SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END,
// 0x5*
SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0,
0, 0, 0, 0, 0, SDLK_MENU, 0, 0,
// 0x6*
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// 0x7*
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static SDL_Keymod KOLIBRI_get_mod_state(void)
{
unsigned controlstate = _ksys_get_control_key_state();
SDL_Keymod res = 0;
if (controlstate & KSYS_CONTROL_LSHIFT)
res |= KMOD_LSHIFT;
if (controlstate & KSYS_CONTROL_RSHIFT)
res |= KMOD_RSHIFT;
if (controlstate & KSYS_CONTROL_LCTRL)
res |= KMOD_LCTRL;
if (controlstate & KSYS_CONTROL_RCTRL)
res |= KMOD_RCTRL;
if (controlstate & KSYS_CONTROL_LALT)
res |= KMOD_LALT;
if (controlstate & KSYS_CONTROL_RALT)
res |= KMOD_RALT;
if (controlstate & KSYS_CONTROL_CAPS)
res |= KMOD_CAPS;
if (controlstate & KSYS_CONTROL_NUM_LOCK)
res |= KMOD_NUM;
return res;
}
void KOLIBRI_InitOSKeymap(void)
{
_ksys_set_key_input_mode(KSYS_KEY_INPUT_MODE_SCANC);
}
void KOLIBRI_PumpEvents(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
SDL_Window *window = SDL_GetWindowFromID(data->window_id);
SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
uint32_t kos_event;
ksys_pos_t mouse_pos;
ksys_pos_t center_pos;
ksys_thread_t thread_info;
int top = 0;
int scancode = 0;
int pressed = 0;
int win_size_w, win_size_h;
SDL_Keycode keycode = SDLK_UNKNOWN;
SDL_Keymod mod = 0;
static int ext_code = 0;
static uint8_t old_mode = 0;
static uint32_t old_mouse_but = 0;
static SDL_bool restored = SDL_TRUE;
while (1) {
kos_event = _ksys_check_event();
switch (kos_event) {
case KSYS_EVENT_NONE:
return;
case KSYS_EVENT_REDRAW:
{
_ksys_thread_info(&thread_info, KSYS_THIS_SLOT);
win_size_w = thread_info.winx_size + 1;
win_size_h = thread_info.winy_size + 1;
if (wdata->skin != 0x01) {
win_size_w -= TRUE_WIN_WIDTH;
win_size_h -= TRUE_WIN_HEIGHT;
}
if (thread_info.winx_start != window->x || thread_info.winy_start != window->y)
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, thread_info.winx_start, thread_info.winy_start);
if (win_size_w != window->w || win_size_h != window->h)
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, win_size_w, win_size_h);
if (thread_info.window_state & 0x01) {
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
restored = SDL_FALSE;
} else if (thread_info.window_state & 0x02) {
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
restored = SDL_FALSE;
} else if (!restored) {
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
restored = SDL_TRUE;
}
KOLIBRI_RepaintWnd(_this);
break;
}
case KSYS_EVENT_KEY:
scancode = _ksys_get_key().code;
if (scancode == 0xE0 || scancode == 0xE1) {
ext_code = scancode;
break;
}
if (ext_code == 0xE1 && (scancode & 0x7F) == 0x1D) {
break;
}
if (ext_code == 0xE1 && scancode == 0xC5) {
ext_code = 0;
break;
}
mod = KOLIBRI_get_mod_state();
if (ext_code == 0xE1)
mod &= ~KMOD_CTRL;
if (!(scancode & 0x80))
old_mode = mod;
SDL_SetModState(mod);
pressed = (scancode & 0x80) ? SDL_RELEASED : SDL_PRESSED;
scancode &= 0x7F;
if (ext_code == 0xE1 && scancode == 0x45)
keycode = SDLK_PAUSE;
else if (ext_code == 0xE0)
keycode = sdlkeys_e0[scancode];
else if (old_mode & KMOD_SHIFT)
keycode = sdlkeys_shift[scancode];
else
keycode = sdlkeys[scancode];
ext_code = 0;
if (!keycode)
break;
SDL_SendKeyboardKey(pressed, SDL_GetScancodeFromKey(keycode));
break;
case KSYS_EVENT_BUTTON:
if (_ksys_get_button() == 1) {
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0, 0);
exit(0);
}
break;
case KSYS_EVENT_MOUSE:
{
mouse_pos = _ksys_get_mouse_pos(KSYS_MOUSE_WINDOW_POS);
if (mouse_pos.x >= 0 && mouse_pos.x < window->w && mouse_pos.y >= 0 && mouse_pos.y < window->h || SDL_GetMouse()->relative_mode) {
if (SDL_GetMouse()->relative_mode) {
center_pos.x = mouse_pos.x - (window->w / 2);
center_pos.y = mouse_pos.y - (window->h / 2);
SDL_SendMouseMotion(window, 0, SDL_TRUE, center_pos.x, center_pos.y);
top = _ksys_thread_info(&thread_info, KSYS_THIS_SLOT);
if (top == thread_info.pos_in_window_stack) {
int x = thread_info.winx_start + thread_info.clientx + (window->w / 2);
int y = thread_info.winy_start + thread_info.clienty + (window->h / 2);
_ksys_set_mouse_pos(x, y);
}
} else
SDL_SendMouseMotion(window, 0, SDL_FALSE, mouse_pos.x, mouse_pos.y);
uint32_t mouse_but = _ksys_get_mouse_buttons();
if ((mouse_but ^ old_mouse_but) & KSYS_MOUSE_LBUTTON_PRESSED) {
if (mouse_but & KSYS_MOUSE_LBUTTON_PRESSED)
SDL_SendMouseButton(window, 0, SDL_PRESSED, SDL_BUTTON_LEFT);
else
SDL_SendMouseButton(window, 0, SDL_RELEASED, SDL_BUTTON_LEFT);
}
if ((mouse_but ^ old_mouse_but) & KSYS_MOUSE_RBUTTON_PRESSED) {
if (mouse_but & KSYS_MOUSE_RBUTTON_PRESSED)
SDL_SendMouseButton(window, 0, SDL_PRESSED, SDL_BUTTON_RIGHT);
else
SDL_SendMouseButton(window, 0, SDL_RELEASED, SDL_BUTTON_RIGHT);
}
if ((mouse_but ^ old_mouse_but) & KSYS_MOUSE_MBUTTON_PRESSED) {
if (mouse_but & KSYS_MOUSE_MBUTTON_PRESSED)
SDL_SendMouseButton(window, 0, SDL_PRESSED, SDL_BUTTON_MIDDLE);
else
SDL_SendMouseButton(window, 0, SDL_RELEASED, SDL_BUTTON_MIDDLE);
}
old_mouse_but = mouse_but;
}
}
}
}
}
#endif /* SDL_VIDEO_DRIVER_KOLIBRI */

View File

@ -0,0 +1,10 @@
#ifndef SDL_kolibrievents_h_
#define SDL_kolibrievents_h_
#include "../../SDL_internal.h"
void KOLIBRI_InitOSKeymap(void);
void KOLIBRI_PumpEvents(_THIS);
#endif /* SDL_kolibrievents_h_ */

View File

@ -0,0 +1,79 @@
#include "../../SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_KOLIBRI
#include <sys/ksys.h>
#include "SDL.h"
#include "../SDL_sysvideo.h"
#include "SDL_kolibriframebuffer.h"
#include "SDL_kolibrivideo.h"
#include "SDL_kolibriwindow.h"
void FreeOldFramebuffer(SDL_Window *window)
{
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
SDL_FreeSurface(data->surface);
}
int KOLIBRI_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
{
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
SDL_Surface *surface;
const Uint32 surface_format = SDL_PIXELFORMAT_BGR24;
int w, h;
/* Free the old framebuffer surface */
FreeOldFramebuffer(window);
/* Create a new one */
SDL_GetWindowSizeInPixels(window, &w, &h);
surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, surface_format);
if (!surface)
return -1;
/* Save the info and return! */
data->surface = surface;
*format = surface_format;
*pixels = surface->pixels;
*pitch = surface->pitch;
#ifdef DEBUG_VIDEO
char *info;
SDL_asprintf(&info, "width = %d, height = %d, pitch = %d, bpp = %d\n", window->w,
window->h, surface->pitch, surface_format);
_ksys_debug_puts(info);
SDL_free(info);
#endif
return 0;
}
int KOLIBRI_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects)
{
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
SDL_Surface *surface;
static int frame_number;
surface = data->surface;
if (!surface)
return SDL_SetError("Couldn't find surface for window");
/* Send the data to the display */
_ksys_draw_bitmap(surface->pixels, 0, 0, surface->w, surface->h);
}
void KOLIBRI_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
{
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
SDL_Surface *surface;
SDL_FreeSurface(data->surface);
data->surface = NULL;
}
#endif /* SDL_VIDEO_DRIVER_KOLIBRI */

View File

@ -0,0 +1,11 @@
#include "../../SDL_internal.h"
#ifndef SDL_kolibriframebuffer_h_
#define SDL_kolibriframebuffer_h_
int KOLIBRI_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch);
int KOLIBRI_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects);
void KOLIBRI_DestroyWindowFramebuffer(_THIS, SDL_Window *window);
#endif /* SDL_kolibriframebuffer_h_ */

View File

@ -0,0 +1,173 @@
#include "../../SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_KOLIBRI
#include <sys/ksys.h>
#include "SDL_events.h"
#include "SDL_hints.h"
#include "SDL_surface.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/default_cursor.h"
#include "../SDL_sysvideo.h"
#include "SDL_kolibrimouse.h"
#include "SDL_kolibrivideo.h"
static SDL_Cursor *KOLIBRI_CreateDefaultCursor(void)
{
KOLIBRI_CursorData *curdata;
SDL_Cursor *cursor;
Uint32 *temp;
cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
if (!cursor) {
SDL_OutOfMemory();
return NULL;
}
curdata = (KOLIBRI_CursorData *)SDL_calloc(1, sizeof(*curdata));
if (!curdata) {
SDL_OutOfMemory();
SDL_free(cursor);
return NULL;
}
/* Convert default SDL cursor to 32x32 */
temp = (Uint32 *)SDL_malloc(32 * 32 * 4);
if (!temp) {
SDL_OutOfMemory();
SDL_free(cursor);
return NULL;
}
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 32; j++) {
if (i >= 16 || j >= 16) {
temp[i * 32 + j] = 0x00000000;
continue;
}
if (default_cmask[i * 16 / 8 + j / 8] & (0x80 >> (j & 7)))
temp[i * 32 + j] = (default_cdata[i * 16 / 8 + j / 8] & (0x80 >> (j & 7)))
? 0xFF000000
: 0xFFFFFFFF;
else
temp[i * 32 + j] = 0x00000000;
}
}
curdata->cursor = _ksys_load_cursor(temp, (DEFAULT_CHOTX << 24) + (DEFAULT_CHOTY << 16) + KSYS_CURSOR_INDIRECT);
cursor->driverdata = curdata;
SDL_free(temp);
return cursor;
}
/* Create a cursor from a surface */
static SDL_Cursor *KOLIBRI_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
{
KOLIBRI_CursorData *curdata;
SDL_Cursor *cursor;
int i, j;
/* Size of cursor must be 32x32 */
if (surface->w == 32 || surface->h == 32) {
SDL_SetError("Size of the cursor must be 32x32");
return NULL;
}
cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
if (!cursor) {
SDL_OutOfMemory();
return NULL;
}
curdata = (KOLIBRI_CursorData *)SDL_calloc(1, sizeof(*curdata));
if (!curdata) {
SDL_OutOfMemory();
SDL_free(cursor);
return NULL;
}
curdata->cursor = _ksys_load_cursor(surface->pixels, (hot_x << 24) + (hot_y << 16) + KSYS_CURSOR_INDIRECT);
cursor->driverdata = curdata;
return cursor;
}
static int KOLIBRI_ShowCursor(SDL_Cursor *cursor)
{
KOLIBRI_CursorData *curdata;
if (cursor) {
curdata = (KOLIBRI_CursorData *)cursor->driverdata;
_ksys_set_cursor(curdata->cursor);
}
return 0;
}
static void KOLIBRI_FreeCursor(SDL_Cursor *cursor)
{
KOLIBRI_CursorData *curdata;
if (cursor) {
curdata = (KOLIBRI_CursorData *)cursor->driverdata;
if (curdata) {
if (curdata->cursor)
_ksys_delete_cursor(curdata->cursor);
if (curdata->has_null_cursor)
_ksys_delete_cursor(curdata->null_cursor);
SDL_free(curdata);
}
SDL_free(cursor);
}
}
static int KOLIBRI_SetRelativeMouseMode(SDL_bool enabled)
{
SDL_Window *window = SDL_GetMouseFocus();
SDL_Cursor *cursor = SDL_GetCursor();
KOLIBRI_CursorData *curdata;
if (!window || !cursor) {
return 0;
}
if (enabled) {
ksys_thread_t thread_info;
int top = _ksys_thread_info(&thread_info, KSYS_THIS_SLOT);
unsigned *u = SDL_calloc(32 * 32, 1);
if (!u)
return 0;
curdata->null_cursor = _ksys_load_cursor(u, KSYS_CURSOR_INDIRECT);
SDL_free(u);
curdata->has_null_cursor = 1;
_ksys_set_cursor(curdata->null_cursor);
if (top == thread_info.pos_in_window_stack) {
int x = thread_info.winx_start + thread_info.clientx + (window->w / 2);
int y = thread_info.winy_start + thread_info.clienty + (window->h / 2);
_ksys_set_mouse_pos(x, y);
}
} else {
curdata->has_null_cursor = 0;
_ksys_delete_cursor(curdata->null_cursor);
}
return 0;
}
void KOLIBRI_InitMouse(void)
{
SDL_Mouse *mouse = SDL_GetMouse();
mouse->CreateCursor = KOLIBRI_CreateCursor;
mouse->ShowCursor = KOLIBRI_ShowCursor;
mouse->FreeCursor = KOLIBRI_FreeCursor;
mouse->SetRelativeMouseMode = KOLIBRI_SetRelativeMouseMode;
SDL_SetDefaultCursor(KOLIBRI_CreateDefaultCursor());
}
#endif /* SDL_VIDEO_DRIVER_KOLIBRI */

View File

@ -0,0 +1,16 @@
#include "../../SDL_internal.h"
#ifndef SDL_kolibrimouse_h_
#define SDL_kolibrimouse_h_
typedef struct _KOLIBRI_CursorData
{
int has_null_cursor;
void *cursor;
void *null_cursor;
} KOLIBRI_CursorData;
void KOLIBRI_InitMouse(void);
#endif /* SDL_kolibrimouse_h_ */

View File

@ -0,0 +1,125 @@
#include "../../SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_KOLIBRI
#include <sys/ksys.h>
#include "../../events/SDL_events_c.h"
#include "../SDL_pixels_c.h"
#include "../SDL_sysvideo.h"
#include "SDL_video.h"
#include "SDL_kolibriclipboard.h"
#include "SDL_kolibrievents.h"
#include "SDL_kolibriframebuffer.h"
#include "SDL_kolibrimouse.h"
#include "SDL_kolibrivideo.h"
#include "SDL_kolibriwindow.h"
#define KOLIBRIVID_DRIVER_NAME "kolibri"
static void KOLIBRI_DeleteDevice(SDL_VideoDevice *device)
{
SDL_free(device->driverdata);
SDL_free(device);
}
int KOLIBRI_VideoInit(_THIS)
{
SDL_DisplayMode mode;
SDL_VideoData *data = _this->driverdata;
ksys_pos_t screen_size;
screen_size = _ksys_screen_size();
/* Use 24-bpp desktop mode */
mode.format = SDL_PIXELFORMAT_BGR24;
mode.w = screen_size.x + 1;
mode.h = screen_size.y + 1;
mode.refresh_rate = 60;
mode.driverdata = NULL;
if (SDL_AddBasicVideoDisplay(&mode) < 0)
return -1;
SDL_zero(mode);
SDL_AddDisplayMode(&_this->displays[0], &mode);
KOLIBRI_InitMouse();
KOLIBRI_InitOSKeymap();
/* We're done! */
return 0;
}
static int KOLIBRI_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
{
return 0;
}
void KOLIBRI_VideoQuit(_THIS)
{
}
static SDL_VideoDevice *KOLIBRI_CreateDevice(void)
{
SDL_VideoDevice *device;
SDL_VideoData *data;
/* Initialize all variables that we clean on shutdown */
device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
SDL_OutOfMemory();
return 0;
}
/* Initialize internal Kolibri specific data */
data = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
if (!data) {
SDL_OutOfMemory();
SDL_free(device);
return 0;
}
/* General video */
device->VideoInit = KOLIBRI_VideoInit;
device->VideoQuit = KOLIBRI_VideoQuit;
device->SetDisplayMode = KOLIBRI_SetDisplayMode;
device->PumpEvents = KOLIBRI_PumpEvents;
device->free = KOLIBRI_DeleteDevice;
/* Framebuffer */
device->CreateWindowFramebuffer = KOLIBRI_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = KOLIBRI_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = KOLIBRI_DestroyWindowFramebuffer;
/* "Window" */
device->CreateSDLWindow = KOLIBRI_CreateWindow;
device->MaximizeWindow = KOLIBRI_MaximizeWindow;
device->MinimizeWindow = KOLIBRI_MinimizeWindow;
device->RestoreWindow = KOLIBRI_RestoreWindow;
device->SetWindowFullscreen = KOLIBRI_SetWindowFullscreen;
device->SetWindowPosition = KOLIBRI_SetWindowPosition;
device->SetWindowResizable = KOLIBRI_SetWindowResizable;
device->SetWindowSize = KOLIBRI_SetWindowSize;
device->SetWindowTitle = KOLIBRI_SetWindowTitle;
device->DestroyWindow = KOLIBRI_DestroyWindow;
/* Clipboard */
device->HasClipboardText = KOLIBRI_HasClipboardText;
device->GetClipboardText = KOLIBRI_GetClipboardText;
device->SetClipboardText = KOLIBRI_SetClipboardText;
/* KolibriOS specific data */
device->driverdata = data;
return device;
}
VideoBootStrap KOLIBRI_bootstrap = {
KOLIBRIVID_DRIVER_NAME, "SDL kolibri video driver",
KOLIBRI_CreateDevice,
NULL /* no ShowMessageBox implementation */
};
#endif /* SDL_VIDEO_DRIVER_KOLIBRI */

View File

@ -0,0 +1,10 @@
#ifndef SDL_kolibrivideo_h_
#define SDL_kolibrivideo_h_
typedef struct SDL_VideoData
{
Uint32 window_id;
} SDL_VideoData;
#endif /* SDL_kolibrivideo_h_ */

View File

@ -0,0 +1,148 @@
#include "../../SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_KOLIBRI
#include <sys/ksys.h>
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../SDL_sysvideo.h"
#include "SDL_syswm.h"
#include "SDL_kolibrivideo.h"
#include "SDL_kolibriwindow.h"
static int pid = 0;
void KOLIBRI_RepaintWnd(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
SDL_Window *window = SDL_GetWindowFromID(data->window_id);
SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
int win_pos_x, win_pos_y;
int win_size_w, win_size_h;
win_size_w = window->w;
win_size_h = window->h;
if (wdata->skin == 0x33 || wdata->skin == 0x34) {
win_size_w += TRUE_WIN_WIDTH;
win_size_h += TRUE_WIN_HEIGHT;
}
_ksys_start_draw();
_ksys_create_window(window->x, window->y, win_size_w, win_size_h, window->title, 0, wdata->skin);
if (wdata->surface->pixels)
_ksys_draw_bitmap(wdata->surface->pixels, 0, 0, wdata->surface->w, wdata->surface->h);
_ksys_end_draw();
}
int KOLIBRI_CreateWindow(_THIS, SDL_Window *window)
{
SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
SDL_WindowData *wdata;
/* Allocate window internal data */
wdata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
if (!wdata)
return SDL_OutOfMemory();
/* Setup driver data for this window */
window->driverdata = wdata;
data->window_id = SDL_GetWindowID(window);
wdata->skin = 0x34;
_ksys_set_event_mask(0x27);
KOLIBRI_RepaintWnd(_this);
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);
return 0;
}
void KOLIBRI_MaximizeWindow(_THIS, SDL_Window *window)
{
// TODO
}
void KOLIBRI_MinimizeWindow(_THIS, SDL_Window *window)
{
ksys_thread_t thread_info;
_ksys_thread_info(&thread_info, KSYS_THIS_SLOT);
pid = thread_info.pid;
asm_inline("int $0x40" ::"a"(18), "b"(22), "c"(1), "d"(pid));
}
void KOLIBRI_RestoreWindow(_THIS, SDL_Window *window)
{
asm_inline("int $0x40" ::"a"(18), "b"(22), "c"(3), "d"(pid));
}
void KOLIBRI_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen)
{
SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
static int old_w, old_h, old_x, old_y;
static unsigned char old_skin;
if (fullscreen) {
old_w = window->w + (TRUE_WIN_WIDTH - 1);
old_h = window->h + (TRUE_WIN_HEIGHT - 1);
old_x = window->x;
old_y = window->y;
old_skin = wdata->skin;
wdata->skin = 0x01;
_ksys_change_window(0, 0, _ksys_screen_size().x + 1, _ksys_screen_size().y + 1);
} else {
wdata->skin = old_skin;
_ksys_change_window(old_x, old_y, old_w, old_h);
}
}
void KOLIBRI_SetWindowPosition(_THIS, SDL_Window *window)
{
_ksys_change_window(window->x, window->y, window->w + (TRUE_WIN_WIDTH - 1), window->h + (TRUE_WIN_HEIGHT - 1));
}
void KOLIBRI_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable)
{
SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
if (resizable)
wdata->skin = 0x33;
else
wdata->skin = 0x34;
KOLIBRI_RepaintWnd(_this);
}
void KOLIBRI_SetWindowSize(_THIS, SDL_Window *window)
{
_ksys_change_window(window->x, window->y, window->w + (TRUE_WIN_WIDTH - 1), window->h + (TRUE_WIN_HEIGHT - 1));
}
void KOLIBRI_SetWindowTitle(_THIS, SDL_Window *window)
{
_ksys_set_window_title(window->title);
}
void KOLIBRI_DestroyWindow(_THIS, SDL_Window *window)
{
if (!window)
return;
SDL_free(window->driverdata);
}
SDL_bool KOLIBRI_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
{
/* What is the point of this? What information should be included? */
if (info->version.major == SDL_MAJOR_VERSION) {
info->subsystem = SDL_SYSWM_KOLIBRI;
return SDL_TRUE;
} else {
SDL_SetError("Application not compiled with SDL %d", SDL_MAJOR_VERSION);
return SDL_FALSE;
}
}
#endif /* SDL_VIDEO_DRIVER_KOLIBRI */

View File

@ -0,0 +1,33 @@
#include "../../SDL_internal.h"
#ifndef SDL_kolibriwindow_h_
#define SDL_kolibriwindow_h_
#define WINDOW_BORDER_H 4
#define WINDOW_BORDER_W 9
#define TRUE_WIN_HEIGHT _ksys_get_skin_height() + WINDOW_BORDER_H
#define TRUE_WIN_WIDTH WINDOW_BORDER_W
typedef struct SDL_WindowData
{
SDL_Surface *surface;
unsigned char skin;
} SDL_WindowData;
void KOLIBRI_RepaintWnd(_THIS);
int KOLIBRI_CreateWindow(_THIS, SDL_Window *window);
void KOLIBRI_MaximizeWindow(_THIS, SDL_Window *window);
void KOLIBRI_MinimizeWindow(_THIS, SDL_Window *window);
void KOLIBRI_RestoreWindow(_THIS, SDL_Window *window);
void KOLIBRI_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen);
void KOLIBRI_SetWindowPosition(_THIS, SDL_Window *window);
void KOLIBRI_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable);
void KOLIBRI_SetWindowSize(_THIS, SDL_Window *window);
void KOLIBRI_SetWindowTitle(_THIS, SDL_Window *window);
void KOLIBRI_DestroyWindow(_THIS, SDL_Window *window);
SDL_bool KOLIBRI_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info);
#endif /* SDL_kolibriwindow_h_ */