mirror of
https://git.yoctoproject.org/libfakekey
synced 2025-11-04 04:55:36 +08:00
added various aux matchbox into single mb repo
git-svn-id: https://svn.o-hand.com/repos/matchbox/trunk/libfakekey@933 b067294f-1dea-0310-9683-c47a78595994
This commit is contained in:
9
Makefile.am
Normal file
9
Makefile.am
Normal file
@@ -0,0 +1,9 @@
|
||||
SUBDIRS=fakekey src tests doc
|
||||
|
||||
EXTRA_DIST = fakekey.pc.in
|
||||
|
||||
pkgconfigdir=$(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libfakekey.pc
|
||||
|
||||
|
||||
|
||||
3
autogen.sh
Executable file
3
autogen.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#! /bin/sh
|
||||
autoreconf -v --install || exit 1
|
||||
./configure --enable-maintainer-mode "$@"
|
||||
130
configure.ac
Normal file
130
configure.ac
Normal file
@@ -0,0 +1,130 @@
|
||||
>AC_PREREQ(2.53)
|
||||
AC_INIT([libfakekey], 0.1, [mallum@openedhand.com])
|
||||
AC_CONFIG_SRCDIR([src/libfakekey.c])
|
||||
|
||||
AM_INIT_AUTOMAKE()
|
||||
AM_CONFIG_HEADER([config.h])
|
||||
AC_CONFIG_AUX_DIR(.)
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_LIBTOOL
|
||||
AC_HEADER_STDC
|
||||
|
||||
dnl ------ libtool versioning -----------------------------------------------
|
||||
|
||||
LT_CURRENT=0
|
||||
LT_REVISION=1
|
||||
AC_SUBST(LT_CURRENT)
|
||||
AC_SUBST(LT_REVISION)
|
||||
LT_AGE=0
|
||||
|
||||
LT_VERSION_INFO="$LT_CURRENT:$LT_REVISION:$LT_AGE"
|
||||
AC_SUBST(LT_VERSION_INFO)
|
||||
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
AC_SUBST(LT_CURRENT_MINUS_AGE)
|
||||
|
||||
dnl ------ Check for X Stuff ------------------------------------------------
|
||||
|
||||
PKG_CHECK_MODULES(X11, x11, [have_libx11pc="yes"], [have_libx11pc="no"])
|
||||
|
||||
if test $have_libx11pc = yes; then
|
||||
PKG_CHECK_MODULES(XLIBS, x11 xtst)
|
||||
|
||||
FAKEKEY_LIBS="$XLIBS_LIBS"
|
||||
FAKEKEY_CFLAGS="$XLIBS_CFLAGS"
|
||||
|
||||
else
|
||||
|
||||
AC_PATH_XTRA
|
||||
|
||||
ALL_X_LIBS="$X_LIBS -lX11"
|
||||
|
||||
AC_CHECK_LIB(Xtst, XTestQueryExtension, XTEST_LIBS=-lXtst have_xtest="yes" , have_xtest="no", $ALL_X_LIBS)
|
||||
|
||||
if test "x$have_xtest" = "xno"; then
|
||||
AC_MSG_ERROR([Cannot find XTest extension library])
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FAKEKEY_CFLAGS="$XLIBS_CLAGS"
|
||||
FAKEKEY_LIBS="$ALL_X_LIBS $XTEST_LIBS"
|
||||
|
||||
fi
|
||||
|
||||
dnl ------ Debug -----------------------------------------------------------
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug enable debug ( verbose ) build],
|
||||
enable_debug=$enableval, enable_debug=no )
|
||||
|
||||
if test x$enable_debug != xno; then
|
||||
FAKEKEY_CFLAGS="$FAKEKEY_CFLAGS -DDEBUG"
|
||||
fi
|
||||
|
||||
dnl ------ Doxygen docs ----------------------------------------------------
|
||||
|
||||
AC_ARG_ENABLE(doxygen-docs,
|
||||
[ --enable-doxygen-docs build DOXYGEN API documentation (requires Doxygen)],
|
||||
enable_doxygen_docs=$enableval,enable_doxygen_docs=no)
|
||||
|
||||
if test x$enable_doxygen_docs = xyes ; then
|
||||
|
||||
AC_PATH_PROG(DOXYGEN, doxygen, no)
|
||||
|
||||
AC_MSG_CHECKING([whether to build Doxygen documentation])
|
||||
|
||||
if test x$DOXYGEN = xno ; then
|
||||
have_doxygen=no
|
||||
else
|
||||
have_doxygen=yes
|
||||
fi
|
||||
|
||||
if test x$have_doxygen = xno; then
|
||||
AC_MSG_ERROR([Building Doxygen docs explicitly required, but Doxygen not found])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_DOXYGEN, test x$enable_doxygen_docs = xyes)
|
||||
|
||||
|
||||
dnl ------ GCC flags --------------------------------------------------------
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
GCC_WARNINGS="-g -Wall -fno-strict-aliasing"
|
||||
FAKEKEY_CFLAGS="$GCC_WARNINGS $FAKEKEY_CFLAGS"
|
||||
fi
|
||||
|
||||
dnl -------------------------------------------------------------------------
|
||||
|
||||
AC_SUBST(FAKEKEY_CFLAGS)
|
||||
AC_SUBST(FAKEKEY_LIBS)
|
||||
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
libfakekey.pc
|
||||
fakekey/Makefile
|
||||
src/Makefile
|
||||
doc/Doxyfile
|
||||
doc/Makefile
|
||||
tests/Makefile
|
||||
|
||||
])
|
||||
|
||||
dnl ==========================================================================
|
||||
echo "
|
||||
LibFakeKey $VERSION
|
||||
======================
|
||||
|
||||
prefix: ${prefix}
|
||||
source code location: ${srcdir}
|
||||
|
||||
Building with Debug: ${enable_debug}
|
||||
Building with API Documentation: ${enable_doxygen_docs}
|
||||
|
||||
"
|
||||
183
doc/Doxyfile.in
Normal file
183
doc/Doxyfile.in
Normal file
@@ -0,0 +1,183 @@
|
||||
# Doxyfile 0.1
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = libfakekey
|
||||
PROJECT_NUMBER = @VERSION@
|
||||
OUTPUT_DIRECTORY = @top_srcdir@/doc
|
||||
OUTPUT_LANGUAGE = English
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
HIDE_UNDOC_MEMBERS = YES
|
||||
HIDE_UNDOC_CLASSES = YES
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
INTERNAL_DOCS = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
CASE_SENSE_NAMES = YES
|
||||
SHORT_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
INHERIT_DOCS = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 8
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
ALIASES =
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
SHOW_USED_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_FORMAT =
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = @top_srcdir@/fakekey
|
||||
FILE_PATTERNS = *.h
|
||||
RECURSIVE = YES
|
||||
#EXCLUDE = test
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
|
||||
# certain files from those directories.
|
||||
|
||||
EXCLUDE_PATTERNS = Makefile.* ChangeLog CHANGES CHANGES.* README \
|
||||
README.* *.png AUTHORS DESIGN DESIGN.* *.desktop \
|
||||
DESKTOP* COMMENTS HOWTO magic NOTES TODO THANKS
|
||||
|
||||
# The EXAMPLE_PATH tag can be used to specify one or more files or
|
||||
# directories that contain example code fragments that are included (see
|
||||
# the \include command).
|
||||
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = NO
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = NO
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT =
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT =
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = NO
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT =
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = YES
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .mb
|
||||
MAN_LINKS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
PERL_PATH =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
TEMPLATE_RELATIONS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 640
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
CGI_NAME =
|
||||
CGI_URL =
|
||||
DOC_URL =
|
||||
DOC_ABSPATH =
|
||||
BIN_ABSPATH =
|
||||
EXT_DOC_PATHS =
|
||||
14
doc/Makefile.am
Normal file
14
doc/Makefile.am
Normal file
@@ -0,0 +1,14 @@
|
||||
EXTRA_DIST = Doxyfile.in
|
||||
|
||||
all: stamp-doxygen
|
||||
|
||||
stamp-doxygen:
|
||||
if HAVE_DOXYGEN
|
||||
doxygen Doxyfile
|
||||
touch stamp-doxygen
|
||||
endif
|
||||
|
||||
clean: clean-local
|
||||
clean-local:
|
||||
-rm -Rf html
|
||||
-rm -f stamp-doxygen
|
||||
5
fakekey/Makefile.am
Normal file
5
fakekey/Makefile.am
Normal file
@@ -0,0 +1,5 @@
|
||||
fakekeyincludedir=$(includedir)/fakekey
|
||||
|
||||
fakekey_headers=fakekey.h
|
||||
|
||||
fakekeyinclude_HEADERS = $(fakekey_headers)
|
||||
131
fakekey/fakekey.h
Normal file
131
fakekey/fakekey.h
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef _HAVE_LIBFAKEKEY_H
|
||||
#define _HAVE_LIBFAKEKEY_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/keysymdef.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/extensions/XTest.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/Xproto.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup FakeKey FakeKey -
|
||||
* @brief yada yada yada
|
||||
*
|
||||
*
|
||||
* Always remember to release held keys
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef FakeKey
|
||||
*
|
||||
* Opaque structure used for all operations.
|
||||
*/
|
||||
typedef struct FakeKey FakeKey;
|
||||
|
||||
/**
|
||||
* @typedef FakeKeyModifier
|
||||
*
|
||||
* enumerated types for #mb_pixbuf_img_transform
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
FAKEKEYMOD_SHIFT = (1<<1),
|
||||
FAKEKEYMOD_CONTROL = (1<<2),
|
||||
FAKEKEYMOD_ALT = (1<<3),
|
||||
FAKEKEYMOD_META = (1<<4)
|
||||
|
||||
} FakeKeyModifier;
|
||||
|
||||
/**
|
||||
* Initiates FakeKey.
|
||||
*
|
||||
* @param xdpy X Display connection.
|
||||
*
|
||||
* @return new #FakeKey reference on success, NULL on fail.
|
||||
*/
|
||||
FakeKey*
|
||||
fakekey_init(Display *xdpy);
|
||||
|
||||
|
||||
/**
|
||||
* Sends a Keypress to the server for the supplied UTF8 character.
|
||||
*
|
||||
* @param fk #FakeKey refernce from #fakekey_init
|
||||
* @param utf8_char_in Pointer to a single UTF8 Character data.
|
||||
* @param len_bytes Lenth in bytes of character, or -1 in ends with 0
|
||||
* @param modifiers OR'd list of #FakeKeyModifier modifiers keys
|
||||
* to press with the key.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int
|
||||
fakekey_press(FakeKey *fk,
|
||||
unsigned char *utf8_char_in,
|
||||
int len_bytes,
|
||||
int modifiers);
|
||||
|
||||
/**
|
||||
* Repreats a press of the currently held key ( from #fakekey_press )
|
||||
*
|
||||
* @param fk #FakeKey refernce from #fakekey_init
|
||||
*/
|
||||
void
|
||||
fakekey_repeat(FakeKey *fk);
|
||||
|
||||
|
||||
/**
|
||||
* Releases the currently held key ( from #fakekey_press )
|
||||
*
|
||||
* @param fk #FakeKey refernce from #fakekey_init
|
||||
*/
|
||||
void
|
||||
fakekey_release(FakeKey *fk);
|
||||
|
||||
/**
|
||||
* Resyncs the internal list of keysyms with the server.
|
||||
* Should be called if a MappingNotify event is recieved.
|
||||
*
|
||||
* @param fk #FakeKey refernce from #fakekey_init
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int
|
||||
fakekey_reload_keysyms(FakeKey *fk);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param fk #FakeKey refernce from #fakekey_init
|
||||
* @param keycode X Keycode to send
|
||||
* @param is_press Is this a press ( or release )
|
||||
* @param modifiers
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int
|
||||
fakekey_send_keyevent(FakeKey *fk,
|
||||
KeyCode keycode,
|
||||
Bool is_press,
|
||||
int modifiers);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HAVE_LIBFAKEKEY_H */
|
||||
10
libfakekey.pc.in
Normal file
10
libfakekey.pc.in
Normal file
@@ -0,0 +1,10 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libfakekey
|
||||
Description: X Virtual Keyboard Library
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} @FAKEKEY_LIBS@
|
||||
Cflags: -I${includedir}
|
||||
10
src/Makefile.am
Normal file
10
src/Makefile.am
Normal file
@@ -0,0 +1,10 @@
|
||||
source_c = libfakekey.c
|
||||
|
||||
AM_CFLAGS = @FAKEKEY_CFLAGS@
|
||||
|
||||
libfakekey_la_SOURCES = $(source_c)
|
||||
|
||||
lib_LTLIBRARIES = libfakekey.la
|
||||
|
||||
libfakekey_la_LDFLAGS = -version-info @LT_VERSION_INFO@
|
||||
libfakekey_la_LIBADD = $(FAKEKEY_LIBS)
|
||||
409
src/libfakekey.c
Normal file
409
src/libfakekey.c
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* libFakeKey
|
||||
*
|
||||
* A simple library for converting utf8 chars into 'fake' keypresses.
|
||||
*
|
||||
* Uses ideas from Fontconfig, libvirtkeys.c, keysym2ucs.c and dasher.
|
||||
*
|
||||
* Authored By Matthew Allum <amllum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2004 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <fakekey/fakekey.h>
|
||||
|
||||
#if (DEBUG)
|
||||
#define FK_DBG(x, a...) \
|
||||
fprintf(stderr, __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
|
||||
#else
|
||||
#define FK_DBG(x, a...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define N_MODIFIER_INDEXES (Mod5MapIndex + 1)
|
||||
|
||||
typedef unsigned int FkChar32;
|
||||
|
||||
struct FakeKey
|
||||
{
|
||||
Display *xdpy;
|
||||
int min_keycode, max_keycode;
|
||||
int n_keysyms_per_keycode;
|
||||
KeySym *keysyms;
|
||||
int held_keycode;
|
||||
int held_state_flags;
|
||||
KeyCode modifier_table[N_MODIFIER_INDEXES];
|
||||
int shift_mod_index, alt_mod_index, meta_mod_index;
|
||||
};
|
||||
|
||||
|
||||
/* utf8_to_ucs4() Borrowed from fontconfig
|
||||
*
|
||||
* Converts the next Unicode char from src into dst and returns the
|
||||
* number of bytes containing the char. src nust be at least len bytes
|
||||
* long.
|
||||
*/
|
||||
static int
|
||||
utf8_to_ucs4 (const unsigned char *src_orig,
|
||||
FkChar32 *dst,
|
||||
int len)
|
||||
{
|
||||
const unsigned char *src = src_orig;
|
||||
unsigned char s;
|
||||
int extra;
|
||||
FkChar32 result;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
s = *src++;
|
||||
len--;
|
||||
|
||||
if (!(s & 0x80))
|
||||
{
|
||||
result = s;
|
||||
extra = 0;
|
||||
}
|
||||
else if (!(s & 0x40))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (!(s & 0x20))
|
||||
{
|
||||
result = s & 0x1f;
|
||||
extra = 1;
|
||||
}
|
||||
else if (!(s & 0x10))
|
||||
{
|
||||
result = s & 0xf;
|
||||
extra = 2;
|
||||
}
|
||||
else if (!(s & 0x08))
|
||||
{
|
||||
result = s & 0x07;
|
||||
extra = 3;
|
||||
}
|
||||
else if (!(s & 0x04))
|
||||
{
|
||||
result = s & 0x03;
|
||||
extra = 4;
|
||||
}
|
||||
else if ( ! (s & 0x02))
|
||||
{
|
||||
result = s & 0x01;
|
||||
extra = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (extra > len)
|
||||
return -1;
|
||||
|
||||
while (extra--)
|
||||
{
|
||||
result <<= 6;
|
||||
s = *src++;
|
||||
|
||||
if ((s & 0xc0) != 0x80)
|
||||
return -1;
|
||||
|
||||
result |= s & 0x3f;
|
||||
}
|
||||
*dst = result;
|
||||
return src - src_orig;
|
||||
}
|
||||
|
||||
FakeKey*
|
||||
fakekey_init(Display *xdpy)
|
||||
{
|
||||
FakeKey *fk = NULL;
|
||||
int event, error, major, minor;
|
||||
XModifierKeymap *modifiers;
|
||||
int mod_index;
|
||||
int mod_key;
|
||||
KeyCode *kp;
|
||||
|
||||
if (xdpy == NULL) return NULL;
|
||||
|
||||
if (!XTestQueryExtension(xdpy, &event, &error, &major, &minor))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fk = malloc(sizeof(FakeKey));
|
||||
memset(fk,0,sizeof(FakeKey));
|
||||
|
||||
fk->xdpy = xdpy;
|
||||
|
||||
/* Find keycode limits */
|
||||
|
||||
XDisplayKeycodes(fk->xdpy, &fk->min_keycode, &fk->max_keycode);
|
||||
|
||||
/* Get the mapping */
|
||||
|
||||
/* TODO: Below needs to be kept in sync with anything else
|
||||
* that may change the keyboard mapping.
|
||||
*
|
||||
* case MappingNotify:
|
||||
* XRefreshKeyboardMapping(&ev.xmapping);
|
||||
*
|
||||
*/
|
||||
|
||||
fk->keysyms = XGetKeyboardMapping(fk->xdpy,
|
||||
fk->min_keycode,
|
||||
fk->max_keycode - fk->min_keycode + 1,
|
||||
&fk->n_keysyms_per_keycode);
|
||||
|
||||
|
||||
modifiers = XGetModifierMapping(fk->xdpy);
|
||||
|
||||
kp = modifiers->modifiermap;
|
||||
|
||||
for (mod_index = 0; mod_index < 8; mod_index++)
|
||||
{
|
||||
fk->modifier_table[mod_index] = 0;
|
||||
|
||||
for (mod_key = 0; mod_key < modifiers->max_keypermod; mod_key++)
|
||||
{
|
||||
int keycode = kp[mod_index * modifiers->max_keypermod + mod_key];
|
||||
|
||||
if (keycode != 0)
|
||||
{
|
||||
fk->modifier_table[mod_index] = keycode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (mod_index = Mod1MapIndex; mod_index <= Mod5MapIndex; mod_index++)
|
||||
{
|
||||
if (fk->modifier_table[mod_index])
|
||||
{
|
||||
KeySym ks = XKeycodeToKeysym(fk->xdpy,
|
||||
fk->modifier_table[mod_index], 0);
|
||||
|
||||
/*
|
||||
* Note: ControlMapIndex is already defined by xlib
|
||||
* ShiftMapIndex
|
||||
*/
|
||||
|
||||
printf("checking ks\n");
|
||||
|
||||
switch (ks)
|
||||
{
|
||||
case XK_Meta_R:
|
||||
case XK_Meta_L:
|
||||
fk->meta_mod_index = mod_index;
|
||||
break;
|
||||
|
||||
case XK_Alt_R:
|
||||
case XK_Alt_L:
|
||||
fk->alt_mod_index = mod_index;
|
||||
break;
|
||||
|
||||
case XK_Shift_R:
|
||||
case XK_Shift_L:
|
||||
printf("got shift\n");
|
||||
fk->shift_mod_index = mod_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modifiers)
|
||||
XFreeModifiermap(modifiers);
|
||||
|
||||
printf("index is %i %i\n",
|
||||
fk->meta_mod_index, fk->modifier_table[ShiftMapIndex]);
|
||||
|
||||
return fk;
|
||||
}
|
||||
|
||||
int
|
||||
fakekey_reload_keysyms(FakeKey *fk)
|
||||
{
|
||||
if (fk->keysyms)
|
||||
XFree(fk->keysyms);
|
||||
|
||||
fk->keysyms = XGetKeyboardMapping(fk->xdpy,
|
||||
fk->min_keycode,
|
||||
fk->max_keycode - fk->min_keycode + 1,
|
||||
&fk->n_keysyms_per_keycode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
fakekey_send_keyevent(FakeKey *fk,
|
||||
KeyCode keycode,
|
||||
Bool is_press,
|
||||
int flags)
|
||||
{
|
||||
if (flags)
|
||||
{
|
||||
if (flags & FAKEKEYMOD_SHIFT)
|
||||
XTestFakeKeyEvent(fk->xdpy, fk->modifier_table[ShiftMapIndex],
|
||||
is_press, CurrentTime);
|
||||
|
||||
if (flags & FAKEKEYMOD_CONTROL)
|
||||
XTestFakeKeyEvent(fk->xdpy, fk->modifier_table[ControlMapIndex],
|
||||
is_press, CurrentTime);
|
||||
|
||||
if (flags & FAKEKEYMOD_ALT)
|
||||
XTestFakeKeyEvent(fk->xdpy, fk->modifier_table[fk->alt_mod_index],
|
||||
is_press, CurrentTime);
|
||||
|
||||
XSync(fk->xdpy, True);
|
||||
}
|
||||
|
||||
XTestFakeKeyEvent(fk->xdpy, keycode, is_press, CurrentTime);
|
||||
|
||||
XSync(fk->xdpy, True);
|
||||
}
|
||||
|
||||
int
|
||||
fakekey_press(FakeKey *fk,
|
||||
unsigned char *utf8_char_in,
|
||||
int len_bytes,
|
||||
int flags)
|
||||
{
|
||||
static int modifiedkey;
|
||||
FkChar32 ucs4_out;
|
||||
KeyCode code = 0;
|
||||
|
||||
if (fk->held_keycode) /* key is already held down */
|
||||
return 0;
|
||||
|
||||
/* TODO: check for Return key here and other chars */
|
||||
|
||||
if (len_bytes < 0)
|
||||
{
|
||||
unsigned char *p = utf8_char_in;
|
||||
while (*p != '\0') len_bytes++;
|
||||
}
|
||||
|
||||
if (utf8_to_ucs4 (utf8_char_in, &ucs4_out, len_bytes) < 1)
|
||||
{
|
||||
printf("failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* first check for Latin-1 characters (1:1 mapping)
|
||||
if ((keysym >= 0x0020 && keysym <= 0x007e) ||
|
||||
(keysym >= 0x00a0 && keysym <= 0x00ff))
|
||||
return keysym;
|
||||
*/
|
||||
|
||||
if (ucs4_out > 0x00ff) /* < 0xff assume Latin-1 1:1 mapping */
|
||||
ucs4_out = ucs4_out | 0x01000000; /* This gives us the magic X keysym */
|
||||
|
||||
if ((code = XKeysymToKeycode(fk->xdpy, ucs4_out)) != 0)
|
||||
{
|
||||
printf("using fast code\n");
|
||||
|
||||
/* we already have a keycode for this keysym */
|
||||
/* Does it need a shift key though ? */
|
||||
if (XKeycodeToKeysym(fk->xdpy, code, 0) != ucs4_out)
|
||||
{
|
||||
printf("does not equal code\n");
|
||||
/* TODO: Assumes 1st modifier is shifted ? */
|
||||
if (XKeycodeToKeysym(fk->xdpy, code, 1) == ucs4_out)
|
||||
flags |= FAKEKEYMOD_SHIFT; /* can get at it via shift */
|
||||
else
|
||||
code = 0; /* urg, some other modifier do it the heavy way */
|
||||
}
|
||||
}
|
||||
|
||||
if (!code)
|
||||
{
|
||||
int index;
|
||||
|
||||
printf("using slow remapping code\n");
|
||||
|
||||
/* Change one of the last 10 keysyms to our converted utf8,
|
||||
* remapping the x keyboard on the fly.
|
||||
*
|
||||
* This make assumption the last 10 arn't already used.
|
||||
* TODO: probably safer to check for this.
|
||||
*/
|
||||
|
||||
modifiedkey = (modifiedkey+1) % 10;
|
||||
|
||||
/* Point at the end of keysyms, modifier 0 */
|
||||
|
||||
index = (fk->max_keycode - fk->min_keycode - modifiedkey - 1) * fk->n_keysyms_per_keycode;
|
||||
|
||||
fk->keysyms[index] = ucs4_out;
|
||||
|
||||
XChangeKeyboardMapping(fk->xdpy,
|
||||
fk->min_keycode,
|
||||
fk->n_keysyms_per_keycode,
|
||||
fk->keysyms,
|
||||
(fk->max_keycode-fk->min_keycode));
|
||||
|
||||
XSync(fk->xdpy, True);
|
||||
|
||||
/* From dasher src;
|
||||
* There's no way whatsoever that this could ever possibly
|
||||
* be guaranteed to work (ever), but it does.
|
||||
*
|
||||
* code = fk->max_keycode - modifiedkey - 1;
|
||||
*
|
||||
* below instead is probably safer.
|
||||
*/
|
||||
|
||||
code = XKeysymToKeycode(fk->xdpy, ucs4_out);
|
||||
}
|
||||
|
||||
if (code != 0)
|
||||
{
|
||||
fakekey_send_keyevent(fk, code, True, flags);
|
||||
|
||||
fk->held_state_flags = flags;
|
||||
fk->held_keycode = code;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
fk->held_state_flags = 0;
|
||||
fk->held_keycode = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
fakekey_repeat(FakeKey *fk)
|
||||
{
|
||||
if (!fk->held_keycode)
|
||||
return;
|
||||
|
||||
fakekey_send_keyevent(fk, fk->held_keycode, True, fk->held_state_flags);
|
||||
}
|
||||
|
||||
void
|
||||
fakekey_release(FakeKey *fk)
|
||||
{
|
||||
if (!fk->held_keycode)
|
||||
return;
|
||||
|
||||
fakekey_send_keyevent(fk, fk->held_keycode, False, fk->held_state_flags);
|
||||
|
||||
fk->held_state_flags = 0;
|
||||
fk->held_keycode = 0;
|
||||
}
|
||||
|
||||
5
tests/Makefile.am
Normal file
5
tests/Makefile.am
Normal file
@@ -0,0 +1,5 @@
|
||||
INCLUDES=-I${top_srcdir}/src -I${top_srcdir} $(FAKEKEY_CFLAGS)
|
||||
|
||||
noinst_PROGRAMS=fakekey-test
|
||||
|
||||
fakekey_test_LDADD=../src/libfakekey.la
|
||||
38
tests/fakekey-test.c
Normal file
38
tests/fakekey-test.c
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "fakekey/fakekey.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Display *dpy;
|
||||
FakeKey *fk;
|
||||
int i;
|
||||
unsigned char str[] = "hello HELLO worldly world", *p = NULL;
|
||||
unsigned char str2[] = "\303\270";
|
||||
|
||||
if ((dpy = XOpenDisplay(NULL)) == NULL)
|
||||
{
|
||||
fprintf(stderr,"Failed to open display\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fk = fakekey_init(dpy);
|
||||
|
||||
p = str;
|
||||
|
||||
/*
|
||||
for (i=0; i<10; i++)
|
||||
{
|
||||
fakekey_press(fk, str2, 2, 0);
|
||||
fakekey_release(fk);
|
||||
}
|
||||
*/
|
||||
|
||||
while (*p != '\0')
|
||||
{
|
||||
fakekey_press(fk, p, 1, 0);
|
||||
fakekey_release(fk);
|
||||
p++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user