Fixed crash if initialization of EGL failed but was tried again later.

The internal function SDL_EGL_LoadLibrary() did not delete and remove a mostly
uninitialized data structure if loading the library first failed. A later try to
use EGL then skipped initialization and assumed it was previously successful
because the data structure now already existed. This led to at least one crash
in the internal function SDL_EGL_ChooseConfig() because a NULL pointer was
dereferenced to make a call to eglBindAPI().
This commit is contained in:
Philipp Wiesemann
2015-06-21 17:33:46 +02:00
commit 0e45984fa0
1596 changed files with 468120 additions and 0 deletions

View File

@@ -0,0 +1,413 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_window.h"
#include "../../events/SDL_windowevents_c.h"
#define COLOR_EXPAND(col) col.r, col.g, col.b, col.a
static DFB_Theme theme_std = {
4, 4, 8, 8,
{255, 200, 200, 200},
24,
{255, 0, 0, 255},
16,
{255, 255, 255, 255},
"/usr/share/fonts/truetype/freefont/FreeSans.ttf",
{255, 255, 0, 0},
{255, 255, 255, 0},
};
static DFB_Theme theme_none = {
0, 0, 0, 0,
{0, 0, 0, 0},
0,
{0, 0, 0, 0},
0,
{0, 0, 0, 0},
NULL
};
static void
DrawTriangle(IDirectFBSurface * s, int down, int x, int y, int w)
{
int x1, x2, x3;
int y1, y2, y3;
if (down) {
x1 = x + w / 2;
x2 = x;
x3 = x + w;
y1 = y + w;
y2 = y;
y3 = y;
} else {
x1 = x + w / 2;
x2 = x;
x3 = x + w;
y1 = y;
y2 = y + w;
y3 = y + w;
}
s->FillTriangle(s, x1, y1, x2, y2, x3, y3);
}
static void
LoadFont(_THIS, SDL_Window * window)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
if (windata->font != NULL) {
SDL_DFB_RELEASE(windata->font);
windata->font = NULL;
SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
}
if (windata->theme.font != NULL)
{
DFBFontDescription fdesc;
SDL_zero(fdesc);
fdesc.flags = DFDESC_HEIGHT;
fdesc.height = windata->theme.font_size;
SDL_DFB_CHECK(devdata->
dfb->CreateFont(devdata->dfb, windata->theme.font,
&fdesc, &windata->font));
SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
}
}
static void
DrawCraption(_THIS, IDirectFBSurface * s, int x, int y, char *text)
{
DFBSurfaceTextFlags flags;
flags = DSTF_CENTER | DSTF_TOP;
s->DrawString(s, text, -1, x, y, flags);
}
void
DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
IDirectFBSurface *s = windata->window_surface;
DFB_Theme *t = &windata->theme;
int i;
int d = (t->caption_size - t->font_size) / 2;
int x, y, w;
if (!windata->is_managed || (window->flags & SDL_WINDOW_FULLSCREEN))
return;
SDL_DFB_CHECK(s->SetSrcBlendFunction(s, DSBF_ONE));
SDL_DFB_CHECK(s->SetDstBlendFunction(s, DSBF_ZERO));
SDL_DFB_CHECK(s->SetDrawingFlags(s, DSDRAW_NOFX));
SDL_DFB_CHECK(s->SetBlittingFlags(s, DSBLIT_NOFX));
LoadFont(_this, window);
/* s->SetDrawingFlags(s, DSDRAW_BLEND); */
s->SetColor(s, COLOR_EXPAND(t->frame_color));
/* top */
for (i = 0; i < t->top_size; i++)
s->DrawLine(s, 0, i, windata->size.w, i);
/* bottom */
for (i = windata->size.h - t->bottom_size; i < windata->size.h; i++)
s->DrawLine(s, 0, i, windata->size.w, i);
/* left */
for (i = 0; i < t->left_size; i++)
s->DrawLine(s, i, 0, i, windata->size.h);
/* right */
for (i = windata->size.w - t->right_size; i < windata->size.w; i++)
s->DrawLine(s, i, 0, i, windata->size.h);
/* Caption */
s->SetColor(s, COLOR_EXPAND(t->caption_color));
s->FillRectangle(s, t->left_size, t->top_size, windata->client.w,
t->caption_size);
/* Close Button */
w = t->caption_size;
x = windata->size.w - t->right_size - w + d;
y = t->top_size + d;
s->SetColor(s, COLOR_EXPAND(t->close_color));
DrawTriangle(s, 1, x, y, w - 2 * d);
/* Max Button */
s->SetColor(s, COLOR_EXPAND(t->max_color));
DrawTriangle(s, window->flags & SDL_WINDOW_MAXIMIZED ? 1 : 0, x - w,
y, w - 2 * d);
/* Caption */
if (*window->title) {
s->SetColor(s, COLOR_EXPAND(t->font_color));
DrawCraption(_this, s, (x - w) / 2, t->top_size + d, window->title);
}
/* Icon */
if (windata->icon) {
DFBRectangle dr;
dr.x = t->left_size + d;
dr.y = t->top_size + d;
dr.w = w - 2 * d;
dr.h = w - 2 * d;
s->SetBlittingFlags(s, DSBLIT_BLEND_ALPHACHANNEL);
s->StretchBlit(s, windata->icon, NULL, &dr);
}
windata->wm_needs_redraw = 0;
}
DFBResult
DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch)
{
SDL_DFB_WINDOWDATA(window);
IDirectFBWindow *dfbwin = windata->dfbwin;
SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, cw, ch));
dfbwin->GetSize(dfbwin, cw, ch);
*cw -= windata->theme.left_size + windata->theme.right_size;
*ch -=
windata->theme.top_size + windata->theme.caption_size +
windata->theme.bottom_size;
return DFB_OK;
}
void
DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h)
{
SDL_DFB_WINDOWDATA(window);
if (!windata->is_managed)
windata->theme = theme_none;
else if (flags & SDL_WINDOW_BORDERLESS)
/* desc.caps |= DWCAPS_NODECORATION;) */
windata->theme = theme_none;
else if (flags & SDL_WINDOW_FULLSCREEN) {
windata->theme = theme_none;
} else if (flags & SDL_WINDOW_MAXIMIZED) {
windata->theme = theme_std;
windata->theme.left_size = 0;
windata->theme.right_size = 0;
windata->theme.top_size = 0;
windata->theme.bottom_size = 0;
} else {
windata->theme = theme_std;
}
windata->client.x = windata->theme.left_size;
windata->client.y = windata->theme.top_size + windata->theme.caption_size;
windata->client.w = w;
windata->client.h = h;
windata->size.w =
w + windata->theme.left_size + windata->theme.right_size;
windata->size.h =
h + windata->theme.top_size +
windata->theme.caption_size + windata->theme.bottom_size;
}
enum
{
WM_POS_NONE = 0x00,
WM_POS_CAPTION = 0x01,
WM_POS_CLOSE = 0x02,
WM_POS_MAX = 0x04,
WM_POS_LEFT = 0x08,
WM_POS_RIGHT = 0x10,
WM_POS_TOP = 0x20,
WM_POS_BOTTOM = 0x40,
};
static int
WMIsClient(DFB_WindowData * p, int x, int y)
{
x -= p->client.x;
y -= p->client.y;
if (x < 0 || y < 0)
return 0;
if (x >= p->client.w || y >= p->client.h)
return 0;
return 1;
}
static int
WMPos(DFB_WindowData * p, int x, int y)
{
int pos = WM_POS_NONE;
if (!WMIsClient(p, x, y)) {
if (y < p->theme.top_size) {
pos |= WM_POS_TOP;
} else if (y < p->client.y) {
if (x <
p->size.w - p->theme.right_size - 2 * p->theme.caption_size) {
pos |= WM_POS_CAPTION;
} else if (x <
p->size.w - p->theme.right_size -
p->theme.caption_size) {
pos |= WM_POS_MAX;
} else {
pos |= WM_POS_CLOSE;
}
} else if (y >= p->size.h - p->theme.bottom_size) {
pos |= WM_POS_BOTTOM;
}
if (x < p->theme.left_size) {
pos |= WM_POS_LEFT;
} else if (x >= p->size.w - p->theme.right_size) {
pos |= WM_POS_RIGHT;
}
}
return pos;
}
int
DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
IDirectFBWindow *dfbwin = windata->dfbwin;
DFBWindowOptions wopts;
if (!windata->is_managed)
return 0;
SDL_DFB_CHECK(dfbwin->GetOptions(dfbwin, &wopts));
switch (evt->type) {
case DWET_BUTTONDOWN:
if (evt->buttons & DIBM_LEFT) {
int pos = WMPos(windata, evt->x, evt->y);
switch (pos) {
case WM_POS_NONE:
return 0;
case WM_POS_CLOSE:
windata->wm_grab = WM_POS_NONE;
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0,
0);
return 1;
case WM_POS_MAX:
windata->wm_grab = WM_POS_NONE;
if (window->flags & SDL_WINDOW_MAXIMIZED) {
SDL_RestoreWindow(window);
} else {
SDL_MaximizeWindow(window);
}
return 1;
case WM_POS_CAPTION:
if (!(wopts & DWOP_KEEP_STACKING)) {
DirectFB_RaiseWindow(_this, window);
}
if (window->flags & SDL_WINDOW_MAXIMIZED)
return 1;
/* fall through */
default:
windata->wm_grab = pos;
if (gwindata != NULL)
SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
SDL_DFB_CHECK(dfbwin->GrabPointer(dfbwin));
windata->wm_lastx = evt->cx;
windata->wm_lasty = evt->cy;
}
}
return 1;
case DWET_BUTTONUP:
if (!windata->wm_grab)
return 0;
if (!(evt->buttons & DIBM_LEFT)) {
if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
int dx = evt->cx - windata->wm_lastx;
int dy = evt->cy - windata->wm_lasty;
if (!(wopts & DWOP_KEEP_SIZE)) {
int cw, ch;
if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
dx = 0;
else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
dy = 0;
SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
/* necessary to trigger an event - ugly */
SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx + 1, ch + dy));
SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
}
}
SDL_DFB_CHECK(dfbwin->UngrabPointer(dfbwin));
if (gwindata != NULL)
SDL_DFB_CHECK(gwindata->dfbwin->GrabPointer(gwindata->dfbwin));
windata->wm_grab = WM_POS_NONE;
return 1;
}
break;
case DWET_MOTION:
if (!windata->wm_grab)
return 0;
if (evt->buttons & DIBM_LEFT) {
int dx = evt->cx - windata->wm_lastx;
int dy = evt->cy - windata->wm_lasty;
if (windata->wm_grab & WM_POS_CAPTION) {
if (!(wopts & DWOP_KEEP_POSITION))
SDL_DFB_CHECK(dfbwin->Move(dfbwin, dx, dy));
}
if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
if (!(wopts & DWOP_KEEP_SIZE)) {
int cw, ch;
/* Make sure all events are disabled for this operation ! */
SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
dx = 0;
else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
dy = 0;
SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
}
}
windata->wm_lastx = evt->cx;
windata->wm_lasty = evt->cy;
return 1;
}
break;
case DWET_KEYDOWN:
break;
case DWET_KEYUP:
break;
default:
;
}
return 0;
}
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */

View File

