Merge branch 'bug_599_picload_fd_leak' into experimental
[vuplus_dvbapp] / lib / gdi / sdl.cpp
1 #include <lib/gdi/sdl.h>
2 #include <lib/actions/action.h>
3 #include <lib/base/init.h>
4 #include <lib/base/init_num.h>
5 #include <lib/driver/input_fake.h>
6 #include <lib/driver/rcsdl.h>
7
8 #include <SDL.h>
9
10 gSDLDC::gSDLDC() : m_pump(eApp, 1)
11 {
12         if (SDL_Init(SDL_INIT_VIDEO) < 0) {
13                 eWarning("Could not initialize SDL: %s", SDL_GetError());
14                 return;
15         }
16
17         setResolution(720, 576);
18
19         CONNECT(m_pump.recv_msg, gSDLDC::pumpEvent);
20
21         m_surface.type = 0;
22         m_surface.clut.colors = 256;
23         m_surface.clut.data = new gRGB[m_surface.clut.colors];
24
25         m_pixmap = new gPixmap(&m_surface);
26
27         memset(m_surface.clut.data, 0, sizeof(*m_surface.clut.data)*m_surface.clut.colors);
28
29         run();
30 }
31
32 gSDLDC::~gSDLDC()
33 {
34         pushEvent(EV_QUIT);
35         kill();
36         SDL_Quit();
37 }
38
39 void gSDLDC::keyEvent(const SDL_Event &event)
40 {
41         eSDLInputDriver *driver = eSDLInputDriver::getInstance();
42
43         eDebug("SDL Key %s: key=%d", (event.type == SDL_KEYDOWN) ? "Down" : "Up", event.key.keysym.sym);
44
45         if (driver)
46                 driver->keyPressed(&event.key);
47 }
48
49 void gSDLDC::pumpEvent(const SDL_Event &event)
50 {
51         switch (event.type) {
52         case SDL_KEYDOWN:
53         case SDL_KEYUP:
54                 keyEvent(event);
55                 break;
56         case SDL_QUIT:
57                 eDebug("SDL Quit");
58                 extern void quitMainloop(int exit_code);
59                 quitMainloop(0);
60                 break;
61         }
62 }
63
64 void gSDLDC::pushEvent(enum event code, void *data1, void *data2)
65 {
66         SDL_Event event;
67
68         event.type = SDL_USEREVENT;
69         event.user.code = code;
70         event.user.data1 = data1;
71         event.user.data2 = data2;
72
73         SDL_PushEvent(&event);
74 }
75
76 void gSDLDC::exec(const gOpcode *o)
77 {
78         switch (o->opcode) {
79         case gOpcode::flush:
80                 pushEvent(EV_FLIP);
81                 eDebug("FLUSH");
82                 break;
83         default:
84                 gDC::exec(o);
85                 break;
86         }
87 }
88
89 void gSDLDC::setResolution(int xres, int yres)
90 {
91         pushEvent(EV_SET_VIDEO_MODE, (void *)xres, (void *)yres);
92 }
93
94 /*
95  * SDL thread below...
96  */
97
98 void gSDLDC::evSetVideoMode(unsigned long xres, unsigned long yres)
99 {
100         m_screen = SDL_SetVideoMode(xres, yres, 32, SDL_HWSURFACE);
101         if (!m_screen) {
102                 eFatal("Could not create SDL surface: %s", SDL_GetError());
103                 return;
104         }
105
106         m_surface.x = m_screen->w;
107         m_surface.y = m_screen->h;
108         m_surface.bpp = m_screen->format->BitsPerPixel;
109         m_surface.bypp = m_screen->format->BytesPerPixel;
110         m_surface.stride = m_screen->pitch;
111         m_surface.data = m_screen->pixels;
112
113         SDL_EnableUNICODE(1);
114 }
115
116 void gSDLDC::evFlip()
117 {
118         SDL_Flip(m_screen);
119 }
120
121 void gSDLDC::thread()
122 {
123         hasStarted();
124
125         bool stop = false;
126         while (!stop) {
127                 SDL_Event event;
128                 if (SDL_WaitEvent(&event)) {
129                         switch (event.type) {
130                         case SDL_KEYDOWN:
131                         case SDL_KEYUP:
132                         case SDL_QUIT:
133                                 m_pump.send(event);
134                                 break;
135                         case SDL_USEREVENT:
136                                 switch (event.user.code) {
137                                 case EV_SET_VIDEO_MODE:
138                                         evSetVideoMode((unsigned long)event.user.data1, (unsigned long)event.user.data2);
139                                         break;
140                                 case EV_FLIP:
141                                         evFlip();
142                                         break;
143                                 case EV_QUIT:
144                                         stop = true;
145                                         break;
146                                 }
147                                 break;
148                         }
149                 }
150         }
151 }
152
153 eAutoInitPtr<gSDLDC> init_gSDLDC(eAutoInitNumbers::graphic-1, "gSDLDC");