Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3583 → Rev 3584

/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:
*/