/programs/network/netsurf/libnsfb/src/surface/Makefile |
---|
0,0 → 1,8 |
# Sources |
OBJS := surface.o able.o ram.o linux.o sdl.o |
OUTFILE = sup.o |
CFLAGS += -I ../../include/ -I ../../ -I ../ -I ./ -I /home/sourcerer/kos_src/newenginek/kolibri/include |
include $(MENUETDEV)/makefiles/Makefile_for_o_lib |
/programs/network/netsurf/libnsfb/src/surface/able.c |
---|
0,0 → 1,59 |
/* |
* Copyright 2009 Vincent Sanders <vince@simtec.co.uk> |
* |
* This file is part of libnsfb, http://www.netsurf-browser.org/ |
* Licenced under the MIT License, |
* http://www.opensource.org/licenses/mit-license.php |
*/ |
#include <stdbool.h> |
#include <stdio.h> |
#include "libnsfb.h" |
#include "libnsfb_plot.h" |
#include "libnsfb_event.h" |
#include "nsfb.h" |
#include "surface.h" |
#define UNUSED(x) ((x) = (x)) |
static int able_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format) |
{ |
if (nsfb->surface_priv != NULL) |
return -1; /* if were already initialised fail */ |
nsfb->width = width; |
nsfb->height = height; |
nsfb->format = format; |
return 0; |
} |
static int able_initialise(nsfb_t *nsfb) |
{ |
UNUSED(nsfb); |
return 0; |
} |
static int able_finalise(nsfb_t *nsfb) |
{ |
UNUSED(nsfb); |
return 0; |
} |
static bool able_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout) |
{ |
UNUSED(nsfb); |
UNUSED(event); |
UNUSED(timeout); |
return false; |
} |
const nsfb_surface_rtns_t able_rtns = { |
.initialise = able_initialise, |
.finalise = able_finalise, |
.input = able_input, |
.geometry = able_set_geometry, |
}; |
NSFB_SURFACE_DEF(able, NSFB_SURFACE_ABLE, &able_rtns) |
/programs/network/netsurf/libnsfb/src/surface/linux.c |
---|
0,0 → 1,109 |
/* |
* Copyright 2012 Vincent Sanders <vince@simtec.co.uk> |
* |
* This file is part of libnsfb, http://www.netsurf-browser.org/ |
* Licenced under the MIT License, |
* http://www.opensource.org/licenses/mit-license.php |
*/ |
#include <stdbool.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <sys/ioctl.h> |
#include <fcntl.h> |
#include <string.h> |
#include <errno.h> |
#include <unistd.h> |
#include <sys/mman.h> |
//#include <linux/fb.h> |
#include "libnsfb.h" |
#include "libnsfb_event.h" |
#include "libnsfb_plot.h" |
#include "libnsfb_plot_util.h" |
#include "nsfb.h" |
#include "plot.h" |
#include "surface.h" |
#include "cursor.h" |
#define UNUSED(x) ((x) = (x)) |
#define FB_NAME "/dev/fb0" |
struct lnx_priv { |
int fd; |
}; |
static int linux_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format) |
{ |
return -1; |
} |
static enum nsfb_format_e |
format_from_lstate(void ) |
{ |
return 0; |
} |
static int linux_initialise(nsfb_t *nsfb) |
{ |
return -1; |
} |
static int linux_finalise(nsfb_t *nsfb) |
{ |
return 0; |
} |
static bool linux_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout) |
{ |
UNUSED(nsfb); |
UNUSED(event); |
UNUSED(timeout); |
return false; |
} |
static int linux_claim(nsfb_t *nsfb, nsfb_bbox_t *box) |
{ |
return 0; |
} |
static int linux_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor) |
{ |
return true; |
} |
static int linux_update(nsfb_t *nsfb, nsfb_bbox_t *box) |
{ |
return 0; |
} |
const nsfb_surface_rtns_t linux_rtns = { |
.initialise = linux_initialise, |
.finalise = linux_finalise, |
.input = linux_input, |
.claim = linux_claim, |
.update = linux_update, |
.cursor = linux_cursor, |
.geometry = linux_set_geometry, |
}; |
NSFB_SURFACE_DEF(linux, NSFB_SURFACE_LINUX, &linux_rtns) |
/* |
* Local variables: |
* c-basic-offset: 4 |
* tab-width: 8 |
* End: |
*/ |
/programs/network/netsurf/libnsfb/src/surface/ram.c |
---|
0,0 → 1,108 |
/* |
* Copyright 2009 Vincent Sanders <vince@simtec.co.uk> |
* |
* This file is part of libnsfb, http://www.netsurf-browser.org/ |
* Licenced under the MIT License, |
* http://www.opensource.org/licenses/mit-license.php |
*/ |
#include <stdbool.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include "libnsfb.h" |
#include "libnsfb_plot.h" |
#include "libnsfb_event.h" |
#include "nsfb.h" |
#include "surface.h" |
#include "plot.h" |
#define UNUSED(x) ((x) = (x)) |
static int ram_defaults(nsfb_t *nsfb) |
{ |
nsfb->width = 0; |
nsfb->height = 0; |
nsfb->format = NSFB_FMT_ABGR8888; |
/* select default sw plotters for bpp */ |
select_plotters(nsfb); |
return 0; |
} |
static int ram_initialise(nsfb_t *nsfb) |
{ |
size_t size = (nsfb->width * nsfb->height * nsfb->bpp) / 8; |
nsfb->ptr = realloc(nsfb->ptr, size); |
nsfb->linelen = (nsfb->width * nsfb->bpp) / 8; |
return 0; |
} |
static int ram_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format) |
{ |
int startsize; |
int endsize; |
startsize = (nsfb->width * nsfb->height * nsfb->bpp) / 8; |
if (width > 0) { |
nsfb->width = width; |
} |
if (height > 0) { |
nsfb->height = height; |
} |
if (format != NSFB_FMT_ANY) { |
nsfb->format = format; |
} |
/* select soft plotters appropriate for format */ |
select_plotters(nsfb); |
endsize = (nsfb->width * nsfb->height * nsfb->bpp) / 8; |
if ((nsfb->ptr != NULL) && (startsize != endsize)) { |
nsfb->ptr = realloc(nsfb->ptr, endsize); |
} |
nsfb->linelen = (nsfb->width * nsfb->bpp) / 8; |
return 0; |
} |
static int ram_finalise(nsfb_t *nsfb) |
{ |
free(nsfb->ptr); |
return 0; |
} |
static bool ram_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout) |
{ |
UNUSED(nsfb); |
UNUSED(event); |
UNUSED(timeout); |
return false; |
} |
const nsfb_surface_rtns_t ram_rtns = { |
.defaults = ram_defaults, |
.initialise = ram_initialise, |
.finalise = ram_finalise, |
.input = ram_input, |
.geometry = ram_set_geometry, |
}; |
NSFB_SURFACE_DEF(ram, NSFB_SURFACE_RAM, &ram_rtns) |
/* |
* Local variables: |
* c-basic-offset: 4 |
* tab-width: 8 |
* End: |
*/ |
/programs/network/netsurf/libnsfb/src/surface/sdl.c |
---|
0,0 → 1,736 |
/* |
* Copyright 2009 Vincent Sanders <vince@simtec.co.uk> |
* |
* This file is part of libnsfb, http://www.netsurf-browser.org/ |
* Licenced under the MIT License, |
* http://www.opensource.org/licenses/mit-license.php |
*/ |
#include <stdbool.h> |
#include <stdlib.h> |
#include <SDL/SDL.h> |
#include "libnsfb.h" |
#include "libnsfb_event.h" |
#include "libnsfb_plot.h" |
#include "libnsfb_plot_util.h" |
#include "nsfb.h" |
#include "surface.h" |
#include "palette.h" |
#include "plot.h" |
#include "cursor.h" |
enum nsfb_key_code_e sdl_nsfb_map[] = { |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_BACKSPACE, |
NSFB_KEY_TAB, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_CLEAR, |
NSFB_KEY_RETURN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_PAUSE, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_ESCAPE, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_SPACE, |
NSFB_KEY_EXCLAIM, |
NSFB_KEY_QUOTEDBL, |
NSFB_KEY_HASH, |
NSFB_KEY_DOLLAR, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_AMPERSAND, |
NSFB_KEY_QUOTE, |
NSFB_KEY_LEFTPAREN, |
NSFB_KEY_RIGHTPAREN, |
NSFB_KEY_ASTERISK, |
NSFB_KEY_PLUS, |
NSFB_KEY_COMMA, |
NSFB_KEY_MINUS, |
NSFB_KEY_PERIOD, |
NSFB_KEY_SLASH, |
NSFB_KEY_0, |
NSFB_KEY_1, |
NSFB_KEY_2, |
NSFB_KEY_3, |
NSFB_KEY_4, |
NSFB_KEY_5, |
NSFB_KEY_6, |
NSFB_KEY_7, |
NSFB_KEY_8, |
NSFB_KEY_9, |
NSFB_KEY_COLON, |
NSFB_KEY_SEMICOLON, |
NSFB_KEY_LESS, |
NSFB_KEY_EQUALS, |
NSFB_KEY_GREATER, |
NSFB_KEY_QUESTION, |
NSFB_KEY_AT, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_LEFTBRACKET, |
NSFB_KEY_BACKSLASH, |
NSFB_KEY_RIGHTBRACKET, |
NSFB_KEY_CARET, |
NSFB_KEY_UNDERSCORE, |
NSFB_KEY_BACKQUOTE, |
NSFB_KEY_a, |
NSFB_KEY_b, |
NSFB_KEY_c, |
NSFB_KEY_d, |
NSFB_KEY_e, |
NSFB_KEY_f, |
NSFB_KEY_g, |
NSFB_KEY_h, |
NSFB_KEY_i, |
NSFB_KEY_j, |
NSFB_KEY_k, |
NSFB_KEY_l, |
NSFB_KEY_m, |
NSFB_KEY_n, |
NSFB_KEY_o, |
NSFB_KEY_p, |
NSFB_KEY_q, |
NSFB_KEY_r, |
NSFB_KEY_s, |
NSFB_KEY_t, |
NSFB_KEY_u, |
NSFB_KEY_v, |
NSFB_KEY_w, |
NSFB_KEY_x, |
NSFB_KEY_y, |
NSFB_KEY_z, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_DELETE, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_KP0, |
NSFB_KEY_KP1, |
NSFB_KEY_KP2, |
NSFB_KEY_KP3, |
NSFB_KEY_KP4, |
NSFB_KEY_KP5, |
NSFB_KEY_KP6, |
NSFB_KEY_KP7, |
NSFB_KEY_KP8, |
NSFB_KEY_KP9, |
NSFB_KEY_KP_PERIOD, |
NSFB_KEY_KP_DIVIDE, |
NSFB_KEY_KP_MULTIPLY, |
NSFB_KEY_KP_MINUS, |
NSFB_KEY_KP_PLUS, |
NSFB_KEY_KP_ENTER, |
NSFB_KEY_KP_EQUALS, |
NSFB_KEY_UP, |
NSFB_KEY_DOWN, |
NSFB_KEY_RIGHT, |
NSFB_KEY_LEFT, |
NSFB_KEY_INSERT, |
NSFB_KEY_HOME, |
NSFB_KEY_END, |
NSFB_KEY_PAGEUP, |
NSFB_KEY_PAGEDOWN, |
NSFB_KEY_F1, |
NSFB_KEY_F2, |
NSFB_KEY_F3, |
NSFB_KEY_F4, |
NSFB_KEY_F5, |
NSFB_KEY_F6, |
NSFB_KEY_F7, |
NSFB_KEY_F8, |
NSFB_KEY_F9, |
NSFB_KEY_F10, |
NSFB_KEY_F11, |
NSFB_KEY_F12, |
NSFB_KEY_F13, |
NSFB_KEY_F14, |
NSFB_KEY_F15, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_NUMLOCK, |
NSFB_KEY_CAPSLOCK, |
NSFB_KEY_SCROLLOCK, |
NSFB_KEY_RSHIFT, |
NSFB_KEY_LSHIFT, |
NSFB_KEY_RCTRL, |
NSFB_KEY_LCTRL, |
NSFB_KEY_RALT, |
NSFB_KEY_LALT, |
NSFB_KEY_RMETA, |
NSFB_KEY_LMETA, |
NSFB_KEY_LSUPER, |
NSFB_KEY_RSUPER, |
NSFB_KEY_MODE, |
NSFB_KEY_COMPOSE, |
NSFB_KEY_HELP, |
NSFB_KEY_PRINT, |
NSFB_KEY_SYSREQ, |
NSFB_KEY_BREAK, |
NSFB_KEY_MENU, |
NSFB_KEY_POWER, |
NSFB_KEY_EURO, |
NSFB_KEY_UNDO, |
}; |
static void |
set_palette(nsfb_t *nsfb) |
{ |
SDL_Surface *sdl_screen = nsfb->surface_priv; |
SDL_Color palette[256]; |
int loop = 0; |
/* Get libnsfb palette */ |
nsfb_palette_generate_nsfb_8bpp(nsfb->palette); |
/* Create SDL palette from nsfb palette */ |
for (loop = 0; loop < 256; loop++) { |
palette[loop].r = (nsfb->palette->data[loop] ) & 0xFF; |
palette[loop].g = (nsfb->palette->data[loop] >> 8) & 0xFF; |
palette[loop].b = (nsfb->palette->data[loop] >> 16) & 0xFF; |
} |
/* Set SDL palette */ |
SDL_SetColors(sdl_screen, palette, 0, 256); |
} |
static bool |
sdlcopy(nsfb_t *nsfb, nsfb_bbox_t *srcbox, nsfb_bbox_t *dstbox) |
{ |
SDL_Rect src; |
SDL_Rect dst; |
SDL_Surface *sdl_screen = nsfb->surface_priv; |
nsfb_bbox_t allbox; |
struct nsfb_cursor_s *cursor = nsfb->cursor; |
nsfb_plot_add_rect(srcbox, dstbox, &allbox); |
/* clear the cursor if its within the region to be altered */ |
if ((cursor != NULL) && |
(cursor->plotted == true) && |
(nsfb_plot_bbox_intersect(&allbox, &cursor->loc))) { |
nsfb_cursor_clear(nsfb, cursor); |
} |
src.x = srcbox->x0; |
src.y = srcbox->y0; |
src.w = srcbox->x1 - srcbox->x0; |
src.h = srcbox->y1 - srcbox->y0; |
dst.x = dstbox->x0; |
dst.y = dstbox->y0; |
dst.w = dstbox->x1 - dstbox->x0; |
dst.h = dstbox->y1 - dstbox->y0; |
SDL_BlitSurface(sdl_screen, &src, sdl_screen , &dst); |
if ((cursor != NULL) && |
(cursor->plotted == false)) { |
nsfb_cursor_plot(nsfb, cursor); |
} |
SDL_UpdateRect(sdl_screen, dst.x, dst.y, dst.w, dst.h); |
return true; |
} |
static int sdl_set_geometry(nsfb_t *nsfb, int width, int height, |
enum nsfb_format_e format) |
{ |
if (nsfb->surface_priv != NULL) |
return -1; /* fail if surface already initialised */ |
nsfb->width = width; |
nsfb->height = height; |
nsfb->format = format; |
/* select default sw plotters for format */ |
select_plotters(nsfb); |
nsfb->plotter_fns->copy = sdlcopy; |
return 0; |
} |
static int sdl_initialise(nsfb_t *nsfb) |
{ |
SDL_Surface *sdl_screen; |
SDL_PixelFormat *sdl_fmt; |
enum nsfb_format_e fmt; |
if (nsfb->surface_priv != NULL) |
return -1; |
/* sanity checked depth. */ |
if ((nsfb->bpp != 32) && (nsfb->bpp != 16) && (nsfb->bpp != 8)) |
return -1; |
/* initialise SDL library */ |
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) < 0 ) { |
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); |
return -1; |
} |
sdl_screen = SDL_SetVideoMode(nsfb->width, |
nsfb->height, |
nsfb->bpp, |
SDL_SWSURFACE); |
if (sdl_screen == NULL ) { |
fprintf(stderr, "Unable to set video: %s\n", SDL_GetError()); |
return -1; |
} |
/* find out what pixel format we got */ |
sdl_fmt = sdl_screen->format; |
switch (sdl_fmt->BitsPerPixel) { |
case 32: |
if (sdl_fmt->Rshift == 0) |
fmt = NSFB_FMT_XBGR8888; |
else |
fmt = NSFB_FMT_XRGB8888; |
break; |
default: |
fmt = nsfb->format; |
break; |
} |
/* If we didn't get what we asked for, reselect plotters */ |
if (nsfb->format != fmt) { |
nsfb->format = fmt; |
if (sdl_set_geometry(nsfb, nsfb->width, nsfb->height, |
nsfb->format) != 0) { |
return -1; |
} |
} |
nsfb->surface_priv = sdl_screen; |
if (nsfb->bpp == 8) { |
nsfb_palette_new(&nsfb->palette, nsfb->width); |
set_palette(nsfb); |
} |
nsfb->ptr = sdl_screen->pixels; |
nsfb->linelen = sdl_screen->pitch; |
SDL_ShowCursor(SDL_DISABLE); |
SDL_EnableKeyRepeat(300, 50); |
return 0; |
} |
static int sdl_finalise(nsfb_t *nsfb) |
{ |
nsfb=nsfb; |
SDL_Quit(); |
return 0; |
} |
static uint32_t wakeeventtimer(uint32_t ival, void *param) |
{ |
SDL_Event event; |
ival = ival; |
param = param; |
event.type = SDL_USEREVENT; |
event.user.code = 0; |
event.user.data1 = 0; |
event.user.data2 = 0; |
SDL_PushEvent(&event); |
return 0; |
} |
static bool sdl_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout) |
{ |
int got_event; |
SDL_Event sdlevent; |
nsfb = nsfb; /* unused */ |
//if (timeout == 0) { |
got_event = SDL_PollEvent(&sdlevent); |
/*} else { |
if (timeout > 0) { |
/* setup wake timer to ensure the wait event below exits no later |
* than when the timeout has occoured. |
*/ |
// SDL_TimerID tid; |
// tid = SDL_AddTimer(timeout, wakeeventtimer, NULL); |
// got_event = SDL_WaitEvent(&sdlevent); |
// if ((got_event == 0) || (sdlevent.type != SDL_USEREVENT)) { |
// SDL_RemoveTimer(tid); |
// } |
// } else { |
// got_event = SDL_WaitEvent(&sdlevent); |
// } |
//} |
/* Do nothing if there was no event */ |
if (got_event == 0) { |
return false; |
} |
event->type = NSFB_EVENT_NONE; |
switch (sdlevent.type) { |
case SDL_KEYDOWN: |
event->type = NSFB_EVENT_KEY_DOWN; |
event->value.keycode = sdl_nsfb_map[sdlevent.key.keysym.sym]; |
break; |
case SDL_KEYUP: |
event->type = NSFB_EVENT_KEY_UP; |
event->value.keycode = sdl_nsfb_map[sdlevent.key.keysym.sym]; |
break; |
case SDL_MOUSEBUTTONDOWN: |
event->type = NSFB_EVENT_KEY_DOWN; |
switch (sdlevent.button.button) { |
case SDL_BUTTON_LEFT: |
event->value.keycode = NSFB_KEY_MOUSE_1; |
break; |
case SDL_BUTTON_MIDDLE: |
event->value.keycode = NSFB_KEY_MOUSE_2; |
break; |
case SDL_BUTTON_RIGHT: |
event->value.keycode = NSFB_KEY_MOUSE_3; |
break; |
/*case SDL_BUTTON_WHEELUP: |
event->value.keycode = NSFB_KEY_MOUSE_4; |
break; |
case SDL_BUTTON_WHEELDOWN: |
event->value.keycode = NSFB_KEY_MOUSE_5; |
break; |
*/ |
} |
break; |
case SDL_MOUSEBUTTONUP: |
event->type = NSFB_EVENT_KEY_UP; |
switch (sdlevent.button.button) { |
case SDL_BUTTON_LEFT: |
event->value.keycode = NSFB_KEY_MOUSE_1; |
break; |
case SDL_BUTTON_MIDDLE: |
event->value.keycode = NSFB_KEY_MOUSE_2; |
break; |
case SDL_BUTTON_RIGHT: |
event->value.keycode = NSFB_KEY_MOUSE_3; |
break; |
/*case SDL_BUTTON_WHEELUP: |
event->value.keycode = NSFB_KEY_MOUSE_4; |
break; |
case SDL_BUTTON_WHEELDOWN: |
event->value.keycode = NSFB_KEY_MOUSE_5; |
break;*/ |
} |
break; |
case SDL_MOUSEMOTION: |
event->type = NSFB_EVENT_MOVE_ABSOLUTE; |
event->value.vector.x = sdlevent.motion.x; |
event->value.vector.y = sdlevent.motion.y; |
event->value.vector.z = 0; |
break; |
case SDL_QUIT: |
event->type = NSFB_EVENT_CONTROL; |
event->value.controlcode = NSFB_CONTROL_QUIT; |
break; |
case SDL_USEREVENT: |
event->type = NSFB_EVENT_CONTROL; |
event->value.controlcode = NSFB_CONTROL_TIMEOUT; |
break; |
} |
return true; |
} |
static int sdl_claim(nsfb_t *nsfb, nsfb_bbox_t *box) |
{ |
struct nsfb_cursor_s *cursor = nsfb->cursor; |
if ((cursor != NULL) && |
(cursor->plotted == true) && |
(nsfb_plot_bbox_intersect(box, &cursor->loc))) { |
nsfb_cursor_clear(nsfb, cursor); |
} |
return 0; |
} |
static int |
sdl_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor) |
{ |
SDL_Surface *sdl_screen = nsfb->surface_priv; |
nsfb_bbox_t redraw; |
nsfb_bbox_t fbarea; |
if ((cursor != NULL) && (cursor->plotted == true)) { |
nsfb_bbox_t loc_shift = cursor->loc; |
loc_shift.x0 -= cursor->hotspot_x; |
loc_shift.y0 -= cursor->hotspot_y; |
loc_shift.x1 -= cursor->hotspot_x; |
loc_shift.y1 -= cursor->hotspot_y; |
nsfb_plot_add_rect(&cursor->savloc, &loc_shift, &redraw); |
/* screen area */ |
fbarea.x0 = 0; |
fbarea.y0 = 0; |
fbarea.x1 = nsfb->width; |
fbarea.y1 = nsfb->height; |
nsfb_plot_clip(&fbarea, &redraw); |
nsfb_cursor_clear(nsfb, cursor); |
nsfb_cursor_plot(nsfb, cursor); |
SDL_UpdateRect(sdl_screen, |
redraw.x0, |
redraw.y0, |
redraw.x1 - redraw.x0, |
redraw.y1 - redraw.y0); |
} |
return true; |
} |
static int sdl_update(nsfb_t *nsfb, nsfb_bbox_t *box) |
{ |
SDL_Surface *sdl_screen = nsfb->surface_priv; |
struct nsfb_cursor_s *cursor = nsfb->cursor; |
if ((cursor != NULL) && |
(cursor->plotted == false)) { |
nsfb_cursor_plot(nsfb, cursor); |
} |
SDL_UpdateRect(sdl_screen, |
box->x0, |
box->y0, |
box->x1 - box->x0, |
box->y1 - box->y0); |
return 0; |
} |
const nsfb_surface_rtns_t sdl_rtns = { |
.initialise = sdl_initialise, |
.finalise = sdl_finalise, |
.input = sdl_input, |
.claim = sdl_claim, |
.update = sdl_update, |
.cursor = sdl_cursor, |
.geometry = sdl_set_geometry, |
}; |
NSFB_SURFACE_DEF(sdl, NSFB_SURFACE_SDL, &sdl_rtns) |
/* |
* Local variables: |
* c-basic-offset: 4 |
* tab-width: 8 |
* End: |
*/ |
/programs/network/netsurf/libnsfb/src/surface/surface.c |
---|
0,0 → 1,159 |
/* |
* Copyright 2009 Vincent Sanders <vince@simtec.co.uk> |
* |
* This file is part of libnsfb, http://www.netsurf-browser.org/ |
* Licenced under the MIT License, |
* http://www.opensource.org/licenses/mit-license.php |
*/ |
#include <stdbool.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <string.h> |
#include "surface.h" |
#include "plot.h" |
#define MAX_SURFACES 16 |
#define UNUSED(x) ((x) = (x)) |
struct nsfb_surface_s { |
enum nsfb_type_e type; |
const nsfb_surface_rtns_t *rtns; |
const char *name; |
}; |
static struct nsfb_surface_s surfaces[MAX_SURFACES]; |
static int surface_count = 0; |
/* internal routine which lets surfaces register their presence at runtime */ |
void _nsfb_register_surface(const enum nsfb_type_e type, |
const nsfb_surface_rtns_t *rtns, |
const char *name) |
{ |
if (surface_count >= MAX_SURFACES) |
return; /* no space for additional surfaces */ |
surfaces[surface_count].type = type; |
surfaces[surface_count].rtns = rtns; |
surfaces[surface_count].name = name; |
surface_count++; |
} |
/* default surface implementations */ |
static int surface_defaults(nsfb_t *nsfb) |
{ |
nsfb->width = 800; |
nsfb->height = 600; |
nsfb->format = NSFB_FMT_XRGB8888; |
/* select default sw plotters for bpp */ |
select_plotters(nsfb); |
return 0; |
} |
static int surface_claim(nsfb_t *nsfb, nsfb_bbox_t *box) |
{ |
UNUSED(nsfb); |
UNUSED(box); |
return 0; |
} |
static int surface_update(nsfb_t *nsfb, nsfb_bbox_t *box) |
{ |
UNUSED(nsfb); |
UNUSED(box); |
return 0; |
} |
static int surface_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor) |
{ |
UNUSED(nsfb); |
UNUSED(cursor); |
return 0; |
} |
static int surface_parameters(nsfb_t *nsfb, const char *parameters) |
{ |
UNUSED(nsfb); |
UNUSED(parameters); |
return 0; |
} |
/* exported interface documented in surface.h */ |
nsfb_surface_rtns_t * |
nsfb_surface_get_rtns(enum nsfb_type_e type) |
{ |
int fend_loop; |
nsfb_surface_rtns_t *rtns = NULL; |
for (fend_loop = 0; fend_loop < surface_count; fend_loop++) { |
/* surface type must match and have a initialisor, finaliser |
* and input method |
*/ |
if ((surfaces[fend_loop].type == type) && |
(surfaces[fend_loop].rtns->initialise != NULL) && |
(surfaces[fend_loop].rtns->finalise != NULL) && |
(surfaces[fend_loop].rtns->input != NULL) ) { |
rtns = malloc(sizeof(nsfb_surface_rtns_t)); |
if (rtns == NULL) { |
continue; |
} |
memcpy(rtns, |
surfaces[fend_loop].rtns, |
sizeof(nsfb_surface_rtns_t)); |
/* The rest may be empty but to avoid the null check every time |
* provide default implementations. |
*/ |
if (rtns->defaults == NULL) { |
rtns->defaults = surface_defaults; |
} |
if (rtns->claim == NULL) { |
rtns->claim = surface_claim; |
} |
if (rtns->update == NULL) { |
rtns->update = surface_update; |
} |
if (rtns->cursor == NULL) { |
rtns->cursor = surface_cursor; |
} |
if (rtns->parameters == NULL) { |
rtns->parameters = surface_parameters; |
} |
break; |
} |
} |
return rtns; |
} |
/* exported interface defined in libnsfb.h */ |
enum nsfb_type_e |
nsfb_type_from_name(const char *name) |
{ |
int fend_loop; |
for (fend_loop = 0; fend_loop < surface_count; fend_loop++) { |
if (strcmp(surfaces[fend_loop].name, name) == 0) |
return surfaces[fend_loop].type; |
} |
return NSFB_SURFACE_NONE; |
} |
/* |
* Local variables: |
* c-basic-offset: 4 |
* tab-width: 8 |
* End: |
*/ |
/programs/network/netsurf/libnsfb/src/surface/vnc.c |
---|
0,0 → 1,567 |
/* |
* Copyright 2009 Vincent Sanders <vince@simtec.co.uk> |
* |
* This file is part of libnsfb, http://www.netsurf-browser.org/ |
* Licenced under the MIT License, |
* http://www.opensource.org/licenses/mit-license.php |
*/ |
#include <stdbool.h> |
#include <stdio.h> |
#include <rfb/rfb.h> |
#include <rfb/keysym.h> |
#include "libnsfb.h" |
#include "libnsfb_event.h" |
#include "libnsfb_plot.h" |
#include "nsfb.h" |
#include "surface.h" |
#include "plot.h" |
#include "cursor.h" |
#define UNUSED(x) ((x) = (x)) |
static nsfb_event_t *gevent; |
/* vnc special set codes */ |
static enum nsfb_key_code_e vnc_nsfb_map[256] = { |
NSFB_KEY_UNKNOWN, /* 0x00 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_BACKSPACE, /* 0x08 */ |
NSFB_KEY_TAB, |
NSFB_KEY_LF, |
NSFB_KEY_CLEAR, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_RETURN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x10 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_RETURN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x18 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_ESCAPE, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_COMPOSE, /* 0x20 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x28 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x30 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x38 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x40 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x48 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_HOME, /* 0x50 */ |
NSFB_KEY_LEFT, |
NSFB_KEY_UP, |
NSFB_KEY_RIGHT, |
NSFB_KEY_DOWN, |
NSFB_KEY_PAGEUP, |
NSFB_KEY_PAGEDOWN, |
NSFB_KEY_END, |
NSFB_KEY_HOME, /* 0x58 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x60 */ |
NSFB_KEY_PRINT, |
NSFB_KEY_HELP, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNDO, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_MENU, |
NSFB_KEY_UNKNOWN, /* 0x68 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_BREAK, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x70 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x78 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_MODE, |
NSFB_KEY_NUMLOCK, |
NSFB_KEY_UNKNOWN, /* 0x80 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x88 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_KP_ENTER, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x90 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0x98 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0xA0 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0xA8 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_KP_MULTIPLY, |
NSFB_KEY_KP_PLUS, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_KP_MINUS, |
NSFB_KEY_KP_PERIOD, |
NSFB_KEY_KP_DIVIDE, |
NSFB_KEY_KP0, /* 0xB0 */ |
NSFB_KEY_KP1, |
NSFB_KEY_KP2, |
NSFB_KEY_KP3, |
NSFB_KEY_KP4, |
NSFB_KEY_KP5, |
NSFB_KEY_KP6, |
NSFB_KEY_KP7, |
NSFB_KEY_KP8, /* 0xB8 */ |
NSFB_KEY_KP9, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_KP_EQUALS, |
NSFB_KEY_F1, |
NSFB_KEY_F2, |
NSFB_KEY_F3, /* 0xC0 */ |
NSFB_KEY_F4, |
NSFB_KEY_F5, |
NSFB_KEY_F6, |
NSFB_KEY_F7, |
NSFB_KEY_F8, |
NSFB_KEY_F9, |
NSFB_KEY_F10, |
NSFB_KEY_F11, /* 0xC8 */ |
NSFB_KEY_F12, |
NSFB_KEY_F13, |
NSFB_KEY_F14, |
NSFB_KEY_F15, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0xD0 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0xD8 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0xE0 */ |
NSFB_KEY_LSHIFT, |
NSFB_KEY_RSHIFT, |
NSFB_KEY_LCTRL, |
NSFB_KEY_RCTRL, |
NSFB_KEY_CAPSLOCK, |
NSFB_KEY_SCROLLOCK, |
NSFB_KEY_LMETA, |
NSFB_KEY_RMETA, /* 0xE8 */ |
NSFB_KEY_LALT, |
NSFB_KEY_RALT, |
NSFB_KEY_LSUPER, |
NSFB_KEY_RSUPER, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0xF0 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, /* 0xF8 */ |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_UNKNOWN, |
NSFB_KEY_DELETE, |
}; |
static void vnc_doptr(int buttonMask,int x,int y,rfbClientPtr cl) |
{ |
static int prevbuttonMask = 0; |
UNUSED(cl); |
if (prevbuttonMask != buttonMask) { |
/* button click */ |
if (((prevbuttonMask ^ buttonMask) & 0x01) == 0x01) { |
if ((buttonMask & 0x01) == 0x01) { |
gevent->type = NSFB_EVENT_KEY_DOWN; |
} else { |
gevent->type = NSFB_EVENT_KEY_UP; |
} |
gevent->value.keycode = NSFB_KEY_MOUSE_1; |
} else if (((prevbuttonMask ^ buttonMask) & 0x02) == 0x02) { |
if ((buttonMask & 0x01) == 0x01) { |
gevent->type = NSFB_EVENT_KEY_DOWN; |
} else { |
gevent->type = NSFB_EVENT_KEY_UP; |
} |
gevent->value.keycode = NSFB_KEY_MOUSE_2; |
} else if (((prevbuttonMask ^ buttonMask) & 0x04) == 0x04) { |
if ((buttonMask & 0x01) == 0x01) { |
gevent->type = NSFB_EVENT_KEY_DOWN; |
} else { |
gevent->type = NSFB_EVENT_KEY_UP; |
} |
gevent->value.keycode = NSFB_KEY_MOUSE_3; |
} else if (((prevbuttonMask ^ buttonMask) & 0x08) == 0x08) { |
if ((buttonMask & 0x01) == 0x01) { |
gevent->type = NSFB_EVENT_KEY_DOWN; |
} else { |
gevent->type = NSFB_EVENT_KEY_UP; |
} |
gevent->value.keycode = NSFB_KEY_MOUSE_4; |
} else if (((prevbuttonMask ^ buttonMask) & 0x10) == 0x10) { |
if ((buttonMask & 0x01) == 0x01) { |
gevent->type = NSFB_EVENT_KEY_DOWN; |
} else { |
gevent->type = NSFB_EVENT_KEY_UP; |
} |
gevent->value.keycode = NSFB_KEY_MOUSE_5; |
} |
prevbuttonMask = buttonMask; |
} else { |
gevent->type = NSFB_EVENT_MOVE_ABSOLUTE; |
gevent->value.vector.x = x; |
gevent->value.vector.y = y; |
gevent->value.vector.z = 0; |
} |
} |
static void vnc_dokey(rfbBool down, rfbKeySym key, rfbClientPtr cl) |
{ |
enum nsfb_key_code_e keycode = NSFB_KEY_UNKNOWN; |
UNUSED(cl); |
if ((key >= XK_space) && (key <= XK_asciitilde)) { |
/* ascii codes line up */ |
keycode = key; |
} else if ((key & 0xff00) == 0xff00) { |
/* bottom 8bits of keysyms in this range map via table */ |
keycode = vnc_nsfb_map[(key & 0xff)]; |
} |
if (down == 0) { |
/* key up */ |
gevent->type = NSFB_EVENT_KEY_UP; |
} else { |
/* key down */ |
gevent->type = NSFB_EVENT_KEY_DOWN; |
} |
gevent->value.keycode = keycode; |
} |
static int vnc_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format) |
{ |
if (nsfb->surface_priv != NULL) |
return -1; /* fail if surface already initialised */ |
if (width > 0) { |
nsfb->width = width; |
} |
if (height > 0) { |
nsfb->height = height; |
} |
if (format != NSFB_FMT_ANY) { |
nsfb->format = format; |
} |
/* select soft plotters appropriate for format */ |
select_plotters(nsfb); |
return 0; |
} |
static int vnc_initialise(nsfb_t *nsfb) |
{ |
rfbScreenInfoPtr vncscreen; |
int argc = 0; |
char **argv = NULL; |
if (nsfb->surface_priv != NULL) |
return -1; /* fail if surface already initialised */ |
/* sanity checked depth. */ |
if (nsfb->bpp != 32) |
return -1; |
/* create vnc screen with 8bits per sample, three samples per |
* pixel and 4 bytes per pixel. */ |
vncscreen = rfbGetScreen(&argc, argv, |
nsfb->width, nsfb->height, |
8, 3, (nsfb->bpp / 8)); |
if (vncscreen == NULL) { |
/* Note libvncserver does not check its own allocations/error |
* paths so the faliure mode of the rfbGetScreen is to segfault. |
*/ |
return -1; |
} |
vncscreen->frameBuffer = malloc(nsfb->width * nsfb->height * (nsfb->bpp / 8)); |
if (vncscreen->frameBuffer == NULL) { |
rfbScreenCleanup(vncscreen); |
return -1; |
} |
switch (nsfb->bpp) { |
case 8: |
break; |
case 16: |
vncscreen->serverFormat.trueColour=TRUE; |
vncscreen->serverFormat.redShift = 11; |
vncscreen->serverFormat.greenShift = 5; |
vncscreen->serverFormat.blueShift = 0; |
vncscreen->serverFormat.redMax = 31; |
vncscreen->serverFormat.greenMax = 63; |
vncscreen->serverFormat.blueMax = 31; |
break; |
case 32: |
vncscreen->serverFormat.trueColour=TRUE; |
vncscreen->serverFormat.redShift = 16; |
vncscreen->serverFormat.greenShift = 8; |
vncscreen->serverFormat.blueShift = 0; |
break; |
} |
vncscreen->alwaysShared = TRUE; |
vncscreen->autoPort = 1; |
vncscreen->ptrAddEvent = vnc_doptr; |
vncscreen->kbdAddEvent = vnc_dokey; |
rfbInitServer(vncscreen); |
/* keep parameters */ |
nsfb->surface_priv = vncscreen; |
nsfb->ptr = (uint8_t *)vncscreen->frameBuffer; |
nsfb->linelen = (nsfb->width * nsfb->bpp) / 8; |
return 0; |
} |
static int vnc_finalise(nsfb_t *nsfb) |
{ |
rfbScreenInfoPtr vncscreen = nsfb->surface_priv; |
if (vncscreen != NULL) { |
rfbScreenCleanup(vncscreen); |
} |
return 0; |
} |
static int vnc_update(nsfb_t *nsfb, nsfb_bbox_t *box) |
{ |
rfbScreenInfoPtr vncscreen = nsfb->surface_priv; |
rfbMarkRectAsModified(vncscreen, box->x0, box->y0, box->x1, box->y1); |
return 0; |
} |
static bool vnc_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout) |
{ |
rfbScreenInfoPtr vncscreen = nsfb->surface_priv; |
int ret; |
if (vncscreen != NULL) { |
gevent = event; /* blergh - have to use global state to pass data */ |
/* set default to timeout */ |
event->type = NSFB_EVENT_CONTROL; |
event->value.controlcode = NSFB_CONTROL_TIMEOUT; |
ret = rfbProcessEvents(vncscreen, timeout * 1000); |
return true; |
} |
return false; |
} |
static int |
vnc_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor) |
{ |
rfbScreenInfoPtr vncscreen = nsfb->surface_priv; |
rfbCursorPtr vnccursor = calloc(1,sizeof(rfbCursor)); |
int rwidth; /* rounded width */ |
int row; |
int col; |
const nsfb_colour_t *pixel; |
uint8_t bit; |
rwidth = (cursor->bmp_width + 7) / 8; |
vnccursor->cleanup = 1; /* rfb lib will free this allocation */ |
vnccursor->width = cursor->bmp_width; |
vnccursor->height = cursor->bmp_height; |
vnccursor->foreRed = vnccursor->foreGreen = vnccursor->foreBlue = 0xffff; |
vnccursor->source = calloc(rwidth, vnccursor->height); |
vnccursor->cleanupSource = 1; /* rfb lib will free this allocation */ |
vnccursor->mask = calloc(rwidth, vnccursor->height); |
vnccursor->cleanupMask = 1; /* rfb lib will free this allocation */ |
for (row = 0, pixel = cursor->pixel; row < vnccursor->height; row++) { |
for (col = 0, bit = 0x80; |
col < vnccursor->width; |
col++, bit = (bit & 1)? 0x80 : bit>>1, pixel++) { |
/* pixel luminance more than 50% */ |
if ((((((*pixel) & 0xff) * 77) + |
((((*pixel) & 0xff00) >> 8) * 151) + |
((((*pixel) & 0xff0000) >> 16) * 28)) / 256) > 128) { |
vnccursor->source[row * rwidth + col/8] |= bit; |
} |
if (((*pixel) & 0xff000000) != 0) { |
vnccursor->mask[row * rwidth + col/8] |= bit; |
} |
} |
} |
rfbSetCursor(vncscreen, vnccursor); |
return true; |
} |
const nsfb_surface_rtns_t vnc_rtns = { |
.initialise = vnc_initialise, |
.finalise = vnc_finalise, |
.input = vnc_input, |
.update = vnc_update, |
.cursor = vnc_cursor, |
.geometry = vnc_set_geometry, |
}; |
NSFB_SURFACE_DEF(vnc, NSFB_SURFACE_VNC, &vnc_rtns) |
/* |
* Local variables: |
* c-basic-offset: 4 |
* tab-width: 8 |
* End: |
*/ |
/programs/network/netsurf/libnsfb/src/surface/x.c |
---|
0,0 → 1,1131 |
/* |
* Copyright 2009 Vincent Sanders <vince@simtec.co.uk> |
* |
* This file is part of libnsfb, http://www.netsurf-browser.org/ |
* Licenced under the MIT License, |
* http://www.opensource.org/licenses/mit-license.php |
*/ |
#define _XOPEN_SOURCE 500 |
#include <stdbool.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <string.h> |
#include <sys/ipc.h> |
#include <sys/shm.h> |
#include <xcb/xcb.h> |
#include <xcb/xcb_image.h> |
#include <xcb/xcb_atom.h> |
#include <xcb/xcb_icccm.h> |
#include <xcb/xcb_aux.h> |
#include <xcb/xcb_keysyms.h> |
#include "libnsfb.h" |
#include "libnsfb_event.h" |
#include "libnsfb_plot.h" |
#include "libnsfb_plot_util.h" |
#include "nsfb.h" |
#include "surface.h" |
#include "plot.h" |
#include "cursor.h" |
#if defined(NSFB_NEED_HINTS_ALLOC) |
static xcb_size_hints_t * |
xcb_alloc_size_hints(void) |
{ |
return calloc(1, sizeof(xcb_size_hints_t)); |
} |
static void |
xcb_free_size_hints(xcb_size_hints_t *hints) |
{ |
free(hints); |
} |
#endif |
#if defined(NSFB_NEED_ICCCM_API_PREFIX) |
#define xcb_size_hints_set_max_size xcb_icccm_size_hints_set_max_size |
#define xcb_size_hints_set_min_size xcb_icccm_size_hints_set_min_size |
#define xcb_set_wm_size_hints xcb_icccm_set_wm_size_hints |
#endif |
#if (NSFB_XCBPROTO_MAJOR_VERSION > 1) || \ |
(NSFB_XCBPROTO_MAJOR_VERSION == 1 && NSFB_XCBPROTO_MINOR_VERSION >= 6) |
#define WM_NORMAL_HINTS XCB_ATOM_WM_NORMAL_HINTS |
#endif |
#define X_BUTTON_LEFT 1 |
#define X_BUTTON_MIDDLE 2 |
#define X_BUTTON_RIGHT 3 |
#define X_BUTTON_WHEELUP 4 |
#define X_BUTTON_WHEELDOWN 5 |
typedef struct xstate_s { |
xcb_connection_t *connection; /* The x server connection */ |
xcb_screen_t *screen; /* The screen to put the window on */ |
xcb_key_symbols_t *keysymbols; /* keysym mappings */ |
xcb_shm_segment_info_t shminfo; |
xcb_image_t *image; /* The X image buffer */ |
xcb_window_t window; /* The handle to the window */ |
xcb_pixmap_t pmap; /* The handle to the backing pixmap */ |
xcb_gcontext_t gc; /* The handle to the pixmap plotting graphics context */ |
xcb_shm_seg_t segment; /* The handle to the image shared memory */ |
} xstate_t; |
/* X keyboard codepage to nsfb mapping*/ |
enum nsfb_key_code_e XCSKeyboardMap[256] = { |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_BACKSPACE, /* XK_BackSpace */ |
NSFB_KEY_TAB, /* XK_Tab */ |
NSFB_KEY_UNKNOWN, /* XK_Linefeed */ |
NSFB_KEY_CLEAR, /* XK_Clear */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_RETURN, /* XK_Return */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0x10 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_PAUSE, /* XK_Pause */ |
NSFB_KEY_UNKNOWN, /* XK_Scroll_Lock */ |
NSFB_KEY_UNKNOWN, /* XK_Sys_Req */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_ESCAPE, /* XK_Escape */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0x20 */ |
NSFB_KEY_UNKNOWN, /* XK_Multi_key */ |
NSFB_KEY_UNKNOWN, /* XK_Kanji */ |
NSFB_KEY_UNKNOWN, /* XK_Muhenkan */ |
NSFB_KEY_UNKNOWN, /* XK_Henkan_Mode */ |
NSFB_KEY_UNKNOWN, /* XK_Henkan */ |
NSFB_KEY_UNKNOWN, /* XK_Romaji */ |
NSFB_KEY_UNKNOWN, /* XK_Hiragana*/ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0x30 */ |
NSFB_KEY_UNKNOWN, /* XK_Eisu_toggle */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* XK_Codeinput */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* XK_SingleCandidate */ |
NSFB_KEY_UNKNOWN, /* XK_MultipleCandidate */ |
NSFB_KEY_UNKNOWN, /* XK_PreviousCandidate */ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0x40 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0x50 */ |
NSFB_KEY_HOME, /* XK_Home */ |
NSFB_KEY_LEFT, /* XK_Left */ |
NSFB_KEY_UP, /* XK_Up */ |
NSFB_KEY_RIGHT, /* XK_Right */ |
NSFB_KEY_DOWN, /* XK_Down */ |
NSFB_KEY_PAGEUP, /* XK_Page_Up */ |
NSFB_KEY_PAGEDOWN, /* XK_Page_Down */ |
NSFB_KEY_END, /* XK_End */ |
NSFB_KEY_UNKNOWN, /* XK_Begin */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0x60 */ |
NSFB_KEY_UNKNOWN, /* XK_Select */ |
NSFB_KEY_UNKNOWN, /* XK_Print*/ |
NSFB_KEY_UNKNOWN, /* XK_Execute*/ |
NSFB_KEY_UNKNOWN, /* XK_Insert*/ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* XK_Undo*/ |
NSFB_KEY_UNKNOWN, /* XK_Redo */ |
NSFB_KEY_UNKNOWN, /* XK_Menu */ |
NSFB_KEY_UNKNOWN, /* XK_Find */ |
NSFB_KEY_UNKNOWN, /* XK_Cancel */ |
NSFB_KEY_UNKNOWN, /* XK_Help */ |
NSFB_KEY_UNKNOWN, /* XK_Break*/ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0x70 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* XK_Mode_switch */ |
NSFB_KEY_UNKNOWN, /* XK_Num_Lock */ |
/* 0x80 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_Space */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* XK_KP_Tab */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* XK_KP_Enter */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0x90 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* XK_KP_F1*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_F2*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_F3*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_F4*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Home*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Left*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Up*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Right*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Down*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Page_Up*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Page_Down*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_End*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Begin*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Insert*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Delete*/ |
/* 0xa0 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* XK_KP_Multiply*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Add*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Separator*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Subtract*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Decimal*/ |
NSFB_KEY_UNKNOWN, /* XK_KP_Divide*/ |
/* 0xb0 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_0 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_1 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_2 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_3 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_4 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_5 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_6 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_7 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_8 */ |
NSFB_KEY_UNKNOWN, /* XK_KP_9 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_F1, /* XK_F1 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* XK_KP_Equal */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_F2, /* XK_F2 */ |
/* 0xc0 */ |
NSFB_KEY_F3, /* XK_F3*/ |
NSFB_KEY_F4, /* XK_F4*/ |
NSFB_KEY_F5, /* XK_F5*/ |
NSFB_KEY_F6, /* XK_F6*/ |
NSFB_KEY_F7, /* XK_F7*/ |
NSFB_KEY_F8, /* XK_F8*/ |
NSFB_KEY_F9, /* XK_F9*/ |
NSFB_KEY_F10, /* XK_F10*/ |
NSFB_KEY_F11, /* XK_F11*/ |
NSFB_KEY_F12, /* XK_F12*/ |
NSFB_KEY_F13, /* XK_F13 */ |
NSFB_KEY_F14, /* XK_F14 */ |
NSFB_KEY_F15, /* XK_F15 */ |
NSFB_KEY_UNKNOWN, /* XK_F16 */ |
NSFB_KEY_UNKNOWN, /* XK_F17 */ |
NSFB_KEY_UNKNOWN, /* XK_F18*/ |
/* 0xd0 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0xe0 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_LSHIFT, /* XK_Shift_L*/ |
NSFB_KEY_RSHIFT, /* XK_Shift_R*/ |
NSFB_KEY_UNKNOWN, /* XK_Control_L*/ |
NSFB_KEY_UNKNOWN, /* XK_Control_R*/ |
NSFB_KEY_UNKNOWN, /* XK_Caps_Lock*/ |
NSFB_KEY_UNKNOWN, /* XK_Shift_Lock*/ |
NSFB_KEY_UNKNOWN, /* XK_Meta_L*/ |
NSFB_KEY_UNKNOWN, /* XK_Meta_R*/ |
NSFB_KEY_UNKNOWN, /* XK_Alt_L */ |
NSFB_KEY_UNKNOWN, /* XK_Alt_R*/ |
NSFB_KEY_UNKNOWN, /* XK_Super_L*/ |
NSFB_KEY_UNKNOWN, /* XK_Super_R*/ |
NSFB_KEY_UNKNOWN, /* XK_Hyper_L*/ |
NSFB_KEY_UNKNOWN, /* XK_Hyper_R*/ |
NSFB_KEY_UNKNOWN, /* */ |
/* 0xf0 */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
NSFB_KEY_UNKNOWN, /* */ |
}; |
/* Convert an X keysym into a nsfb key code. |
* |
* Our approach is primarily to assume both codings are roughly ascii like. |
* |
* The Keysyms are defined in X11/keysymdef.h and our mapping for the |
* "keyboard" keys i.e. those from code set 255 is from there |
*/ |
static enum nsfb_key_code_e |
xkeysym_to_nsfbkeycode(xcb_keysym_t ks) |
{ |
enum nsfb_key_code_e nsfb_key = NSFB_KEY_UNKNOWN; |
uint8_t codeset = (ks & 0xFF00) >> 8; |
uint8_t chrcode = ks & 0xFF; |
if (ks != XCB_NO_SYMBOL) { |
switch (codeset) { |
case 0x00: /* Latin 1 */ |
case 0x01: /* Latin 2 */ |
case 0x02: /* Latin 3 */ |
case 0x03: /* Latin 4 */ |
case 0x04: /* Katakana */ |
case 0x05: /* Arabic */ |
case 0x06: /* Cyrillic */ |
case 0x07: /* Greek */ |
case 0x08: /* Technical */ |
case 0x0A: /* Publishing */ |
case 0x0C: /* Hebrew */ |
case 0x0D: /* Thai */ |
/* this is somewhat incomplete, but the nsfb codes are lined up on |
* the ascii codes and x seems to have done similar |
*/ |
nsfb_key = (enum nsfb_key_code_e)chrcode; |
break; |
case 0xFF: /* Keyboard */ |
nsfb_key = XCSKeyboardMap[chrcode]; |
break; |
} |
} |
return nsfb_key; |
} |
/* |
static void |
set_palette(nsfb_t *nsfb) |
{ |
X_Surface *x_screen = nsfb->surface_priv; |
X_Color palette[256]; |
int rloop, gloop, bloop; |
int loop = 0; |
// build a linear R:3 G:3 B:2 colour cube palette. |
for (rloop = 0; rloop < 8; rloop++) { |
for (gloop = 0; gloop < 8; gloop++) { |
for (bloop = 0; bloop < 4; bloop++) { |
palette[loop].r = (rloop << 5) | (rloop << 2) | (rloop >> 1); |
palette[loop].g = (gloop << 5) | (gloop << 2) | (gloop >> 1); |
palette[loop].b = (bloop << 6) | (bloop << 4) | (bloop << 2) | (bloop); |
nsfb->palette[loop] = palette[loop].r | |
palette[loop].g << 8 | |
palette[loop].b << 16; |
loop++; |
} |
} |
} |
// Set palette |
//X_SetColors(x_screen, palette, 0, 256); |
} |
*/ |
static int |
update_pixmap(xstate_t *xstate, int x, int y, int width, int height) |
{ |
if (xstate->shminfo.shmseg == 0) { |
/* not using shared memory */ |
xcb_put_image(xstate->connection, |
xstate->image->format, |
xstate->pmap, |
xstate->gc, |
xstate->image->width, |
height, |
0, |
y, |
0, |
xstate->image->depth, |
(height) * xstate->image->stride, |
xstate->image->data + (y * xstate->image->stride)); |
} else { |
/* shared memory */ |
xcb_image_shm_put(xstate->connection, |
xstate->pmap, |
xstate->gc, |
xstate->image, |
xstate->shminfo, |
x,y, |
x,y, |
width,height,0); |
} |
return 0; |
} |
static int |
update_and_redraw_pixmap(xstate_t *xstate, int x, int y, int width, int height) |
{ |
update_pixmap(xstate, x, y, width, height); |
xcb_copy_area(xstate->connection, |
xstate->pmap, |
xstate->window, |
xstate->gc, |
x, y, |
x, y, |
width, height); |
xcb_flush(xstate->connection); |
return 0; |
} |
static bool |
xcopy(nsfb_t *nsfb, nsfb_bbox_t *srcbox, nsfb_bbox_t *dstbox) |
{ |
xstate_t *xstate = nsfb->surface_priv; |
nsfb_bbox_t allbox; |
struct nsfb_cursor_s *cursor = nsfb->cursor; |
uint8_t *srcptr; |
uint8_t *dstptr; |
int srcx = srcbox->x0; |
int srcy = srcbox->y0; |
int dstx = dstbox->x0; |
int dsty = dstbox->y0; |
int width = dstbox->x1 - dstbox->x0; |
int height = dstbox->y1 - dstbox->y0; |
int hloop; |
nsfb_plot_add_rect(srcbox, dstbox, &allbox); |
/* clear the cursor if its within the region to be altered */ |
if ((cursor != NULL) && |
(cursor->plotted == true) && |
(nsfb_plot_bbox_intersect(&allbox, &cursor->loc))) { |
nsfb_cursor_clear(nsfb, cursor); |
update_pixmap(xstate, |
cursor->savloc.x0, |
cursor->savloc.y0, |
cursor->savloc.x1 - cursor->savloc.x0, |
cursor->savloc.y1 - cursor->savloc.y0); |
/* must sync here or local framebuffer and remote pixmap will not be |
* consistant |
*/ |
xcb_aux_sync(xstate->connection); |
} |
/* copy the area on the server */ |
xcb_copy_area(xstate->connection, |
xstate->pmap, |
xstate->pmap, |
xstate->gc, |
srcbox->x0, |
srcbox->y0, |
dstbox->x0, |
dstbox->y0, |
srcbox->x1 - srcbox->x0, |
srcbox->y1 - srcbox->y0); |
/* do the copy in the local memory too */ |
srcptr = (nsfb->ptr + |
(srcy * nsfb->linelen) + |
((srcx * nsfb->bpp) / 8)); |
dstptr = (nsfb->ptr + |
(dsty * nsfb->linelen) + |
((dstx * nsfb->bpp) / 8)); |
if (width == nsfb->width) { |
/* take shortcut and use memmove */ |
memmove(dstptr, srcptr, (width * height * nsfb->bpp) / 8); |
} else { |
if (srcy > dsty) { |
for (hloop = height; hloop > 0; hloop--) { |
memmove(dstptr, srcptr, (width * nsfb->bpp) / 8); |
srcptr += nsfb->linelen; |
dstptr += nsfb->linelen; |
} |
} else { |
srcptr += height * nsfb->linelen; |
dstptr += height * nsfb->linelen; |
for (hloop = height; hloop > 0; hloop--) { |
srcptr -= nsfb->linelen; |
dstptr -= nsfb->linelen; |
memmove(dstptr, srcptr, (width * nsfb->bpp) / 8); |
} |
} |
} |
if ((cursor != NULL) && |
(cursor->plotted == false)) { |
nsfb_cursor_plot(nsfb, cursor); |
} |
/* update the x window */ |
xcb_copy_area(xstate->connection, |
xstate->pmap, |
xstate->window, |
xstate->gc, |
dstx, dsty, |
dstx, dsty, |
width, height); |
return true; |
} |
static int |
x_set_geometry(nsfb_t *nsfb, int width, int height, enum nsfb_format_e format) |
{ |
if (nsfb->surface_priv != NULL) |
return -1; /* if were already initialised fail */ |
nsfb->width = width; |
nsfb->height = height; |
nsfb->format = format; |
/* select default sw plotters for format */ |
select_plotters(nsfb); |
nsfb->plotter_fns->copy = xcopy; |
return 0; |
} |
static xcb_format_t * |
find_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp) |
{ |
const xcb_setup_t *setup = xcb_get_setup(c); |
xcb_format_t *fmt = xcb_setup_pixmap_formats(setup); |
xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup); |
for(; fmt != fmtend; ++fmt) { |
if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp)) { |
return fmt; |
} |
} |
return 0; |
} |
static xcb_image_t * |
create_shm_image(xstate_t *xstate, int width, int height, int bpp) |
{ |
const xcb_setup_t *setup = xcb_get_setup(xstate->connection); |
unsigned char *image_data; |
xcb_format_t *fmt; |
int depth = bpp; |
uint32_t image_size; |
int shmid; |
xcb_shm_query_version_reply_t *rep; |
xcb_shm_query_version_cookie_t ck; |
xcb_void_cookie_t shm_attach_cookie; |
xcb_generic_error_t *generic_error; |
ck = xcb_shm_query_version(xstate->connection); |
rep = xcb_shm_query_version_reply(xstate->connection, ck , NULL); |
if (!rep) { |
fprintf (stderr, "Server has no shm support.\n"); |
return NULL; |
} |
if ((rep->major_version < 1) || |
(rep->major_version == 1 && rep->minor_version == 0)) { |
fprintf(stderr, "server SHM support is insufficient.\n"); |
free(rep); |
return NULL; |
} |
free(rep); |
if (bpp == 32) |
depth = 24; |
fmt = find_format(xstate->connection, depth, bpp); |
if (fmt == NULL) |
return NULL; |
/* doing it this way ensures we deal with bpp smaller than 8 */ |
image_size = (bpp * width * height) >> 3; |
/* get the shared memory segment */ |
shmid = shmget(IPC_PRIVATE, image_size, IPC_CREAT|0777); |
if (shmid == -1) |
return NULL; |
xstate->shminfo.shmid = shmid; |
xstate->shminfo.shmaddr = shmat(xstate->shminfo.shmid, 0, 0); |
image_data = xstate->shminfo.shmaddr; |
xstate->shminfo.shmseg = xcb_generate_id(xstate->connection); |
shm_attach_cookie = xcb_shm_attach_checked(xstate->connection, |
xstate->shminfo.shmseg, |
xstate->shminfo.shmid, |
0); |
generic_error = xcb_request_check(xstate->connection, shm_attach_cookie); |
/* either there is an error and the shm us no longer needed, or it now |
* belongs to the x server - regardless release local reference to shared |
* memory segment |
*/ |
shmctl(xstate->shminfo.shmid, IPC_RMID, 0); |
if (generic_error != NULL) { |
/* unable to attach shm */ |
xstate->shminfo.shmseg = 0; |
free(generic_error); |
return NULL; |
} |
return xcb_image_create(width, |
height, |
XCB_IMAGE_FORMAT_Z_PIXMAP, |
fmt->scanline_pad, |
fmt->depth, |
fmt->bits_per_pixel, |
0, |
setup->image_byte_order, |
XCB_IMAGE_ORDER_LSB_FIRST, |
image_data, |
image_size, |
image_data); |
} |
static xcb_image_t * |
create_image(xcb_connection_t *c, int width, int height, int bpp) |
{ |
const xcb_setup_t *setup = xcb_get_setup(c); |
unsigned char *image_data; |
xcb_format_t *fmt; |
int depth = bpp; |
uint32_t image_size; |
if (bpp == 32) |
depth = 24; |
fmt = find_format(c, depth, bpp); |
if (fmt == NULL) |
return NULL; |
/* doing it this way ensures we deal with bpp smaller than 8 */ |
image_size = (bpp * width * height) >> 3; |
image_data = calloc(1, image_size); |
if (image_data == NULL) |
return NULL; |
return xcb_image_create(width, |
height, |
XCB_IMAGE_FORMAT_Z_PIXMAP, |
fmt->scanline_pad, |
fmt->depth, |
fmt->bits_per_pixel, |
0, |
setup->image_byte_order, |
XCB_IMAGE_ORDER_LSB_FIRST, |
image_data, |
image_size, |
image_data); |
} |
/** |
* Create a blank cursor. |
* The empty pixmaps is leaked. |
* |
* @param conn xcb connection |
* @param scr xcb XCB screen |
*/ |
static xcb_cursor_t |
create_blank_cursor(xcb_connection_t *conn, const xcb_screen_t *scr) |
{ |
xcb_cursor_t cur = xcb_generate_id(conn); |
xcb_pixmap_t pix = xcb_generate_id(conn); |
xcb_void_cookie_t ck; |
xcb_generic_error_t *err; |
ck = xcb_create_pixmap_checked (conn, 1, pix, scr->root, 1, 1); |
err = xcb_request_check (conn, ck); |
if (err) { |
fprintf (stderr, "Cannot create pixmap: %d", err->error_code); |
free (err); |
} |
ck = xcb_create_cursor_checked (conn, cur, pix, pix, 0, 0, 0, 0, 0, 0, 0, 0); |
err = xcb_request_check (conn, ck); |
if (err) { |
fprintf (stderr, "Cannot create cursor: %d", err->error_code); |
free (err); |
} |
return cur; |
} |
static int x_initialise(nsfb_t *nsfb) |
{ |
uint32_t mask; |
uint32_t values[3]; |
xcb_size_hints_t *hints; |
xstate_t *xstate = nsfb->surface_priv; |
xcb_cursor_t blank_cursor; |
if (xstate != NULL) |
return -1; /* already initialised */ |
/* sanity check bpp. */ |
if ((nsfb->bpp != 32) && (nsfb->bpp != 16) && (nsfb->bpp != 8)) |
return -1; |
xstate = calloc(1, sizeof(xstate_t)); |
if (xstate == NULL) |
return -1; /* no memory */ |
/* open connection with the server */ |
xstate->connection = xcb_connect(NULL, NULL); |
if (xstate->connection == NULL) { |
fprintf(stderr, "Memory error opening display\n"); |
free(xstate); |
return -1; /* no memory */ |
} |
if (xcb_connection_has_error(xstate->connection) != 0) { |
fprintf(stderr, "Error opening display\n"); |
free(xstate); |
return -1; /* no memory */ |
} |
/* get screen */ |
xstate->screen = xcb_setup_roots_iterator(xcb_get_setup(xstate->connection)).data; |
/* create image */ |
xstate->image = create_shm_image(xstate, nsfb->width, nsfb->height, nsfb->bpp); |
if (xstate->image == NULL) |
xstate->image = create_image(xstate->connection, nsfb->width, nsfb->height, nsfb->bpp); |
if (xstate->image == NULL) { |
fprintf(stderr, "Unable to create image\n"); |
free(xstate); |
xcb_disconnect(xstate->connection); |
return -1; |
} |
/* ensure plotting information is stored */ |
nsfb->surface_priv = xstate; |
nsfb->ptr = xstate->image->data; |
nsfb->linelen = xstate->image->stride; |
/* get blank cursor */ |
blank_cursor = create_blank_cursor(xstate->connection, xstate->screen); |
/* get keysymbol maps */ |
xstate->keysymbols = xcb_key_symbols_alloc(xstate->connection); |
/* create window */ |
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_CURSOR; |
values[0] = xstate->screen->white_pixel; |
values[1] = XCB_EVENT_MASK_EXPOSURE | |
XCB_EVENT_MASK_KEY_PRESS | |
XCB_EVENT_MASK_KEY_RELEASE | |
XCB_EVENT_MASK_BUTTON_PRESS | |
XCB_EVENT_MASK_BUTTON_RELEASE | |
XCB_EVENT_MASK_POINTER_MOTION; |
values[2] = blank_cursor; |
xstate->window = xcb_generate_id(xstate->connection); |
xcb_create_window (xstate->connection, |
XCB_COPY_FROM_PARENT, |
xstate->window, |
xstate->screen->root, |
0, 0, xstate->image->width, xstate->image->height, 1, |
XCB_WINDOW_CLASS_INPUT_OUTPUT, |
xstate->screen->root_visual, |
mask, values); |
/* set size hits on window */ |
hints = xcb_alloc_size_hints(); |
xcb_size_hints_set_max_size(hints, xstate->image->width, xstate->image->height); |
xcb_size_hints_set_min_size(hints, xstate->image->width, xstate->image->height); |
xcb_set_wm_size_hints(xstate->connection, xstate->window, WM_NORMAL_HINTS, hints); |
xcb_free_size_hints(hints); |
/* create backing pixmap */ |
xstate->pmap = xcb_generate_id(xstate->connection); |
xcb_create_pixmap(xstate->connection, 24, xstate->pmap, xstate->window, xstate->image->width, xstate->image->height); |
/* create pixmap plot gc */ |
mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; |
values[0] = xstate->screen->black_pixel; |
values[1] = 0xffffff; |
xstate->gc = xcb_generate_id (xstate->connection); |
xcb_create_gc(xstate->connection, xstate->gc, xstate->pmap, mask, values); |
/* if (nsfb->bpp == 8) |
set_palette(nsfb); |
*/ |
/* put the image into the pixmap */ |
update_and_redraw_pixmap(xstate, 0, 0, xstate->image->width, xstate->image->height); |
/* show the window */ |
xcb_map_window (xstate->connection, xstate->window); |
xcb_flush(xstate->connection); |
return 0; |
} |
static int x_finalise(nsfb_t *nsfb) |
{ |
xstate_t *xstate = nsfb->surface_priv; |
if (xstate == NULL) |
return 0; |
xcb_key_symbols_free(xstate->keysymbols); |
/* free pixmap */ |
xcb_free_pixmap(xstate->connection, xstate->pmap); |
/* close connection to server */ |
xcb_disconnect(xstate->connection); |
return 0; |
} |
static bool x_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout) |
{ |
xcb_generic_event_t *e; |
xcb_expose_event_t *ee; |
xcb_motion_notify_event_t *emn; |
xcb_button_press_event_t *ebp; |
xcb_key_press_event_t *ekp; |
xcb_key_press_event_t *ekr; |
xstate_t *xstate = nsfb->surface_priv; |
if (xstate == NULL) |
return false; |
xcb_flush(xstate->connection); |
/* try and retrive an event immediately */ |
e = xcb_poll_for_event(xstate->connection); |
if ((e == NULL) && (timeout != 0)) { |
if (timeout > 0) { |
int confd; |
fd_set rfds; |
struct timeval tv; |
int retval; |
confd = xcb_get_file_descriptor(xstate->connection); |
FD_ZERO(&rfds); |
FD_SET(confd, &rfds); |
tv.tv_sec = timeout / 1000; |
tv.tv_usec = timeout % 1000; |
retval = select(confd + 1, &rfds, NULL, NULL, &tv); |
if (retval == 0) { |
/* timeout, nothing happened */ |
event->type = NSFB_EVENT_CONTROL; |
event->value.controlcode = NSFB_CONTROL_TIMEOUT; |
return true; |
} |
} |
e = xcb_wait_for_event(xstate->connection); |
} |
if (e == NULL) { |
if (xcb_connection_has_error(xstate->connection) != 0) { |
/* connection closed quiting time */ |
event->type = NSFB_EVENT_CONTROL; |
event->value.controlcode = NSFB_CONTROL_QUIT; |
return true; |
} else { |
return false; /* no event */ |
} |
} |
event->type = NSFB_EVENT_NONE; |
switch (e->response_type) { |
case XCB_EXPOSE: |
ee = (xcb_expose_event_t *)e; |
xcb_copy_area(xstate->connection, |
xstate->pmap, |
xstate->window, |
xstate->gc, |
ee->x, ee->y, |
ee->x, ee->y, |
ee->width, ee->height); |
xcb_flush (xstate->connection); |
break; |
case XCB_MOTION_NOTIFY: |
emn = (xcb_motion_notify_event_t *)e; |
event->type = NSFB_EVENT_MOVE_ABSOLUTE; |
event->value.vector.x = emn->event_x; |
event->value.vector.y = emn->event_y; |
event->value.vector.z = 0; |
break; |
case XCB_BUTTON_PRESS: |
ebp = (xcb_button_press_event_t *)e; |
event->type = NSFB_EVENT_KEY_DOWN; |
switch (ebp->detail) { |
case X_BUTTON_LEFT: |
event->value.keycode = NSFB_KEY_MOUSE_1; |
break; |
case X_BUTTON_MIDDLE: |
event->value.keycode = NSFB_KEY_MOUSE_2; |
break; |
case X_BUTTON_RIGHT: |
event->value.keycode = NSFB_KEY_MOUSE_3; |
break; |
case X_BUTTON_WHEELUP: |
event->value.keycode = NSFB_KEY_MOUSE_4; |
break; |
case X_BUTTON_WHEELDOWN: |
event->value.keycode = NSFB_KEY_MOUSE_5; |
break; |
} |
break; |
case XCB_BUTTON_RELEASE: |
ebp = (xcb_button_press_event_t *)e; |
event->type = NSFB_EVENT_KEY_UP; |
switch (ebp->detail) { |
case X_BUTTON_LEFT: |
event->value.keycode = NSFB_KEY_MOUSE_1; |
break; |
case X_BUTTON_MIDDLE: |
event->value.keycode = NSFB_KEY_MOUSE_2; |
break; |
case X_BUTTON_RIGHT: |
event->value.keycode = NSFB_KEY_MOUSE_3; |
break; |
case X_BUTTON_WHEELUP: |
event->value.keycode = NSFB_KEY_MOUSE_4; |
break; |
case X_BUTTON_WHEELDOWN: |
event->value.keycode = NSFB_KEY_MOUSE_5; |
break; |
} |
break; |
case XCB_KEY_PRESS: |
ekp = (xcb_key_press_event_t *)e; |
event->type = NSFB_EVENT_KEY_DOWN; |
event->value.keycode = xkeysym_to_nsfbkeycode(xcb_key_symbols_get_keysym(xstate->keysymbols, ekp->detail, 0)); |
break; |
case XCB_KEY_RELEASE: |
ekr = (xcb_key_release_event_t *)e; |
event->type = NSFB_EVENT_KEY_UP; |
event->value.keycode = xkeysym_to_nsfbkeycode(xcb_key_symbols_get_keysym(xstate->keysymbols, ekr->detail, 0)); |
break; |
} |
free(e); |
return true; |
} |
static int x_claim(nsfb_t *nsfb, nsfb_bbox_t *box) |
{ |
struct nsfb_cursor_s *cursor = nsfb->cursor; |
if ((cursor != NULL) && |
(cursor->plotted == true) && |
(nsfb_plot_bbox_intersect(box, &cursor->loc))) { |
nsfb_cursor_clear(nsfb, cursor); |
} |
return 0; |
} |
static int |
x_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor) |
{ |
xstate_t *xstate = nsfb->surface_priv; |
nsfb_bbox_t redraw; |
nsfb_bbox_t fbarea; |
if ((cursor != NULL) && (cursor->plotted == true)) { |
nsfb_plot_add_rect(&cursor->savloc, &cursor->loc, &redraw); |
/* screen area */ |
fbarea.x0 = 0; |
fbarea.y0 = 0; |
fbarea.x1 = nsfb->width; |
fbarea.y1 = nsfb->height; |
nsfb_plot_clip(&fbarea, &redraw); |
nsfb_cursor_clear(nsfb, cursor); |
nsfb_cursor_plot(nsfb, cursor); |
/* TODO: This is hediously ineficient - should keep the pointer image |
* as a pixmap and plot server side |
*/ |
update_and_redraw_pixmap(xstate, redraw.x0, redraw.y0, redraw.x1 - redraw.x0, redraw.y1 - redraw.y0); |
} |
return true; |
} |
static int x_update(nsfb_t *nsfb, nsfb_bbox_t *box) |
{ |
xstate_t *xstate = nsfb->surface_priv; |
struct nsfb_cursor_s *cursor = nsfb->cursor; |
if ((cursor != NULL) && |
(cursor->plotted == false)) { |
nsfb_cursor_plot(nsfb, cursor); |
} |
update_and_redraw_pixmap(xstate, box->x0, box->y0, box->x1 - box->x0, box->y1 - box->y0); |
return 0; |
} |
const nsfb_surface_rtns_t x_rtns = { |
.initialise = x_initialise, |
.finalise = x_finalise, |
.input = x_input, |
.claim = x_claim, |
.update = x_update, |
.cursor = x_cursor, |
.geometry = x_set_geometry, |
}; |
NSFB_SURFACE_DEF(x, NSFB_SURFACE_X, &x_rtns) |
/* |
* Local variables: |
* c-basic-offset: 4 |
* tab-width: 8 |
* End: |
*/ |