Commit 8087c3e5 authored by Dorota Czaplejewicz's avatar Dorota Czaplejewicz

build: Use only meson for squeekboard

This breaks autoconf. The only resulting binary is the squeekboard GUI. It still needs the autotools-built eekboard client in order to do anything useful. That one needs to be built using a different branch, making this a WIP.
parent 10bd0ea0
Pipeline #5074 passed with stage
in 1 minute and 23 seconds
......@@ -12,9 +12,6 @@ build_automake:
tags:
- librem5
script:
- ./autogen.sh --enable-vala=no --enable-xtest=no --prefix=`pwd`/../eekboard-install/
- make
- make install
- mkdir -p ../build
- PKG_CONFIG_PATH=`pwd`/../eekboard-install/lib/pkgconfig/ meson ../build/ --prefix=`pwd`/../squeekboard-install/
- cd ../build
......
install_data(
'themes/default.css',
install_dir: pkgdatadir + '/themes',
)
install_data(
'keyboards/keyboards.xml',
install_dir: pkgdatadir + '/keyboards/',
)
install_data(
'keyboards/geometry/compact.xml',
install_dir: pkgdatadir + '/keyboards/geometry/',
)
symbols = [
'ar.xml',
'as-inscript.xml',
'be.xml',
'bn-inscript.xml',
'fa.xml',
'gu-inscript.xml',
'he.xml',
'hi-inscript.xml',
'ja-kana.xml',
'kk.xml',
'kn-inscript.xml',
'ks-inscript.xml',
'ks.xml',
'mai-inscript.xml',
'ml-inscript.xml',
'mr-inscript.xml',
'my.xml',
'or-inscript.xml',
'pa-inscript.xml',
'ru.xml',
'sd-inscript.xml',
'ta-inscript.xml',
'te-inscript.xml',
'th.xml',
'ua.xml',
'ug.xml',
'us.xml',
'zh-bopomofo.xml',
]
foreach symbol: symbols
install_data(
'keyboards/symbols/' + symbol,
install_dir: pkgdatadir + '/keyboards/symbols/',
)
endforeach
......@@ -2,6 +2,7 @@
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
# Copyright (C) 2010-2011 Red Hat, Inc.
# Copyright (C) 2019 Purism, SPC
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
......@@ -21,12 +22,17 @@
import sys
import re
if len(sys.argv) != 2:
print >> sys.stderr, "Usage: %s TABLE-NAME" % sys.argv[0]
if len(sys.argv) > 3:
print >> sys.stderr, "Usage: %s TABLE-NAME [INPUT_FILE]" % sys.argv[0]
sys.exit(-1)
if len(sys.argv) < 3:
in_stream = sys.stdin
else:
in_stream = open(sys.argv[2])
table = dict()
for line in sys.stdin:
for line in in_stream:
line = line.decode('UTF-8')
match = re.match(r'\s*(0x[0-9A-F]+)\s+(\S*)\s+(\S*)', line, re.I)
if match:
......
gnome = import('gnome')
enum_headers = [
'eek-symbol.h',
'eek-types.h',
]
enums = gnome.mkenums_simple('eek-enumtypes', sources: enum_headers)
marshalers = gnome.genmarshal(
'eek-marshalers',
sources: ['eek-marshalers.list'],
prefix: '_eek_marshal',
internal: true,
)
python = find_program('python2')
gen_keysym_entries_special = generator(
python,
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'special_keysym_entries', '@INPUT@'],
capture: true,
output: 'eek-@BASENAME@.h',
)
gen_keysym_entries_unicode = generator(
python,
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'unicode_keysym_entries', '@INPUT@'],
capture: true,
output: 'eek-@BASENAME@.h',
)
gen_keysym_entries_xkeysym = generator(
python,
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'xkeysym_keysym_entries', '@INPUT@'],
capture: true,
output: 'eek-@BASENAME@.h',
)
keysym_entries = [
gen_keysym_entries_special.process('./special-keysym-entries.txt'),
gen_keysym_entries_unicode.process('./unicode-keysym-entries.txt'),
gen_keysym_entries_xkeysym.process('./xkeysym-keysym-entries.txt'),
]
......@@ -29,6 +29,7 @@
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "eekboard/key-emitter.h"
#include "eekboard/eekboard-context-service.h"
#include "eekboard/eekboard-xklutil.h"
#include "eek/eek-xkl.h"
......@@ -62,6 +63,7 @@ static guint signals[LAST_SIGNAL] = { 0, };
struct _EekboardContextServicePrivate {
GDBusConnection *connection;
GDBusNodeInfo *introspection_data;
guint registration_id;
char *object_path;
char *client_name;
......@@ -166,6 +168,7 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
GError *error;
if (g_str_has_prefix (keyboard_type, "xkb:")) {
/* TODO: Depends on xklavier
XklConfigRec *rec =
eekboard_xkl_config_rec_from_string (&keyboard_type[4]);
......@@ -186,6 +189,8 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
g_object_unref (layout);
return NULL;
}
*/
return NULL;
} else {
error = NULL;
layout = eek_xml_layout_new (keyboard_type, &error);
......@@ -719,9 +724,20 @@ on_key_released (EekKeyboard *keyboard,
g_source_remove (context->priv->repeat_timeout_id);
context->priv->repeat_timeout_id = 0;
guint keycode = eek_key_get_keycode (key);
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
guint modifiers = eek_keyboard_get_modifiers (context->priv->keyboard);
/* KeyActivated signal has not been emitted in repeat handler */
emit_key_activated_dbus_signal (context,
context->priv->repeat_key);
// Insert
EekboardContext ec = {0};
Client c = {&ec, 0, {0}};
emit_key_activated(&ec, keycode, symbol, modifiers, &c);
//emit_key_activated_dbus_signal (context,
// context->priv->repeat_key);
}
}
......
......@@ -29,7 +29,7 @@
#endif /* HAVE_CONFIG_H */
#include "eekboard/eekboard-context.h"
#include "eekboard/eekboard-marshalers.h"
//#include "eekboard/eekboard-marshalers.h"
#define I_(string) g_intern_static_string (string)
......@@ -251,6 +251,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
* The ::key-activated signal is emitted each time a key is
* pressed in @context.
*/
/*
signals[KEY_ACTIVATED] =
g_signal_new (I_("key-activated"),
G_TYPE_FROM_CLASS(gobject_class),
......@@ -264,7 +265,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
G_TYPE_UINT,
G_TYPE_OBJECT,
G_TYPE_UINT);
*/
/**
* EekboardContext::destroyed:
* @context: an #EekboardContext
......
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2011 Red Hat, Inc.
* Copyright (C) 2019 Purism, SPC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file is responsible for managing keycode data and emitting keycodes. */
#include "eekboard/key-emitter.h"
#include <gdk/gdk.h>
/* The following functions for keyboard mapping change are direct
translation of the code in Caribou (in libcaribou/xadapter.vala):
- get_replaced_keycode (Caribou: get_reserved_keycode)
- replace_keycode
- get_keycode_from_gdk_keymap (Caribou: best_keycode_keyval_match)
*/
/* Find an unused keycode where a keysym can be assigned. Restricted to Level 1 */
static guint
get_replaced_keycode (Client *client)
{
guint keycode;
return 0; // FIXME: no xkb allocated yet
for (keycode = client->xkb->max_key_code;
keycode >= client->xkb->min_key_code;
--keycode) {
guint offset = client->xkb->map->key_sym_map[keycode].offset;
if (client->xkb->map->key_sym_map[keycode].kt_index[0] == XkbOneLevelIndex &&
client->xkb->map->syms[offset] != NoSymbol) {
return keycode;
}
}
return 0;
}
/* Replace keysym assigned to KEYCODE to KEYSYM. Both args are used
as in-out. If KEYCODE points to 0, this function picks a keycode
from the current map and replace the associated keysym to KEYSYM.
In that case, the replaced keycode is stored in KEYCODE and the old
keysym is stored in KEYSYM. If otherwise (KEYCODE points to
non-zero keycode), it simply changes the current map with the
specified KEYCODE and KEYSYM. */
static gboolean
replace_keycode (Client *client,
guint keycode,
guint *keysym)
{
GdkDisplay *display = gdk_display_get_default ();
//Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
guint old_keysym;
int keysyms_per_keycode;
KeySym *syms;
return TRUE; // FIXME: no xkb allocated at the moment, pretending all is fine
g_return_val_if_fail (client->xkb->min_key_code <= keycode &&
keycode <= client->xkb->max_key_code,
FALSE);
g_return_val_if_fail (keysym != NULL, FALSE);
/*
* Update keyboard mapping. Wayland receives keyboard mapping as a string, so XChangeKeyboardMapping needs to translate from the symbol tbale t the string. TODO.
*
syms = XGetKeyboardMapping (xdisplay, keycode, 1, &keysyms_per_keycode);
old_keysym = syms[0];
syms[0] = *keysym;
XChangeKeyboardMapping (xdisplay, keycode, 1, syms, 1);
XSync (xdisplay, False);
XFree (syms);
*keysym = old_keysym;
*/
return TRUE;
}
static gboolean
get_keycode_from_gdk_keymap (Client *client,
guint keysym,
guint *keycode,
guint *modifiers)
{
GdkKeymap *keymap = gdk_keymap_get_default ();
GdkKeymapKey *keys, *best_match = NULL;
gint n_keys, i;
if (!gdk_keymap_get_entries_for_keyval (keymap, keysym, &keys, &n_keys))
return FALSE;
for (i = 0; i < n_keys; i++)
if (keys[i].group == client->context->group)
best_match = &keys[i];
if (!best_match) {
g_free (keys);
return FALSE;
}
*keycode = best_match->keycode;
*modifiers = best_match->level == 1 ? EEK_SHIFT_MASK : 0;
g_free (keys);
return TRUE;
}
int WaylandFakeKeyEvent(
Display* dpy,
unsigned int keycode,
Bool is_press,
unsigned long delay
) {
printf("Sending fake event %d press %d delay %d\n", keycode, is_press, delay);
}
static void
send_fake_modifier_key_event (Client *client,
EekModifierType modifiers,
gboolean is_pressed)
{
GdkDisplay *display = gdk_display_get_default ();
Display *xdisplay = NULL; //GDK_DISPLAY_XDISPLAY (display);
gint i;
for (i = 0; i < G_N_ELEMENTS(client->modifier_keycodes); i++) {
if (modifiers & (1 << i)) {
guint keycode = client->modifier_keycodes[i];
printf("Trying to send a modifier %d press %ld\n", i, is_pressed);
g_return_if_fail (keycode > 0);
WaylandFakeKeyEvent (xdisplay,
keycode,
is_pressed,
CurrentTime);
}
}
}
static void
send_fake_key_event (Client *client,
guint xkeysym,
guint keyboard_modifiers)
{
GdkDisplay *display = gdk_display_get_default ();
Display *xdisplay = NULL; // GDK_DISPLAY_XDISPLAY (display);
EekModifierType modifiers;
guint keycode;
guint old_keysym = xkeysym;
g_return_if_fail (xkeysym > 0);
modifiers = 0;
if (!get_keycode_from_gdk_keymap (client, xkeysym, &keycode, &modifiers)) {
keycode = get_replaced_keycode (client);
if (keycode == 0) {
g_warning ("no available keycode to replace");
return;
}
if (!replace_keycode (client, keycode, &old_keysym)) {
g_warning ("failed to lookup X keysym %X", xkeysym);
return;
}
}
/* Clear level shift modifiers */
keyboard_modifiers &= ~EEK_SHIFT_MASK;
keyboard_modifiers &= ~EEK_LOCK_MASK;
/* FIXME: may need to remap ISO_Level3_Shift and NumLock */
#if 0
keyboard_modifiers &= ~EEK_MOD5_MASK;
keyboard_modifiers &= ~client->alt_gr_mask;
keyboard_modifiers &= ~client->num_lock_mask;
#endif
modifiers |= keyboard_modifiers;
send_fake_modifier_key_event (client, modifiers, TRUE);
WaylandFakeKeyEvent (xdisplay, keycode, TRUE, 20);
//XSync (xdisplay, False);
WaylandFakeKeyEvent (xdisplay, keycode, FALSE, 20);
// XSync (xdisplay, False);
send_fake_modifier_key_event (client, modifiers, FALSE);
if (old_keysym != xkeysym)
replace_keycode (client, keycode, &old_keysym);
}
static void
send_fake_key_events (Client *client,
EekSymbol *symbol,
guint keyboard_modifiers)
{
/* Ignore modifier keys */
if (eek_symbol_is_modifier (symbol))
return;
/* If symbol is a text, convert chars in it to keysym */
if (EEK_IS_TEXT(symbol)) {
const gchar *utf8 = eek_text_get_text (EEK_TEXT(symbol));
printf("Attempting to send text %s\n", utf8);
/* FIXME:
glong items_written;
gunichar *ucs4 = g_utf8_to_ucs4_fast (utf8, -1, &items_written);
gint i;
for (i = 0; i < items_written; i++) {
guint xkeysym;
EekKeysym *keysym;
gchar *name;
name = g_strdup_printf ("U%04X", ucs4[i]);
xkeysym = XStringToKeysym (name); // TODO: use xkb_get_keysym_from_name
g_free (name);
keysym = eek_keysym_new (xkeysym);
send_fake_key_events (client,
EEK_SYMBOL(keysym),
keyboard_modifiers);
}
g_free (ucs4);
*/
return;
}
if (EEK_IS_KEYSYM(symbol)) {
guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
send_fake_key_event (client, xkeysym, keyboard_modifiers);
}
}
void
emit_key_activated (EekboardContext *context,
guint keycode,
EekSymbol *symbol,
guint modifiers,
Client *client)
{
/* FIXME: figure out how to deal with Client after key presses go through
if (g_strcmp0 (eek_symbol_get_name (symbol), "cycle-keyboard") == 0) {
client->keyboards_head = g_slist_next (client->keyboards_head);
if (client->keyboards_head == NULL)
client->keyboards_head = client->keyboards;
eekboard_context_set_keyboard (client->context,
GPOINTER_TO_UINT(client->keyboards_head->data),
NULL);
return;
}
if (g_strcmp0 (eek_symbol_get_name (symbol), "preferences") == 0) {
gchar *argv[2];
GError *error;
argv[0] = g_build_filename (LIBEXECDIR, "eekboard-setup", NULL);
argv[1] = NULL;
error = NULL;
if (!g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, &error)) {
g_warning ("can't spawn %s: %s", argv[0], error->message);
g_error_free (error);
}
g_free (argv[0]);
return;
}
*/
send_fake_key_events (client, symbol, modifiers);
}
/* Finds the first key code for each modifier and saves it in modifier_keycodes */
static void
update_modifier_keycodes (Client *client)
{
GdkDisplay *display = gdk_display_get_default ();
Display *xdisplay = NULL; // GDK_DISPLAY_XDISPLAY (display);
return; // FIXME: need to get those codes somehow
XModifierKeymap *mods;
gint i, j;
//mods = XGetModifierMapping (xdisplay);
for (i = 0; i < 8; i++) {
client->modifier_keycodes[i] = 0;
for (j = 0; j < mods->max_keypermod; j++) {
KeyCode keycode = mods->modifiermap[mods->max_keypermod * i + j];
if (keycode != 0) {
client->modifier_keycodes[i] = keycode;
break;
}
}
}
//XFreeModifiermap (mods);
}
gboolean
client_enable_xtest (Client *client)
{
//GdkDisplay *display = gdk_display_get_default ();
//Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
int opcode, event_base, error_base, major_version, minor_version;
/* FIXME: need at least to fetch an xkb keymap (but what for?)
g_assert (display);
if (!XTestQueryExtension (xdisplay,
&event_base, &error_base,
&major_version, &minor_version)) {
g_warning ("XTest extension is not available");
return FALSE;
}
if (!XkbQueryExtension (xdisplay,
&opcode, &event_base, &error_base,
&major_version, &minor_version)) {
g_warning ("Xkb extension is not available");
return FALSE;
}
if (!client->xkb)
client->xkb = XkbGetMap (xdisplay, XkbKeySymsMask, XkbUseCoreKbd);
g_assert (client->xkb);
*/
update_modifier_keycodes (client);
return TRUE;
}
void
client_disable_xtest (Client *client)
{
//if (client->xkb) {
// XkbFreeKeyboard (client->xkb, 0, TRUE); /* free_all = TRUE */
//client->xkb = NULL;
//}
}
//#endif /* HAVE_XTEST */
#ifndef KEYEMITTER_H
#define KEYEMITTER_H
#include <glib.h>
#include <X11/XKBlib.h>
#include "eek/eek.h"
typedef struct {
gint group;
} EekboardContext;
typedef struct {
EekboardContext *context;
XkbDescRec *xkb;
guint modifier_keycodes[8];
} Client;
void
emit_key_activated (EekboardContext *context,
guint keycode,
EekSymbol *symbol,
guint modifiers,
Client *client);
gboolean
client_enable_xtest (Client *client);
void
client_disable_xtest (Client *client);
#endif // KEYEMITTER_H
......@@ -3,7 +3,7 @@ project(
'c',
version: '1.0.9',
license: 'GPLv3',
meson_version: '>=0.40.1',
meson_version: '>=0.43.0',
default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ],
)
......@@ -11,9 +11,6 @@ prefix = get_option('prefix')
datadir = join_paths(prefix, get_option('datadir'))
pkgdatadir = join_paths(datadir, meson.project_name())
install_data(
'data/themes/default.css',
install_dir: pkgdatadir + '/themes',
)
subdir('data')
subdir('eek')
subdir('src')
......@@ -2,27 +2,59 @@ sources = [
'server-service.c',
'server-context-service.c',
'server-main.c',
'../eekboard/eekboard-service.c',
'../eek/eek.c',
'../eek/eek-container.c',
'../eek/eek-element.c',
'../eek/eek-gtk-keyboard.c',
'../eek/eek-gtk-renderer.c',
'../eek/eek-key.c',
'../eek/eek-keyboard.c',
'../eek/eek-keyboard-drawing.c',
'../eek/eek-keysym.c',
'../eek/eek-layout.c',
'../eek/eek-renderer.c',
'../eek/eek-section.c',
'../eek/eek-serializable.c',
'../eek/eek-symbol.c',
'../eek/eek-symbol-matrix.c',
'../eek/eek-text.c',
'../eek/eek-theme.c',
'../eek/eek-theme-context.c',
'../eek/eek-theme-node.c',
'../eek/eek-types.c',
'../eek/eek-xml-layout.c',
enums,
keysym_entries,
marshalers,
'../eekboard/key-emitter.c',
'../eekboard/eekboard-context-service.c',
# $(srcdir)/eekboard-client.c \
# $(srcdir)/eekboard-context.c \
'../eekboard/eekboard-xklutil.c',
'../eekboard/eekboard-context.c',
'../eekboard/eekboard-service.c',
# '../eekboard/eekboard-xklutil.c',
]
cc = meson.get_compiler('c')
deps = [
# dependency('glib-2.0', version: '>=2.26.0'),
dependency('gio-2.0', version: '>=2.26.0'),
dependency('gtk+-3.0', version: '>=3.0'),
dependency('eek-gtk-0.90'),
dependency('libxklavier'), # FIXME remove
dependency('libcroco-0.6'),
cc.find_library('m'),
# dependency('libxklavier'), # FIXME remove
]
# Replacement for eekboard-server
squeekboard = executable('squeekboard',
sources,
include_directories: [include_directories('..')],
include_directories: [include_directories('..'), include_directories('../eek')],
dependencies: deps,
install: true,
c_args: ['-DTHEMESDIR="' + pkgdatadir + '/themes"', '-DEEKBOARD_COMPILATION=1'],
c_args: [
'-DTHEMESDIR="' + pkgdatadir + '/themes"',
'-DKEYBOARDSDIR="' + pkgdatadir + '/keyboards"',
'-DEEKBOARD_COMPILATION=1',
'-DEEK_COMPILATION=1'],
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment