mirror of
https://github.com/encounter/SDL.git
synced 2025-12-15 16:16:16 +00:00
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:
413
src/video/directfb/SDL_DirectFB_WM.c
Normal file
413
src/video/directfb/SDL_DirectFB_WM.c
Normal 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 */
|
||||
56
src/video/directfb/SDL_DirectFB_WM.h
Normal file
56
src/video/directfb/SDL_DirectFB_WM.h
Normal 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: */
|
||||
117
src/video/directfb/SDL_DirectFB_dyn.c
Normal file
117
src/video/directfb/SDL_DirectFB_dyn.c
Normal 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 */
|
||||
39
src/video/directfb/SDL_DirectFB_dyn.h
Normal file
39
src/video/directfb/SDL_DirectFB_dyn.h
Normal 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
|
||||
751
src/video/directfb/SDL_DirectFB_events.c
Normal file
751
src/video/directfb/SDL_DirectFB_events.c
Normal 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 */
|
||||
32
src/video/directfb/SDL_DirectFB_events.h
Normal file
32
src/video/directfb/SDL_DirectFB_events.h
Normal 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
|
||||
414
src/video/directfb/SDL_DirectFB_modes.c
Normal file
414
src/video/directfb/SDL_DirectFB_modes.c
Normal 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: */
|
||||
59
src/video/directfb/SDL_DirectFB_modes.h
Normal file
59
src/video/directfb/SDL_DirectFB_modes.h
Normal 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: */
|
||||
394
src/video/directfb/SDL_DirectFB_mouse.c
Normal file
394
src/video/directfb/SDL_DirectFB_mouse.c
Normal 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: */
|
||||
44
src/video/directfb/SDL_DirectFB_mouse.h
Normal file
44
src/video/directfb/SDL_DirectFB_mouse.h
Normal 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: */
|
||||
345
src/video/directfb/SDL_DirectFB_opengl.c
Normal file
345
src/video/directfb/SDL_DirectFB_opengl.c
Normal 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: */
|
||||
64
src/video/directfb/SDL_DirectFB_opengl.h
Normal file
64
src/video/directfb/SDL_DirectFB_opengl.h
Normal 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: */
|
||||
1328
src/video/directfb/SDL_DirectFB_render.c
Normal file
1328
src/video/directfb/SDL_DirectFB_render.c
Normal file
File diff suppressed because it is too large
Load Diff
25
src/video/directfb/SDL_DirectFB_render.h
Normal file
25
src/video/directfb/SDL_DirectFB_render.h
Normal 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: */
|
||||
134
src/video/directfb/SDL_DirectFB_shape.c
Normal file
134
src/video/directfb/SDL_DirectFB_shape.c
Normal 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 */
|
||||
39
src/video/directfb/SDL_DirectFB_shape.h
Normal file
39
src/video/directfb/SDL_DirectFB_shape.h
Normal 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 */
|
||||
424
src/video/directfb/SDL_DirectFB_video.c
Normal file
424
src/video/directfb/SDL_DirectFB_video.c
Normal 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 */
|
||||
170
src/video/directfb/SDL_DirectFB_video.h
Normal file
170
src/video/directfb/SDL_DirectFB_video.h
Normal 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 */
|
||||
532
src/video/directfb/SDL_DirectFB_window.c
Normal file
532
src/video/directfb/SDL_DirectFB_window.c
Normal 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 */
|
||||
81
src/video/directfb/SDL_DirectFB_window.h
Normal file
81
src/video/directfb/SDL_DirectFB_window.h
Normal 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: */
|
||||
Reference in New Issue
Block a user