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