-include Python.h \
-include $(top_builddir)/enigma2_config.h
+AM_CXXFLAGS = \
+ $(LIBSDL_CFLAGS)
+
noinst_LIBRARIES = libenigma_driver.a
libenigma_driver_a_SOURCES = \
rcdreambox2.h \
rcinput.h \
rfmod.h
+
+if HAVE_LIBSDL
+libenigma_driver_a_SOURCES += \
+ rcsdl.cpp \
+ rcsdl.h
+endif
--- /dev/null
+#include <lib/driver/rcsdl.h>
+//#include <lib/actions/action.h>
+#include <lib/base/init.h>
+#include <lib/base/init_num.h>
+#include <lib/driver/input_fake.h>
+
+/*
+ * eSDLInputDevice
+ */
+
+eSDLInputDevice::eSDLInputDevice(eRCDriver *driver) : eRCDevice("SDL", driver), m_escape(false), m_unicode(0)
+{
+}
+
+eSDLInputDevice::~eSDLInputDevice()
+{
+}
+
+void eSDLInputDevice::handleCode(long arg)
+{
+ const SDL_KeyboardEvent *event = (const SDL_KeyboardEvent *)arg;
+ const SDL_keysym *key = &event->keysym;
+ int km = input->getKeyboardMode();
+ int code, flags;
+
+ if (event->type == SDL_KEYDOWN) {
+ m_unicode = key->unicode;
+ flags = eRCKey::flagMake;
+ } else {
+ flags = eRCKey::flagBreak;
+ }
+
+ if (km == eRCInput::kmNone) {
+ code = translateKey(key->sym);
+ } else {
+ eDebug("unicode=%04x scancode=%02x", m_unicode, key->scancode);
+ if (m_unicode & 0xff80) {
+ eDebug("SDL: skipping unicode character");
+ return;
+ }
+ code = m_unicode & ~0xff80;
+ // unicode not set...!? use key symbol
+ if (code == 0) {
+ // keysym is ascii
+ if (key->sym >= 128) {
+ eDebug("SDL: cannot emulate ASCII");
+ return;
+ }
+ eDebug("SDL: emulate ASCII");
+ code = key->sym;
+ }
+ if (km == eRCInput::kmAscii) {
+ // skip ESC c or ESC '[' c
+ if (m_escape) {
+ if (code != '[')
+ m_escape = false;
+ return;
+ }
+
+ if (code == SDLK_ESCAPE)
+ m_escape = true;
+
+ if ((code < SDLK_SPACE) ||
+ (code == 0x7e) || // really?
+ (code == SDLK_DELETE))
+ return;
+ }
+ flags |= eRCKey::flagAscii;
+ }
+
+ eDebug("SDL code=%d flags=%d", code, flags);
+ input->keyPressed(eRCKey(this, code, flags));
+}
+
+const char *eSDLInputDevice::getDescription() const
+{
+ return "SDL";
+}
+
+int eSDLInputDevice::translateKey(SDLKey key)
+{
+ #define P(a) case SDLK_##a: return KEY_##a
+ #define P2(a,b) case SDLK_##a: return KEY_##b
+
+ switch (key) {
+ P(BACKSPACE);
+ P(TAB);
+ P(CLEAR);
+ P2(RETURN,ENTER);
+ P(PAUSE);
+ P2(ESCAPE,ESC);
+ P(SPACE);
+#if 0
+ P(EXCLAIM);
+ P(QUOTEDBL);
+ P(HASH);
+#endif
+ P(DOLLAR);
+#if 0
+ P(AMPERSAND);
+#endif
+ P2(QUOTE,APOSTROPHE);
+#if 0
+ P(LEFTPAREN);
+ P(RIGHTPAREN);
+ P(ASTERISK);
+ P(PLUS);
+#endif
+ P(COMMA);
+ P(MINUS);
+ P2(PERIOD,DOT);
+ P(SLASH);
+ P(0);
+ P(1);
+ P(2);
+ P(3);
+ P(4);
+ P(5);
+ P(6);
+ P(7);
+ P(8);
+ P(9);
+#if 0
+ P(COLON);
+#endif
+ P(SEMICOLON);
+#if 0
+ P(LESS);
+#endif
+ P2(EQUALS,EQUAL);
+#if 0
+ P(GREATER);
+#endif
+ P(QUESTION);
+#if 0
+ P(AT);
+#endif
+ P2(LEFTBRACKET,LEFTBRACE);
+ P(BACKSLASH);
+ P2(RIGHTBRACKET,RIGHTBRACE);
+ P2(CARET,GRAVE);
+#if 0
+ P(UNDERSCORE);
+ P(BACKQUOTE);
+#endif
+ P2(a,A);
+ P2(b,B);
+ P2(c,C);
+ P2(d,D);
+ P2(e,E);
+ P2(f,F);
+ P2(g,G);
+ P2(h,H);
+ P2(i,I);
+ P2(j,J);
+ P2(k,K);
+ P2(l,L);
+ P2(m,M);
+ P2(n,N);
+ P2(o,O);
+ P2(p,P);
+ P2(q,Q);
+ P2(r,R);
+ P2(s,S);
+ P2(t,T);
+ P2(u,U);
+ P2(v,V);
+ P2(w,W);
+ P2(x,X);
+ P2(y,Y);
+ P2(z,Z);
+ P(DELETE);
+#if 0
+ P(WORLD_0);
+ P(WORLD_1);
+ P(WORLD_2);
+ P(WORLD_3);
+ P(WORLD_4);
+ P(WORLD_5);
+ P(WORLD_6);
+ P(WORLD_7);
+ P(WORLD_8);
+ P(WORLD_9);
+ P(WORLD_10);
+ P(WORLD_11);
+ P(WORLD_12);
+ P(WORLD_13);
+ P(WORLD_14);
+ P(WORLD_15);
+ P(WORLD_16);
+ P(WORLD_17);
+ P(WORLD_18);
+ P(WORLD_19);
+ P(WORLD_20);
+ P(WORLD_21);
+ P(WORLD_22);
+ P(WORLD_23);
+ P(WORLD_24);
+ P(WORLD_25);
+ P(WORLD_26);
+ P(WORLD_27);
+ P(WORLD_28);
+ P(WORLD_29);
+ P(WORLD_30);
+ P(WORLD_31);
+ P(WORLD_32);
+ P(WORLD_33);
+ P(WORLD_34);
+ P(WORLD_35);
+ P(WORLD_36);
+ P(WORLD_37);
+ P(WORLD_38);
+ P(WORLD_39);
+ P(WORLD_40);
+ P(WORLD_41);
+ P(WORLD_42);
+ P(WORLD_43);
+ P(WORLD_44);
+ P(WORLD_45);
+ P(WORLD_46);
+ P(WORLD_47);
+ P(WORLD_48);
+ P(WORLD_49);
+ P(WORLD_50);
+ P(WORLD_51);
+ P(WORLD_52);
+ P(WORLD_53);
+ P(WORLD_54);
+ P(WORLD_55);
+ P(WORLD_56);
+ P(WORLD_57);
+ P(WORLD_58);
+ P(WORLD_59);
+ P(WORLD_60);
+ P(WORLD_61);
+ P(WORLD_62);
+ P(WORLD_63);
+ P(WORLD_64);
+ P(WORLD_65);
+ P(WORLD_66);
+ P(WORLD_67);
+ P(WORLD_68);
+ P(WORLD_69);
+ P(WORLD_70);
+ P(WORLD_71);
+ P(WORLD_72);
+ P(WORLD_73);
+ P(WORLD_74);
+ P(WORLD_75);
+ P(WORLD_76);
+ P(WORLD_77);
+ P(WORLD_78);
+ P(WORLD_79);
+ P(WORLD_80);
+ P(WORLD_81);
+ P(WORLD_82);
+ P(WORLD_83);
+ P(WORLD_84);
+ P(WORLD_85);
+ P(WORLD_86);
+ P(WORLD_87);
+ P(WORLD_88);
+ P(WORLD_89);
+ P(WORLD_90);
+ P(WORLD_91);
+ P(WORLD_92);
+ P(WORLD_93);
+ P(WORLD_94);
+ P(WORLD_95);
+#endif
+ P(KP0);
+ P(KP1);
+ P(KP2);
+ P(KP3);
+ P(KP4);
+ P(KP5);
+ P(KP6);
+ P(KP7);
+ P(KP8);
+ P(KP9);
+ P2(KP_PERIOD,KPDOT);
+ P2(KP_DIVIDE,KPSLASH);
+ P2(KP_MULTIPLY,KPASTERISK);
+ P2(KP_MINUS,KPMINUS);
+ P2(KP_PLUS,KPPLUS);
+ P2(KP_ENTER,KPENTER);
+ P2(KP_EQUALS,KPEQUAL);
+ P(UP);
+ P(DOWN);
+ P(RIGHT);
+ P(LEFT);
+ P(INSERT);
+ P(HOME);
+ P(END);
+ P(PAGEUP);
+ P(PAGEDOWN);
+ P(F1);
+ P(F2);
+ P(F3);
+ P(F4);
+ P(F5);
+ P(F6);
+ P(F7);
+ P(F8);
+ P(F9);
+ P(F10);
+ P(F11);
+ P(F12);
+ P(F13);
+ P(F14);
+ P(F15);
+ P(NUMLOCK);
+ P(CAPSLOCK);
+ P2(SCROLLOCK,SCROLLLOCK);
+ P2(RSHIFT,RIGHTSHIFT);
+ P2(LSHIFT,LEFTSHIFT);
+ P2(RCTRL,RIGHTCTRL);
+ P2(LCTRL,LEFTCTRL);
+ P2(RALT,RIGHTALT);
+ P2(LALT,LEFTALT);
+ P2(RMETA,RIGHTMETA);
+ P2(LMETA,LEFTMETA);
+#if 0
+ P(LSUPER);
+ P(RSUPER);
+#endif
+ P(MODE);
+ P(COMPOSE);
+ P(HELP);
+ P(PRINT);
+ P2(SYSREQ,SYSRQ);
+ P(BREAK);
+ P(MENU);
+ P(POWER);
+ P(EURO);
+ P(UNDO);
+ default:
+ eDebug("unhandled SDL keycode: %d", key);
+ return KEY_RESERVED;
+ }
+
+ #undef P2
+ #undef P
+}
+
+/*
+ * eSDLInputDriver
+ */
+
+eSDLInputDriver *eSDLInputDriver::instance;
+
+eSDLInputDriver::eSDLInputDriver() : eRCDriver(eRCInput::getInstance())
+{
+ ASSERT(instance == 0);
+ instance = this;
+}
+
+eSDLInputDriver::~eSDLInputDriver()
+{
+ instance = 0;
+}
+
+void eSDLInputDriver::keyPressed(const SDL_KeyboardEvent *key)
+{
+ eDebug("km=%d enabled=%d locked=%d",
+ input->getKeyboardMode(), enabled, input->islocked());
+
+ if (!enabled || input->islocked())
+ return;
+
+ std::list<eRCDevice*>::iterator i(listeners.begin());
+ while (i != listeners.end()) {
+ (*i)->handleCode((long)key);
+ ++i;
+ }
+}
+
+class eRCSDLInit
+{
+private:
+ eSDLInputDriver driver;
+ eSDLInputDevice device;
+
+public:
+ eRCSDLInit(): driver(), device(&driver)
+ {
+ }
+};
+
+eAutoInitP0<eRCSDLInit> init_rcSDL(eAutoInitNumbers::rc+1, "SDL RC Driver");
--- /dev/null
+#ifndef __lib_driver_rcsdl_h
+#define __lib_driver_rcsdl_h
+
+#include <lib/driver/rc.h>
+
+#include <SDL.h>
+
+class eSDLInputDevice : public eRCDevice
+{
+private:
+ bool m_escape;
+ unsigned int m_unicode;
+ int translateKey(SDLKey key);
+
+public:
+ eSDLInputDevice(eRCDriver *driver);
+ ~eSDLInputDevice();
+
+ virtual void handleCode(long arg);
+ virtual const char *getDescription() const;
+};
+
+class eSDLInputDriver : public eRCDriver
+{
+private:
+ static eSDLInputDriver *instance;
+
+public:
+ eSDLInputDriver();
+ ~eSDLInputDriver();
+
+ static eSDLInputDriver *getInstance() { return instance; }
+
+ void keyPressed(const SDL_KeyboardEvent *key);
+};
+
+#endif
#include <lib/gdi/sdl.h>
-
+#include <lib/actions/action.h>
#include <lib/base/init.h>
#include <lib/base/init_num.h>
+#include <lib/driver/input_fake.h>
+#include <lib/driver/rcsdl.h>
#include <SDL.h>
-gSDLDC::gSDLDC()
+gSDLDC::gSDLDC() : m_pump(eApp, 1)
{
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
- {
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
eWarning("Could not initialize SDL: %s", SDL_GetError());
return;
}
CONNECT(m_pump.recv_msg, gSDLDC::pumpEvent);
m_surface.type = 0;
- m_surface.clut.colors=256;
- m_surface.clut.data=new gRGB[m_surface.clut.colors];
-
+ m_surface.clut.colors = 256;
+ m_surface.clut.data = new gRGB[m_surface.clut.colors];
+
m_pixmap = new gPixmap(&m_surface);
-
+
memset(m_surface.clut.data, 0, sizeof(*m_surface.clut.data)*m_surface.clut.colors);
+
+ run();
}
gSDLDC::~gSDLDC()
{
+ pushEvent(EV_QUIT);
+ kill();
SDL_Quit();
}
-void gSDLDC::setPalette()
+void gSDLDC::keyEvent(const SDL_Event &event)
{
- if (!m_surface.clut.data)
- return;
-
-/* for (int i=0; i<256; ++i)
- {
- fb->CMAP()->red[i]=ramp[m_surface.clut.data[i].r]<<8;
- fb->CMAP()->green[i]=ramp[m_surface.clut.data[i].g]<<8;
- fb->CMAP()->blue[i]=ramp[m_surface.clut.data[i].b]<<8;
- fb->CMAP()->transp[i]=rampalpha[m_surface.clut.data[i].a]<<8;
- if (!fb->CMAP()->red[i])
- fb->CMAP()->red[i]=0x100;
- }
- fb->PutCMAP(); */
+ eSDLInputDriver *driver = eSDLInputDriver::getInstance();
+
+ eDebug("SDL Key %s: key=%d", (event.type == SDL_KEYDOWN) ? "Down" : "Up", event.key.keysym.sym);
+
+ if (driver)
+ driver->keyPressed(&event.key);
}
-void gSDLDC::exec(const gOpcode *o)
+void gSDLDC::pumpEvent(const SDL_Event &event)
{
- switch (o->opcode)
- {
- case gOpcode::setPalette:
- {
- gDC::exec(o);
- setPalette();
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ keyEvent(event);
+ break;
+ case SDL_QUIT:
+ eDebug("SDL Quit");
+ extern void quitMainloop(int exit_code);
+ quitMainloop(0);
break;
}
+}
+
+void gSDLDC::pushEvent(enum event code, void *data1, void *data2)
+{
+ SDL_Event event;
+
+ event.type = SDL_USEREVENT;
+ event.user.code = code;
+ event.user.data1 = data1;
+ event.user.data2 = data2;
+
+ SDL_PushEvent(&event);
+}
+
+void gSDLDC::exec(const gOpcode *o)
+{
+ switch (o->opcode) {
case gOpcode::flush:
- SDL_Flip(m_screen);
+ pushEvent(EV_FLIP);
eDebug("FLUSH");
break;
default:
void gSDLDC::setResolution(int xres, int yres)
{
+ pushEvent(EV_SET_VIDEO_MODE, (void *)xres, (void *)yres);
+}
+
+/*
+ * SDL thread below...
+ */
+
+void gSDLDC::evSetVideoMode(unsigned long xres, unsigned long yres)
+{
m_screen = SDL_SetVideoMode(xres, yres, 32, SDL_HWSURFACE);
- if (!m_screen)
- {
- eWarning("Could not create SDL surface: %s", SDL_GetError());
+ if (!m_screen) {
+ eFatal("Could not create SDL surface: %s", SDL_GetError());
return;
}
m_surface.bypp = m_screen->format->BytesPerPixel;
m_surface.stride = m_screen->pitch;
m_surface.data = m_screen->pixels;
+
+ SDL_EnableUNICODE(1);
+}
+
+void gSDLDC::evFlip()
+{
+ SDL_Flip(m_screen);
+}
+
+void gSDLDC::thread()
+{
+ hasStarted();
+
+ bool stop = false;
+ while (!stop) {
+ SDL_Event event;
+ if (SDL_WaitEvent(&event)) {
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ case SDL_QUIT:
+ m_pump.send(event);
+ break;
+ case SDL_USEREVENT:
+ switch (event.user.code) {
+ case EV_SET_VIDEO_MODE:
+ evSetVideoMode((unsigned long)event.user.data1, (unsigned long)event.user.data2);
+ break;
+ case EV_FLIP:
+ evFlip();
+ break;
+ case EV_QUIT:
+ stop = true;
+ break;
+ }
+ break;
+ }
+ }
+ }
}
eAutoInitPtr<gSDLDC> init_gSDLDC(eAutoInitNumbers::graphic-1, "gSDLDC");
#ifndef __lib_gdi_sdl_h
#define __lib_gdi_sdl_h
-#include "fb.h"
-#include "gpixmap.h"
-#include "gmaindc.h"
+#include <lib/base/thread.h>
+#include <lib/gdi/gmaindc.h>
#include <SDL.h>
-class gSDLDC: public gMainDC
+class gSDLDC: public gMainDC, public eThread, public Object
{
+private:
SDL_Surface *m_screen;
void exec(const gOpcode *opcode);
- void setPalette();
gSurface m_surface;
+
+ eFixedMessagePump<SDL_Event> m_pump;
+ void keyEvent(const SDL_Event &event);
+ void pumpEvent(const SDL_Event &event);
+ virtual void thread();
+
+ enum event {
+ EV_SET_VIDEO_MODE,
+ EV_FLIP,
+ EV_QUIT,
+ };
+
+ void pushEvent(enum event code, void *data1 = 0, void *data2 = 0);
+ void evSetVideoMode(unsigned long xres, unsigned long yres);
+ void evFlip();
+
public:
-
void setResolution(int xres, int yres);
gSDLDC();
virtual ~gSDLDC();