1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <time.h>
5
6 #include <directfb.h>
7
8 #define DFBCHECK(x...) { \
9 err = x; \
10 if(err != DFB_OK) { \
11 fprintf(stderr, "%s <%d>:\n\t", __FILE__, __LINE__); \
12 DirectFBErrorFatal(#x, err); \
13 } \
14 }
15
16 int main(int argc, char *argv[]) {
17 IDirectFB *dfb;
18 IDirectFBDisplayLayer *canal;
19 IDirectFBImageProvider *proveedor;
20 IDirectFBVideoProvider *video_proveedor;
21 IDirectFBSurface *fondo;
22 IDirectFBWindow *ventana1;
23 IDirectFBWindow *ventana2;
24 IDirectFBSurface *ventana1_superficie;
25 IDirectFBSurface *ventana2_superficie;
26 IDirectFBEventBuffer *buffer;
27 DFBDisplayLayerConfig canal_config;
28 DFBGraphicsDeviceDescription gdesc;
29 IDirectFBWindow* encima;
30 DFBWindowID id1;
31
32 int err;
33 int quit = 0;
34
35 DFBCHECK(DirectFBInit(&argc, &argv));
36 DFBCHECK(DirectFBCreate(&dfb));
37
38 dfb -> GetDeviceDescription(dfb, &gdesc);
39
40 DFBCHECK(dfb -> GetDisplayLayer(dfb, DLID_PRIMARY, &canal));
41
42 canal -> SetCooperativeLevel(canal, DLSCL_ADMINISTRATIVE);
43
44 if(!((gdesc.blitting_flags & DSBLIT_BLEND_ALPHACHANNEL) && (gdesc.blitting_flags & DSBLIT_BLEND_COLORALPHA))) {
45 canal_config.flags = DLCONF_BUFFERMODE;
46 canal_config.buffermode = DLBM_BACKSYSTEM;
47
48 canal -> SetConfiguration(canal, &canal_config);
49 }
50
51 canal -> GetConfiguration(canal, &canal_config);
52 canal -> EnableCursor(canal, 1);
53
54 if(argc < 2 || dfb -> CreateVideoProvider(dfb, argv[1], &video_proveedor) != DFB_OK) {
55 video_proveedor = NULL;
56 }
57
58 {
59 DFBSurfaceDescription desc;
60
61 DFBCHECK(dfb -> CreateImageProvider(dfb, "desktop.png", &proveedor));
62
63 desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT;
64 desc.width = canal_config.width;
65 desc.height = canal_config.height;
66
67 DFBCHECK(dfb -> CreateSurface(dfb, &desc, &fondo));
68
69 proveedor -> RenderTo(proveedor, fondo, NULL);
70 proveedor -> Release(proveedor);
71 canal -> SetBackgroundImage(canal, fondo);
72 canal -> SetBackgroundMode(canal, DLBM_IMAGE);
73 }
74
75 {
76 DFBSurfaceDescription sdsc;
77 DFBWindowDescription desc;
78
79 desc.flags = (DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT);
80
81 if(!video_proveedor) {
82 desc.caps = DWCAPS_ALPHACHANNEL;
83 desc.flags |= DWDESC_CAPS;
84 sdsc.width = 300;
85 sdsc.height = 200;
86 }
87 else {
88 video_proveedor -> GetSurfaceDescription(video_proveedor, &sdsc);
89 if(sdsc.flags & DSDESC_CAPS) {
90 desc.flags |= DWDESC_SURFACE_CAPS;
91 desc.surface_caps = sdsc.caps;
92 }
93 }
94
95 desc.posx = (canal_config.width / 2) - (sdsc.width / 2);
96 desc.posy = canal_config.height / 10;
97 desc.width = sdsc.width;
98 desc.height = sdsc.height;
99
100 DFBCHECK(canal -> CreateWindow(canal, &desc, &ventana2));
101
102 ventana2 -> GetSurface(ventana2, &ventana2_superficie);
103 ventana2 -> SetOpacity(ventana2, 0xFF);
104 ventana2 -> CreateEventBuffer(ventana2, &buffer);
105
106 if(video_proveedor) {
107 video_proveedor -> PlayTo(video_proveedor, ventana2_superficie, NULL, NULL, NULL);
108 }
109 else {
110 ventana2_superficie -> SetColor(ventana2_superficie, 0x00, 0x30, 0x10, 0xC0);
111 ventana2_superficie -> DrawRectangle(ventana2_superficie, 0, 0, desc.width, desc.height);
112 ventana2_superficie -> SetColor(ventana2_superficie, 0x80, 0xA0, 0x00, 0x90);
113 ventana2_superficie -> FillRectangle(ventana2_superficie, 1, 1, desc.width - 2, desc.height - 2);
114 }
115
116 ventana2_superficie -> Flip(ventana2_superficie, NULL, 0);
117 }
118
119 {
120 DFBWindowDescription desc;
121 DFBSurfaceDescription sdsc;
122
123 desc.flags = (DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS);
124
125 dfb -> CreateImageProvider(dfb, "dfblogo.png", &proveedor);
126 proveedor -> GetSurfaceDescription(proveedor, &sdsc);
127
128 desc.posx = (canal_config.width / 2) - (sdsc.width / 2);
129 desc.posy = (canal_config.height / 2);
130 desc.width = sdsc.width;
131 desc.height = sdsc.height;
132 desc.caps = DWCAPS_ALPHACHANNEL;
133
134 DFBCHECK(canal -> CreateWindow(canal, &desc, &ventana1));
135
136 ventana1 -> GetSurface(ventana1, &ventana1_superficie);
137
138 proveedor -> RenderTo(proveedor, ventana1_superficie, NULL);
139
140 ventana1_superficie -> SetColor(ventana1_superficie, 0xFF, 0x20, 0x20, 0x90);
141 ventana1_superficie -> DrawRectangle(ventana1_superficie, 0, 0, desc.width, desc.height);
142 ventana1_superficie -> Flip(ventana1_superficie, NULL, 0);
143 proveedor -> Release(proveedor);
144 ventana1 -> AttachEventBuffer(ventana1, buffer);
145 ventana1 -> SetOpacity(ventana1, 0xFF);
146 ventana1 -> GetID(ventana1, &id1);
147 }
148
149 ventana1 -> RaiseToTop(ventana1);
150 encima = ventana1;
151
152 while(!quit) {
153 static IDirectFBWindow* activa = NULL;
154
155 static int grabada = 0;
156 static int iniciox = 0;
157 static int inicioy = 0;
158 static int finx = 0;
159 static int finy = 0;
160
161 DFBWindowEvent evt;
162
163 buffer -> WaitForEventWithTimeout(buffer, 0, 10);
164
165 while(buffer -> GetEvent(buffer, DFB_EVENT(&evt)) == DFB_OK) {
166 IDirectFBWindow* ventana;
167 if(evt.window_id == id1)
168 ventana = ventana1;
169 else
170 ventana = ventana2;
171
172 if(evt.type == DWET_GOTFOCUS) {
173 activa = ventana;
174 }
175 else if(activa) {
176 switch(evt.type) {
177 case DWET_BUTTONDOWN:
178 if(!grabada && evt.button == DIBI_LEFT) {
179 grabada = 1;
180 iniciox = evt.cx;
181 inicioy = evt.cy;
182 ventana -> GrabPointer(ventana);
183 }
184 break;
185
186 case DWET_BUTTONUP:
187 switch(evt.button) {
188 case DIBI_LEFT:
189 if(grabada) {
190 ventana -> UngrabPointer(ventana);
191 grabada = 0;
192 }
193 break;
194
195 case DIBI_MIDDLE:
196 encima -> LowerToBottom(encima);
197 encima = (encima == ventana1) ? ventana2 : ventana1;
198 break;
199
200 case DIBI_RIGHT:
201 quit = DIKS_DOWN;
202 break;
203
204 default:
205 break;
206 }
207 break;
208
209 case DWET_KEYDOWN:
210 if(grabada)
211 break;
212 switch(evt.key_id) {
213 case DIKI_RIGHT:
214 activa -> Move(activa, 1, 0);
215 break;
216
217 case DIKI_LEFT:
218 activa -> Move(activa, -1, 0);
219 break;
220
221 case DIKI_UP:
222 activa -> Move(activa, 0, -1);
223 break;
224
225 case DIKI_DOWN:
226 activa -> Move(activa, 0, 1);
227 break;
228
229 default:
230 break;
231 }
232 break;
233
234 case DWET_LOSTFOCUS:
235 if(!grabada && activa == ventana)
236 activa = NULL;
237 ventana -> SetOpacity(ventana, 0xFF);
238 break;
239
240 default:
241 break;
242 }
243 }
244
245 switch(evt.type) {
246 case DWET_MOTION:
247 finx = evt.cx;
248 finy = evt.cy;
249 break;
250
251 case DWET_KEYDOWN:
252 switch(evt.key_symbol) {
253 case DIKS_ESCAPE:
254 case DIKS_SMALL_Q:
255 case DIKS_CAPITAL_Q:
256 case DIKS_BACK:
257 case DIKS_STOP:
258 quit = 1;
259 break;
260
261 default:
262 break;
263 }
264 break;
265
266 default:
267 break;
268 }
269 }
270
271 if(video_proveedor)
272 ventana2_superficie -> Flip(ventana2_superficie, NULL, 0);
273
274 if(activa) {
275 if(grabada) {
276 activa -> Move(activa, finx - iniciox, finy - inicioy);
277 iniciox = finx;
278 inicioy = finy;
279 }
280
281 activa -> SetOpacity(activa, 0x80);
282 }
283 }
284
285 if(video_proveedor)
286 video_proveedor -> Release(video_proveedor);
287
288 buffer -> Release(buffer);
289 ventana2_superficie -> Release(ventana2_superficie);
290 ventana1_superficie -> Release(ventana1_superficie);
291 ventana2 -> Release(ventana2);
292 ventana1 -> Release(ventana1);
293 canal -> Release(canal);
294 fondo -> Release(fondo);
295 dfb -> Release(dfb);
296
297 return 42;
298 }
299