Files
gpac/modules/directfb_out/directfb_wrapper.c
Romain Bouqueau cbf29a3937 fix directfb build
2022-05-17 12:48:19 +02:00

883 lines
21 KiB
C

/*
* GPAC Multimedia Framework
*
* Authors: Romain Bouqueau - Jean Le Feuvre
* Copyright (c) Telecom ParisTech 2010-2012
* All rights reserved
*
* This file is part of GPAC / DirectFB video output module
*
* GPAC is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* GPAC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/* DirectFB */
#include <directfb.h>
#include <directfb_strings.h>
#include <directfb_util.h>
#include <direct/util.h>
#include <gpac/constants.h>
#include <gpac/events_constants.h>
#include <gpac/events.h>
#include "directfb_out.h"
static int do_xor = 0;
/* macro for a safe call to DirectFB functions */
#define DFBCHECK(x...) \
do { \
err = x; \
if (err != DFB_OK) { \
fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
DirectFBErrorFatal( #x, err ); \
} \
} while (0)
#define SET_DRAWING_FLAGS( flags ) \
ctx->primary->SetDrawingFlags( ctx->primary, (flags) | (do_xor ? DSDRAW_XOR : 0) )
/* Structs */
struct __DirectFBVidCtx
{
/* the super interface */
IDirectFB *dfb;
/* the primary surface */
IDirectFBSurface *primary;
/* for keyboard input */
//~ IDirectFBInputDevice *keyboard;
/* screen width, height */
u32 width, height, pixel_format;
Bool use_systems_memory, disable_aa, is_init;
/* acceleration */
int accel_drawline, accel_fillrect;
DFBSurfaceFlipFlags flip_mode;
/*===== for key events =====*/
/* Input interfaces: devices and its buffer */
IDirectFBEventBuffer *events;
/* mouse events */
IDirectFBInputDevice *mouse;
/*=============================
if using window
============================= */
/* DirectFB window */
IDirectFBWindow *window;
/* display layer */
IDirectFBDisplayLayer *layer;
};
size_t DirectFBVid_GetCtxSizeOf(void)
{
return sizeof(DirectFBVidCtx);
}
typedef struct _DeviceInfo DeviceInfo;
struct _DeviceInfo {
DFBInputDeviceID device_id;
DFBInputDeviceDescription desc;
DeviceInfo *next;
};
/* Wrapper to DirectFB members */
/**
* function DirectFBVid_DrawHLineWrapper
* - using hardware accelerator to draw horizontal line
**/
void DirectFBVid_DrawHLineWrapper(DirectFBVidCtx *ctx, u32 x, u32 y, u32 length, u8 r, u8 g, u8 b)
{
//GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] in DirectFBVid_DrawHLine(). Drawing line x %d y %d length %d color %08X\n", x, y, length, color));
// DSDRAW_NOFX: flag controlling drawing command, drawing without using any effects
SET_DRAWING_FLAGS( DSDRAW_NOFX );
// set the color used without alpha
ctx->primary->SetColor(ctx->primary, r, g, b, 0xFF);
// to draw a line using hardware accelerators, we can use either DrawLine (in our STB, DrawLine() function is not accelerated) or FillRectangle function with height equals to 1
//ctx->primary->DrawLine(ctx->primary, x, y, x+length, y); // no acceleration
ctx->primary->FillRectangle(ctx->primary, x, y,length, 1);
}
/**
* function DirectFBVid_DrawHLineWrapper
* - using hardware accelerator to draw horizontal line with alpha
**/
void DirectFBVid_DrawHLineAlphaWrapper(DirectFBVidCtx *ctx, u32 x, u32 y, u32 length, u8 r, u8 g, u8 b, u8 alpha)
{
//GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] in DirectFBVid_DrawHLineAlpha(). Alpha line drawing x %d y %d length %d color %08X alpha %d\n", x, y, length, color, alpha));
// DSDRAW_BLEND: using alpha from color
SET_DRAWING_FLAGS( DSDRAW_BLEND );
ctx->primary->SetColor(ctx->primary, r, g, b, alpha);
//ctx->primary->DrawLine(ctx->primary, x, y, x+length, y);
ctx->primary->FillRectangle(ctx->primary, x, y, length, 1); // with acceleration
}
/**
* function DirectFBVid_DrawRectangleWrapper
* - using hardware accelerator to fill a rectangle with the given color
**/
void DirectFBVid_DrawRectangleWrapper(DirectFBVidCtx *ctx, u32 x, u32 y, u32 width, u32 height, u8 r, u8 g, u8 b, u8 a)
{
//GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] in DirectFBVid_DrawRectangle(). Drawing rectangle x %d y %d width %d height %d color %08x\n", x, y, width, height, color));
SET_DRAWING_FLAGS( DSDRAW_NOFX );
ctx->primary->SetColor(ctx->primary, r, g, b, a);
ctx->primary->FillRectangle(ctx->primary, x, y, width, height);
//ctx->primary->Blit( ctx->primary, ctx->primary, NULL, x, y );
}
/**
* function DirectFBVid_CtxPrimaryLock
* - lock the surface (in order to access certain data)
**/
u32 DirectFBVid_CtxPrimaryLock(DirectFBVidCtx *ctx, void **buf, u32 *pitch)
{
DFBResult ret = ctx->primary->Lock(ctx->primary, DSLF_READ | DSLF_WRITE, buf, pitch);
if (ret != DFB_OK) return 1;
return 0;
}
static DFBEnumerationResult enum_input_device(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, void *data )
{
DeviceInfo **devices = data;
DeviceInfo *device = malloc(sizeof(DeviceInfo) );
device->device_id = device_id;
device->desc = desc;
device->next = *devices;
*devices = device;
return 0;
}
/**
* function DirectFBVid_InitAndCreateSurface
* - initialize and create DirectFB surface
**/
u32 DirectFBVid_TranslatePixelFormatToGPAC(u32 dfbpf);
void DirectFBVid_InitAndCreateSurface(DirectFBVidCtx *ctx, char *dfb_system)
{
DFBResult err;
DFBSurfaceDescription dsc;
DFBSurfacePixelFormat dfbpf;
DeviceInfo *devices = NULL;
//fake arguments and DirectFBInit()
{
int i, argc=2, argc_ro=2;
char **argv = malloc(argc*sizeof(char*));
char *argv_ro[2];
//http://directfb.org/wiki/index.php/Configuring_DirectFB
argv_ro[0]=argv[0]=strdup("gpac");
char dev_name[100];
snprintf(dev_name, 99, "--dfb:system=%s", dfb_system ? dfb_system : "x11");
dev_name[99]=0;
strlwr(dev_name);
argv_ro[1] = argv[1] = strdup(dev_name);
// screen resolution 640x480
//~ argv_ro[2]=argv[2]=strdup("--dfb:mode=640x480");
//~ argv_ro[2]=argv[2]=strdup("");
/* create the super interface */
DFBCHECK(DirectFBInit(&argc, &argv));
for (i=0; i<argc_ro; i++)
free(argv_ro[i]);
free(argv);
}
// disable background handling
DFBCHECK(DirectFBSetOption ("bg-none", NULL));
// disable layers
DFBCHECK(DirectFBSetOption ("no-init-layer", NULL));
/* create the surface */
DFBCHECK(DirectFBCreate( &(ctx->dfb) ));
/* create a list of input devices */
ctx->dfb->EnumInputDevices(ctx->dfb, enum_input_device, &devices );
if (devices->desc.type & DIDTF_JOYSTICK) {
// for mouse
DFBCHECK(ctx->dfb->GetInputDevice(ctx->dfb, devices->device_id, &(ctx->mouse)));
}
/* create an event buffer for all devices */
DFBCHECK(ctx->dfb->CreateInputEventBuffer(ctx->dfb, DICAPS_KEYS, DFB_FALSE, &(ctx->events) ));
/* Set the cooperative level */
DFBCHECK(ctx->dfb->SetCooperativeLevel( ctx->dfb, DFSCL_FULLSCREEN ));
/* Get the primary surface, i.e. the surface of the primary layer. */
// capabilities field is valid
dsc.flags = DSDESC_CAPS;
// primary, double-buffered surface
dsc.caps = DSCAPS_PRIMARY | DSCAPS_DOUBLE;
// if using system memory, data is permanently stored in this memory (no video memory allocation)
if (ctx->use_systems_memory) dsc.caps |= DSCAPS_SYSTEMONLY;
DFBCHECK(ctx->dfb->CreateSurface( ctx->dfb, &dsc, &(ctx->primary) ));
// fetch pixel format
ctx->primary->GetPixelFormat( ctx->primary, &dfbpf );
// translate DirectFB pixel format to GPAC
ctx->pixel_format = DirectFBVid_TranslatePixelFormatToGPAC(dfbpf);
// surface width and height in pixel
ctx->primary->GetSize( ctx->primary, &(ctx->width), &(ctx->height) );
ctx->primary->Clear( ctx->primary, 0, 0, 0, 0xFF);
}
/**
* function DirectFBVid_CtxPrimaryUnlock
* - unlock a surface after direct access (in order to fetch data)
**/
void DirectFBVid_CtxPrimaryUnlock(DirectFBVidCtx *ctx)
{
ctx->primary->Unlock(ctx->primary);
}
/**
* function DirectFBVid_CtxGetWidth
* - returns screen width
**/
u32 DirectFBVid_CtxGetWidth(DirectFBVidCtx *ctx)
{
return ctx->width;
}
/**
* function DirectFBVid_CtxGetHeight
* - returns screen height
**/
u32 DirectFBVid_CtxGetHeight(DirectFBVidCtx *ctx)
{
return ctx->height;
}
/**
* function DirectFBVid_CtxGetPrimary
* - return the primary surface
**/
void *DirectFBVid_CtxGetPrimary(DirectFBVidCtx *ctx)
{
return ctx->primary;
}
/**
* function DirectFBVid_CtxGetPixelFormat
* - get pixel format
**/
u32 DirectFBVid_CtxGetPixelFormat(DirectFBVidCtx *ctx)
{
return ctx->pixel_format;
}
/**
* function DirectFBVid_CtxIsHwMemory
* - return value whether system memory is used or not
**/
Bool DirectFBVid_CtxIsHwMemory(DirectFBVidCtx *ctx)
{
return ctx->use_systems_memory;
}
/**
* function DirectFBVid_CtxPrimaryFlip
* - flipping buffers
**/
u32 DirectFBVid_CtxPrimaryFlip(DirectFBVidCtx *ctx)
{
return ctx->primary->Flip(ctx->primary, NULL, ctx->flip_mode);
}
/**
* function DirectFBVid_CtxSetIsInit
* - boolean showing whether DirectFB is initialized
**/
void DirectFBVid_CtxSetIsInit(DirectFBVidCtx *ctx, Bool val)
{
ctx->is_init = val;
}
/**
* function DirectFBVid_CtxSetFlipMode
* - set flip mode
**/
void DirectFBVid_CtxSetFlipMode(DirectFBVidCtx *ctx, u32 flip_mode)
{
ctx->flip_mode = DSFLIP_BLIT;
switch(flip_mode) {
case FLIP_WAITFORSYNC:
ctx->flip_mode |= DSFLIP_WAITFORSYNC;
break;
case FLIP_WAIT:
ctx->flip_mode |= DSFLIP_WAIT;
break;
case FLIP_ONSYNC:
ctx->flip_mode |= DSFLIP_ONSYNC;
break;
case FLIP_SWAP:
ctx->flip_mode &= ~DSFLIP_BLIT;
break;
}
}
/**
* function DirectFBVid_CtxPrimaryProcessGetAccelerationMask
* - Get a mask of drawing functions that are hardware accelerated with the current settings.
**/
void DirectFBVid_CtxPrimaryProcessGetAccelerationMask(DirectFBVidCtx *ctx)
{
DFBAccelerationMask mask;
ctx->primary->GetAccelerationMask( ctx->primary, NULL, &mask );
if (mask & DFXL_DRAWLINE ) // DrawLine() is accelerated. DFXL_DRAWLINE
ctx->accel_drawline = 1;
if (mask & DFXL_FILLRECTANGLE) // FillRectangle() is accelerated.
ctx->accel_fillrect = 1;
}
/**
* function DirectFBVid_ShutdownWrapper
* - shutdown DirectFB module
**/
u32 DirectFBVid_ShutdownWrapper(DirectFBVidCtx *ctx)
{
// case where initialization is not done
if (!ctx->is_init) return 1;
//~ ctx->keyboard->Release( ctx->keyboard );
ctx->primary->Release( ctx->primary );
ctx->events->Release( ctx->events );
ctx->dfb->Release( ctx->dfb );
ctx->is_init = 0;
//we use x11 thus it should be useless:
//system("stgfb_control /dev/fb0 a 0")
return 0;
}
/**
* Blit a surface
**/
u32 DirectFBVid_TranslatePixelFormatFromGPAC(u32 gpacpf);
u32 DirectFBVid_BlitWrapper(DirectFBVidCtx *ctx, u32 video_src_width, u32 video_src_height, u32 video_src_pixel_format, char *video_src_buffer, s32 video_src_pitch_y, u32 src_wnd_x, u32 src_wnd_y, u32 src_wnd_w, u32 src_wnd_h, u32 dst_wnd_x, u32 dst_wnd_y, u32 dst_wnd_w, u32 dst_wnd_h, u32 overlay_type)
{
DFBResult res;
DFBSurfaceDescription srcdesc;
IDirectFBSurface *src;
DFBRectangle dfbsrc, dfbdst;
if (overlay_type != 0) return 1;
memset(&srcdesc, 0, sizeof(srcdesc));
srcdesc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_PREALLOCATED;
srcdesc.width = video_src_width;
srcdesc.height = video_src_height;
srcdesc.pixelformat = DirectFBVid_TranslatePixelFormatFromGPAC(video_src_pixel_format);
srcdesc.preallocated[0].data = video_src_buffer;
srcdesc.preallocated[0].pitch = video_src_pitch_y;
switch (video_src_pixel_format) {
case GF_PIXEL_ARGB: //return DSPF_ARGB;
case GF_PIXEL_RGBA: //return DSPF_ARGB;
ctx->primary->SetBlittingFlags(ctx->primary, DSBLIT_BLEND_ALPHACHANNEL);
break;
default:
ctx->primary->SetBlittingFlags(ctx->primary, DSBLIT_NOFX);
}
// create a surface with the new surface description
res = ctx->dfb->CreateSurface(ctx->dfb, &srcdesc, &src);
if (res != DFB_OK) {
//GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DirectFB] cannot create blit source surface for pixel format %s: %s (%d)\n", gf_4cc_to_str(video_src->pixel_format), DirectFBErrorString(res), res));
return 1;
}
dfbsrc.x = src_wnd_x;
dfbsrc.y = src_wnd_y;
dfbsrc.w = src_wnd_w;
dfbsrc.h = src_wnd_h;
// blit on the surface
if (!src_wnd_x && !src_wnd_y && (dst_wnd_w==src_wnd_w) && (dst_wnd_h==src_wnd_h)) {
ctx->primary->Blit(ctx->primary, src, &dfbsrc, dst_wnd_x, dst_wnd_y);
// blit an area scaled from the source to the destination rectangle
} else {
dfbdst.x = dst_wnd_x;
dfbdst.y = dst_wnd_y;
dfbdst.w = dst_wnd_w;
dfbdst.h = dst_wnd_h;
ctx->primary->StretchBlit(ctx->primary, src, &dfbsrc, &dfbdst);
}
src->Release(src);
return 0;
}
/**
* function DirectFBVid_ProcessMessageQueueWrapper
* - handle DirectFB events
* - key events
**/
void directfb_translate_key(DFBInputDeviceKeyIdentifier DirectFBkey, u32 *flags, u32 *key_code);
u32 DirectFBVid_ProcessMessageQueueWrapper(DirectFBVidCtx *ctx, u8 *type, u32 *flags, u32 *key_code, s32 *x, s32 *y, u32 *button)
{
DFBInputEvent directfb_evt;
if (ctx->events->GetEvent( ctx->events, DFB_EVENT(&directfb_evt) ) == DFB_OK)
{
switch (directfb_evt.type) {
case DIET_KEYPRESS:
case DIET_KEYRELEASE:
directfb_translate_key(directfb_evt.key_id, flags, key_code);
*type = (directfb_evt.type == DIET_KEYPRESS) ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP;
break;
case DIET_BUTTONPRESS:
case DIET_BUTTONRELEASE:
*type = (directfb_evt.type == DIET_BUTTONPRESS) ? GF_EVENT_MOUSEUP : GF_EVENT_MOUSEDOWN;
switch(directfb_evt.button) {
case DIBI_LEFT:
*button = GF_MOUSE_LEFT;
break;
case DIBI_RIGHT:
*button = GF_MOUSE_RIGHT;
break;
case DIBI_MIDDLE:
*button = GF_MOUSE_MIDDLE;
break;
default:
//fprintf(stderr, "in here for others\n");
break;
}
break;
case DIET_AXISMOTION:
*type = GF_EVENT_MOUSEMOVE;
ctx->mouse->GetXY(ctx->mouse, x, y);
default:
break;
}
return 0;
}
return 1;
}
/* Events translation */
/**
* function DirectFBVid_TranslatePixelFormatToGPAC
* - translate pixel from DirectFb to GPAC
**/
u32 DirectFBVid_TranslatePixelFormatToGPAC(u32 dfbpf)
{
switch (dfbpf) {
case DSPF_RGB16:
return GF_PIXEL_RGB_565;
case DSPF_RGB555:
return GF_PIXEL_RGB_555;
case DSPF_RGB24:
return GF_PIXEL_RGB;
case DSPF_RGB32:
return GF_PIXEL_RGBX;
case DSPF_ARGB:
return GF_PIXEL_ARGB;
default:
return 0;
}
}
/**
* function DirectFBVid_TranslatePixelFormatToGPAC
* - translate pixel from GPAC to DirectFB
**/
u32 DirectFBVid_TranslatePixelFormatFromGPAC(u32 gpacpf)
{
switch (gpacpf) {
case GF_PIXEL_RGB_565:
return DSPF_RGB16;
case GF_PIXEL_RGB_555 :
return DSPF_RGB555;
case GF_PIXEL_BGR:
return DSPF_RGB24;
case GF_PIXEL_RGB:
return DSPF_RGB24;
case GF_PIXEL_RGBX:
return DSPF_RGB32;
case GF_PIXEL_ARGB:
return DSPF_ARGB;
case GF_PIXEL_RGBA:
return DSPF_ARGB;
case GF_PIXEL_UYVY :
return DSPF_YUY2;
case GF_PIXEL_YUV:
return DSPF_YV12;
default:
;//GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DirectFB] pixel format %s not supported\n", gf_4cc_to_str(gpacpf)));
}
return 0;
}
/**
* function directfb_translate_key
* - translate key from DirectFB to GPAC
**/
void directfb_translate_key(DFBInputDeviceKeyIdentifier DirectFBkey, u32 *flags, u32 *key_code)
{
//~ fprintf(stderr, "DirectFBkey=%d\n", DirectFBkey);
switch (DirectFBkey) {
case DIKI_BACKSPACE:
*key_code = GF_KEY_BACKSPACE;
//~ fprintf(stderr, "DIKI_BACKSPACE\n");
break;
case DIKI_TAB:
*key_code = GF_KEY_TAB;
//~ fprintf(stderr, "DIKI_TAB\n");
break;
case DIKI_ENTER:
*key_code = GF_KEY_ENTER;
//~ fprintf(stderr, "DIKI_ENTER\n");
break;
case DIKI_ESCAPE:
*key_code = GF_KEY_ESCAPE;
//~ fprintf(stderr, "DIKI_ESCAPE\n");
break;
case DIKI_SPACE:
*key_code = GF_KEY_SPACE;
//~ fprintf(stderr, "DIKI_SPACE\n");
break;
case DIKI_SHIFT_L:
case DIKI_SHIFT_R:
*key_code = GF_KEY_SHIFT;
//~ fprintf(stderr, "DIKI_SHIFT_R/DIKI_SHIFT_L\n");
break;
case DIKI_CONTROL_L:
case DIKI_CONTROL_R:
*key_code = GF_KEY_CONTROL;
//~ fprintf(stderr, "DIKI_CONTROL_L/DIKI_CONTROL_R\n");
break;
case DIKI_ALT_L:
case DIKI_ALT_R:
*key_code = GF_KEY_ALT;
//~ fprintf(stderr, "DIKI_ALT_L/DIKI_ALT_R\n");
break;
case DIKI_CAPS_LOCK:
*key_code = GF_KEY_CAPSLOCK;
//~ fprintf(stderr, "DIKI_CAPS_LOCK\n");
break;
case DIKI_META_L:
case DIKI_META_R:
*key_code = GF_KEY_META;
break;
case DIKI_KP_EQUAL:
*key_code = GF_KEY_EQUALS;
break;
case DIKI_SUPER_L:
case DIKI_SUPER_R:
*key_code = GF_KEY_WIN;
break;
/* alphabets */
case DIKI_A:
*key_code = GF_KEY_A;
//~ fprintf(stderr, "DIKI_A\n");
break;
case DIKI_B:
*key_code = GF_KEY_B;
//~ fprintf(stderr, "DIKI_B\n");
break;
case DIKI_C:
*key_code = GF_KEY_C;
//~ fprintf(stderr, "DIKI_C\n");
break;
case DIKI_D:
*key_code = GF_KEY_D;
//~ fprintf(stderr, "DIKI_D\n");
break;
case DIKI_E:
*key_code = GF_KEY_E;
//~ fprintf(stderr, "DIKI_E\n");
break;
case DIKI_F:
*key_code = GF_KEY_F;
break;
case DIKI_G:
*key_code = GF_KEY_G;
break;
case DIKI_H:
*key_code = GF_KEY_H;
break;
case DIKI_I:
*key_code = GF_KEY_I;
break;
case DIKI_J:
*key_code = GF_KEY_J;
break;
case DIKI_K:
*key_code = GF_KEY_K;
break;
case DIKI_L:
*key_code = GF_KEY_L;
break;
case DIKI_M:
*key_code = GF_KEY_M;
break;
case DIKI_N:
*key_code = GF_KEY_N;
break;
case DIKI_O:
*key_code = GF_KEY_O;
break;
case DIKI_P:
*key_code = GF_KEY_P;
break;
case DIKI_Q:
*key_code = GF_KEY_Q;
break;
case DIKI_R:
*key_code = GF_KEY_R;
break;
case DIKI_S:
*key_code = GF_KEY_S;
break;
case DIKI_T:
*key_code = GF_KEY_T;
break;
case DIKI_U:
*key_code = GF_KEY_U;
break;
case DIKI_V:
*key_code = GF_KEY_V;
break;
case DIKI_W:
*key_code = GF_KEY_W;
break;
case DIKI_X:
*key_code = GF_KEY_X;
break;
case DIKI_Y:
*key_code = GF_KEY_Y;
break;
case DIKI_Z:
*key_code = GF_KEY_Z;
break;
case DIKI_PRINT:
*key_code = GF_KEY_PRINTSCREEN;
break;
case DIKI_SCROLL_LOCK:
*key_code = GF_KEY_SCROLL;
break;
case DIKI_PAUSE:
*key_code = GF_KEY_PAUSE;
break;
case DIKI_INSERT:
*key_code = GF_KEY_INSERT;
break;
case DIKI_DELETE:
*key_code = GF_KEY_DEL;
break;
case DIKI_HOME:
*key_code = GF_KEY_HOME;
break;
case DIKI_END:
*key_code = GF_KEY_END;
break;
case DIKI_PAGE_UP:
*key_code = GF_KEY_PAGEUP;
break;
case DIKI_PAGE_DOWN:
*key_code = GF_KEY_PAGEDOWN;
break;
/* arrows */
case DIKI_UP:
*key_code = GF_KEY_UP;
break;
case DIKI_DOWN:
*key_code = GF_KEY_DOWN;
break;
case DIKI_RIGHT:
*key_code = GF_KEY_RIGHT;
break;
case DIKI_LEFT:
*key_code = GF_KEY_LEFT;
break;
/* extended numerical pad */
case DIKI_NUM_LOCK:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_NUMLOCK;
break;
case DIKI_KP_DIV:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_SLASH;
break;
case DIKI_KP_MULT:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_STAR;
break;
case DIKI_KP_MINUS:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_HYPHEN;
break;
case DIKI_KP_PLUS:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_PLUS;
break;
case DIKI_KP_ENTER:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_ENTER;
break;
case DIKI_KP_DECIMAL:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_FULLSTOP;
break;
case DIKI_KP_0:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_0;
break;
case DIKI_KP_1:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_1;
break;
case DIKI_KP_2:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_2;
break;
case DIKI_KP_3:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_3;
break;
case DIKI_KP_4:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_4;
break;
case DIKI_KP_5:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_5;
break;
case DIKI_KP_6:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_6;
break;
case DIKI_KP_7:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_7;
break;
case DIKI_KP_8:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_8;
break;
case DIKI_KP_9:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_9;
break;
/* Fn functions */
case DIKI_F1:
*key_code = GF_KEY_F1;
break;
case DIKI_F2:
*key_code = GF_KEY_F2;
break;
case DIKI_F3:
*key_code = GF_KEY_F3;
break;
case DIKI_F4:
*key_code = GF_KEY_F4;
break;
case DIKI_F5:
*key_code = GF_KEY_F5;
break;
case DIKI_F6:
*key_code = GF_KEY_F6;
break;
case DIKI_F7:
*key_code = GF_KEY_F7;
break;
case DIKI_F8:
*key_code = GF_KEY_F8;
break;
case DIKI_F9:
*key_code = GF_KEY_F9;
break;
case DIKI_F10:
*key_code = GF_KEY_F10;
break;
case DIKI_F11:
*key_code = GF_KEY_F11;
break;
case DIKI_F12:
*key_code = GF_KEY_F12;
break;
default:
*key_code = GF_KEY_UNIDENTIFIED;
break;
}
}