@@ -0,0 +1,56 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_directfb_wm_h
#define _SDL_directfb_wm_h
#include "SDL_DirectFB_video.h"
typedef struct _DFB_Theme DFB_Theme;
struct _DFB_Theme
{
int left_size;
int right_size;
int top_size;
int bottom_size;
DFBColor frame_color;
int caption_size;
DFBColor caption_color;
int font_size;
DFBColor font_color;
char *font;
DFBColor close_color;
DFBColor max_color;
};
extern void DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h);
extern void DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window);
extern int DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window,
DFBWindowEvent * evt);
extern DFBResult DirectFB_WM_GetClientSize(_THIS, SDL_Window * window,
int *cw, int *ch);
#endif /* _SDL_directfb_wm_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,117 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_dyn.h"
#ifdef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC
#include "SDL_name.h"
#include "SDL_loadso.h"
#define DFB_SYM(ret, name, args, al, func) ret (*name) args;
static struct _SDL_DirectFB_Symbols
{
DFB_SYMS
const unsigned int *directfb_major_version;
const unsigned int *directfb_minor_version;
const unsigned int *directfb_micro_version;
} SDL_DirectFB_Symbols;
#undef DFB_SYM
#define DFB_SYM(ret, name, args, al, func) ret name args { func SDL_DirectFB_Symbols.name al ; }
DFB_SYMS
#undef DFB_SYM
static void *handle = NULL;
int
SDL_DirectFB_LoadLibrary(void)
{
int retval = 0;
if (handle == NULL) {
handle = SDL_LoadObject(SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC);
if (handle != NULL) {
retval = 1;
#define DFB_SYM(ret, name, args, al, func) if (!(SDL_DirectFB_Symbols.name = SDL_LoadFunction(handle, # name))) retval = 0;
DFB_SYMS
#undef DFB_SYM
if (!
(SDL_DirectFB_Symbols.directfb_major_version =
SDL_LoadFunction(handle, "directfb_major_version")))
retval = 0;
if (!
(SDL_DirectFB_Symbols.directfb_minor_version =
SDL_LoadFunction(handle, "directfb_minor_version")))
retval = 0;
if (!
(SDL_DirectFB_Symbols.directfb_micro_version =
SDL_LoadFunction(handle, "directfb_micro_version")))
retval = 0;
}
}
if (retval) {
const char *stemp = DirectFBCheckVersion(DIRECTFB_MAJOR_VERSION,
DIRECTFB_MINOR_VERSION,
DIRECTFB_MICRO_VERSION);
/* Version Check */
if (stemp != NULL) {
fprintf(stderr,
"DirectFB Lib: Version mismatch. Compiled: %d.%d.%d Library %d.%d.%d\n",
DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION,
DIRECTFB_MICRO_VERSION,
*SDL_DirectFB_Symbols.directfb_major_version,
*SDL_DirectFB_Symbols.directfb_minor_version,
*SDL_DirectFB_Symbols.directfb_micro_version);
retval = 0;
}
}
if (!retval)
SDL_DirectFB_UnLoadLibrary();
return retval;
}
void
SDL_DirectFB_UnLoadLibrary(void)
{
if (handle != NULL) {
SDL_UnloadObject(handle);
handle = NULL;
}
}
#else
int
SDL_DirectFB_LoadLibrary(void)
{
return 1;
}
void
SDL_DirectFB_UnLoadLibrary(void)
{
}
#endif
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */

View File

@@ -0,0 +1,39 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_DirectFB_dyn_h
#define _SDL_DirectFB_dyn_h
#define DFB_SYMS \
DFB_SYM(DFBResult, DirectFBError, (const char *msg, DFBResult result), (msg, result), return) \
DFB_SYM(DFBResult, DirectFBErrorFatal, (const char *msg, DFBResult result), (msg, result), return) \
DFB_SYM(const char *, DirectFBErrorString, (DFBResult result), (result), return) \
DFB_SYM(const char *, DirectFBUsageString, ( void ), (), return) \
DFB_SYM(DFBResult, DirectFBInit, (int *argc, char *(*argv[]) ), (argc, argv), return) \
DFB_SYM(DFBResult, DirectFBSetOption, (const char *name, const char *value), (name, value), return) \
DFB_SYM(DFBResult, DirectFBCreate, (IDirectFB **interface), (interface), return) \
DFB_SYM(const char *, DirectFBCheckVersion, (unsigned int required_major, unsigned int required_minor, unsigned int required_micro), \
(required_major, required_minor, required_micro), return)
int SDL_DirectFB_LoadLibrary(void);
void SDL_DirectFB_UnLoadLibrary(void);
#endif

View File

