Ejemplo n.º 1
0
DFBEventBuffer::DFBEventBuffer() {
    IDirectFB* dfb;
    dfb = (IDirectFB*)(LocalDeviceManager::getInstance()->getGfxRoot());

    //dfb_true => the focus doesn't matter
    DFBCHECK(dfb->CreateInputEventBuffer(
                 dfb,
                 DICAPS_ALL,
                 DFB_TRUE,
                 &eventBuffer));

    pool->insert(eventBuffer);
}
Ejemplo n.º 2
0
int
main( int argc, char *argv[] )
{
     DFBResult              ret;
     bool                   quit = false;
     int                    i;
     IDirectFB              dfb;
     IDirectFBDisplayLayer  layer;
     IDirectFBSurface       surface;
     DFBDisplayLayerConfig  config;
     DFBDimension           sizes[2]  = { {400, 400}, {600, 600} };
     size_t                 num_sizes = D_ARRAY_SIZE(sizes);
     DFBInputEvent          evt;
     IDirectFBEventBuffer   keybuffer;

     /* Initialize DirectFB. */
     DirectFB::Init( &argc, &argv );

     /* Create super interface. */
     dfb = DirectFB::Create();

     layer = dfb.GetDisplayLayer( DLID_PRIMARY );

     /* Create an input buffer for key events */
     keybuffer = dfb.CreateInputEventBuffer( DICAPS_KEYS, DFB_TRUE );

     layer.SetCooperativeLevel( DLSCL_EXCLUSIVE );

     layer.GetConfiguration( &config );

     config.width  = sizes[0].w;
     config.height = sizes[0].h;

     layer.SetConfiguration( config );

     surface = layer.GetSurface();

     while (true) {
          surface.Clear( 0, 0, 0, 0xff );

          surface.SetColor( 0x00, 0xff, 0x00, 0xff );
          surface.DrawRectangle( 0, 0, config.width, config.height );

          surface.Flip( NULL, DSFLIP_NONE );


          keybuffer.WaitForEventWithTimeout( 3, 0 );

          /* Process keybuffer */
          while (keybuffer.GetEvent( DFB_EVENT(&evt) )) {
              if (evt.type == DIET_KEYPRESS) {
                  switch (DFB_LOWER_CASE(evt.key_symbol)) {
                      case DIKS_ESCAPE:
                      case DIKS_SMALL_Q:
                      case DIKS_BACK:
                      case DIKS_STOP:
                      case DIKS_EXIT:
                          /* Quit main loop & test thread */
                          quit = 1;
                          break;

                      case DIKS_SPACE:
                      case DIKS_OK:
                          i++;

                          config.width  = sizes[i % num_sizes].w;
                          config.height = sizes[i % num_sizes].h;

                          layer.SetConfiguration( config );
                          break;

                      default:
                          break;
                  }
              }
          }
     }

     return 0;
}
Ejemplo n.º 3
0
static void *input_thread(void *data)
{
	int uinput;
	int i;
	struct input_event u;
	struct uinput_user_dev ud;
	FILE *f;

	DFBResult err;
	IDirectFB *dfb = (IDirectFB *)data;
	fprintf(stderr, "DFB input converter thread starting...\n");

	/* modprobe does not complain if the module is already loaded... */
	system("/sbin/modprobe uinput");
	system("/sbin/modprobe evdev");
	uinput = open("/dev/misc/uinput", O_WRONLY|O_NDELAY);
	if (uinput < 0)
	{
		fprintf(stderr, "DFB input thread: unable to open /dev/misc/uinput (%m)\n");
		return NULL;
	}

	memset(&u, 0, sizeof(u));
	fcntl(uinput, F_SETFD, FD_CLOEXEC);

	/* configure the device */
	memset(&ud, 0, sizeof(ud));
	strncpy(ud.name, "Neutrino TD to Input Device converter", UINPUT_MAX_NAME_SIZE);
	ud.id.version = 0x42;
	ud.id.vendor  = 0x1234;
	ud.id.product = 0x5678;
	ud.id.bustype = BUS_I2C; /* ?? */
	write(uinput, &ud, sizeof(ud));
	ioctl(uinput, UI_SET_EVBIT, EV_KEY);
	ioctl(uinput, UI_SET_EVBIT, EV_REP);
	/* register keys */
	for (i = 0; key_list[i] != -1; i++)
		ioctl(uinput, UI_SET_KEYBIT, key_list[i]);

	if (ioctl(uinput, UI_DEV_CREATE))
	{
		perror("DFB input thread UI_DEV_CREATE");
		close(uinput);
		return NULL;
	}

	/* this is ugly: parse the new input device from /proc/...devices
	 * and symlink it to /dev/input/nevis_ir... */
#define DEVLINE "I: Bus=0018 Vendor=1234 Product=5678 Version=0042"
	f = fopen("/proc/bus/input/devices", "r");
	if (f)
	{
		int found = 0;
		int evdev = -1;
		size_t n = 0;
		char *line = NULL;
		char *p;
		char newdev[20];
		while (getline(&line, &n, f) != -1)
		{
			switch(line[0])
			{
				case 'I':
					if (strncmp(line, DEVLINE, strlen(DEVLINE)) == 0)
						found = 1;
					break;
				case 'H':
					if (! found)
						break;
					p = strstr(line, " event");
					if (! p)
					{
						evdev = -1;
						break;
					}
					evdev = atoi(p + 6);
					sprintf(newdev, "event%d", evdev);
					fprintf(stderr, "DFB input thread: symlink /dev/input/nevis_ir to %s\n", newdev);
					unlink("/dev/input/nevis_ir");
					symlink(newdev, "/dev/input/nevis_ir");
					break;
				default:
					break;
			}
			if (evdev != -1)
				break;
		}
		fclose(f);
		free(line);
	}

	u.type = EV_KEY;
	u.value = 0; /* initialize: first event wil be a key press */

	dfb->EnumInputDevices(dfb, enum_input_device, &inputs);
	DFBCHECK(dfb->CreateInputEventBuffer(dfb, DICAPS_ALL, DFB_FALSE, &events));

	thread_running = 1;
	while (thread_running)
	{
		/* check every 250ms (if a key is pressed on remote, we might
		 * even check earlier, but it does not really hurt... */
		if (_vdec)
			_vdec->VideoParamWatchdog();

		if (events->WaitForEventWithTimeout(events, 0, 250) == DFB_TIMEOUT)
			continue;
		DFBInputEvent e;
		while (events->GetEvent(events, DFB_EVENT(&e)) == DFB_OK)
		{
#if 0
			fprintf(stderr, "type: %x devid: %x flags: %03x "
					"key_id: %4x key_sym: %4x keycode: %d\n",
					e.type, e.device_id, e.flags,
					e.key_id, e.key_symbol, e.key_code);
#endif
			switch (e.key_symbol)
			{
				/* will a lookup table be more efficient? */
				case 0x0030: u.code = KEY_0;		break;
				case 0x0031: u.code = KEY_1;		break;
				case 0x0032: u.code = KEY_2;		break;
				case 0x0033: u.code = KEY_3;		break;
				case 0x0034: u.code = KEY_4;		break;
				case 0x0035: u.code = KEY_5;		break;
				case 0x0036: u.code = KEY_6;		break;
				case 0x0037: u.code = KEY_7;		break;
				case 0x0038: u.code = KEY_8;		break;
				case 0x0039: u.code = KEY_9;		break;
				case 0x000d: u.code = KEY_OK;		break;
				case 0xf504: u.code = KEY_TIME;		break;
				case 0xf01a: u.code = KEY_FAVORITES;	break; /* blue heart */
				case 0xf021: u.code = KEY_ZOOMOUT;	break;
				case 0xf022: u.code = KEY_ZOOMIN;	break;
				case 0xf505: u.code = KEY_NEXT;		break; /* red hand */
				case 0xf00f: u.code = KEY_POWER;	break;
				case 0xf04e: u.code = KEY_MUTE;		break;
				case 0xf012: u.code = KEY_MENU;		break;
				case 0xf01b: u.code = KEY_EPG;		break;
				case 0xf014: u.code = KEY_INFO;		break;
				case 0x001b: u.code = KEY_EXIT;		break;
				case 0xf046: u.code = KEY_PAGEUP;	break;
				case 0xf047: u.code = KEY_PAGEDOWN;	break;
				case 0xf000: u.code = KEY_LEFT;		break;
				case 0xf001: u.code = KEY_RIGHT;	break;
				case 0xf002: u.code = KEY_UP;		break;
				case 0xf003: u.code = KEY_DOWN;		break;
				case 0xf04c: u.code = KEY_VOLUMEUP;	break;
				case 0xf04d: u.code = KEY_VOLUMEDOWN;	break;
				case 0xf042: u.code = KEY_RED;		break;
				case 0xf043: u.code = KEY_GREEN;	break;
				case 0xf044: u.code = KEY_YELLOW;	break;
				case 0xf045: u.code = KEY_BLUE;		break;
				case 0xf027: u.code = KEY_TV;		break;
				case 0xf035: u.code = KEY_VIDEO;	break;
				case 0xf033: u.code = KEY_AUDIO;	break;
				case 0xf034: u.code = KEY_AUX;		break;
				case 0xf032: u.code = KEY_TEXT;		break;
				case 0xf501: u.code = KEY_TTTV;		break;
				case 0xf502: u.code = KEY_TTZOOM;	break;
				case 0xf503: u.code = KEY_REVEAL;	break;
				case 0xf059: u.code = KEY_REWIND;	break;
				case 0xf052: u.code = KEY_STOP;		break;
				case 0xf051: u.code = KEY_PAUSE;	break;
				case 0xf05a: u.code = KEY_FORWARD;	break;
			/*	case 0xf05b: u.code = KEY_PREV;		break; */
				case 0xf057: u.code = KEY_EJECTCD;	break;
				case 0xf056: u.code = KEY_RECORD;	break;
			/*	case 0xf05c: u.code = KEY_NEXT;		break; */
				/* front panel left / right */
				case 0xf506: u.code = KEY_LEFT;		break;
				case 0xf507: u.code = KEY_RIGHT;	break;
				default:
					continue;
			}
			switch (e.type)
			{
				case 1: u.value = 1; break;	/* 1 = key press */
				case 2: u.value = 0; break;	/* 0 = key release */
								/* 2 = key repeat (not used) */
				default:
					continue;
			}
			// fprintf(stderr, "uinput write: value: %d code: %d\n", u.value, u.code);
			write(uinput, &u, sizeof(u));
		}
	}
	/* clean up */
	ioctl(uinput, UI_DEV_DESTROY);
	while (inputs) {
		DeviceInfo *next = inputs->next;
		free(inputs);
		inputs = next;
	}
	events->Release(events);
	return NULL;
}
Ejemplo n.º 4
0
static int
DirectFB_VideoInit(_THIS)
{
    IDirectFB *dfb = NULL;
    DFB_DeviceData *devdata = NULL;
    char *stemp;
    DFBResult ret;

    SDL_DFB_CALLOC(devdata, 1, sizeof(*devdata));

    SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));

    /* avoid switching to the framebuffer when we
     * are running X11 */
    stemp = SDL_getenv(DFBENV_USE_X11_CHECK);
    if (stemp)
        ret = atoi(stemp);
    else
        ret = 1;

    if (ret) {
        if (SDL_getenv("DISPLAY"))
            DirectFBSetOption("system", "x11");
        else
            DirectFBSetOption("disable-module", "x11input");
    }

    devdata->use_linux_input = 1;       /* default: on */
    stemp = SDL_getenv(DFBENV_USE_LINUX_INPUT);
    if (stemp)
        devdata->use_linux_input = atoi(stemp);

    if (!devdata->use_linux_input)
        DirectFBSetOption("disable-module", "linux_input");

    SDL_DFB_CHECKERR(DirectFBCreate(&dfb));

    DirectFB_DeviceInformation(dfb);
    devdata->use_yuv_underlays = 0;     /* default: off */
    stemp = SDL_getenv(DFBENV_USE_YUV_UNDERLAY);
    if (stemp)
        devdata->use_yuv_underlays = atoi(stemp);


    /* 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));
    }

    devdata->initialized = 1;

    /* simple window manager support */
    stemp = SDL_getenv(DFBENV_USE_WM);
    if (stemp)
        devdata->has_own_wm = atoi(stemp);
    else
        devdata->has_own_wm = 0;

    devdata->dfb = dfb;
    devdata->firstwin = NULL;

    _this->driverdata = devdata;

    DirectFB_InitModes(_this);

