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