@@ -0,0 +1,751 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
/* Handle the event stream, converting DirectFB input events into SDL events */
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_window.h"
#include "SDL_DirectFB_modes.h"
#include "SDL_syswm.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_windowevents_c.h"
#include "../../events/SDL_events_c.h"
#include "../../events/scancodes_linux.h"
#include "../../events/scancodes_xfree86.h"
#include "SDL_DirectFB_events.h"
#if USE_MULTI_API
#define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y, p)
#define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
#define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(id, state, scancode)
#define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(id, text)
#else
#define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y)
#define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
#define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(state, scancode)
#define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(text)
#endif
typedef struct _cb_data cb_data;
struct _cb_data
{
DFB_DeviceData *devdata;
int sys_ids;
int sys_kbd;
};
/* The translation tables from a DirectFB keycode to a SDL keysym */
static SDL_Scancode oskeymap[256];
static SDL_Keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt,
SDL_Keysym * keysym, Uint32 *unicode);
static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
SDL_Keysym * keysym, Uint32 *unicode);
static void DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keypmap, int numkeys);
static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button);
static void UnicodeToUtf8( Uint16 w , char *utf8buf)
{
unsigned char *utf8s = (unsigned char *) utf8buf;
if ( w < 0x0080 ) {
utf8s[0] = ( unsigned char ) w;
utf8s[1] = 0;
}
else if ( w < 0x0800 ) {
utf8s[0] = 0xc0 | (( w ) >> 6 );
utf8s[1] = 0x80 | (( w ) & 0x3f );
utf8s[2] = 0;
}
else {
utf8s[0] = 0xe0 | (( w ) >> 12 );
utf8s[1] = 0x80 | (( ( w ) >> 6 ) & 0x3f );
utf8s[2] = 0x80 | (( w ) & 0x3f );
utf8s[3] = 0;
}
}
static void
FocusAllMice(_THIS, SDL_Window *window)
{
#if USE_MULTI_API
SDL_DFB_DEVICEDATA(_this);
int index;
for (index = 0; index < devdata->num_mice; index++)
SDL_SetMouseFocus(devdata->mouse_id[index], id);
#else
SDL_SetMouseFocus(window);
#endif
}
static void
FocusAllKeyboards(_THIS, SDL_Window *window)
{
#if USE_MULTI_API
SDL_DFB_DEVICEDATA(_this);
int index;
for (index = 0; index < devdata->num_keyboard; index++)
SDL_SetKeyboardFocus(index, id);
#else
SDL_SetKeyboardFocus(window);
#endif
}
static void
MotionAllMice(_THIS, int x, int y)
{
#if USE_MULTI_API
SDL_DFB_DEVICEDATA(_this);
int index;
for (index = 0; index < devdata->num_mice; index++) {
SDL_Mouse *mouse = SDL_GetMouse(index);
mouse->x = mouse->last_x = x;
mouse->y = mouse->last_y = y;
/* SDL_SendMouseMotion(devdata->mouse_id[index], 0, x, y, 0); */
}
#endif
}
static int
KbdIndex(_THIS, int id)
{
SDL_DFB_DEVICEDATA(_this);
int index;
for (index = 0; index < devdata->num_keyboard; index++) {
if (devdata->keyboard[index].id == id)
return index;
}
return -1;
}
static int
ClientXY(DFB_WindowData * p, int *x, int *y)
{
int cx, cy;
cx = *x;
cy = *y;
cx -= p->client.x;
cy -= p->client.y;
if (cx < 0 || cy < 0)
return 0;
if (cx >= p->client.w || cy >= p->client.h)
return 0;
*x = cx;
*y = cy;
return 1;
}
static void
ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(sdlwin);
SDL_Keysym keysym;
Uint32 unicode;
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
if (evt->clazz == DFEC_WINDOW) {
switch (evt->type) {
case DWET_BUTTONDOWN:
if (ClientXY(windata, &evt->x, &evt->y)) {
if (!devdata->use_linux_input) {
SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
evt->y, 0);
SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
SDL_PRESSED,
DirectFB_TranslateButton
(evt->button));
} else {
MotionAllMice(_this, evt->x, evt->y);
}
}
break;
case DWET_BUTTONUP:
if (ClientXY(windata, &evt->x, &evt->y)) {
if (!devdata->use_linux_input) {
SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
evt->y, 0);
SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
SDL_RELEASED,
DirectFB_TranslateButton
(evt->button));
} else {
MotionAllMice(_this, evt->x, evt->y);
}
}
break;
case DWET_MOTION:
if (ClientXY(windata, &evt->x, &evt->y)) {
if (!devdata->use_linux_input) {
if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED))
SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0,
evt->x, evt->y, 0);
} else {
/* relative movements are not exact!
* This code should limit the number of events sent.
* However it kills MAME axis recognition ... */
static int cnt = 0;
if (1 && ++cnt > 20) {
MotionAllMice(_this, evt->x, evt->y);
cnt = 0;
}
}
if (!(sdlwin->flags & SDL_WINDOW_MOUSE_FOCUS))
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0,
0);
}
break;
case DWET_KEYDOWN:
if (!devdata->use_linux_input) {
DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
/* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
SDL_SendKeyboardKey_ex(0, SDL_PRESSED, keysym.scancode);
if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
SDL_zero(text);
UnicodeToUtf8(unicode, text);
if (*text) {
SDL_SendKeyboardText_ex(0, text);
}
}
}
break;
case DWET_KEYUP:
if (!devdata->use_linux_input) {
DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
SDL_SendKeyboardKey_ex(0, SDL_RELEASED, keysym.scancode);
}
break;
case DWET_POSITION:
if (ClientXY(windata, &evt->x, &evt->y)) {
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
evt->x, evt->y);
}
break;
case DWET_POSITION_SIZE:
if (ClientXY(windata, &evt->x, &evt->y)) {
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
evt->x, evt->y);
}
/* fall throught */
case DWET_SIZE:
/* FIXME: what about < 0 */
evt->w -= (windata->theme.right_size + windata->theme.left_size);
evt->h -=
(windata->theme.top_size + windata->theme.bottom_size +
windata->theme.caption_size);
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED,
evt->w, evt->h);
break;
case DWET_CLOSE:
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_CLOSE, 0, 0);
break;
case DWET_GOTFOCUS:
DirectFB_SetContext(_this, sdlwin);
FocusAllKeyboards(_this, sdlwin);
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_GAINED,
0, 0);
break;
case DWET_LOSTFOCUS:
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
FocusAllKeyboards(_this, 0);
break;
case DWET_ENTER:
/* SDL_DirectFB_ReshowCursor(_this, 0); */
FocusAllMice(_this, sdlwin);
/* FIXME: when do we really enter ? */
if (ClientXY(windata, &evt->x, &evt->y))
MotionAllMice(_this, evt->x, evt->y);
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, 0);
break;
case DWET_LEAVE:
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_LEAVE, 0, 0);
FocusAllMice(_this, 0);
/* SDL_DirectFB_ReshowCursor(_this, 1); */
break;
default:
;
}
} else
printf("Event Clazz %d\n", evt->clazz);
}
static void
ProcessInputEvent(_THIS, DFBInputEvent * ievt)
{
SDL_DFB_DEVICEDATA(_this);
SDL_Keysym keysym;
int kbd_idx;
Uint32 unicode;
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
if (!devdata->use_linux_input) {
if (ievt->type == DIET_AXISMOTION) {
if ((devdata->grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) {
if (ievt->axis == DIAI_X)
SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
ievt->axisrel, 0, 0);
else if (ievt->axis == DIAI_Y)
SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
ievt->axisrel, 0);
}
}
} else {
static int last_x, last_y;
switch (ievt->type) {
case DIET_AXISMOTION:
if (ievt->flags & DIEF_AXISABS) {
if (ievt->axis == DIAI_X)
last_x = ievt->axisabs;
else if (ievt->axis == DIAI_Y)
last_y = ievt->axisabs;
if (!(ievt->flags & DIEF_FOLLOW)) {
#if USE_MULTI_API
SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id);
SDL_Window *window = SDL_GetWindowFromID(mouse->focus);
#else
SDL_Window *window = devdata->grabbed_window;
#endif
if (window) {
DFB_WindowData *windata =
(DFB_WindowData *) window->driverdata;
int x, y;
windata->dfbwin->GetPosition(windata->dfbwin, &x, &y);
SDL_SendMouseMotion_ex(window, ievt->device_id, 0,
last_x - (x +
windata->client.x),
last_y - (y +
windata->client.y), 0);
} else {
SDL_SendMouseMotion_ex(window, ievt->device_id, 0, last_x,
last_y, 0);
}
}
} else if (ievt->flags & DIEF_AXISREL) {
if (ievt->axis == DIAI_X)
SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
ievt->axisrel, 0, 0);
else if (ievt->axis == DIAI_Y)
SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
ievt->axisrel, 0);
}
break;
case DIET_KEYPRESS:
kbd_idx = KbdIndex(_this, ievt->device_id);
DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
/* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
SDL_SendKeyboardKey_ex(kbd_idx, SDL_PRESSED, keysym.scancode);
if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
SDL_zero(text);
UnicodeToUtf8(unicode, text);
if (*text) {
SDL_SendKeyboardText_ex(kbd_idx, text);
}
}
break;
case DIET_KEYRELEASE:
kbd_idx = KbdIndex(_this, ievt->device_id);
DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
SDL_SendKeyboardKey_ex(kbd_idx, SDL_RELEASED, keysym.scancode);
break;
case DIET_BUTTONPRESS:
if (ievt->buttons & DIBM_LEFT)
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 1);
if (ievt->buttons & DIBM_MIDDLE)
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 2);
if (ievt->buttons & DIBM_RIGHT)
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 3);
break;
case DIET_BUTTONRELEASE:
if (!(ievt->buttons & DIBM_LEFT))
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 1);
if (!(ievt->buttons & DIBM_MIDDLE))
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 2);
if (!(ievt->buttons & DIBM_RIGHT))
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 3);
break;
default:
break; /* please gcc */
}
}
}
void
DirectFB_PumpEventsWindow(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
DFBInputEvent ievt;
SDL_Window *w;
for (w = devdata->firstwin; w != NULL; w = w->next) {
SDL_DFB_WINDOWDATA(w);
DFBWindowEvent evt;
while (windata->eventbuffer->GetEvent(windata->eventbuffer,
DFB_EVENT(&evt)) == DFB_OK) {
if (!DirectFB_WM_ProcessEvent(_this, w, &evt)) {
/* Send a SDL_SYSWMEVENT if the application wants them */
if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
SDL_SysWMmsg wmmsg;
SDL_VERSION(&wmmsg.version);
wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
wmmsg.msg.dfb.event.window = evt;
SDL_SendSysWMEvent(&wmmsg);
}
ProcessWindowEvent(_this, w, &evt);
}
}
}
/* Now get relative events in case we need them */
while (devdata->events->GetEvent(devdata->events,
DFB_EVENT(&ievt)) == DFB_OK) {
if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
SDL_SysWMmsg wmmsg;
SDL_VERSION(&wmmsg.version);
wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
wmmsg.msg.dfb.event.input = ievt;
SDL_SendSysWMEvent(&wmmsg);
}
ProcessInputEvent(_this, &ievt);
}
}
void
DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys)
{
int i;
/* Initialize the DirectFB key translation table */
for (i = 0; i < numkeys; ++i)
keymap[i] = SDL_SCANCODE_UNKNOWN;
keymap[DIKI_A - DIKI_UNKNOWN] = SDL_SCANCODE_A;
keymap[DIKI_B - DIKI_UNKNOWN] = SDL_SCANCODE_B;
keymap[DIKI_C - DIKI_UNKNOWN] = SDL_SCANCODE_C;
keymap[DIKI_D - DIKI_UNKNOWN] = SDL_SCANCODE_D;
keymap[DIKI_E - DIKI_UNKNOWN] = SDL_SCANCODE_E;
keymap[DIKI_F - DIKI_UNKNOWN] = SDL_SCANCODE_F;
keymap[DIKI_G - DIKI_UNKNOWN] = SDL_SCANCODE_G;
keymap[DIKI_H - DIKI_UNKNOWN] = SDL_SCANCODE_H;
keymap[DIKI_I - DIKI_UNKNOWN] = SDL_SCANCODE_I;
keymap[DIKI_J - DIKI_UNKNOWN] = SDL_SCANCODE_J;
keymap[DIKI_K - DIKI_UNKNOWN] = SDL_SCANCODE_K;
keymap[DIKI_L - DIKI_UNKNOWN] = SDL_SCANCODE_L;
keymap[DIKI_M - DIKI_UNKNOWN] = SDL_SCANCODE_M;
keymap[DIKI_N - DIKI_UNKNOWN] = SDL_SCANCODE_N;
keymap[DIKI_O - DIKI_UNKNOWN] = SDL_SCANCODE_O;
keymap[DIKI_P - DIKI_UNKNOWN] = SDL_SCANCODE_P;
keymap[DIKI_Q - DIKI_UNKNOWN] = SDL_SCANCODE_Q;
keymap[DIKI_R - DIKI_UNKNOWN] = SDL_SCANCODE_R;
keymap[DIKI_S - DIKI_UNKNOWN] = SDL_SCANCODE_S;
keymap[DIKI_T - DIKI_UNKNOWN] = SDL_SCANCODE_T;
keymap[DIKI_U - DIKI_UNKNOWN] = SDL_SCANCODE_U;
keymap[DIKI_V - DIKI_UNKNOWN] = SDL_SCANCODE_V;
keymap[DIKI_W - DIKI_UNKNOWN] = SDL_SCANCODE_W;
keymap[DIKI_X - DIKI_UNKNOWN] = SDL_SCANCODE_X;
keymap[DIKI_Y - DIKI_UNKNOWN] = SDL_SCANCODE_Y;
keymap[DIKI_Z - DIKI_UNKNOWN] = SDL_SCANCODE_Z;
keymap[DIKI_0 - DIKI_UNKNOWN] = SDL_SCANCODE_0;
keymap[DIKI_1 - DIKI_UNKNOWN] = SDL_SCANCODE_1;
keymap[DIKI_2 - DIKI_UNKNOWN] = SDL_SCANCODE_2;
keymap[DIKI_3 - DIKI_UNKNOWN] = SDL_SCANCODE_3;
keymap[DIKI_4 - DIKI_UNKNOWN] = SDL_SCANCODE_4;
keymap[DIKI_5 - DIKI_UNKNOWN] = SDL_SCANCODE_5;
keymap[DIKI_6 - DIKI_UNKNOWN] = SDL_SCANCODE_6;
keymap[DIKI_7 - DIKI_UNKNOWN] = SDL_SCANCODE_7;
keymap[DIKI_8 - DIKI_UNKNOWN] = SDL_SCANCODE_8;
keymap[DIKI_9 - DIKI_UNKNOWN] = SDL_SCANCODE_9;
keymap[DIKI_F1 - DIKI_UNKNOWN] = SDL_SCANCODE_F1;
keymap[DIKI_F2 - DIKI_UNKNOWN] = SDL_SCANCODE_F2;
keymap[DIKI_F3 - DIKI_UNKNOWN] = SDL_SCANCODE_F3;
keymap[DIKI_F4 - DIKI_UNKNOWN] = SDL_SCANCODE_F4;
keymap[DIKI_F5 - DIKI_UNKNOWN] = SDL_SCANCODE_F5;
keymap[DIKI_F6 - DIKI_UNKNOWN] = SDL_SCANCODE_F6;
keymap[DIKI_F7 - DIKI_UNKNOWN] = SDL_SCANCODE_F7;
keymap[DIKI_F8 - DIKI_UNKNOWN] = SDL_SCANCODE_F8;
keymap[DIKI_F9 - DIKI_UNKNOWN] = SDL_SCANCODE_F9;
keymap[DIKI_F10 - DIKI_UNKNOWN] = SDL_SCANCODE_F10;
keymap[DIKI_F11 - DIKI_UNKNOWN] = SDL_SCANCODE_F11;
keymap[DIKI_F12 - DIKI_UNKNOWN] = SDL_SCANCODE_F12;
keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDL_SCANCODE_ESCAPE;
keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFT;
keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHT;
keymap[DIKI_UP - DIKI_UNKNOWN] = SDL_SCANCODE_UP;
keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_DOWN;
keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDL_SCANCODE_LCTRL;
keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDL_SCANCODE_RCTRL;
keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LSHIFT;
keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RSHIFT;
keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LALT;
keymap[DIKI_ALT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RALT;
keymap[DIKI_META_L - DIKI_UNKNOWN] = SDL_SCANCODE_LGUI;
keymap[DIKI_META_R - DIKI_UNKNOWN] = SDL_SCANCODE_RGUI;
keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
keymap[DIKI_SUPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
/* FIXME:Do we read hyper keys ?
* keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
* keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
*/
keymap[DIKI_TAB - DIKI_UNKNOWN] = SDL_SCANCODE_TAB;
keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_RETURN;
keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDL_SCANCODE_SPACE;
keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSPACE;
keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDL_SCANCODE_INSERT;
keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDL_SCANCODE_DELETE;
keymap[DIKI_HOME - DIKI_UNKNOWN] = SDL_SCANCODE_HOME;
keymap[DIKI_END - DIKI_UNKNOWN] = SDL_SCANCODE_END;
keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEUP;
keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEDOWN;
keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_CAPSLOCK;
keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_NUMLOCKCLEAR;
keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_SCROLLLOCK;
keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDL_SCANCODE_PRINTSCREEN;
keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDL_SCANCODE_PAUSE;
keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_EQUALS;
keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PERIOD;
keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_0;
keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_1;
keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_2;
keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_3;
keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_4;
keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_5;
keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_6;
keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_7;
keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_8;
keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_9;
keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDL_SCANCODE_KP_DIVIDE;
keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MULTIPLY;
keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MINUS;
keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PLUS;
keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_KP_ENTER;
keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_GRAVE; /* TLDE */
keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_MINUS; /* AE11 */
keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_EQUALS; /* AE12 */
keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHTBRACKET; /* AD11 */
keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFTBRACKET; /* AD12 */
keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSLASH; /* BKSL */
keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDL_SCANCODE_SEMICOLON; /* AC10 */
keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_APOSTROPHE; /* AC11 */
keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDL_SCANCODE_COMMA; /* AB08 */
keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDL_SCANCODE_PERIOD; /* AB09 */
keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDL_SCANCODE_SLASH; /* AB10 */
keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_NONUSBACKSLASH; /* 103rd */
}
static SDL_Keysym *
DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym, Uint32 *unicode)
{
SDL_DFB_DEVICEDATA(_this);
int kbd_idx = 0; /* Window events lag the device source KbdIndex(_this, evt->device_id); */
DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
keysym->scancode = SDL_SCANCODE_UNKNOWN;
if (kbd->map && evt->key_code >= kbd->map_adjust &&
evt->key_code < kbd->map_size + kbd->map_adjust)
keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
if (keysym->scancode == SDL_SCANCODE_UNKNOWN ||
devdata->keyboard[kbd_idx].is_generic) {
if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
else
keysym->scancode = SDL_SCANCODE_UNKNOWN;
}
*unicode =
(DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
if (*unicode == 0 &&
(evt->key_symbol > 0 && evt->key_symbol < 255))
*unicode = evt->key_symbol;
return keysym;
}
static SDL_Keysym *
DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
SDL_Keysym * keysym, Uint32 *unicode)
{
SDL_DFB_DEVICEDATA(_this);
int kbd_idx = KbdIndex(_this, evt->device_id);
DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
keysym->scancode = SDL_SCANCODE_UNKNOWN;
if (kbd->map && evt->key_code >= kbd->map_adjust &&
evt->key_code < kbd->map_size + kbd->map_adjust)
keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
if (keysym->scancode == SDL_SCANCODE_UNKNOWN || devdata->keyboard[kbd_idx].is_generic) {
if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
else
keysym->scancode = SDL_SCANCODE_UNKNOWN;
}
*unicode =
(DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
if (*unicode == 0 &&
(evt->key_symbol > 0 && evt->key_symbol < 255))
*unicode = evt->key_symbol;
return keysym;
}
static int
DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)
{
switch (button) {
case DIBI_LEFT:
return 1;
case DIBI_MIDDLE:
return 2;
case DIBI_RIGHT:
return 3;
default:
return 0;
}
}
static DFBEnumerationResult
EnumKeyboards(DFBInputDeviceID device_id,
DFBInputDeviceDescription desc, void *callbackdata)
{
cb_data *cb = callbackdata;
DFB_DeviceData *devdata = cb->devdata;
#if USE_MULTI_API
SDL_Keyboard keyboard;
#endif
SDL_Keycode keymap[SDL_NUM_SCANCODES];
if (!cb->sys_kbd) {
if (cb->sys_ids) {
if (device_id >= 0x10)
return DFENUM_OK;
} else {
if (device_id < 0x10)
return DFENUM_OK;
}
} else {
if (device_id != DIDID_KEYBOARD)
return DFENUM_OK;
}
if ((desc.caps & DIDTF_KEYBOARD)) {
#if USE_MULTI_API
SDL_zero(keyboard);
SDL_AddKeyboard(&keyboard, devdata->num_keyboard);
#endif
devdata->keyboard[devdata->num_keyboard].id = device_id;
devdata->keyboard[devdata->num_keyboard].is_generic = 0;
if (!strncmp("X11", desc.name, 3))
{
devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2;
devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2);
devdata->keyboard[devdata->num_keyboard].map_adjust = 8;
} else {
devdata->keyboard[devdata->num_keyboard].map = linux_scancode_table;
devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(linux_scancode_table);
devdata->keyboard[devdata->num_keyboard].map_adjust = 0;
}
SDL_DFB_LOG("Keyboard %d - %s\n", device_id, desc.name);
SDL_GetDefaultKeymap(keymap);
#if USE_MULTI_API
SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES);
#else
SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
#endif
devdata->num_keyboard++;
if (cb->sys_kbd)
return DFENUM_CANCEL;
}
return DFENUM_OK;
}
void
DirectFB_InitKeyboard(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
cb_data cb;
DirectFB_InitOSKeymap(_this, &oskeymap[0], SDL_arraysize(oskeymap));
devdata->num_keyboard = 0;
cb.devdata = devdata;
if (devdata->use_linux_input) {
cb.sys_kbd = 0;
cb.sys_ids = 0;
SDL_DFB_CHECK(devdata->dfb->
EnumInputDevices(devdata->dfb, EnumKeyboards, &cb));
if (devdata->num_keyboard == 0) {
cb.sys_ids = 1;
SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
EnumKeyboards,
&cb));
}
} else {
cb.sys_kbd = 1;
SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
EnumKeyboards,
&cb));
}
}
void
DirectFB_QuitKeyboard(_THIS)
{
/* SDL_DFB_DEVICEDATA(_this); */
SDL_KeyboardQuit();
}
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */

View File

@@ -0,0 +1,32 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_DirectFB_events_h
#define _SDL_DirectFB_events_h
#include "../SDL_sysvideo.h"
/* Functions to be exported */
extern void DirectFB_InitKeyboard(_THIS);
extern void DirectFB_QuitKeyboard(_THIS);
extern void DirectFB_PumpEventsWindow(_THIS);
#endif

View File

@@ -0,0 +1,414 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_modes.h"
#define DFB_MAX_MODES 200
struct screen_callback_t
{
int numscreens;
DFBScreenID screenid[DFB_MAX_SCREENS];
DFBDisplayLayerID gralayer[DFB_MAX_SCREENS];
DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS];
int aux; /* auxiliary integer for callbacks */
};
struct modes_callback_t
{
int nummodes;
SDL_DisplayMode *modelist;
};
static DFBEnumerationResult
EnumModesCallback(int width, int height, int bpp, void *data)
{
struct modes_callback_t *modedata = (struct modes_callback_t *) data;
SDL_DisplayMode mode;
mode.w = width;
mode.h = height;
mode.refresh_rate = 0;
mode.driverdata = NULL;
mode.format = SDL_PIXELFORMAT_UNKNOWN;
if (modedata->nummodes < DFB_MAX_MODES) {
modedata->modelist[modedata->nummodes++] = mode;
}
return DFENUM_OK;
}
static DFBEnumerationResult
EnumScreensCallback(DFBScreenID screen_id, DFBScreenDescription desc,
void *callbackdata)
{
struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata;
devdata->screenid[devdata->numscreens++] = screen_id;
return DFENUM_OK;
}
static DFBEnumerationResult
EnumLayersCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc,
void *callbackdata)
{
struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata;
if (desc.caps & DLCAPS_SURFACE) {
if ((desc.type & DLTF_GRAPHICS) && (desc.type & DLTF_VIDEO)) {
if (devdata->vidlayer[devdata->aux] == -1)
devdata->vidlayer[devdata->aux] = layer_id;
} else if (desc.type & DLTF_GRAPHICS) {
if (devdata->gralayer[devdata->aux] == -1)
devdata->gralayer[devdata->aux] = layer_id;
}
}
return DFENUM_OK;
}
static void
CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, SDL_DisplayMode * mode)
{
SDL_DFB_DEVICEDATA(_this);
DFBDisplayLayerConfig config;
DFBDisplayLayerConfigFlags failed;
SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
DLSCL_ADMINISTRATIVE));
config.width = mode->w;
config.height = mode->h;
config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format);
config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
if (devdata->use_yuv_underlays) {
config.flags |= DLCONF_OPTIONS;
config.options = DLOP_ALPHACHANNEL;
}
failed = 0;
data->layer->TestConfiguration(data->layer, &config, &failed);
SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
DLSCL_SHARED));
if (failed == 0)
{
SDL_AddDisplayMode(display, mode);
SDL_DFB_LOG("Mode %d x %d Added\n", mode->w, mode->h);
}
else
SDL_DFB_ERR("Mode %d x %d not available: %x\n", mode->w,
mode->h, failed);
return;
error:
return;
}
void
DirectFB_SetContext(_THIS, SDL_Window *window)
{
#if (DFB_VERSION_ATLEAST(1,0,0))
/* FIXME: does not work on 1.0/1.2 with radeon driver
* the approach did work with the matrox driver
* This has simply no effect.
*/
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
/* FIXME: should we handle the error */
if (dispdata->vidIDinuse)
SDL_DFB_CHECK(dispdata->vidlayer->SwitchContext(dispdata->vidlayer,
DFB_TRUE));
#endif
}
void
DirectFB_InitModes(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
IDirectFBDisplayLayer *layer = NULL;
SDL_VideoDisplay display;
DFB_DisplayData *dispdata = NULL;
SDL_DisplayMode mode;
DFBGraphicsDeviceDescription caps;
DFBDisplayLayerConfig dlc;
struct screen_callback_t *screencbdata;
int tcw[DFB_MAX_SCREENS];
int tch[DFB_MAX_SCREENS];
int i;
DFBResult ret;
SDL_DFB_ALLOC_CLEAR(screencbdata, sizeof(*screencbdata));
screencbdata->numscreens = 0;
for (i = 0; i < DFB_MAX_SCREENS; i++) {
screencbdata->gralayer[i] = -1;
screencbdata->vidlayer[i] = -1;
}
SDL_DFB_CHECKERR(devdata->dfb->EnumScreens(devdata->dfb, &EnumScreensCallback,
screencbdata));
for (i = 0; i < screencbdata->numscreens; i++) {
IDirectFBScreen *screen;
SDL_DFB_CHECKERR(devdata->dfb->GetScreen(devdata->dfb,
screencbdata->screenid
[i], &screen));
screencbdata->aux = i;
SDL_DFB_CHECKERR(screen->EnumDisplayLayers(screen, &EnumLayersCallback,
screencbdata));
screen->GetSize(screen, &tcw[i], &tch[i]);
screen->Release(screen);
}
/* Query card capabilities */
devdata->dfb->GetDeviceDescription(devdata->dfb, &caps);
for (i = 0; i < screencbdata->numscreens; i++) {
SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
screencbdata->gralayer
[i], &layer));
SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer,
DLSCL_ADMINISTRATIVE));
layer->EnableCursor(layer, 1);
SDL_DFB_CHECKERR(layer->SetCursorOpacity(layer, 0xC0));
if (devdata->use_yuv_underlays) {
dlc.flags = DLCONF_PIXELFORMAT | DLCONF_OPTIONS;
dlc.pixelformat = DSPF_ARGB;
dlc.options = DLOP_ALPHACHANNEL;
ret = layer->SetConfiguration(layer, &dlc);
if (ret != DFB_OK) {
/* try AiRGB if the previous failed */
dlc.pixelformat = DSPF_AiRGB;
SDL_DFB_CHECKERR(layer->SetConfiguration(layer, &dlc));
}
}
/* Query layer configuration to determine the current mode and pixelformat */
dlc.flags = DLCONF_ALL;
SDL_DFB_CHECKERR(layer->GetConfiguration(layer, &dlc));
mode.format = DirectFB_DFBToSDLPixelFormat(dlc.pixelformat);
if (mode.format == SDL_PIXELFORMAT_UNKNOWN) {
SDL_DFB_ERR("Unknown dfb pixelformat %x !\n", dlc.pixelformat);
goto error;
}
mode.w = dlc.width;
mode.h = dlc.height;
mode.refresh_rate = 0;
mode.driverdata = NULL;
SDL_DFB_ALLOC_CLEAR(dispdata, sizeof(*dispdata));
dispdata->layer = layer;
dispdata->pixelformat = dlc.pixelformat;
dispdata->cw = tcw[i];
dispdata->ch = tch[i];
/* YUV - Video layer */
dispdata->vidID = screencbdata->vidlayer[i];
dispdata->vidIDinuse = 0;
SDL_zero(display);
display.desktop_mode = mode;
display.current_mode = mode;
display.driverdata = dispdata;
#if (DFB_VERSION_ATLEAST(1,2,0))
dlc.flags =
DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
DLCONF_OPTIONS;
ret = layer->SetConfiguration(layer, &dlc);
#endif
SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED));
SDL_AddVideoDisplay(&display);
}
SDL_DFB_FREE(screencbdata);
return;
error:
/* FIXME: Cleanup not complete, Free existing displays */
SDL_DFB_FREE(dispdata);
SDL_DFB_RELEASE(layer);
return;
}
void
DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
SDL_DFB_DEVICEDATA(_this);
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
SDL_DisplayMode mode;
struct modes_callback_t data;
int i;
data.nummodes = 0;
/* Enumerate the available fullscreen modes */
SDL_DFB_CALLOC(data.modelist, DFB_MAX_MODES, sizeof(SDL_DisplayMode));
SDL_DFB_CHECKERR(devdata->dfb->EnumVideoModes(devdata->dfb,
EnumModesCallback, &data));
for (i = 0; i < data.nummodes; ++i) {
mode = data.modelist[i];
mode.format = SDL_PIXELFORMAT_ARGB8888;
CheckSetDisplayMode(_this, display, dispdata, &mode);
mode.format = SDL_PIXELFORMAT_RGB888;
CheckSetDisplayMode(_this, display, dispdata, &mode);
mode.format = SDL_PIXELFORMAT_RGB24;
CheckSetDisplayMode(_this, display, dispdata, &mode);
mode.format = SDL_PIXELFORMAT_RGB565;
CheckSetDisplayMode(_this, display, dispdata, &mode);
mode.format = SDL_PIXELFORMAT_INDEX8;
CheckSetDisplayMode(_this, display, dispdata, &mode);
}
SDL_DFB_FREE(data.modelist);
error:
return;
}
int
DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
/*
* FIXME: video mode switch is currently broken for 1.2.0
*
*/
SDL_DFB_DEVICEDATA(_this);
DFB_DisplayData *data = (DFB_DisplayData *) display->driverdata;
DFBDisplayLayerConfig config, rconfig;
DFBDisplayLayerConfigFlags fail = 0;
SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
DLSCL_ADMINISTRATIVE));
SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &config));
config.flags = DLCONF_WIDTH | DLCONF_HEIGHT;
if (mode->format != SDL_PIXELFORMAT_UNKNOWN) {
config.flags |= DLCONF_PIXELFORMAT;
config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format);
data->pixelformat = config.pixelformat;
}
config.width = mode->w;
config.height = mode->h;
if (devdata->use_yuv_underlays) {
config.flags |= DLCONF_OPTIONS;
config.options = DLOP_ALPHACHANNEL;
}
data->layer->TestConfiguration(data->layer, &config, &fail);
if (fail &
(DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
DLCONF_OPTIONS)) {
SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h,
mode->format);
return -1;
}
config.flags &= ~fail;
SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
#if (DFB_VERSION_ATLEAST(1,2,0))
/* Need to call this twice ! */
SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
#endif
/* Double check */
SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig));
SDL_DFB_CHECKERR(data->
layer->SetCooperativeLevel(data->layer, DLSCL_SHARED));
if ((config.width != rconfig.width) || (config.height != rconfig.height)
|| ((mode->format != SDL_PIXELFORMAT_UNKNOWN)
&& (config.pixelformat != rconfig.pixelformat))) {
SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h,
mode->format);
return -1;
}
data->pixelformat = rconfig.pixelformat;
data->cw = config.width;
data->ch = config.height;
display->current_mode = *mode;
return 0;
error:
return -1;
}
void
DirectFB_QuitModes(_THIS)
{
SDL_DisplayMode tmode;
int i;
for (i = 0; i < _this->num_displays; ++i) {
SDL_VideoDisplay *display = &_this->displays[i];
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
SDL_GetDesktopDisplayMode(i, &tmode);
tmode.format = SDL_PIXELFORMAT_UNKNOWN;
DirectFB_SetDisplayMode(_this, display, &tmode);
SDL_GetDesktopDisplayMode(i, &tmode);
DirectFB_SetDisplayMode(_this, display, &tmode);
if (dispdata->layer) {
SDL_DFB_CHECK(dispdata->
layer->SetCooperativeLevel(dispdata->layer,
DLSCL_ADMINISTRATIVE));
SDL_DFB_CHECK(dispdata->
layer->SetCursorOpacity(dispdata->layer, 0x00));
SDL_DFB_CHECK(dispdata->
layer->SetCooperativeLevel(dispdata->layer,
DLSCL_SHARED));
}
SDL_DFB_RELEASE(dispdata->layer);
SDL_DFB_RELEASE(dispdata->vidlayer);
}
}
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,59 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_directfb_modes_h
#define _SDL_directfb_modes_h
#include <directfb.h>
#include "../SDL_sysvideo.h"
#define SDL_DFB_DISPLAYDATA(win) DFB_DisplayData *dispdata = ((win) ? (DFB_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata : NULL)
typedef struct _DFB_DisplayData DFB_DisplayData;
struct _DFB_DisplayData
{
IDirectFBDisplayLayer *layer;
DFBSurfacePixelFormat pixelformat;
/* FIXME: support for multiple video layer.
* However, I do not know any card supporting
* more than one
*/
DFBDisplayLayerID vidID;
IDirectFBDisplayLayer *vidlayer;
int vidIDinuse;
int cw;
int ch;
};
extern void DirectFB_InitModes(_THIS);
extern void DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
extern int DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
extern void DirectFB_QuitModes(_THIS);
extern void DirectFB_SetContext(_THIS, SDL_Window *window);
#endif /* _SDL_directfb_modes_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,394 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
#include "SDL_assert.h"
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_mouse.h"
#include "SDL_DirectFB_modes.h"
#include "SDL_DirectFB_window.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_mouse_c.h"
static SDL_Cursor *DirectFB_CreateDefaultCursor(void);
static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface,
int hot_x, int hot_y);
static int DirectFB_ShowCursor(SDL_Cursor * cursor);
static void DirectFB_MoveCursor(SDL_Cursor * cursor);
static void DirectFB_FreeCursor(SDL_Cursor * cursor);
static void DirectFB_WarpMouse(SDL_Window * window, int x, int y);
static void DirectFB_FreeMouse(SDL_Mouse * mouse);
static const char *arrow[] = {
/* pixels */
"X ",
"XX ",
"X.X ",
"X..X ",
"X...X ",
"X....X ",
"X.....X ",
"X......X ",
"X.......X ",
"X........X ",
"X.....XXXXX ",
"X..X..X ",
"X.X X..X ",
"XX X..X ",
"X X..X ",
" X..X ",
" X..X ",
" X..X ",
" XX ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
};
static SDL_Cursor *
DirectFB_CreateDefaultCursor(void)
{
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_DFB_DEVICEDATA(dev);
DFB_CursorData *curdata;
DFBResult ret;
DFBSurfaceDescription dsc;
SDL_Cursor *cursor;
Uint32 *dest;
Uint32 *p;
int pitch, i, j;
SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
dsc.flags =
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
dsc.caps = DSCAPS_VIDEOONLY;
dsc.width = 32;
dsc.height = 32;
dsc.pixelformat = DSPF_ARGB;
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
&curdata->surf));
curdata->hotx = 0;
curdata->hoty = 0;
cursor->driverdata = curdata;
SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
(void *) &dest, &pitch));
/* Relies on the fact that this is only called with ARGB surface. */
for (i = 0; i < 32; i++)
{
for (j = 0; j < 32; j++)
{
switch (arrow[i][j])
{
case ' ': dest[j] = 0x00000000; break;
case '.': dest[j] = 0xffffffff; break;
case 'X': dest[j] = 0xff000000; break;
}
}
dest += (pitch >> 2);
}
curdata->surf->Unlock(curdata->surf);
return cursor;
error:
return NULL;
}
/* Create a cursor from a surface */
static SDL_Cursor *
DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_DFB_DEVICEDATA(dev);
DFB_CursorData *curdata;
DFBResult ret;
DFBSurfaceDescription dsc;
SDL_Cursor *cursor;
Uint32 *dest;
Uint32 *p;
int pitch, i;
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
SDL_assert(surface->pitch == surface->w * 4);
SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
dsc.flags =
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
dsc.caps = DSCAPS_VIDEOONLY;
dsc.width = surface->w;
dsc.height = surface->h;
dsc.pixelformat = DSPF_ARGB;
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
&curdata->surf));
curdata->hotx = hot_x;
curdata->hoty = hot_y;
cursor->driverdata = curdata;
SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
(void *) &dest, &pitch));
p = surface->pixels;
for (i = 0; i < surface->h; i++)
memcpy((char *) dest + i * pitch,
(char *) p + i * surface->pitch, 4 * surface->w);
curdata->surf->Unlock(curdata->surf);
return cursor;
error:
return NULL;
}
/* Show the specified cursor, or hide if cursor is NULL */
static int
DirectFB_ShowCursor(SDL_Cursor * cursor)
{
SDL_DFB_CURSORDATA(cursor);
DFBResult ret;
SDL_Window *window;
window = SDL_GetFocusWindow();
if (!window)
return -1;
else {
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
if (display) {
DFB_DisplayData *dispdata =
(DFB_DisplayData *) display->driverdata;
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
if (cursor)
SDL_DFB_CHECKERR(windata->dfbwin->
SetCursorShape(windata->dfbwin,
curdata->surf, curdata->hotx,
curdata->hoty));
SDL_DFB_CHECKERR(dispdata->layer->
SetCooperativeLevel(dispdata->layer,
DLSCL_ADMINISTRATIVE));
SDL_DFB_CHECKERR(dispdata->layer->
SetCursorOpacity(dispdata->layer,
cursor ? 0xC0 : 0x00));
SDL_DFB_CHECKERR(dispdata->layer->
SetCooperativeLevel(dispdata->layer,
DLSCL_SHARED));
}
}
return 0;
error:
return -1;
}
/* Free a window manager cursor */
static void
DirectFB_FreeCursor(SDL_Cursor * cursor)
{
SDL_DFB_CURSORDATA(cursor);
SDL_DFB_RELEASE(curdata->surf);
SDL_DFB_FREE(cursor->driverdata);
SDL_DFB_FREE(cursor);
}
/* Warp the mouse to (x,y) */
static void
DirectFB_WarpMouse(SDL_Window * window, int x, int y)
{
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
DFBResult ret;
int cx, cy;
SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
cx + x + windata->client.x,
cy + y + windata->client.y));
error:
return;
}
#if USE_MULTI_API
static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window,
int x, int y);
static int id_mask;
static DFBEnumerationResult
EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc,
void *callbackdata)
{
DFB_DeviceData *devdata = callbackdata;
if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) {
SDL_Mouse mouse;
SDL_zero(mouse);
mouse.id = device_id;
mouse.CreateCursor = DirectFB_CreateCursor;
mouse.ShowCursor = DirectFB_ShowCursor;
mouse.MoveCursor = DirectFB_MoveCursor;
mouse.FreeCursor = DirectFB_FreeCursor;
mouse.WarpMouse = DirectFB_WarpMouse;
mouse.FreeMouse = DirectFB_FreeMouse;
mouse.cursor_shown = 1;
SDL_AddMouse(&mouse, desc.name, 0, 0, 1);
devdata->mouse_id[devdata->num_mice++] = device_id;
}
return DFENUM_OK;
}
void
DirectFB_InitMouse(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
devdata->num_mice = 0;
if (devdata->use_linux_input) {
/* try non-core devices first */
id_mask = 0xF0;
devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
if (devdata->num_mice == 0) {
/* try core devices */
id_mask = 0x0F;
devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
}
}
if (devdata->num_mice == 0) {
SDL_Mouse mouse;
SDL_zero(mouse);
mouse.CreateCursor = DirectFB_CreateCursor;
mouse.ShowCursor = DirectFB_ShowCursor;
mouse.MoveCursor = DirectFB_MoveCursor;
mouse.FreeCursor = DirectFB_FreeCursor;
mouse.WarpMouse = DirectFB_WarpMouse;
mouse.FreeMouse = DirectFB_FreeMouse;
mouse.cursor_shown = 1;
SDL_AddMouse(&mouse, "Mouse", 0, 0, 1);
devdata->num_mice = 1;
}
}
void
DirectFB_QuitMouse(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
if (devdata->use_linux_input) {
SDL_MouseQuit();
} else {
SDL_DelMouse(0);
}
}
/* This is called when a mouse motion event occurs */
static void
DirectFB_MoveCursor(SDL_Cursor * cursor)
{
}
/* Warp the mouse to (x,y) */
static void
DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y)
{
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
DFBResult ret;
int cx, cy;
SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
cx + x + windata->client.x,
cy + y + windata->client.y));
error:
return;
}
/* Free the mouse when it's time */
static void
DirectFB_FreeMouse(SDL_Mouse * mouse)
{
/* nothing yet */
}
#else /* USE_MULTI_API */
void
DirectFB_InitMouse(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
SDL_Mouse *mouse = SDL_GetMouse();
mouse->CreateCursor = DirectFB_CreateCursor;
mouse->ShowCursor = DirectFB_ShowCursor;
mouse->WarpMouse = DirectFB_WarpMouse;
mouse->FreeCursor = DirectFB_FreeCursor;
SDL_SetDefaultCursor(DirectFB_CreateDefaultCursor());
devdata->num_mice = 1;
}
void
DirectFB_QuitMouse(_THIS)
{
}
#endif
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,44 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_DirectFB_mouse_h
#define _SDL_DirectFB_mouse_h
#include <directfb.h>
#include "../SDL_sysvideo.h"
typedef struct _DFB_CursorData DFB_CursorData;
struct _DFB_CursorData
{
IDirectFBSurface *surf;
int hotx;
int hoty;
};
#define SDL_DFB_CURSORDATA(curs) DFB_CursorData *curdata = (DFB_CursorData *) ((curs) ? (curs)->driverdata : NULL)
extern void DirectFB_InitMouse(_THIS);
extern void DirectFB_QuitMouse(_THIS);
#endif /* _SDL_DirectFB_mouse_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,345 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
#include "SDL_DirectFB_video.h"
#if SDL_DIRECTFB_OPENGL
#include "SDL_DirectFB_opengl.h"
#include "SDL_DirectFB_window.h"
#include <directfbgl.h>
#include "SDL_loadso.h"
#endif
#if SDL_DIRECTFB_OPENGL
struct SDL_GLDriverData
{
int gl_active; /* to stop switching drivers while we have a valid context */
int initialized;
DirectFB_GLContext *firstgl; /* linked list */
/* OpenGL */
void (*glFinish) (void);
void (*glFlush) (void);
};
#define OPENGL_REQUIRS_DLOPEN
#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
#include <dlfcn.h>
#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
#define GL_LoadFunction dlsym
#define GL_UnloadObject dlclose
#else
#define GL_LoadObject SDL_LoadObject
#define GL_LoadFunction SDL_LoadFunction
#define GL_UnloadObject SDL_UnloadObject
#endif
static void DirectFB_GL_UnloadLibrary(_THIS);
int
DirectFB_GL_Initialize(_THIS)
{
if (_this->gl_data) {
return 0;
}
_this->gl_data =
(struct SDL_GLDriverData *) SDL_calloc(1,
sizeof(struct
SDL_GLDriverData));
if (!_this->gl_data) {
return SDL_OutOfMemory();
}
_this->gl_data->initialized = 0;
++_this->gl_data->initialized;
_this->gl_data->firstgl = NULL;
if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
return -1;
}
/* Initialize extensions */
/* FIXME needed?
* X11_GL_InitExtensions(_this);
*/
return 0;
}
void
DirectFB_GL_Shutdown(_THIS)
{
if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
return;
}
DirectFB_GL_UnloadLibrary(_this);
SDL_free(_this->gl_data);
_this->gl_data = NULL;
}
int
DirectFB_GL_LoadLibrary(_THIS, const char *path)
{
void *handle = NULL;
SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
if (_this->gl_data->gl_active) {
return SDL_SetError("OpenGL context already created");
}
if (path == NULL) {
path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
if (path == NULL) {
path = "libGL.so";
}
}
handle = GL_LoadObject(path);
if (handle == NULL) {
SDL_DFB_ERR("Library not found: %s\n", path);
/* SDL_LoadObject() will call SDL_SetError() for us. */
return -1;
}
SDL_DFB_DEBUG("Loaded library: %s\n", path);
_this->gl_config.dll_handle = handle;
_this->gl_config.driver_loaded = 1;
if (path) {
SDL_strlcpy(_this->gl_config.driver_path, path,
SDL_arraysize(_this->gl_config.driver_path));
} else {
*_this->gl_config.driver_path = '\0';
}
_this->gl_data->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
_this->gl_data->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
return 0;
}
static void
DirectFB_GL_UnloadLibrary(_THIS)
{
#if 0
int ret;
if (_this->gl_config.driver_loaded) {
ret = GL_UnloadObject(_this->gl_config.dll_handle);
if (ret)
SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
_this->gl_config.dll_handle = NULL;
_this->gl_config.driver_loaded = 0;
}
#endif
/* Free OpenGL memory */
SDL_free(_this->gl_data);
_this->gl_data = NULL;
}
void *
DirectFB_GL_GetProcAddress(_THIS, const char *proc)
{
void *handle;
handle = _this->gl_config.dll_handle;
return GL_LoadFunction(handle, proc);
}
SDL_GLContext
DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
DirectFB_GLContext *context;
SDL_DFB_ALLOC_CLEAR(context, sizeof(DirectFB_GLContext));
SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface,
&context->context));
if (!context->context)
return NULL;
context->is_locked = 0;
context->sdl_window = window;
context->next = _this->gl_data->firstgl;
_this->gl_data->firstgl = context;
SDL_DFB_CHECK(context->context->Unlock(context->context));
if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
DirectFB_GL_DeleteContext(_this, context);
return NULL;
}
return context;
error:
return NULL;
}
int
DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
{
DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
DirectFB_GLContext *p;
for (p = _this->gl_data->firstgl; p; p = p->next)
{
if (p->is_locked) {
SDL_DFB_CHECKERR(p->context->Unlock(p->context));
p->is_locked = 0;
}
}
if (ctx != NULL) {
SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context));
ctx->is_locked = 1;
}
return 0;
error:
return -1;
}
int
DirectFB_GL_SetSwapInterval(_THIS, int interval)
{
return SDL_Unsupported();
}
int
DirectFB_GL_GetSwapInterval(_THIS)
{
return 0;
}
void
DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
DFBRegion region;
DirectFB_GLContext *p;
region.x1 = 0;
region.y1 = 0;
region.x2 = window->w;
region.y2 = window->h;
#if 0
if (devdata->glFinish)
devdata->glFinish();
else if (devdata->glFlush)
devdata->glFlush();
#endif
for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
if (p->sdl_window == window && p->is_locked)
{
SDL_DFB_CHECKERR(p->context->Unlock(p->context));
p->is_locked = 0;
}
SDL_DFB_CHECKERR(windata->window_surface->Flip(windata->window_surface,NULL, DSFLIP_PIPELINE |DSFLIP_BLIT | DSFLIP_ONSYNC ));
return;
error:
return;
}
void
DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
{
DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
DirectFB_GLContext *p;
if (ctx->is_locked)
SDL_DFB_CHECK(ctx->context->Unlock(ctx->context));
SDL_DFB_RELEASE(ctx->context);
for (p = _this->gl_data->firstgl; p && p->next != ctx; p = p->next)
;
if (p)
p->next = ctx->next;
else
_this->gl_data->firstgl = ctx->next;
SDL_DFB_FREE(ctx);
}
void
DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window)
{
DirectFB_GLContext *p;
for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
if (p->sdl_window == window)
{
if (p->is_locked)
SDL_DFB_CHECK(p->context->Unlock(p->context));
SDL_DFB_RELEASE(p->context);
}
}
void
DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window)
{
DirectFB_GLContext *p;
for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
if (p->sdl_window == window)
{
SDL_DFB_WINDOWDATA(window);
SDL_DFB_CHECK(windata->surface->GetGL(windata->surface,
&p->context));
if (p->is_locked)
SDL_DFB_CHECK(p->context->Lock(p->context));
}
}
void
DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window)
{
DirectFB_GLContext *p;
for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
if (p->sdl_window == window)
DirectFB_GL_DeleteContext(_this, p);
}
#endif
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,64 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_directfb_opengl_h
#define _SDL_directfb_opengl_h
#include "SDL_DirectFB_video.h"
#if SDL_DIRECTFB_OPENGL
#include "SDL_opengl.h"
typedef struct _DirectFB_GLContext DirectFB_GLContext;
struct _DirectFB_GLContext
{
IDirectFBGL *context;
DirectFB_GLContext *next;
SDL_Window *sdl_window;
int is_locked;
};
/* OpenGL functions */
extern int DirectFB_GL_Initialize(_THIS);
extern void DirectFB_GL_Shutdown(_THIS);
extern int DirectFB_GL_LoadLibrary(_THIS, const char *path);
extern void *DirectFB_GL_GetProcAddress(_THIS, const char *proc);
extern SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window);
extern int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window,
SDL_GLContext context);
extern int DirectFB_GL_SetSwapInterval(_THIS, int interval);
extern int DirectFB_GL_GetSwapInterval(_THIS);
extern void DirectFB_GL_SwapWindow(_THIS, SDL_Window * window);
extern void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context);
extern void DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window);
extern void DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window);
extern void DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window);
#endif /* SDL_DIRECTFB_OPENGL */
#endif /* _SDL_directfb_opengl_h */
/* vi: set ts=4 sw=4 expandtab: */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* SDL surface based renderer implementation */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,134 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
#include "SDL_assert.h"
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_shape.h"
#include "SDL_DirectFB_window.h"
#include "../SDL_shape_internals.h"
SDL_Window*
DirectFB_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags) {
return SDL_CreateWindow(title,x,y,w,h,flags /* | SDL_DFB_WINDOW_SHAPED */);
}
SDL_WindowShaper*
DirectFB_CreateShaper(SDL_Window* window) {
SDL_WindowShaper* result = NULL;
result = malloc(sizeof(SDL_WindowShaper));
result->window = window;
result->mode.mode = ShapeModeDefault;
result->mode.parameters.binarizationCutoff = 1;
result->userx = result->usery = 0;
SDL_ShapeData* data = SDL_malloc(sizeof(SDL_ShapeData));
result->driverdata = data;
data->surface = NULL;
window->shaper = result;
int resized_properly = DirectFB_ResizeWindowShape(window);
SDL_assert(resized_properly == 0);
return result;
}
int
DirectFB_ResizeWindowShape(SDL_Window* window) {
SDL_ShapeData* data = window->shaper->driverdata;
SDL_assert(data != NULL);
if (window->x != -1000)
{
window->shaper->userx = window->x;
window->shaper->usery = window->y;
}
SDL_SetWindowPosition(window,-1000,-1000);
return 0;
}
int
DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) {
if(shaper == NULL || shape == NULL || shaper->driverdata == NULL)
return -1;
if(shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode))
return -2;
if(shape->w != shaper->window->w || shape->h != shaper->window->h)
return -3;
{
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(shaper->window);
SDL_DFB_DEVICEDATA(display->device);
Uint32 *pixels;
Sint32 pitch;
Uint32 h,w;
Uint8 *src, *bitmap;
DFBSurfaceDescription dsc;
SDL_ShapeData *data = shaper->driverdata;
SDL_DFB_RELEASE(data->surface);
dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
dsc.width = shape->w;
dsc.height = shape->h;
dsc.caps = DSCAPS_PREMULTIPLIED;
dsc.pixelformat = DSPF_ARGB;
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, &data->surface));
/* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
SDL_DFB_ALLOC_CLEAR(bitmap, shape->w * shape->h);
SDL_CalculateShapeBitmap(shaper->mode,shape,bitmap,1);
src = bitmap;
SDL_DFB_CHECK(data->surface->Lock(data->surface, DSLF_WRITE | DSLF_READ, (void **) &pixels, &pitch));
h = shaper->window->h;
while (h--) {
for (w = 0; w < shaper->window->w; w++) {
if (*src)
pixels[w] = 0xFFFFFFFF;
else
pixels[w] = 0;
src++;
}
pixels += (pitch >> 2);
}
SDL_DFB_CHECK(data->surface->Unlock(data->surface));
SDL_DFB_FREE(bitmap);
/* FIXME: Need to call this here - Big ?? */
DirectFB_WM_RedrawLayout(SDL_GetDisplayForWindow(shaper->window)->device, shaper->window);
}
return 0;
error:
return -1;
}
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */

View File

@@ -0,0 +1,39 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_DirectFB_shape_h
#define _SDL_DirectFB_shape_h
#include <directfb.h>
#include "../SDL_sysvideo.h"
#include "SDL_shape.h"
typedef struct {
IDirectFBSurface *surface;
} SDL_ShapeData;
extern SDL_Window* DirectFB_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags);
extern SDL_WindowShaper* DirectFB_CreateShaper(SDL_Window* window);
extern int DirectFB_ResizeWindowShape(SDL_Window* window);
extern int DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode);
#endif /* _SDL_DirectFB_shape_h */

View File

@@ -0,0 +1,424 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_events.h"
/*
* #include "SDL_DirectFB_keyboard.h"
*/
#include "SDL_DirectFB_modes.h"
#include "SDL_DirectFB_mouse.h"
#include "SDL_DirectFB_opengl.h"
#include "SDL_DirectFB_window.h"
#include "SDL_DirectFB_WM.h"
/* DirectFB video driver implementation.
*/
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <directfb.h>
#include <directfb_version.h>
#include <directfb_strings.h>
#include "SDL_video.h"
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_events.h"
#include "SDL_DirectFB_render.h"
#include "SDL_DirectFB_mouse.h"
#include "SDL_DirectFB_shape.h"
#include "SDL_DirectFB_dyn.h"
/* Initialization/Query functions */
static int DirectFB_VideoInit(_THIS);
static void DirectFB_VideoQuit(_THIS);
static int DirectFB_Available(void);
static SDL_VideoDevice *DirectFB_CreateDevice(int devindex);
VideoBootStrap DirectFB_bootstrap = {
"directfb", "DirectFB",
DirectFB_Available, DirectFB_CreateDevice
};
static const DirectFBSurfaceDrawingFlagsNames(drawing_flags);
static const DirectFBSurfaceBlittingFlagsNames(blitting_flags);
static const DirectFBAccelerationMaskNames(acceleration_mask);
/* DirectFB driver bootstrap functions */
static int
DirectFB_Available(void)
{
if (!SDL_DirectFB_LoadLibrary())
return 0;
SDL_DirectFB_UnLoadLibrary();
return 1;
}
static void
DirectFB_DeleteDevice(SDL_VideoDevice * device)
{
SDL_DirectFB_UnLoadLibrary();
SDL_DFB_FREE(device->driverdata);
SDL_DFB_FREE(device);
}
static SDL_VideoDevice *
DirectFB_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
if (!SDL_DirectFB_LoadLibrary()) {
return NULL;
}
/* Initialize all variables that we clean on shutdown */
SDL_DFB_ALLOC_CLEAR(device, sizeof(SDL_VideoDevice));
/* Set the function pointers */
/* Set the function pointers */
device->VideoInit = DirectFB_VideoInit;
device->VideoQuit = DirectFB_VideoQuit;
device->GetDisplayModes = DirectFB_GetDisplayModes;
device->SetDisplayMode = DirectFB_SetDisplayMode;
device->PumpEvents = DirectFB_PumpEventsWindow;
device->CreateWindow = DirectFB_CreateWindow;
device->CreateWindowFrom = DirectFB_CreateWindowFrom;
device->SetWindowTitle = DirectFB_SetWindowTitle;
device->SetWindowIcon = DirectFB_SetWindowIcon;
device->SetWindowPosition = DirectFB_SetWindowPosition;
device->SetWindowSize = DirectFB_SetWindowSize;
device->ShowWindow = DirectFB_ShowWindow;
device->HideWindow = DirectFB_HideWindow;
device->RaiseWindow = DirectFB_RaiseWindow;
device->MaximizeWindow = DirectFB_MaximizeWindow;
device->MinimizeWindow = DirectFB_MinimizeWindow;
device->RestoreWindow = DirectFB_RestoreWindow;
device->SetWindowGrab = DirectFB_SetWindowGrab;
device->DestroyWindow = DirectFB_DestroyWindow;
device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
/* !!! FIXME: implement SetWindowBordered */
#if SDL_DIRECTFB_OPENGL
device->GL_LoadLibrary = DirectFB_GL_LoadLibrary;
device->GL_GetProcAddress = DirectFB_GL_GetProcAddress;
device->GL_MakeCurrent = DirectFB_GL_MakeCurrent;
device->GL_CreateContext = DirectFB_GL_CreateContext;
device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval;
device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval;
device->GL_SwapWindow = DirectFB_GL_SwapWindow;
device->GL_DeleteContext = DirectFB_GL_DeleteContext;
#endif
/* Shaped window support */
device->shape_driver.CreateShaper = DirectFB_CreateShaper;
device->shape_driver.SetWindowShape = DirectFB_SetWindowShape;
device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape;
device->free = DirectFB_DeleteDevice;
return device;
error:
if (device)
SDL_free(device);
return (0);
}
static void
DirectFB_DeviceInformation(IDirectFB * dfb)
{
DFBGraphicsDeviceDescription desc;
int n;
dfb->GetDeviceDescription(dfb, &desc);
SDL_DFB_LOG( "DirectFB Device Information");
SDL_DFB_LOG( "===========================");
SDL_DFB_LOG( "Name: %s", desc.name);
SDL_DFB_LOG( "Vendor: %s", desc.vendor);
SDL_DFB_LOG( "Driver Name: %s", desc.driver.name);
SDL_DFB_LOG( "Driver Vendor: %s", desc.driver.vendor);
SDL_DFB_LOG( "Driver Version: %d.%d", desc.driver.major,
desc.driver.minor);
SDL_DFB_LOG( "Video memoory: %d", desc.video_memory);
SDL_DFB_LOG( "Blitting flags:");
for (n = 0; blitting_flags[n].flag; n++) {
if (desc.blitting_flags & blitting_flags[n].flag)
SDL_DFB_LOG( " %s", blitting_flags[n].name);
}
SDL_DFB_LOG( "Drawing flags:");
for (n = 0; drawing_flags[n].flag; n++) {
if (desc.drawing_flags & drawing_flags[n].flag)
SDL_DFB_LOG( " %s", drawing_flags[n].name);
}
SDL_DFB_LOG( "Acceleration flags:");
for (n = 0; acceleration_mask[n].mask; n++) {
if (desc.acceleration_mask & acceleration_mask[n].mask)
SDL_DFB_LOG( " %s", acceleration_mask[n].name);
}
}
static int readBoolEnv(const char *env_name, int def_val)
{
char *stemp;
stemp = SDL_getenv(env_name);
if (stemp)
return atoi(stemp);
else
return def_val;
}
static int
DirectFB_VideoInit(_THIS)
{
IDirectFB *dfb = NULL;
DFB_DeviceData *devdata = NULL;
DFBResult ret;
SDL_DFB_ALLOC_CLEAR(devdata, sizeof(*devdata));
SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));
/* avoid switching to the framebuffer when we
* are running X11 */
ret = readBoolEnv(DFBENV_USE_X11_CHECK , 1);
if (ret) {
if (SDL_getenv("DISPLAY"))
DirectFBSetOption("system", "x11");
else
DirectFBSetOption("disable-module", "x11input");
}
/* FIXME: Reenable as default once multi kbd/mouse interface is sorted out */
devdata->use_linux_input = readBoolEnv(DFBENV_USE_LINUX_INPUT, 0); /* default: on */
if (!devdata->use_linux_input)
{
SDL_DFB_LOG("Disabling linux input\n");
DirectFBSetOption("disable-module", "linux_input");
}
SDL_DFB_CHECKERR(DirectFBCreate(&dfb));
DirectFB_DeviceInformation(dfb);
devdata->use_yuv_underlays = readBoolEnv(DFBENV_USE_YUV_UNDERLAY, 0); /* default: off */
devdata->use_yuv_direct = readBoolEnv(DFBENV_USE_YUV_DIRECT, 0); /* default is off! */
/* Create global Eventbuffer for axis events */
if (devdata->use_linux_input) {
SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_ALL,
DFB_TRUE,
&devdata->events));
} else {
SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_AXES
/* DICAPS_ALL */ ,
DFB_TRUE,
&devdata->events));
}
/* simple window manager support */
devdata->has_own_wm = readBoolEnv(DFBENV_USE_WM, 0);
devdata->initialized = 1;
devdata->dfb = dfb;
devdata->firstwin = NULL;
devdata->grabbed_window = NULL;
_this->driverdata = devdata;
DirectFB_InitModes(_this);
#if SDL_DIRECTFB_OPENGL
DirectFB_GL_Initialize(_this);
#endif
DirectFB_InitMouse(_this);
DirectFB_InitKeyboard(_this);
return 0;
error:
SDL_DFB_FREE(devdata);
SDL_DFB_RELEASE(dfb);
return -1;
}
static void
DirectFB_VideoQuit(_THIS)
{
DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata;
DirectFB_QuitModes(_this);
DirectFB_QuitKeyboard(_this);
DirectFB_QuitMouse(_this);
devdata->events->Reset(devdata->events);
SDL_DFB_RELEASE(devdata->events);
SDL_DFB_RELEASE(devdata->dfb);
#if SDL_DIRECTFB_OPENGL
DirectFB_GL_Shutdown(_this);
#endif
devdata->initialized = 0;
}
/* DirectFB driver general support functions */
static const struct {
DFBSurfacePixelFormat dfb;
Uint32 sdl;
} pixelformat_tab[] =
{
{ DSPF_RGB32, SDL_PIXELFORMAT_RGB888 }, /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
{ DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 }, /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */
{ DSPF_RGB16, SDL_PIXELFORMAT_RGB565 }, /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
{ DSPF_RGB332, SDL_PIXELFORMAT_RGB332 }, /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
{ DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 }, /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */
{ DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 }, /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */
{ DSPF_RGB24, SDL_PIXELFORMAT_RGB24 }, /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
{ DSPF_RGB444, SDL_PIXELFORMAT_RGB444 }, /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */
{ DSPF_YV12, SDL_PIXELFORMAT_YV12 }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */
{ DSPF_I420,SDL_PIXELFORMAT_IYUV }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */
{ DSPF_YUY2, SDL_PIXELFORMAT_YUY2 }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */
{ DSPF_UYVY, SDL_PIXELFORMAT_UYVY }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */
{ DSPF_RGB555, SDL_PIXELFORMAT_RGB555 }, /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */
#if (ENABLE_LUT8)
{ DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 }, /* 8 bit LUT (8 bit color and alpha lookup from palette) */
#endif
#if (DFB_VERSION_ATLEAST(1,2,0))
{ DSPF_BGR555, SDL_PIXELFORMAT_BGR555 }, /* 16 bit BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */
#else
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR555 },
#endif
/* Pfff ... nonmatching formats follow */
{ DSPF_ALUT44, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit ALUT (1 byte, alpha 4@4, color lookup 4@0) */
{ DSPF_A8, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit alpha (1 byte, alpha 8@0), e.g. anti-aliased glyphs */
{ DSPF_AiRGB, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */
{ DSPF_A1, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */
{ DSPF_NV12, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CbCr [15:0] plane) */
{ DSPF_NV16, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit YUV (8 bit Y plane followed by one 16 bit half width CbCr [15:0] plane) */
{ DSPF_ARGB2554, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */
{ DSPF_NV21, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CrCb [15:0] plane) */
{ DSPF_AYUV, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */
{ DSPF_A4, SDL_PIXELFORMAT_UNKNOWN }, /* 4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */
{ DSPF_ARGB1666, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (3 byte/ alpha 1@18, red 6@16, green 6@6, blue 6@0) */
{ DSPF_ARGB6666, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit alpha (3 byte/ alpha 6@18, red 6@16, green 6@6, blue 6@0) */
{ DSPF_RGB18, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit RGB (3 byte/ red 6@16, green 6@6, blue 6@0) */
{ DSPF_LUT2, SDL_PIXELFORMAT_UNKNOWN }, /* 2 bit LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */
#if (DFB_VERSION_ATLEAST(1,3,0))
{ DSPF_RGBA4444, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 4@12, green 4@8, blue 4@4, alpha 4@0) */
#endif
#if (DFB_VERSION_ATLEAST(1,4,3))
{ DSPF_RGBA5551, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 5@11, green 5@6, blue 5@1, alpha 1@0) */
{ DSPF_YUV444P, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit full YUV planar (8 bit Y plane followed by an 8 bit Cb and an 8 bit Cr plane) */
{ DSPF_ARGB8565, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit ARGB (3 byte, alpha 8@16, red 5@11, green 6@5, blue 5@0) */
{ DSPF_AVYU, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AVYU 4:4:4 (4 byte, alpha 8@24, Cr 8@16, Y 8@8, Cb 8@0) */
{ DSPF_VYU, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit VYU 4:4:4 (3 byte, Cr 8@16, Y 8@8, Cb 8@0) */
#endif
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1MSB },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4LSB },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4MSB },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR24 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR888 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_RGBA8888 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR8888 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGRA8888 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ARGB2101010 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR4444 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR1555 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR565 },
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU }, /**< Packed mode: Y0+V0+Y1+U0 (1 pla */
};
Uint32
DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat)
{
int i;
for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
if (pixelformat_tab[i].dfb == pixelformat)
{
return pixelformat_tab[i].sdl;
}
return SDL_PIXELFORMAT_UNKNOWN;
}
DFBSurfacePixelFormat
DirectFB_SDLToDFBPixelFormat(Uint32 format)
{
int i;
for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
if (pixelformat_tab[i].sdl == format)
{
return pixelformat_tab[i].dfb;
}
return DSPF_UNKNOWN;
}
void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo* ri)
{
int i, j;
for (i=0, j=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
if (pixelformat_tab[i].sdl != SDL_PIXELFORMAT_UNKNOWN)
ri->texture_formats[j++] = pixelformat_tab[i].sdl;
ri->num_texture_formats = j;
}
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */

View File

@@ -0,0 +1,170 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef _SDL_DirectFB_video_h
#define _SDL_DirectFB_video_h
#include <directfb.h>
#include <directfb_version.h>
#include "../SDL_sysvideo.h"
#include "SDL_scancode.h"
#include "SDL_render.h"
#include "SDL_log.h"
#define DFB_VERSIONNUM(X, Y, Z) \
((X)*1000 + (Y)*100 + (Z))
#define DFB_COMPILEDVERSION \
DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION)
#define DFB_VERSION_ATLEAST(X, Y, Z) \
(DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z))
#if (DFB_VERSION_ATLEAST(1,0,0))
#ifdef SDL_VIDEO_OPENGL
#define SDL_DIRECTFB_OPENGL 1
#endif
#else
#error "SDL_DIRECTFB: Please compile against libdirectfb version >= 1.0.0"
#endif
/* Set below to 1 to compile with (old) multi mice/keyboard api. Code left in
* in case we see this again ...
*/
#define USE_MULTI_API (0)
/* Support for LUT8/INDEX8 pixel format.
* This is broken in DirectFB 1.4.3. It works in 1.4.0 and 1.4.5
* occurred.
*/
#if (DFB_COMPILEDVERSION == DFB_VERSIONNUM(1, 4, 3))
#define ENABLE_LUT8 (0)
#else
#define ENABLE_LUT8 (1)
#endif
#define DIRECTFB_DEBUG 1
#define DFBENV_USE_YUV_UNDERLAY "SDL_DIRECTFB_YUV_UNDERLAY" /* Default: off */
#define DFBENV_USE_YUV_DIRECT "SDL_DIRECTFB_YUV_DIRECT" /* Default: off */
#define DFBENV_USE_X11_CHECK "SDL_DIRECTFB_X11_CHECK" /* Default: on */
#define DFBENV_USE_LINUX_INPUT "SDL_DIRECTFB_LINUX_INPUT" /* Default: on */
#define DFBENV_USE_WM "SDL_DIRECTFB_WM" /* Default: off */
#define SDL_DFB_RELEASE(x) do { if ( (x) != NULL ) { SDL_DFB_CHECK(x->Release(x)); x = NULL; } } while (0)
#define SDL_DFB_FREE(x) do { SDL_free((x)); (x) = NULL; } while (0)
#define SDL_DFB_UNLOCK(x) do { if ( (x) != NULL ) { x->Unlock(x); } } while (0)
#define SDL_DFB_CONTEXT "SDL_DirectFB"
#define SDL_DFB_ERR(x...) SDL_LogError(SDL_LOG_CATEGORY_ERROR, x)
#if (DIRECTFB_DEBUG)
#define SDL_DFB_LOG(x...) SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, x)
#define SDL_DFB_DEBUG(x...) SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, x)
static SDL_INLINE DFBResult sdl_dfb_check(DFBResult ret, const char *src_file, int src_line) {
if (ret != DFB_OK) {
SDL_DFB_LOG("%s (%d):%s", src_file, src_line, DirectFBErrorString (ret) );
SDL_SetError("%s:%s", SDL_DFB_CONTEXT, DirectFBErrorString (ret) );
}
return ret;
}
#define SDL_DFB_CHECK(x...) do { sdl_dfb_check( x, __FILE__, __LINE__); } while (0)
#define SDL_DFB_CHECKERR(x...) do { if ( sdl_dfb_check( x, __FILE__, __LINE__) != DFB_OK ) goto error; } while (0)
#else
#define SDL_DFB_CHECK(x...) x
#define SDL_DFB_CHECKERR(x...) do { if (x != DFB_OK ) goto error; } while (0)
#define SDL_DFB_LOG(x...) do {} while (0)
#define SDL_DFB_DEBUG(x...) do {} while (0)
#endif
#define SDL_DFB_CALLOC(r, n, s) \
do { \
r = SDL_calloc (n, s); \
if (!(r)) { \
SDL_DFB_ERR("Out of memory"); \
SDL_OutOfMemory(); \
goto error; \
} \
} while (0)
#define SDL_DFB_ALLOC_CLEAR(r, s) SDL_DFB_CALLOC(r, 1, s)
/* Private display data */
#define SDL_DFB_DEVICEDATA(dev) DFB_DeviceData *devdata = (dev ? (DFB_DeviceData *) ((dev)->driverdata) : NULL)
#define DFB_MAX_SCREENS 10
typedef struct _DFB_KeyboardData DFB_KeyboardData;
struct _DFB_KeyboardData
{
const SDL_Scancode *map; /* keyboard scancode map */
int map_size; /* size of map */
int map_adjust; /* index adjust */
int is_generic; /* generic keyboard */
int id;
};
typedef struct _DFB_DeviceData DFB_DeviceData;
struct _DFB_DeviceData
{
int initialized;
IDirectFB *dfb;
int num_mice;
int mouse_id[0x100];
int num_keyboard;
DFB_KeyboardData keyboard[10];
SDL_Window *firstwin;
int use_yuv_underlays;
int use_yuv_direct;
int use_linux_input;
int has_own_wm;
/* window grab */
SDL_Window *grabbed_window;
/* global events */
IDirectFBEventBuffer *events;
};
Uint32 DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat);
DFBSurfacePixelFormat DirectFB_SDLToDFBPixelFormat(Uint32 format);
void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo *ri);
#endif /* _SDL_DirectFB_video_h */

View File

@@ -0,0 +1,532 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_DIRECTFB
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_modes.h"
#include "SDL_DirectFB_window.h"
#include "SDL_DirectFB_shape.h"
#if SDL_DIRECTFB_OPENGL
#include "SDL_DirectFB_opengl.h"
#endif
#include "SDL_syswm.h"
#include "../SDL_pixels_c.h"
int
DirectFB_CreateWindow(_THIS, SDL_Window * window)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_DISPLAYDATA(window);
DFB_WindowData *windata = NULL;
DFBWindowOptions wopts;
DFBWindowDescription desc;
int x, y;
int bshaped = 0;
SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
SDL_memset(&desc, 0, sizeof(DFBWindowDescription));
windata = (DFB_WindowData *) window->driverdata;
windata->is_managed = devdata->has_own_wm;
#if 1
SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
DFSCL_NORMAL));
SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
DLSCL_ADMINISTRATIVE));
#endif
/* FIXME ... ughh, ugly */
if (window->x == -1000 && window->y == -1000)
bshaped = 1;
/* Fill the window description. */
x = window->x;
y = window->y;
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
/* Create Window */
desc.caps = 0;
desc.flags =
DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
if (bshaped) {
desc.flags |= DWDESC_CAPS;
desc.caps |= DWCAPS_ALPHACHANNEL;
}
else
{
desc.flags |= DWDESC_PIXELFORMAT;
}
if (!(window->flags & SDL_WINDOW_BORDERLESS))
desc.caps |= DWCAPS_NODECORATION;
desc.posx = x;
desc.posy = y;
desc.width = windata->size.w;
desc.height = windata->size.h;
desc.pixelformat = dispdata->pixelformat;
desc.surface_caps = DSCAPS_PREMULTIPLIED;
#if DIRECTFB_MAJOR_VERSION == 1 && DIRECTFB_MINOR_VERSION >= 6
if (window->flags & SDL_WINDOW_OPENGL) {
desc.surface_caps |= DSCAPS_GL;
}
#endif
/* Create the window. */
SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
&windata->dfbwin));
/* Set Options */
SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
/* explicit rescaling of surface */
wopts |= DWOP_SCALE;
if (window->flags & SDL_WINDOW_RESIZABLE) {
wopts &= ~DWOP_KEEP_SIZE;
}
else {
wopts |= DWOP_KEEP_SIZE;
}
if (window->flags & SDL_WINDOW_FULLSCREEN) {
wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
}
if (bshaped) {
wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
wopts &= ~DWOP_OPAQUE_REGION;
}
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
/* See what we got */
SDL_DFB_CHECK(DirectFB_WM_GetClientSize
(_this, window, &window->w, &window->h));
/* Get the window's surface. */
SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
&windata->window_surface));
/* And get a subsurface for rendering */
SDL_DFB_CHECKERR(windata->window_surface->
GetSubSurface(windata->window_surface, &windata->client,
&windata->surface));
SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));
/* Create Eventbuffer */
SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
&windata->
eventbuffer));
SDL_DFB_CHECKERR(windata->dfbwin->
EnableEvents(windata->dfbwin, DWET_ALL));
/* Create a font */
/* FIXME: once during Video_Init */
windata->font = NULL;
/* Make it the top most window. */
SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
/* remember parent */
/* windata->sdlwin = window; */
/* Add to list ... */
windata->next = devdata->firstwin;
windata->opacity = 0xFF;
devdata->firstwin = window;
/* Draw Frame */
DirectFB_WM_RedrawLayout(_this, window);
return 0;
error:
SDL_DFB_RELEASE(windata->surface);
SDL_DFB_RELEASE(windata->dfbwin);
return -1;
}
int
DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
return SDL_Unsupported();
}
void
DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
if (windata->is_managed) {
windata->wm_needs_redraw = 1;
DirectFB_WM_RedrawLayout(_this, window);
} else {
SDL_Unsupported();
}
}
void
DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
SDL_Surface *surface = NULL;
if (icon) {
SDL_PixelFormat format;
DFBSurfaceDescription dsc;
Uint32 *dest;
Uint32 *p;
int pitch, i;
/* Convert the icon to ARGB for modern window managers */
SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
surface = SDL_ConvertSurface(icon, &format, 0);
if (!surface) {
return;
}
dsc.flags =
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
dsc.caps = DSCAPS_VIDEOONLY;
dsc.width = surface->w;
dsc.height = surface->h;
dsc.pixelformat = DSPF_ARGB;
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
&windata->icon));
SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
(void *) &dest, &pitch));
p = surface->pixels;
for (i = 0; i < surface->h; i++)
memcpy((char *) dest + i * pitch,
(char *) p + i * surface->pitch, 4 * surface->w);
SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
SDL_FreeSurface(surface);
} else {
SDL_DFB_RELEASE(windata->icon);
}
return;
error:
SDL_FreeSurface(surface);
SDL_DFB_RELEASE(windata->icon);
return;
}
void
DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
int x, y;
x = window->x;
y = window->y;
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
}
void
DirectFB_SetWindowSize(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
if(SDL_IsShapedWindow(window))
DirectFB_ResizeWindowShape(window);
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
int cw;
int ch;
/* Make sure all events are disabled for this operation ! */
SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
DWET_ALL));
SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));
if (cw != window->w || ch != window->h) {
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
windata->size.w,
windata->size.h));
}
SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
(_this, window, &window->w, &window->h));
DirectFB_AdjustWindowSurface(window);
SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
DWET_ALL));
}
return;
error:
SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
return;
}
void
DirectFB_ShowWindow(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));
}
void
DirectFB_HideWindow(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
}
void
DirectFB_RaiseWindow(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
}
void
DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
DFBWindowOptions wopts;
SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
&windata->restore.x, &windata->restore.y));
SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
&windata->restore.h));
DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ;
SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
display->current_mode.w, display->current_mode.h));
/* Set Options */
SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
}
void
DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
{
/* FIXME: Size to 32x32 ? */
SDL_Unsupported();
}
void
DirectFB_RestoreWindow(_THIS, SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
DFBWindowOptions wopts;
/* Set Options */
SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
/* Window layout */
DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED),
windata->restore.w, windata->restore.h);
SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
windata->restore.h));
SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
windata->restore.y));
if (!(window->flags & SDL_WINDOW_RESIZABLE))
wopts |= DWOP_KEEP_SIZE;
if (window->flags & SDL_WINDOW_FULLSCREEN)
wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
}
void
DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
if (gwindata != NULL)
{
SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
}
SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
devdata->grabbed_window = window;
} else {
SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
devdata->grabbed_window = NULL;
}
}
void
DirectFB_DestroyWindow(_THIS, SDL_Window * window)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
DFB_WindowData *p;
/* Some cleanups */
SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
#if SDL_DIRECTFB_OPENGL
DirectFB_GL_DestroyWindowContexts(_this, window);
#endif
if (window->shaper)
{
SDL_ShapeData *data = window->shaper->driverdata;
SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
SDL_DFB_RELEASE(data->surface);
SDL_DFB_FREE(data);
SDL_DFB_FREE(window->shaper);
}
SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
SDL_DFB_RELEASE(windata->icon);
SDL_DFB_RELEASE(windata->font);
SDL_DFB_RELEASE(windata->eventbuffer);
SDL_DFB_RELEASE(windata->surface);
SDL_DFB_RELEASE(windata->window_surface);
SDL_DFB_RELEASE(windata->dfbwin);
/* Remove from list ... */
p = devdata->firstwin->driverdata;
while (p && p->next != window)
p = (p->next ? p->next->driverdata : NULL);
if (p)
p->next = windata->next;
else
devdata->firstwin = windata->next;
SDL_free(windata);
return;
}
SDL_bool
DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo * info)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DFB_WINDOWDATA(window);
if (info->version.major == SDL_MAJOR_VERSION &&
info->version.minor == SDL_MINOR_VERSION) {
info->subsystem = SDL_SYSWM_DIRECTFB;
info->info.dfb.dfb = devdata->dfb;
info->info.dfb.window = windata->dfbwin;
info->info.dfb.surface = windata->surface;
return SDL_TRUE;
} else {
SDL_SetError("Application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
}
void
DirectFB_AdjustWindowSurface(SDL_Window * window)
{
SDL_DFB_WINDOWDATA(window);
int adjust = windata->wm_needs_redraw;
int cw, ch;
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
SDL_DFB_CHECKERR(windata->
window_surface->GetSize(windata->window_surface, &cw,
&ch));
if (cw != windata->size.w || ch != windata->size.h) {
adjust = 1;
}
if (adjust) {
#if SDL_DIRECTFB_OPENGL
DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
#endif
#if (DFB_VERSION_ATLEAST(1,2,1))
SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
windata->size.w,
windata->size.h));
SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
windata->
window_surface,
&windata->client));
#else
DFBWindowOptions opts;
SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
/* recreate subsurface */
SDL_DFB_RELEASE(windata->surface);
if (opts & DWOP_SCALE)
SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
windata->size.w,
windata->size.h));
SDL_DFB_CHECKERR(windata->window_surface->
GetSubSurface(windata->window_surface,
&windata->client, &windata->surface));
#endif
DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window);
#if SDL_DIRECTFB_OPENGL
DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
#endif
}
error:
return;
}
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */

View File

@@ -0,0 +1,81 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_directfb_window_h
#define _SDL_directfb_window_h
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_WM.h"
#define SDL_DFB_WINDOWDATA(win) DFB_WindowData *windata = ((win) ? (DFB_WindowData *) ((win)->driverdata) : NULL)
typedef struct _DFB_WindowData DFB_WindowData;
struct _DFB_WindowData
{
IDirectFBSurface *window_surface; /* window surface */
IDirectFBSurface *surface; /* client drawing surface */
IDirectFBWindow *dfbwin;
IDirectFBEventBuffer *eventbuffer;
/* SDL_Window *sdlwin; */
SDL_Window *next;
Uint8 opacity;
DFBRectangle client;
DFBDimension size;
DFBRectangle restore;
/* WM extras */
int is_managed;
int wm_needs_redraw;
IDirectFBSurface *icon;
IDirectFBFont *font;
DFB_Theme theme;
/* WM moving and sizing */
int wm_grab;
int wm_lastx;
int wm_lasty;
};
extern int DirectFB_CreateWindow(_THIS, SDL_Window * window);
extern int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window,
const void *data);
extern void DirectFB_SetWindowTitle(_THIS, SDL_Window * window);
extern void DirectFB_SetWindowIcon(_THIS, SDL_Window * window,
SDL_Surface * icon);
extern void DirectFB_SetWindowPosition(_THIS, SDL_Window * window);
extern void DirectFB_SetWindowSize(_THIS, SDL_Window * window);
extern void DirectFB_ShowWindow(_THIS, SDL_Window * window);
extern void DirectFB_HideWindow(_THIS, SDL_Window * window);
extern void DirectFB_RaiseWindow(_THIS, SDL_Window * window);
extern void DirectFB_MaximizeWindow(_THIS, SDL_Window * window);
extern void DirectFB_MinimizeWindow(_THIS, SDL_Window * window);
extern void DirectFB_RestoreWindow(_THIS, SDL_Window * window);
extern void DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void DirectFB_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
extern void DirectFB_AdjustWindowSurface(SDL_Window * window);
#endif /* _SDL_directfb_window_h */
/* vi: set ts=4 sw=4 expandtab: */