#if SDL_DIRECTFB_OPENGL
    DirectFB_GL_Initialize(_this);
#endif

    DirectFB_AddRenderDriver(_this);
    DirectFB_InitMouse(_this);
    DirectFB_InitKeyboard(_this);

    return 0;


  error:
    SDL_DFB_FREE(devdata);
    SDL_DFB_RELEASE(dfb);
    return -1;
}
Ejemplo n.º 5
0
int
main( int argc, char *argv[] )
{
     DFBResult               ret;
     int                     i;
     DFBSurfaceDescription   desc;
     IDirectFB              *dfb;
     IDirectFBSurface       *dest          = NULL;
     DFBSurfacePixelFormat   dest_format   = DSPF_UNKNOWN;
     char                    pixel_buffer[100*100*4];
     IDirectFBSurface       *source        = NULL;
     IDirectFBEventBuffer   *keybuffer;
     DFBInputEvent           evt;
     bool                    quit          = false;

     /* Initialize DirectFB. */
     ret = DirectFBInit( &argc, &argv );
     if (ret) {
          D_DERROR( ret, "DFBTest/PreAlloc: DirectFBInit() failed!\n" );
          return ret;
     }

     /* Parse arguments. */
     for (i=1; i<argc; i++) {
          const char *arg = argv[i];

          if (strcmp( arg, "-h" ) == 0 || strcmp (arg, "--help") == 0)
               return print_usage( argv[0] );
          else if (strcmp (arg, "-v") == 0 || strcmp (arg, "--version") == 0) {
               fprintf (stderr, "dfbtest_blit version %s\n", DIRECTFB_VERSION);
               return false;
          }
          else if (strcmp (arg, "-d") == 0 || strcmp (arg, "--dest") == 0) {
               if (++i == argc) {
                    print_usage (argv[0]);
                    return false;
               }

               if (!parse_format( argv[i], &dest_format ))
                    return false;
          }
          else if (strcmp (arg, "-s") == 0 || strcmp (arg, "--static") == 0) {
               static_caps = DSCAPS_STATIC_ALLOC;
          }
          else
               return print_usage( argv[0] );
     }

     /* Create super interface. */
     ret = DirectFBCreate( &dfb );
     if (ret) {
          D_DERROR( ret, "DFBTest/PreAlloc: DirectFBCreate() failed!\n" );
          return ret;
     }

     /* Fill description for a primary surface. */
     desc.flags = DSDESC_CAPS;
     desc.caps  = DSCAPS_PRIMARY | DSCAPS_FLIPPING;

     if (dest_format != DSPF_UNKNOWN) {
          desc.flags       |= DSDESC_PIXELFORMAT;
          desc.pixelformat  = dest_format;
     }

     dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN );

     /* Create an input buffer for key events */
     dfb->CreateInputEventBuffer( dfb, DICAPS_KEYS,
                                  DFB_TRUE, &keybuffer);

     /* Create a primary surface. */
     ret = dfb->CreateSurface( dfb, &desc, &dest );
     if (ret) {
          D_DERROR( ret, "DFBTest/PreAlloc: IDirectFB::CreateSurface() for the destination failed!\n" );
          goto out;
     }

     dest->GetSize( dest, &desc.width, &desc.height );
     dest->GetPixelFormat( dest, &desc.pixelformat );

     D_INFO( "DFBTest/PreAlloc: Destination is %dx%d using %s\n",
             desc.width, desc.height, dfb_pixelformat_name(desc.pixelformat) );

     /* Create a preallocated surface. */
     desc.flags                 = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS | DSDESC_PREALLOCATED;
     desc.width                 = 100;
     desc.height                = 100;
     desc.pixelformat           = DSPF_ARGB;
     desc.caps                  = static_caps;
     desc.preallocated[0].data  = pixel_buffer;
     desc.preallocated[0].pitch = 100 * 4;

     ret = dfb->CreateSurface( dfb, &desc, &source );
     if (ret) {
          D_DERROR( ret, "DFBTest/PreAlloc: IDirectFB::CreateSurface() for the preallocated source failed!\n" );
          goto out;
     }

     /* Before any other operation the pixel data can be written to without locking */
     gen_pixels( pixel_buffer, 100 * 4, 100 );

     while (!quit) {
          void *ptr;
          int   pitch;


          /* Lock source surface for writing before making updates to the pixel buffer */
          source->Lock( source, DSLF_WRITE, &ptr, &pitch );

          if (ptr == pixel_buffer)
               D_INFO( "DFBTest/PreAlloc: Locking preallocated source gave original preallocated pixel buffer :-)\n" );
          else {
               if (static_caps)
                    D_INFO( "DFBTest/PreAlloc: Locking preallocated source gave different pixel buffer, ERROR with static alloc!\n" );
               else
                    D_INFO( "DFBTest/PreAlloc: Locking preallocated source gave different pixel buffer, but OK (no static alloc)\n" );
          }

          update_pixels( ptr, pitch, 100 );

          /* Unlock source surface after writing, before making further Blits,
             to have the buffer be transfered to master again */
          source->Unlock( source );


          dest->Clear( dest, 0, 0, 0, 0xff );

          /* First Blit from preallocated source, data will be transfered to master */
          dest->Blit( dest, source, NULL, 50, 50 );

          /* Second Blit from preallocated source, data is already master */
          dest->Blit( dest, source, NULL, 150, 150 );

          dest->Flip( dest, NULL, DSFLIP_NONE );

          /* This will upload again the preallocated buffer to the master, where it is
             modified and outdates the preallocated buffer. Now it depends on the static
             alloc flag whether the next Lock will directly go into the shared memory
             allocation or the preallocated buffer again (with a transfer back from master
             to us). */
          source->FillRectangle( source, 0, 0, 10, 10 );

          /* Process keybuffer */
          while (keybuffer->GetEvent( keybuffer, DFB_EVENT(&evt)) == DFB_OK)
          {
              if (evt.type == DIET_KEYPRESS) {
                  switch (DFB_LOWER_CASE(evt.key_symbol)) {
                      case DIKS_ESCAPE:
                      case DIKS_SMALL_Q:
                      case DIKS_BACK:
                      case DIKS_STOP:
                      case DIKS_EXIT:
                          /* Quit main loop & test thread */
                          quit = true;
                          break;
                      default:
                          break;
                  }
              }
          }
          if (!quit)
          sleep( 5 );
     }

out:
     if (source)
          source->Release( source );

     if (dest)
          dest->Release( dest );

     keybuffer->Release( keybuffer );

     /* Shutdown DirectFB. */
     dfb->Release( dfb );

     return ret;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
int
main( int argc, char *argv[] )
{
     DFBResult              ret;
     int                    i;
     int                    x, y;
     int                    dx, dy;
     int                    sw3, sh3;
     int                    opacity       = 255;
     int                    opacity_delta = -1;
     IDirectFB             *dfb;
     IDirectFBDisplayLayer *layer;
     IDirectFBSurface      *surface;
     DFBDisplayLayerConfig  config;
     DFBDimension           size;
     DFBInputEvent          evt;

     /* Initialize DirectFB. */
     ret = DirectFBInit( &argc, &argv );
     if (ret) {
          D_DERROR( ret, "DFBTest/Layer: DirectFBInit() failed!\n" );
          return ret;
     }


     /* Create super interface. */
     ret = DirectFBCreate( &dfb );
     if (ret) {
          D_DERROR( ret, "DFBTest/Layer: DirectFBCreate() failed!\n" );
          return ret;
     }

     dfb->GetDisplayLayer( dfb, DLID_PRIMARY, &layer );

     /* Create an input buffer for key events */
     dfb->CreateInputEventBuffer( dfb, DICAPS_KEYS,
                                  DFB_TRUE, &keybuffer);

     layer->SetCooperativeLevel( layer, DFSCL_EXCLUSIVE );

     layer->GetConfiguration( layer, &config );


     config.options    = DLOP_OPACITY | DLOP_SRC_COLORKEY;
     config.buffermode = DLBM_FRONTONLY;

     layer->SetConfiguration( layer, &config );
     layer->SetSrcColorKey( layer, 0x00, 0xff, 0x00 );



     ret = layer->GetSurface( layer, &surface );
     if (ret) {
          D_DERROR( ret, "DFBTest/Layer: GetSurface() failed!\n" );
          dfb->Release( dfb );
          return ret;
     }

     surface->GetSize( surface, &size.w, &size.h );

     sw3 = ((size.w / 3) + 1) & ~1;
     sh3 = ((size.h / 3) + 1) & ~1;


     surface->Clear( surface, 0, 0, 0, 0xff );

     for (i=0; i<10; i++) {
          surface->SetColor( surface, 0xff - i*16, 0xff - i*16, 0xff - i*16, 0xff );
          surface->DrawRectangle( surface, i, i, size.w - i*2, size.h - i*2 );
     }

     surface->FillRectangle( surface, 10, size.h/2, size.w - 20, 1 );
     surface->FillRectangle( surface, size.w/2, 10, 1, size.h - 20 );

     surface->SetColor( surface, 0xff, 0x00, 0x00, 0xff );
     surface->FillRectangle( surface, size.w/3, size.h/3, size.w/3, size.h/3 );

     surface->SetColor( surface, 0x00, 0xff, 0x00, 0xff );
     surface->FillRectangle( surface, size.w/3 + size.w/9, size.h/3 + size.h/9, size.w/9, size.h/9 );

     surface->Flip( surface, NULL, DSFLIP_NONE );

#ifdef BUILD_AUTOMATION
     sleep( 2 );
#else
     sleep( 12 );
#endif
     layer->SetSourceRectangle( layer, 0, 0, size.w - sw3, size.h - sh3 );

     layer->SetScreenPosition( layer, 100, 100 );
     layer->SetScreenRectangle( layer, 100, 100, size.w - sw3, size.h - sh3 );

     sleep( 2 );
#ifdef BUILD_AUTOMATION
     sleep( 20 );
     quit = 1;
#endif

     for (x=0, y=0, dx=1, dy=1; !quit ; x+=dx, y+=dy) {
          layer->SetOpacity( layer, opacity );

          if (opacity == 255)
               opacity_delta = -1;
          else if (opacity == 0)
               opacity_delta = 1;

          opacity += opacity_delta;


          layer->SetSourceRectangle( layer, x, y, size.w - sw3, size.h - sh3 );

          surface->Flip( surface, NULL, DSFLIP_UPDATE );

          if (dx > 0) {
               if (x == size.w/3) {
                    dx = -1;

                    usleep( 500000 );
               }
          }
          else if (x == 0) {
               dx = 1;

               usleep( 500000 );
          }

          if (dy > 0) {
               if (y == size.h/3) {
                    dy = -1;

                    usleep( 500000 );
               }
          }
          else if (y == 0) {
               dy = 1;

               usleep( 500000 );
          }

          usleep( 10000 );

          /* Process keybuffer */
          while (keybuffer->GetEvent( keybuffer, DFB_EVENT(&evt)) == DFB_OK)
          {
              if (evt.type == DIET_KEYPRESS) {
                  switch (DFB_LOWER_CASE(evt.key_symbol)) {
                      case DIKS_ESCAPE:
                      case DIKS_SMALL_Q:
                      case DIKS_BACK:
                      case DIKS_STOP:
                      case DIKS_EXIT:
                          /* Quit main loop & test thread */
                          quit = 1;
                          break;
                      default:
                          break;
                  }
              }
          }

     }

     surface->Release( surface );
     layer->Release( layer );

     /* Shutdown DirectFB. */
     dfb->Release( dfb );

     return ret;
}