Merge remote-tracking branch 'origin/5.12' into dev
Conflicts: src/gui/painting/qdrawhelper.cpp Change-Id: I4916e07b635e1d3830e9b46ef7914f99bec3098e
This commit is contained in:
commit
5d5c00c676
@ -306,10 +306,7 @@ Gui, printing, widget options:
|
||||
-mtdev ............. Enable mtdev support [auto]
|
||||
-tslib ............. Enable tslib support [auto]
|
||||
-xcb-xinput ........ Enable XInput2 support [auto]
|
||||
-xkbcommon-x11 ..... Select xkbcommon used in combination with xcb
|
||||
[system/qt/no]
|
||||
-xkbcommon-evdev ... Enable X-less xkbcommon in combination with libinput
|
||||
[auto]
|
||||
-xkbcommon ......... Enable key mapping support [auto]
|
||||
|
||||
Image formats:
|
||||
-gif ............... Enable reading support for GIF [auto]
|
||||
|
@ -212,7 +212,7 @@
|
||||
"verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "qmakeargs", "commit" ],
|
||||
"compile": [ "verifyspec" ],
|
||||
"detectPkgConfig": [ "cross_compile", "machineTuple" ],
|
||||
"library": [ "pkg-config" ],
|
||||
"library": [ "pkg-config", "compiler-flags" ],
|
||||
"getPkgConfigVariable": [ "pkg-config" ]
|
||||
},
|
||||
|
||||
|
@ -2,10 +2,15 @@ QT += widgets
|
||||
requires(qtConfig(filedialog))
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
previewform.h
|
||||
previewform.h \
|
||||
encodingdialog.h
|
||||
|
||||
SOURCES += main.cpp \
|
||||
mainwindow.cpp \
|
||||
previewform.cpp
|
||||
previewform.cpp \
|
||||
encodingdialog.cpp
|
||||
|
||||
RESOURCES += codecs.qrc
|
||||
|
||||
EXAMPLE_FILES = encodedfiles
|
||||
|
||||
|
5
examples/widgets/tools/codecs/codecs.qrc
Normal file
5
examples/widgets/tools/codecs/codecs.qrc
Normal file
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file>images/editcopy.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
333
examples/widgets/tools/codecs/encodingdialog.cpp
Normal file
333
examples/widgets/tools/codecs/encodingdialog.cpp
Normal file
@ -0,0 +1,333 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "encodingdialog.h"
|
||||
|
||||
#if QT_CONFIG(action)
|
||||
# include <QAction>
|
||||
#endif
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFormLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#if QT_CONFIG(clipboard)
|
||||
# include <QGuiApplication>
|
||||
# include <QClipboard>
|
||||
#endif
|
||||
|
||||
#include <QTextStream>
|
||||
|
||||
// Helpers for formatting character sequences
|
||||
|
||||
// Format a special character like '\x0a'
|
||||
template <class Int>
|
||||
static void formatEscapedNumber(QTextStream &str, Int value, int base,
|
||||
int width = 0,char prefix = 0)
|
||||
{
|
||||
str << '\\';
|
||||
if (prefix)
|
||||
str << prefix;
|
||||
const auto oldPadChar = str.padChar();
|
||||
const auto oldFieldWidth = str.fieldWidth();
|
||||
const auto oldFieldAlignment = str.fieldAlignment();
|
||||
const auto oldIntegerBase = str.integerBase();
|
||||
str.setPadChar(QLatin1Char('0'));
|
||||
str.setFieldWidth(width);
|
||||
str.setFieldAlignment(QTextStream::AlignRight);
|
||||
str.setIntegerBase(base);
|
||||
str << value;
|
||||
str.setIntegerBase(oldIntegerBase);
|
||||
str.setFieldAlignment(oldFieldAlignment);
|
||||
str.setFieldWidth(oldFieldWidth);
|
||||
str.setPadChar(oldPadChar);
|
||||
}
|
||||
|
||||
template <class Int>
|
||||
static bool formatSpecialCharacter(QTextStream &str, Int value)
|
||||
{
|
||||
bool result = true;
|
||||
switch (value) {
|
||||
case '\\':
|
||||
str << "\\\\";
|
||||
break;
|
||||
case '\"':
|
||||
str << "\\\"";
|
||||
break;
|
||||
case '\n':
|
||||
str << "\\n";
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Format a sequence of characters (QChar, ushort (UTF-16), uint (UTF-32)
|
||||
// or just char (Latin1, Utf-8)) with the help of traits specifying
|
||||
// how to obtain the code for checking the printable-ness and how to
|
||||
// stream out the plain ASCII values.
|
||||
|
||||
template <EncodingDialog::Encoding>
|
||||
struct FormattingTraits
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FormattingTraits<EncodingDialog::Unicode>
|
||||
{
|
||||
static ushort code(QChar c) { return c.unicode(); }
|
||||
static char toAscii(QChar c) { return c.toLatin1(); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FormattingTraits<EncodingDialog::Utf8>
|
||||
{
|
||||
static ushort code(char c) { return uchar(c); }
|
||||
static char toAscii(char c) { return c; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FormattingTraits<EncodingDialog::Utf16>
|
||||
{
|
||||
static ushort code(ushort c) { return c; }
|
||||
static char toAscii(ushort c) { return char(c); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FormattingTraits<EncodingDialog::Utf32>
|
||||
{
|
||||
static uint code(uint c) { return c; }
|
||||
static char toAscii(uint c) { return char(c); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FormattingTraits<EncodingDialog::Latin1>
|
||||
{
|
||||
static uchar code(char c) { return uchar(c); }
|
||||
static char toAscii(char c) { return c; }
|
||||
};
|
||||
|
||||
static bool isHexDigit(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')
|
||||
|| (c >= 'A' && c <= 'F');
|
||||
}
|
||||
|
||||
template <EncodingDialog::Encoding encoding, class Iterator>
|
||||
static void formatStringSequence(QTextStream &str, Iterator i1, Iterator i2,
|
||||
int escapeIntegerBase, int escapeWidth,
|
||||
char escapePrefix = 0)
|
||||
{
|
||||
str << '"';
|
||||
bool separateHexEscape = false;
|
||||
for (; i1 != i2; ++i1) {
|
||||
const auto code = FormattingTraits<encoding>::code(*i1);
|
||||
if (code >= 0x80) {
|
||||
formatEscapedNumber(str, code, escapeIntegerBase, escapeWidth, escapePrefix);
|
||||
separateHexEscape = escapeIntegerBase == 16 && escapeWidth == 0;
|
||||
} else {
|
||||
if (!formatSpecialCharacter(str, code)) {
|
||||
const char c = FormattingTraits<encoding>::toAscii(*i1);
|
||||
// For variable width/hex: Terminate the literal to stop digit parsing
|
||||
// ("\x12" "34...").
|
||||
if (separateHexEscape && isHexDigit(c))
|
||||
str << "\" \"";
|
||||
str << c;
|
||||
}
|
||||
separateHexEscape = false;
|
||||
}
|
||||
}
|
||||
str << '"';
|
||||
}
|
||||
|
||||
static QString encodedString(const QString &value, EncodingDialog::Encoding e)
|
||||
{
|
||||
QString result;
|
||||
QTextStream str(&result);
|
||||
switch (e) {
|
||||
case EncodingDialog::Unicode:
|
||||
formatStringSequence<EncodingDialog::Unicode>(str, value.cbegin(), value.cend(),
|
||||
16, 4, 'u');
|
||||
break;
|
||||
case EncodingDialog::Utf8: {
|
||||
const QByteArray utf8 = value.toUtf8();
|
||||
str << "u8";
|
||||
formatStringSequence<EncodingDialog::Utf8>(str, utf8.cbegin(), utf8.cend(),
|
||||
8, 3);
|
||||
}
|
||||
break;
|
||||
case EncodingDialog::Utf16: {
|
||||
auto utf16 = value.utf16();
|
||||
auto utf16End = utf16 + value.size();
|
||||
str << 'u';
|
||||
formatStringSequence<EncodingDialog::Utf16>(str, utf16, utf16End,
|
||||
16, 0, 'x');
|
||||
}
|
||||
break;
|
||||
case EncodingDialog::Utf32: {
|
||||
auto utf32 = value.toUcs4();
|
||||
str << 'U';
|
||||
formatStringSequence<EncodingDialog::Utf32>(str, utf32.cbegin(), utf32.cend(),
|
||||
16, 0, 'x');
|
||||
}
|
||||
break;
|
||||
case EncodingDialog::Latin1: {
|
||||
const QByteArray latin1 = value.toLatin1();
|
||||
formatStringSequence<EncodingDialog::Latin1>(str, latin1.cbegin(), latin1.cend(),
|
||||
16, 0, 'x');
|
||||
}
|
||||
break;
|
||||
case EncodingDialog::EncodingCount:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Dialog helpers
|
||||
|
||||
static const char *encodingLabels[]
|
||||
{
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "Unicode:"),
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "UTF-8:"),
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "UTF-16:"),
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "UTF-32:"),
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "Latin1:")
|
||||
};
|
||||
|
||||
static const char *encodingToolTips[]
|
||||
{
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "Unicode points for use with any encoding (C++, Python)"),
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "QString::fromUtf8()"),
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "QStringViewLiteral(), wchar_t on Windows"),
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "wchar_t on Unix (Ucs4)"),
|
||||
QT_TRANSLATE_NOOP("EncodingDialog", "QLatin1String")
|
||||
};
|
||||
|
||||
// A read-only line edit with a tool button to copy the contents
|
||||
class DisplayLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DisplayLineEdit(const QIcon &icon, QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void copyAll();
|
||||
};
|
||||
|
||||
DisplayLineEdit::DisplayLineEdit(const QIcon &icon, QWidget *parent) :
|
||||
QLineEdit(parent)
|
||||
{
|
||||
setReadOnly(true);
|
||||
#if QT_CONFIG(clipboard) && QT_CONFIG(action)
|
||||
auto copyAction = addAction(icon, QLineEdit::TrailingPosition);
|
||||
connect(copyAction, &QAction::triggered, this, &DisplayLineEdit::copyAll);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DisplayLineEdit::copyAll()
|
||||
{
|
||||
#if QT_CONFIG(clipboard)
|
||||
QGuiApplication::clipboard()->setText(text());
|
||||
#endif
|
||||
}
|
||||
|
||||
static void addFormLayoutRow(QFormLayout *formLayout, const QString &text,
|
||||
QWidget *w, const QString &toolTip)
|
||||
{
|
||||
auto label = new QLabel(text);
|
||||
label->setToolTip(toolTip);
|
||||
w->setToolTip(toolTip);
|
||||
label->setBuddy(w);
|
||||
formLayout->addRow(label, w);
|
||||
}
|
||||
|
||||
EncodingDialog::EncodingDialog(QWidget *parent) :
|
||||
QDialog(parent)
|
||||
{
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setWindowTitle(tr("Encodings"));
|
||||
|
||||
auto formLayout = new QFormLayout;
|
||||
auto sourceLineEdit = new QLineEdit(this);
|
||||
sourceLineEdit->setClearButtonEnabled(true);
|
||||
connect(sourceLineEdit, &QLineEdit::textChanged, this, &EncodingDialog::textChanged);
|
||||
|
||||
addFormLayoutRow(formLayout, tr("&Source:"), sourceLineEdit, tr("Enter text"));
|
||||
|
||||
const auto copyIcon = QIcon::fromTheme(QLatin1String("edit-copy"),
|
||||
QIcon(QLatin1String(":/images/editcopy")));
|
||||
for (int i = 0; i < EncodingCount; ++i) {
|
||||
m_lineEdits[i] = new DisplayLineEdit(copyIcon, this);
|
||||
addFormLayoutRow(formLayout, tr(encodingLabels[i]),
|
||||
m_lineEdits[i], tr(encodingToolTips[i]));
|
||||
}
|
||||
|
||||
auto mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->addLayout(formLayout);
|
||||
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
}
|
||||
|
||||
void EncodingDialog::textChanged(const QString &t)
|
||||
{
|
||||
if (t.isEmpty()) {
|
||||
for (auto lineEdit : m_lineEdits)
|
||||
lineEdit->clear();
|
||||
} else {
|
||||
for (int i = 0; i < EncodingCount; ++i)
|
||||
m_lineEdits[i]->setText(encodedString(t, static_cast<Encoding>(i)));
|
||||
}
|
||||
}
|
||||
|
||||
#include "encodingdialog.moc"
|
73
examples/widgets/tools/codecs/encodingdialog.h
Normal file
73
examples/widgets/tools/codecs/encodingdialog.h
Normal file
@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef ENCODINGDIALOG_H
|
||||
#define ENCODINGDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QLineEdit)
|
||||
|
||||
class EncodingDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EncodingDialog(QWidget *parent = nullptr);
|
||||
|
||||
enum Encoding { Unicode, Utf8, Utf16, Utf32, Latin1, EncodingCount };
|
||||
|
||||
private slots:
|
||||
void textChanged(const QString &t);
|
||||
|
||||
private:
|
||||
QLineEdit *m_lineEdits[EncodingCount];
|
||||
};
|
||||
|
||||
#endif // ENCODINGDIALOG_H
|
BIN
examples/widgets/tools/codecs/images/editcopy.png
Normal file
BIN
examples/widgets/tools/codecs/images/editcopy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -51,6 +51,7 @@
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "encodingdialog.h"
|
||||
#include "previewform.h"
|
||||
|
||||
MainWindow::MainWindow()
|
||||
@ -188,9 +189,27 @@ void MainWindow::createMenus()
|
||||
QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close);
|
||||
exitAct->setShortcuts(QKeySequence::Quit);
|
||||
|
||||
auto toolMenu = menuBar()->addMenu(tr("&Tools"));
|
||||
auto encodingAction = toolMenu->addAction(tr("Encodings"), this, &MainWindow::encodingDialog);
|
||||
encodingAction->setShortcut(Qt::CTRL + Qt::Key_E);
|
||||
encodingAction->setToolTip(tr("Shows a dialog allowing to convert to common encoding in programming languages."));
|
||||
|
||||
|
||||
menuBar()->addSeparator();
|
||||
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
||||
helpMenu->addAction(tr("&About"), this, &MainWindow::about);
|
||||
helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
|
||||
}
|
||||
|
||||
void MainWindow::encodingDialog()
|
||||
{
|
||||
if (!m_encodingDialog) {
|
||||
m_encodingDialog = new EncodingDialog(this);
|
||||
const QRect screenGeometry = QApplication::desktop()->screenGeometry(this);
|
||||
m_encodingDialog->setMinimumWidth(screenGeometry.width() / 4);
|
||||
}
|
||||
m_encodingDialog->show();
|
||||
m_encodingDialog->raise();
|
||||
|
||||
}
|
||||
|
@ -59,6 +59,8 @@ class QAction;
|
||||
class QTextCodec;
|
||||
class QPlainTextEdit;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class EncodingDialog;
|
||||
class PreviewForm;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
@ -73,6 +75,7 @@ private slots:
|
||||
void save();
|
||||
void about();
|
||||
void aboutToShowSaveAsMenu();
|
||||
void encodingDialog();
|
||||
|
||||
private:
|
||||
void findCodecs();
|
||||
@ -82,6 +85,7 @@ private:
|
||||
QPlainTextEdit *textEdit;
|
||||
PreviewForm *previewForm;
|
||||
QList<QTextCodec *> codecs;
|
||||
EncodingDialog *m_encodingDialog = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -87,6 +87,3 @@ QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
|
||||
!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.")
|
||||
|
||||
load(qt_config)
|
||||
|
||||
QMAKE_DEFAULT_LIBDIRS = $$QMAKE_LIBDIR
|
||||
QMAKE_DEFAULT_INCDIRS = $$QMAKE_INCDIR
|
||||
|
@ -106,7 +106,7 @@ QMAKE_LIBS_OPENGL_ES2_DEBUG = gdi32.lib user32.lib
|
||||
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
|
||||
QMAKE_LIBS_QT_ENTRY = -lqtmain
|
||||
|
||||
QMAKE_IDL = midl /NOLOGO
|
||||
QMAKE_IDL = midl
|
||||
QMAKE_LIB = lib /NOLOGO
|
||||
QMAKE_RC = rc /NOLOGO
|
||||
|
||||
|
@ -65,7 +65,8 @@ for (MODULE_UNDER_TEST, CMAKE_QT_MODULES_UNDER_TEST) {
|
||||
CMAKE_MODULES_UNDER_TEST = $$join(CMAKE_MODULES_UNDER_TEST, ;)
|
||||
|
||||
check.commands = \
|
||||
$(MKDIR) $$BUILD_DIR && $$QMAKE_CD $$BUILD_DIR && \
|
||||
$$sprintf($$QMAKE_MKDIR_CMD, $$BUILD_DIR) $$escape_expand(\\n\\t) \
|
||||
$$QMAKE_CD $$BUILD_DIR && \
|
||||
cmake $$CMAKE_TEST_LOCATION $$CMAKE_GENERATOR \
|
||||
-DCMAKE_C_COMPILER=$$QMAKE_CC \
|
||||
-DCMAKE_CXX_COMPILER=$$QMAKE_CXX \
|
||||
|
@ -146,7 +146,7 @@ inspect_binary() {
|
||||
echo "found namespaced class names, updating class entries..."
|
||||
fi
|
||||
|
||||
classes=$(otool -o "$target" | grep class_ro_t)
|
||||
classes=$(otool -o -v "$target" | grep class_ro_t)
|
||||
while read -a class; do
|
||||
address="$(sanitize_address ${class[1]})"
|
||||
|
||||
|
@ -9,7 +9,6 @@ for(ever) {
|
||||
error("Library '$$name' is not defined.")
|
||||
|
||||
!contains(use, nolink) {
|
||||
QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu)
|
||||
debug: \
|
||||
LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu)
|
||||
else: \
|
||||
|
@ -365,9 +365,13 @@ defineTest(qtConfTest_linkerSupportsFlag) {
|
||||
}
|
||||
|
||||
defineReplace(qtConfFindInPathList) {
|
||||
# This nesting is consistent with Apple ld -search_paths_first,
|
||||
# and presumably with GNU ld (no actual documentation found).
|
||||
for (dir, 2) {
|
||||
exists("$$dir/$${1}"): \
|
||||
return("$$dir/$${1}")
|
||||
for (file, 1) {
|
||||
exists("$$dir/$$file"): \
|
||||
return("$$dir/$$file")
|
||||
}
|
||||
}
|
||||
return()
|
||||
}
|
||||
@ -488,6 +492,110 @@ defineTest(qtConfSetupLibraries) {
|
||||
}
|
||||
}
|
||||
|
||||
# libs-var, libs, in-paths, out-paths-var
|
||||
defineTest(qtConfResolveLibs) {
|
||||
ret = true
|
||||
paths = $$3
|
||||
out =
|
||||
copy = false
|
||||
for (l, 2) {
|
||||
$$copy {
|
||||
copy = false
|
||||
out += $$l
|
||||
} else: equals(l, "-s") {
|
||||
# em++ flag to link libraries from emscripten-ports; passed on literally.
|
||||
copy = true
|
||||
out += $$l
|
||||
} else: contains(l, "^-L.*") {
|
||||
lp = $$replace(l, "^-L", )
|
||||
!exists($$lp/.) {
|
||||
qtLog("Library path $$val_escape(lp) is invalid.")
|
||||
ret = false
|
||||
} else {
|
||||
paths += $$lp
|
||||
}
|
||||
} else: contains(l, "^-l.*") {
|
||||
lib = $$replace(l, "^-l", )
|
||||
lcan =
|
||||
unix {
|
||||
# Under UNIX, we look for actual shared libraries, in addition
|
||||
# to static ones.
|
||||
lcan += \
|
||||
$${QMAKE_PREFIX_SHLIB}$${lib}.$${QMAKE_EXTENSION_SHLIB} \
|
||||
$${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB}
|
||||
} else {
|
||||
# Under Windows, we look only for static libraries, as even for DLLs
|
||||
# one actually links against a static import library.
|
||||
mingw {
|
||||
lcan += \
|
||||
# MinGW supports UNIX-style library naming in addition to
|
||||
# the MSVC style.
|
||||
lib$${lib}.dll.a lib$${lib}.a \
|
||||
# Fun fact: prefix-less libraries are also supported.
|
||||
$${lib}.dll.a $${lib}.a
|
||||
}
|
||||
lcan += $${lib}.lib
|
||||
}
|
||||
l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS)
|
||||
isEmpty(l) {
|
||||
qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.")
|
||||
ret = false
|
||||
} else {
|
||||
out += $$l
|
||||
}
|
||||
} else {
|
||||
out += $$l
|
||||
}
|
||||
}
|
||||
$$1 = $$out
|
||||
export($$1)
|
||||
!isEmpty(4) {
|
||||
$$4 = $$paths
|
||||
export($$4)
|
||||
}
|
||||
return($$ret)
|
||||
}
|
||||
|
||||
# source-var
|
||||
defineTest(qtConfResolveAllLibs) {
|
||||
ret = true
|
||||
!qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \
|
||||
ret = false
|
||||
for (b, $${1}.builds._KEYS_): \
|
||||
!qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \
|
||||
ret = false
|
||||
return($$ret)
|
||||
}
|
||||
|
||||
# libs-var, in-paths, libs
|
||||
defineTest(qtConfResolvePathLibs) {
|
||||
ret = true
|
||||
for (libdir, 2) {
|
||||
!exists($$libdir/.) {
|
||||
qtLog("Library path $$val_escape(libdir) is invalid.")
|
||||
ret = false
|
||||
}
|
||||
}
|
||||
!qtConfResolveLibs($$1, $$3, $$2): \
|
||||
ret = false
|
||||
return($$ret)
|
||||
}
|
||||
|
||||
# includes-var, includes
|
||||
defineTest(qtConfResolvePathIncs) {
|
||||
ret = true
|
||||
for (incdir, 2) {
|
||||
!exists($$incdir/.) {
|
||||
qtLog("Include path $$val_escape(incdir) is invalid.")
|
||||
ret = false
|
||||
}
|
||||
}
|
||||
2 -= $$QMAKE_DEFAULT_INCDIRS
|
||||
$$1 = $$2
|
||||
export($$1)
|
||||
return($$ret)
|
||||
}
|
||||
|
||||
# the library is specified inline in a 'libs' field.
|
||||
# overrides from the command line are accepted.
|
||||
defineTest(qtConfLibrary_inline) {
|
||||
@ -517,7 +625,6 @@ defineTest(qtConfLibrary_inline) {
|
||||
vars += $$eval(config.commandline.rev_assignments.$${iv})
|
||||
defined(config.input.$${iv}, var) {
|
||||
eval($${1}.builds.$${b} = $$eval(config.input.$${iv}))
|
||||
export($${1}.builds.$${b})
|
||||
$${1}.builds._KEYS_ *= $${b}
|
||||
any = true
|
||||
} else {
|
||||
@ -532,35 +639,30 @@ defineTest(qtConfLibrary_inline) {
|
||||
export($${1}.builds._KEYS_)
|
||||
# we also reset the generic libs, to avoid surprises.
|
||||
$${1}.libs =
|
||||
export($${1}.libs)
|
||||
}
|
||||
|
||||
# direct libs. overwrites inline libs.
|
||||
defined(config.input.$${input}.libs, var) {
|
||||
defined(config.input.$${input}.libs, var): \
|
||||
eval($${1}.libs = $$eval(config.input.$${input}.libs))
|
||||
export($${1}.libs)
|
||||
}
|
||||
|
||||
includes = $$eval(config.input.$${input}.incdir)
|
||||
|
||||
# prefix. prepends to (possibly overwritten) inline libs.
|
||||
prefix = $$eval(config.input.$${input}.prefix)
|
||||
!isEmpty(prefix) {
|
||||
$${1}.includedir = $$prefix/include
|
||||
export($${1}.includedir)
|
||||
includes += $$prefix/include
|
||||
$${1}.libs = -L$$prefix/lib $$eval($${1}.libs)
|
||||
export($${1}.libs)
|
||||
}
|
||||
|
||||
incdir = $$eval(config.input.$${input}.incdir)
|
||||
!isEmpty(incdir) {
|
||||
$${1}.includedir = $$incdir
|
||||
export($${1}.includedir)
|
||||
}
|
||||
|
||||
libdir = $$eval(config.input.$${input}.libdir)
|
||||
!isEmpty(libdir) {
|
||||
!isEmpty(libdir): \
|
||||
$${1}.libs = -L$$libdir $$eval($${1}.libs)
|
||||
export($${1}.libs)
|
||||
}
|
||||
|
||||
!qtConfResolveAllLibs($$1): \
|
||||
return(false)
|
||||
|
||||
!qtConfResolvePathIncs($${1}.includedir, $$includes): \
|
||||
return(false)
|
||||
|
||||
return(true)
|
||||
}
|
||||
@ -572,17 +674,13 @@ defineTest(qtConfLibrary_makeSpec) {
|
||||
isEmpty(spec): \
|
||||
error("makeSpec source in library '$$eval($${1}.library)' does not specify 'spec'.")
|
||||
|
||||
$${1}.includedir = $$eval(QMAKE_INCDIR_$$spec)
|
||||
export($${1}.includedir)
|
||||
$${1}.libs =
|
||||
for (l, QMAKE_LIBDIR_$$spec): \
|
||||
$${1}.libs += -L$$l
|
||||
$${1}.libs += $$eval(QMAKE_LIBS_$$spec)
|
||||
export($${1}.libs)
|
||||
!qtConfResolvePathLibs($${1}.libs, $$eval(QMAKE_LIBDIR_$$spec), $$eval(QMAKE_LIBS_$$spec)): \
|
||||
return(false)
|
||||
|
||||
# the library definition is always in scope, so no point in exporting it.
|
||||
$${1}.export = false
|
||||
export($${1}.export)
|
||||
!qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec)): \
|
||||
return(false)
|
||||
|
||||
# note that the object is re-exported, because we resolve the libraries.
|
||||
|
||||
return(true)
|
||||
}
|
||||
@ -602,13 +700,15 @@ defineTest(qtConfLibrary_pkgConfig) {
|
||||
}
|
||||
|
||||
qtRunLoggedCommand("$$pkg_config --modversion $$args", version)|return(false)
|
||||
qtRunLoggedCommand("$$pkg_config --libs-only-L $$args", libpaths)|return(false)
|
||||
qtRunLoggedCommand("$$pkg_config --libs-only-l $$args", libs)|return(false)
|
||||
version ~= s/[^0-9.].*$//
|
||||
$${1}.version = $$first(version)
|
||||
export($${1}.version)
|
||||
eval($${1}.libs = $$libpaths $$libs)
|
||||
export($${1}.libs)
|
||||
|
||||
qtRunLoggedCommand("$$pkg_config --libs-only-L $$args", libpaths)|return(false)
|
||||
qtRunLoggedCommand("$$pkg_config --libs-only-l $$args", libs)|return(false)
|
||||
eval(libs = $$libpaths $$libs)
|
||||
!qtConfResolveLibs($${1}.libs, $$libs): \
|
||||
return(false)
|
||||
|
||||
qtRunLoggedCommand("$$pkg_config --cflags $$args", $${1}.cflags)|return(false)
|
||||
# Split CFLAGS into stuff that goes into DEFINES, INCLUDEPATH, and other stuff.
|
||||
@ -633,10 +733,11 @@ defineTest(qtConfLibrary_pkgConfig) {
|
||||
}
|
||||
!isEmpty(ignored): \
|
||||
qtLog("Note: Dropped compiler flags '$$ignored'.")
|
||||
!qtConfResolvePathIncs($${1}.includedir, $$includes): \
|
||||
return(false)
|
||||
$${1}.defines = $$defines
|
||||
export($${1}.defines)
|
||||
$${1}.includedir = $$includes
|
||||
export($${1}.includedir)
|
||||
|
||||
return(true)
|
||||
}
|
||||
|
||||
|
@ -34,19 +34,30 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET)
|
||||
MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri
|
||||
ucmodule = $$upper($$MODULE)
|
||||
|
||||
win32|CONFIG(static, static|shared) {
|
||||
prefix = $$QMAKE_PREFIX_STATICLIB
|
||||
suffix = $$QMAKE_EXTENSION_STATICLIB
|
||||
} else {
|
||||
prefix = $$QMAKE_PREFIX_SHLIB
|
||||
suffix = $$QMAKE_EXTENSION_SHLIB
|
||||
}
|
||||
MODULE_PRI_CONT = \
|
||||
"QMAKE_INCDIR_$${ucmodule} = $$val_escape(MODULE_INCLUDEPATH)" \
|
||||
"QMAKE_DEFINES_$${ucmodule} = $$val_escape(MODULE_DEFINES)"
|
||||
debug_and_release {
|
||||
win32: MODULE_DEBUG_LIBS = -L$$DESTDIR -l$${TARGET}d
|
||||
darwin: MODULE_DEBUG_LIBS = -L$$DESTDIR -l$${TARGET}_debug
|
||||
MODULE_RELEASE_LIBS = -L$$DESTDIR -l$$TARGET
|
||||
win32: \
|
||||
MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}d.$$suffix
|
||||
else: darwin: \
|
||||
MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}_debug.$$suffix
|
||||
else: \
|
||||
error("'$$QMAKE_PLATFORM' does not do debug_and_release.")
|
||||
MODULE_RELEASE_LIBS = $$DESTDIR/$$prefix$${TARGET}.$$suffix
|
||||
MODULE_PRI_CONT += \
|
||||
"QMAKE_LIBS_$${ucmodule} =" \ # Needed for the module to be recognized.
|
||||
"QMAKE_LIBS_$${ucmodule}_DEBUG = $$val_escape(MODULE_DEBUG_LIBS)" \
|
||||
"QMAKE_LIBS_$${ucmodule}_RELEASE = $$val_escape(MODULE_RELEASE_LIBS)"
|
||||
} else {
|
||||
MODULE_LIBS = -L$$DESTDIR -l$$THE_TARGET
|
||||
MODULE_LIBS = $$DESTDIR/$$prefix$${THE_TARGET}.$$suffix
|
||||
MODULE_PRI_CONT += \
|
||||
"QMAKE_LIBS_$${ucmodule} = $$val_escape(MODULE_LIBS)"
|
||||
}
|
||||
|
@ -128,8 +128,8 @@ isEmpty($${target_prefix}.INCDIRS) {
|
||||
# paths, so it can't just be used in place of the above code).
|
||||
# What's more, -print-search-dirs can't be used on clang on Apple because it
|
||||
# won't print all the library paths (only the clang-internal ones).
|
||||
output = $$system("$$cmd_prefix $$QMAKE_CXX -print-search-dirs", lines, ec)
|
||||
!equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output)
|
||||
output = $$system("$$cmd_prefix $$QMAKE_LINK $$QMAKE_LFLAGS -print-search-dirs", lines, ec)
|
||||
!equals(ec, 0): qtCompilerErrror($$QMAKE_LINK, $$output)
|
||||
|
||||
for (line, output) {
|
||||
contains(line, "^libraries: .*") {
|
||||
|
@ -41,14 +41,14 @@ contains(TEMPLATE, .*app) {
|
||||
|
||||
appjs.name = application qtloader.js
|
||||
appjs.output = $$DESTDIR/qtloader.js
|
||||
appjs.commands = $$QMAKE_COPY $$WASM_PLUGIN_PATH/qtloader.js $$DESTDIR
|
||||
appjs.commands = $$QMAKE_COPY $$shell_path($$WASM_PLUGIN_PATH/qtloader.js) $$shell_path($$DESTDIR)
|
||||
appjs.input = $$WASM_PLUGIN_PATH/qtloader.js
|
||||
appjs.depends = $$appjs.input
|
||||
QMAKE_EXTRA_COMPILERS += appjs
|
||||
|
||||
appsvg.name = application qtlogo.svg
|
||||
appsvg.output = $$DESTDIR/qtlogo.svg
|
||||
appsvg.commands = $$QMAKE_COPY $$WASM_PLUGIN_PATH/qtlogo.svg $$DESTDIR
|
||||
appsvg.commands = $$QMAKE_COPY $$shell_path($$WASM_PLUGIN_PATH/qtlogo.svg) $$shell_path($$DESTDIR)
|
||||
appsvg.input = $$WASM_PLUGIN_PATH/qtlogo.svg
|
||||
appsvg.depends = $$appsvg.input
|
||||
QMAKE_EXTRA_COMPILERS += appsvg
|
||||
|
@ -2325,6 +2325,7 @@ MakefileGenerator::writeHeader(QTextStream &t)
|
||||
if (ofile.lastIndexOf(Option::dir_sep) != -1)
|
||||
ofile.remove(0, ofile.lastIndexOf(Option::dir_sep) +1);
|
||||
t << "MAKEFILE = " << escapeFilePath(ofile) << endl << endl;
|
||||
t << "EQ = =\n\n";
|
||||
}
|
||||
|
||||
QList<MakefileGenerator::SubTarget*>
|
||||
@ -2869,6 +2870,7 @@ MakefileGenerator::escapeDependencyPath(const QString &path) const
|
||||
static const QRegExp criticalChars(QStringLiteral("([\t #])"));
|
||||
#endif
|
||||
ret.replace(criticalChars, QStringLiteral("\\\\1"));
|
||||
ret.replace(QLatin1Char('='), QStringLiteral("$(EQ)"));
|
||||
debug_msg(2, "escapeDependencyPath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData());
|
||||
}
|
||||
return ret;
|
||||
|
@ -109,10 +109,10 @@ int QMakeVfs::idForFileName(const QString &fn, VfsFlags flags)
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
if (!(flags & VfsAccessedOnly)) {
|
||||
#ifdef PROPARSER_THREAD_SAFE
|
||||
QMutexLocker locker(&s_mutex);
|
||||
QMutexLocker locker(&s_mutex);
|
||||
#endif
|
||||
if (!(flags & VfsAccessedOnly)) {
|
||||
int &id = s_fileIdMap[fn];
|
||||
if (!id) {
|
||||
id = ++s_fileIdCounter;
|
||||
|
14
src/3rdparty/xkbcommon-x11.pri
vendored
14
src/3rdparty/xkbcommon-x11.pri
vendored
@ -1,14 +0,0 @@
|
||||
include(xkbcommon.pri)
|
||||
|
||||
# Build xkbcommon-x11 support library, it depends on -lxcb and -lxcb-xkb, linking is done
|
||||
# in xcb-plugin.pro (linked to system libraries or if Qt was configured with -qt-xcb then
|
||||
# linked to -lxcb-static).
|
||||
INCLUDEPATH += $$PWD/xkbcommon/src/x11
|
||||
|
||||
# Need to rename several files, qmake has problems processing a project when
|
||||
# sub-directories contain files with an equal names.
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/xkbcommon/src/x11/util.c \
|
||||
$$PWD/xkbcommon/src/x11/x11-keymap.c \ # renamed: keymap.c -> x11-keymap.c
|
||||
$$PWD/xkbcommon/src/x11/x11-state.c # renamed: state.c -> x11-state.c
|
60
src/3rdparty/xkbcommon.pri
vendored
60
src/3rdparty/xkbcommon.pri
vendored
@ -1,60 +0,0 @@
|
||||
# Requires GNU C extensions
|
||||
CONFIG -= strict_c
|
||||
|
||||
INCLUDEPATH += $$PWD/xkbcommon \
|
||||
$$PWD/xkbcommon/xkbcommon \
|
||||
$$PWD/xkbcommon/src \
|
||||
$$PWD/xkbcommon/src/xkbcomp
|
||||
|
||||
include($$shadowed($$PWD/../gui/qtgui-config.pri))
|
||||
|
||||
# Unused (but needs to be set to something) - we don't use APIs that read xkb
|
||||
# config files from file system. We use APIs that fetch the necessary keymap
|
||||
# details directly from X server.
|
||||
DEFINES += DFLT_XKB_CONFIG_ROOT='\\"/usr/share/X11/xkb\\"'
|
||||
# Unused (but needs to be set to something) - After QTBUG-42181, this needs to
|
||||
# be become a configure switch.
|
||||
DEFINES += XLOCALEDIR='\\"/usr/share/X11/locale/\\"'
|
||||
|
||||
### RMLVO names can be overwritten with environmental variables (see libxkbcommon documentation)
|
||||
DEFINES += DEFAULT_XKB_RULES='\\"evdev\\"'
|
||||
DEFINES += DEFAULT_XKB_MODEL='\\"pc105\\"'
|
||||
DEFINES += DEFAULT_XKB_LAYOUT='\\"us\\"'
|
||||
|
||||
# Need to rename several files, qmake has problems processing a project when
|
||||
# sub-directories contain files with an equal names.
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/xkbcommon/src/keysym-utf.c \
|
||||
$$PWD/xkbcommon/src/keymap.c \
|
||||
$$PWD/xkbcommon/src/keymap-priv.c \
|
||||
$$PWD/xkbcommon/src/utils.c \
|
||||
$$PWD/xkbcommon/src/atom.c \
|
||||
$$PWD/xkbcommon/src/compose/paths.c \
|
||||
$$PWD/xkbcommon/src/compose/parser.c \
|
||||
$$PWD/xkbcommon/src/compose/compose-state.c \ # renamed: keymap.c -> compose-state.c
|
||||
$$PWD/xkbcommon/src/compose/table.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/xkbcomp-keymap.c \ # renamed: keymap.c -> xkbcomp-keymap.c
|
||||
$$PWD/xkbcommon/src/xkbcomp/xkbcomp.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/keymap-dump.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/rules.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/expr.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/action.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/compat.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/types.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/scanner.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/xkbcomp-parser.c \ # renamed: parser.c -> xkbcomp-parser.c
|
||||
$$PWD/xkbcommon/src/xkbcomp/ast-build.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/keywords.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/keycodes.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/vmod.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/include.c \
|
||||
$$PWD/xkbcommon/src/xkbcomp/symbols.c \
|
||||
$$PWD/xkbcommon/src/context-priv.c \
|
||||
$$PWD/xkbcommon/src/text.c \
|
||||
$$PWD/xkbcommon/src/context.c \
|
||||
$$PWD/xkbcommon/src/keysym.c \
|
||||
$$PWD/xkbcommon/src/utf8.c \
|
||||
$$PWD/xkbcommon/src/state.c
|
||||
|
||||
TR_EXCLUDE += $$PWD/*
|
215
src/3rdparty/xkbcommon/LICENSE
vendored
215
src/3rdparty/xkbcommon/LICENSE
vendored
@ -1,215 +0,0 @@
|
||||
The following is a list of all copyright notices and license statements which
|
||||
appear in the xkbcommon source tree.
|
||||
|
||||
If making new contributions, the first form (i.e. Daniel Stone, Ran Benita,
|
||||
etc) is vastly preferred.
|
||||
|
||||
All licenses are derivative of the MIT/X11 license, mostly identical other
|
||||
than no-endorsement clauses (e.g. paragraph 4 of The Open Group's license).
|
||||
|
||||
These statements are split into two sections: one for the code compiled and
|
||||
distributed as part of the libxkbcommon shared library and the code
|
||||
component of all tests (i.e. everything under src/ and xkbcommon/, plus the
|
||||
.c and .h files under test/), and another for the test data under test/data,
|
||||
which is distributed with the xkbcommon source tarball, but not installed to
|
||||
the system.
|
||||
|
||||
|
||||
BEGINNING OF SOFTWARE COPYRIGHT/LICENSE STATEMENTS:
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2009-2012, 2016 Daniel Stone
|
||||
Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
Copyright © 2010, 2012 Intel Corporation
|
||||
Copyright © 2008, 2009 Dan Nicholson
|
||||
Copyright © 2010 Francisco Jerez <currojerez@riseup.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Copyright 1985, 1987, 1988, 1990, 1998 The Open Group
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the names of the authors or their
|
||||
institutions shall not be used in advertising or otherwise to promote the
|
||||
sale, use or other dealings in this Software without prior written
|
||||
authorization from the authors.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Copyright (c) 1993, 1994, 1995, 1996 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Copyright (C) 2011 Joseph Adams <joeyadams3.14159@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
END OF SOFTWARE COPYRIGHT/LICENSE STATEMENTS
|
||||
|
||||
|
||||
BEGINNING OF LICENSE STATEMENTS FOR UNDISTRIBUTED DATA FILES IN test/data,
|
||||
derived from xkeyboard-config:
|
||||
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright 1996 by Joseph Moss
|
||||
Copyright (C) 2002-2007 Free Software Foundation, Inc.
|
||||
Copyright (C) Dmitry Golubev <lastguru@mail.ru>, 2003-2004
|
||||
Copyright (C) 2004, Gregory Mokhin <mokhin@bog.msu.ru>
|
||||
Copyright (C) 2006 Erdal Ronahî
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation, and that the name of the copyright holder(s) not be used in
|
||||
advertising or publicity pertaining to distribution of the software without
|
||||
specific, written prior permission. The copyright holder(s) makes no
|
||||
representations about the suitability of this software for any purpose. It
|
||||
is provided "as is" without express or implied warranty.
|
||||
|
||||
THE COPYRIGHT HOLDER(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright 1992 by Oki Technosystems Laboratory, Inc.
|
||||
Copyright 1992 by Fuji Xerox Co., Ltd.
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software
|
||||
and its documentation for any purpose is hereby granted without fee,
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both that copyright notice and this permission notice appear
|
||||
in supporting documentation, and that the name of Oki Technosystems
|
||||
Laboratory and Fuji Xerox not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific, written
|
||||
prior permission.
|
||||
Oki Technosystems Laboratory and Fuji Xerox make no representations
|
||||
about the suitability of this software for any purpose. It is provided
|
||||
"as is" without express or implied warranty.
|
||||
|
||||
OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS
|
||||
LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||
OR PERFORMANCE OF THIS SOFTWARE.
|
404
src/3rdparty/xkbcommon/NEWS
vendored
404
src/3rdparty/xkbcommon/NEWS
vendored
@ -1,404 +0,0 @@
|
||||
libxkbcommon 0.8.2 - 2018-08-05
|
||||
==================
|
||||
|
||||
- Fix various problems found with fuzzing (see commit messages for
|
||||
more details):
|
||||
|
||||
- Fix a few NULL-dereferences, out-of-bounds access and undefined behavior
|
||||
in the XKB text format parser.
|
||||
|
||||
|
||||
libxkbcommon 0.8.1 - 2018-08-03
|
||||
==================
|
||||
|
||||
- Fix various problems found in the meson build (see commit messages for more
|
||||
details):
|
||||
|
||||
- Fix compilation on Darwin.
|
||||
|
||||
- Fix compilation of the x11 tests and demos when XCB is installed in a
|
||||
non-standard location.
|
||||
|
||||
- Fix xkbcommon-x11.pc missing the Requires specification.
|
||||
|
||||
- Fix various problems found with fuzzing and Coverity (see commit messages for
|
||||
more details):
|
||||
|
||||
- Fix stack overflow in the XKB text format parser when evaluating boolean
|
||||
negation.
|
||||
|
||||
- Fix NULL-dereferences in the XKB text format parser when some unsupported
|
||||
tokens appear (the tokens are still parsed for backward compatibility).
|
||||
|
||||
- Fix NULL-dereference in the XKB text format parser when parsing an
|
||||
xkb_geometry section.
|
||||
|
||||
- Fix an infinite loop in the Compose text format parser on some inputs.
|
||||
|
||||
- Fix an invalid free() when using multiple keysyms.
|
||||
|
||||
- Replace the Unicode characters for the leftanglebracket and rightanglebracket
|
||||
keysyms from the deprecated LEFT/RIGHT-POINTING ANGLE BRACKET to
|
||||
MATHEMATICAL LEFT/RIGHT ANGLE BRACKET.
|
||||
|
||||
- Reject out-of-range Unicode codepoints in xkb_keysym_to_utf8 and
|
||||
xkb_keysym_to_utf32.
|
||||
|
||||
|
||||
libxkbcommon 0.8.0 - 2017-12-15
|
||||
==================
|
||||
|
||||
- Added xkb_keysym_to_{upper,lower} to perform case-conversion directly on
|
||||
keysyms. This is useful in some odd cases, but working with the Unicode
|
||||
representations should be preferred when possible.
|
||||
|
||||
- Added Unicode conversion rules for the signifblank and permille keysyms.
|
||||
|
||||
- Fixed a bug in the parsing of XKB key type definitions where the number
|
||||
of levels were determined by the number of level *names*. Keymaps which
|
||||
omit level names were hence miscompiled.
|
||||
|
||||
This regressed in version 0.4.3. Keymaps from xkeyboard-config were not
|
||||
affected since they don't omit level names.
|
||||
|
||||
- New API:
|
||||
xkb_keysym_to_upper()
|
||||
xkb_keysym_to_lower()
|
||||
|
||||
|
||||
libxkbcommon 0.7.2 - 2017-08-04
|
||||
==================
|
||||
|
||||
- Added a Meson build system as an alternative to existing autotools build
|
||||
system.
|
||||
|
||||
The intent is to remove the autotools build in one of the next releases.
|
||||
Please try to convert to it and report any problems.
|
||||
|
||||
See http://mesonbuild.com/Quick-guide.html for basic usage, the
|
||||
meson_options.txt for the project-specific configuration options,
|
||||
and the PACKAGING file for more details.
|
||||
|
||||
There are some noteworthy differences compared to the autotools build:
|
||||
|
||||
- Feature auto-detection is not performed. By default, all features are
|
||||
enabled (currently: docs, x11, wayland). The build fails if any of
|
||||
the required dependencies are not available. To disable a feature,
|
||||
pass -Denable-<feature>=false to meson.
|
||||
|
||||
- The libraries are either installed as shared or static, as specified
|
||||
by the -Ddefault_library=shared/static option. With autotools, both
|
||||
versions are installed by default.
|
||||
|
||||
- xorg-util-macros is not used.
|
||||
|
||||
- A parser generator (bison/byacc) is always required - there is no
|
||||
fallback to pre-generated output bundled in the tarball, as there is
|
||||
in autotools.
|
||||
|
||||
- Removed Android.mk support.
|
||||
|
||||
- Removed the *-uninstalled.pc pkgconfig files.
|
||||
|
||||
- Ported the interactive-wayland demo program to v6 of the xdg-shell
|
||||
protocol.
|
||||
|
||||
- Added new keysym definitions from xproto.
|
||||
|
||||
- New API:
|
||||
XKB_KEY_XF86Keyboard
|
||||
XKB_KEY_XF86WWAN
|
||||
XKB_KEY_XF86RFKill
|
||||
XKB_KEY_XF86AudioPreset
|
||||
|
||||
|
||||
libxkbcommon 0.7.1 - 2017-01-18
|
||||
==================
|
||||
|
||||
- Fixed various reported problems when the current locale is tr_TR.UTF-8.
|
||||
|
||||
The function xkb_keysym_from_name() used to perform case-insensitive
|
||||
string comparisons in a locale-dependent way, but required it to to
|
||||
work as in the C/ASCII locale (the so called "Turkish i problem").
|
||||
|
||||
The function is now no longer affected by the current locale.
|
||||
|
||||
- Fixed compilation in NetBSD.
|
||||
|
||||
|
||||
libxkbcommon 0.7.0 - 2016-11-11
|
||||
==================
|
||||
|
||||
- Added support for different "modes" of calculating consumed modifiers.
|
||||
The existing mode, based on the XKB standard, has proven to be
|
||||
unintuitive in various shortcut implementations.
|
||||
|
||||
A new mode, based on the calculation used by the GTK toolkit, is added.
|
||||
This mode is less eager to declare a modifier as consumed.
|
||||
|
||||
- Added a new interactive demo program using the Wayland protocol.
|
||||
See the PACKAGING file for the new (optional) test dependencies.
|
||||
|
||||
- Fixed a compilation error on GNU Hurd.
|
||||
|
||||
- New API:
|
||||
enum xkb_consumed_mode
|
||||
XKB_CONSUMED_MODE_XKB
|
||||
XKB_CONSUMED_MODE_GTK
|
||||
xkb_state_key_get_consumed_mods2
|
||||
xkb_state_mod_index_is_consumed2
|
||||
|
||||
|
||||
libxkbcommon 0.6.1 - 2016-04-08
|
||||
==================
|
||||
|
||||
- Added LICENSE to distributed files in tarball releases.
|
||||
|
||||
- Minor typo fix in xkb_keymap_get_as_string() documentation.
|
||||
|
||||
|
||||
libxkbcommon 0.6.0 - 2016-03-16
|
||||
==================
|
||||
|
||||
- If the XKB_CONFIG_ROOT environment variable is set, it is used as the XKB
|
||||
configuration root instead of the path determined at build time.
|
||||
|
||||
- Tests and benchmarks now build correctly on OSX.
|
||||
|
||||
- An XKB keymap provides a name for each key it defines. Traditionally,
|
||||
these names are limited to at most 4 characters, and are thus somewhat
|
||||
obscure, but might still be useful (xkbcommon lifts the 4 character limit).
|
||||
|
||||
The new functions xkb_keymap_key_get_name() and xkb_keymap_key_by_name()
|
||||
can be used to get the name of a key or find a key by name. Note that
|
||||
a key may have aliases.
|
||||
|
||||
- Documentation improvements.
|
||||
|
||||
- New API:
|
||||
xkb_keymap_key_by_name()
|
||||
xkb_keymap_key_get_name()
|
||||
|
||||
|
||||
libxkbcommon 0.5.0 - 2014-10-18
|
||||
==================
|
||||
|
||||
- Added support for Compose/dead keys in a new module (included in
|
||||
libxkbcommon). See the documentation or the
|
||||
xkbcommon/xkbcommon-compose.h header file for more details.
|
||||
|
||||
- Improved and reordered some sections of the documentation.
|
||||
|
||||
- The doxygen HTML pages were made nicer to read.
|
||||
|
||||
- Most tests now run also on non-linux platforms.
|
||||
|
||||
- A warning is emitted by default about RMLVO values which are not used
|
||||
during keymap compilation, which are most often a user misconfiguration.
|
||||
For example, "terminate:ctrl_alt_backspace" instead of
|
||||
"terminate:ctrl_alt_bksp".
|
||||
|
||||
- Added symbol versioning for libxkbcommon and libxkbcommon-x11.
|
||||
Note: binaries compiled against this and future versions will not be
|
||||
able to link against the previous versions of the library.
|
||||
|
||||
- Removed several compatablity symbols from the binary (the API isn't
|
||||
affected). This affects binaries which
|
||||
|
||||
1. Were compiled against a pre-stable (<0.2.0) version of libxkbcommon, and
|
||||
2. Are linked against the this or later version of libxkbcommon.
|
||||
|
||||
Such a scenario is likely to fail already.
|
||||
|
||||
- If Xvfb is not available, the x11comp test is now correctly skipped
|
||||
instead of hanging.
|
||||
|
||||
- Benchmarks were moved to a separate bench/ directory.
|
||||
|
||||
- Build fixes from OpenBSD.
|
||||
|
||||
- Fixed a bug where key type entries such as "map[None] = Level2;" were
|
||||
ignored.
|
||||
|
||||
- New API:
|
||||
XKB_COMPOSE_*
|
||||
xkb_compose_*
|
||||
|
||||
|
||||
libxkbcommon 0.4.3 - 2014-08-19
|
||||
==================
|
||||
|
||||
- Fixed a bug which caused xkb_x11_keymap_new_from_device() to misrepresent
|
||||
modifiers for some keymaps.
|
||||
|
||||
https://github.com/xkbcommon/libxkbcommon/issues/9
|
||||
|
||||
- Fixed a bug which caused xkb_x11_keymap_new_from_device() to ignore XKB
|
||||
PrivateAction's.
|
||||
|
||||
- Modifiers are now always fully resolved after xkb_state_update_mask().
|
||||
Previously the given state components were used as-is, without
|
||||
considering virtual modifier mappings.
|
||||
Note: this only affects non-standard uses of xkb_state_update_mask().
|
||||
|
||||
- Added a test for xkbcommon-x11, "x11comp". The test uses the system's
|
||||
Xvfb server and xkbcomp. If they do not exist or fail, the test is
|
||||
skipped.
|
||||
|
||||
- Fixed memory leaks after parse errors in the XKB yacc parser.
|
||||
The fix required changes which are currently incompatible with byacc.
|
||||
|
||||
|
||||
libxkbcommon 0.4.2 - 2014-05-15
|
||||
==================
|
||||
|
||||
- Fixed a bug where explicitly passing "--enable-x11" to ./configure would
|
||||
in fact disable it (regressed in 0.4.1).
|
||||
|
||||
- Added @since version annotations to the API documentation for everything
|
||||
introduced after the initial stable release (0.2.0).
|
||||
|
||||
- Added a section to the documentation about keysym transformations, and
|
||||
clarified which functions perform a given transformation.
|
||||
|
||||
- XKB files which fail to compile during keymap construction can no longer
|
||||
have any effect on the resulting keymap: changes are only applied when
|
||||
the entire compilation succeeds.
|
||||
Note: this was a minor correctness issue inherited from xkbcomp.
|
||||
|
||||
- Fix an out-of-bounds array access in src/x11/util.c:adopt_atoms()
|
||||
error-handling code.
|
||||
Note: it seems impossible to trigger in the current code since the input
|
||||
size cannot exceed the required size.
|
||||
|
||||
|
||||
libxkbcommon 0.4.1 - 2014-03-27
|
||||
==================
|
||||
|
||||
- Converted README to markdown and added a Quick Guide to the
|
||||
documentation, which breezes through the most common parts of
|
||||
xkbcommon.
|
||||
|
||||
- Added two new functions, xkb_state_key_get_utf{8,32}(). They
|
||||
combine the operations of xkb_state_key_get_syms() and
|
||||
xkb_keysym_to_utf{8,32}(), and provide a nicer interface for it
|
||||
(espcially for multiple-keysyms-per-level).
|
||||
|
||||
- The xkb_state_key_get_utf{8,32}() functions now apply Control
|
||||
transformation: when the Control modifier is active, the string
|
||||
is converted to an appropriate control character.
|
||||
This matches the behavior of libX11's XLookupString(3), and
|
||||
required by the XKB specification:
|
||||
https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
|
||||
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=75892
|
||||
|
||||
- The consumed modifiers for a key are now calculated similarly
|
||||
to libX11. The previous behavior caused a bug where Shift would
|
||||
not cancel an active Caps Lock.
|
||||
|
||||
- Make xkbcommon-x11 work with the keymap reported by the XQuartz
|
||||
X server.
|
||||
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=75798
|
||||
|
||||
- Reduce memory usage during keymap compilation some more.
|
||||
|
||||
- New API:
|
||||
xkb_state_key_get_consumed_mods()
|
||||
xkb_state_key_get_utf8()
|
||||
xkb_state_key_get_utf32()
|
||||
|
||||
- Deprecated API:
|
||||
XKB_MAP_COMPILE_PLACEHOLDER, XKB_MAP_NO_FLAGS
|
||||
use XKB_KEYMAP_NO_FLAGS instead.
|
||||
|
||||
- Bug fixes.
|
||||
|
||||
|
||||
libxkbcommon 0.4.0 - 2014-02-02
|
||||
==================
|
||||
|
||||
- Add a new add-on library, xkbcommon-x11, to support creating keymaps
|
||||
with the XKB X11 protocol, by querying the X server directly.
|
||||
See the xkbcommon/xkbcommon-x11.h header file for more details.
|
||||
This library requires libxcb-xkb >= 1.10, and is enabled by default.
|
||||
It can be disabled with the --disable-x11 configure switch.
|
||||
Distributions are encouraged to split the necessary files for this
|
||||
library (libxkbcommon-x11.so, xkbcommon-x11.pc, xkbcommon/xkbcommon-x11.h)
|
||||
to a separate package, such that the main package does not depend on
|
||||
X11 libraries.
|
||||
|
||||
- Fix the keysym <-> name lookup table to not require huge amounts of
|
||||
relocations.
|
||||
|
||||
- Fix a bug in the keysym <-> name lookup, whereby lookup might fail in
|
||||
some rare cases.
|
||||
|
||||
- Reduce memory usage during keymap compilation.
|
||||
|
||||
- New API:
|
||||
New keysyms from xproto 7.0.25 (German T3 layout keysyms).
|
||||
XKB_MOD_NAME_NUM for the usual NumLock modifier.
|
||||
xkb_x11_* types and functions, XKB_X11_* constants.
|
||||
|
||||
|
||||
libxkbcommon 0.3.2 - 2013-11-22
|
||||
==================
|
||||
|
||||
- Log messages from the library now look like "xkbcommon: ERROR" by
|
||||
default, instead of xkbcomp-like "Error: ".
|
||||
|
||||
- Apply capitalization transformation on keysyms in
|
||||
xkb_keysym_get_one_sym(), to match the behavior specified in the XKB
|
||||
specification:
|
||||
https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
|
||||
|
||||
- Support byacc for generating the parser, in addition to Bison.
|
||||
|
||||
- New API:
|
||||
XKB_KEY_XF86AudioMicMute keysym from xproto 7.0.24.
|
||||
XKB_KEYSYM_NO_FLAGS
|
||||
XKB_CONTEXT_NO_FLAGS
|
||||
XKB_MAP_COMPILE_NO_FLAGS
|
||||
|
||||
- Bug fixes.
|
||||
|
||||
|
||||
libxkbcommon 0.3.1 - 2013-06-03
|
||||
==================
|
||||
|
||||
- Replace the flex scanner with a hand-written one. flex is no longer
|
||||
a build requirement.
|
||||
|
||||
- New API:
|
||||
xkb_keymap_min_keycode()
|
||||
xkb_keymap_max_keycode()
|
||||
xkb_keymap_key_for_each()
|
||||
|
||||
|
||||
libxkbcommon 0.3.0 - 2013-04-01
|
||||
==================
|
||||
|
||||
- Allow passing NULL to *_unref() functions; do nothing instead of
|
||||
crashing.
|
||||
|
||||
- The functions xkb_keymap_num_levels_for_key() and
|
||||
xkb_keymap_get_syms_by_level() now allow out-of-range values for the
|
||||
'layout' parameter. The functions now wrap the value around the number
|
||||
of layouts instead of failing.
|
||||
|
||||
- The function xkb_keysym_get_name() now types unicode keysyms in
|
||||
uppercase and 0-padding, to match the format used by XKeysymToString().
|
||||
|
||||
- Building Linux-specific tests is no longer attempted on non-Linux
|
||||
environments.
|
||||
|
||||
- The function xkb_keymap_new_from_names() now accepts a NULL value for
|
||||
the 'names' parameter, instead of failing. This is equivalent to passing
|
||||
a 'struct xkb_rule_names' with all fields set to NULL.
|
||||
|
||||
- New API:
|
||||
xkb_keymap_new_from_buffer()
|
||||
|
||||
- Bug fixes.
|
75
src/3rdparty/xkbcommon/README.md
vendored
75
src/3rdparty/xkbcommon/README.md
vendored
@ -1,75 +0,0 @@
|
||||
# libxkbcommon
|
||||
|
||||
libxkbcommon is a keyboard keymap compiler and support library which
|
||||
processes a reduced subset of keymaps as defined by the XKB (X Keyboard
|
||||
Extension) specification. It also contains a module for handling Compose
|
||||
and dead keys.
|
||||
|
||||
## Quick Guide
|
||||
|
||||
See [Quick Guide](doc/quick-guide.md).
|
||||
|
||||
## Building
|
||||
|
||||
libxkbcommon is built with [Meson](http://mesonbuild.com/):
|
||||
|
||||
meson setup build
|
||||
ninja -C build
|
||||
|
||||
To build for use with Wayland, you can disable X11 support while still
|
||||
using the X11 keyboard configuration resource files thusly:
|
||||
|
||||
meson setup build \
|
||||
-Denable-x11=false \
|
||||
-Dxkb-config-root=/usr/share/X11/xkb \
|
||||
-Dx-locale-root=/usr/share/X11/locale
|
||||
ninja -C build
|
||||
|
||||
## API
|
||||
|
||||
While libxkbcommon's API is somewhat derived from the classic XKB API as found
|
||||
in X11/extensions/XKB.h and friends, it has been substantially reworked to
|
||||
expose fewer internal details to clients.
|
||||
|
||||
See the [API Documentation](https://xkbcommon.org/doc/current/modules.html).
|
||||
|
||||
## Dataset
|
||||
|
||||
libxkbcommon does not distribute a keymap dataset itself, other than for
|
||||
testing purposes. The most common dataset is xkeyboard-config, which is used
|
||||
by all current distributions for their X11 XKB data. More information on
|
||||
xkeyboard-config is available here:
|
||||
https://www.freedesktop.org/wiki/Software/XKeyboardConfig
|
||||
|
||||
The dataset for Compose is distributed in libX11, as part of the X locale
|
||||
data.
|
||||
|
||||
## Relation to X11
|
||||
|
||||
See [Compatibility](doc/compat.md) notes.
|
||||
|
||||
## Development
|
||||
|
||||
An extremely rudimentary homepage can be found at
|
||||
https://xkbcommon.org
|
||||
|
||||
xkbcommon is maintained in git at
|
||||
https://github.com/xkbcommon/libxkbcommon
|
||||
|
||||
Patches are always welcome, and may be sent to either
|
||||
<xorg-devel@lists.x.org> or <wayland-devel@lists.freedesktop.org>
|
||||
or through github.
|
||||
|
||||
Bug reports are also welcome, and may be filed either at
|
||||
Bugzilla https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon
|
||||
or
|
||||
Github https://github.com/xkbcommon/libxkbcommon/issues
|
||||
|
||||
The maintainers are
|
||||
- Daniel Stone <daniel@fooishbar.org>
|
||||
- Ran Benita <ran234@gmail.com>
|
||||
|
||||
## Credits
|
||||
|
||||
Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon
|
||||
off the ground initially.
|
29
src/3rdparty/xkbcommon/qt_attribution.json
vendored
29
src/3rdparty/xkbcommon/qt_attribution.json
vendored
@ -1,29 +0,0 @@
|
||||
{
|
||||
"Id": "xkbcommon",
|
||||
"Name": "xkbcommon",
|
||||
"QDocModule": "qtgui",
|
||||
"QtUsage": "Used in xcb platform plugin. Configure with -system-xkbcommon-x11 to avoid.",
|
||||
|
||||
"Description": "xkbcommon is a keymap compiler and support library which processes a reduced subset of keymaps as defined by the XKB specification.",
|
||||
"Homepage": "http://xkbcommon.org/",
|
||||
"Version": "0.8.2 + subsequent commits up to 31f1f355700870c6615399fbfa7934934b3a9a57",
|
||||
"License": "MIT Licenses (with no-advertisement clause)",
|
||||
"LicenseId": "MIT",
|
||||
"LicenseFile": "LICENSE",
|
||||
"Copyright": "Copyright 2009-2012, 2016 Daniel Stone
|
||||
Copyright 2012 Ran Benita <ran234@gmail.com>
|
||||
Copyright 2010, 2012 Intel Corporation
|
||||
Copyright 2008, 2009 Dan Nicholson
|
||||
Copyright 2010 Francisco Jerez <currojerez@riseup.net>
|
||||
Copyright 1985, 1987, 1988, 1990, 1998 The Open Group
|
||||
Copyright 1993, 1994, 1995, 1996 by Silicon Graphics Computer Systems, Inc.
|
||||
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
Copyright 2011 Joseph Adams <joeyadams3.14159@gmail.com>
|
||||
Copyright 1996 by Joseph Moss
|
||||
Copyright 2002-2007 Free Software Foundation, Inc.
|
||||
Copyright 2003-2004 Dmitry Golubev <lastguru@mail.ru>
|
||||
Copyright 2004, Gregory Mokhin <mokhin@bog.msu.ru>
|
||||
Copyright 2006 Erdal Ronahî
|
||||
Copyright 1992 by Oki Technosystems Laboratory, Inc.
|
||||
Copyright 1992 by Fuji Xerox Co., Ltd."
|
||||
}
|
225
src/3rdparty/xkbcommon/src/atom.c
vendored
225
src/3rdparty/xkbcommon/src/atom.c
vendored
@ -1,225 +0,0 @@
|
||||
/***********************************************************
|
||||
* Copyright 1987, 1998 The Open Group
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of The Open Group shall not be
|
||||
* used in advertising or otherwise to promote the sale, use or other dealings
|
||||
* in this Software without prior written authorization from The Open Group.
|
||||
*
|
||||
*
|
||||
* Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and that
|
||||
* both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of Digital not be
|
||||
* used in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
*
|
||||
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
* DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
/************************************************************
|
||||
* Copyright 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#include "utils.h"
|
||||
#include "atom.h"
|
||||
|
||||
struct atom_node {
|
||||
xkb_atom_t left, right;
|
||||
xkb_atom_t atom;
|
||||
unsigned int fingerprint;
|
||||
char *string;
|
||||
};
|
||||
|
||||
struct atom_table {
|
||||
xkb_atom_t root;
|
||||
darray(struct atom_node) table;
|
||||
};
|
||||
|
||||
struct atom_table *
|
||||
atom_table_new(void)
|
||||
{
|
||||
struct atom_table *table;
|
||||
|
||||
table = calloc(1, sizeof(*table));
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
darray_init(table->table);
|
||||
/* The original throw-away root is here, at the illegal atom 0. */
|
||||
darray_resize0(table->table, 1);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
void
|
||||
atom_table_free(struct atom_table *table)
|
||||
{
|
||||
struct atom_node *node;
|
||||
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
darray_foreach(node, table->table)
|
||||
free(node->string);
|
||||
darray_free(table->table);
|
||||
free(table);
|
||||
}
|
||||
|
||||
const char *
|
||||
atom_text(struct atom_table *table, xkb_atom_t atom)
|
||||
{
|
||||
if (atom == XKB_ATOM_NONE || atom >= darray_size(table->table))
|
||||
return NULL;
|
||||
|
||||
return darray_item(table->table, atom).string;
|
||||
}
|
||||
|
||||
static bool
|
||||
find_atom_pointer(struct atom_table *table, const char *string, size_t len,
|
||||
xkb_atom_t **atomp_out, unsigned int *fingerprint_out)
|
||||
{
|
||||
xkb_atom_t *atomp = &table->root;
|
||||
unsigned int fingerprint = 0;
|
||||
bool found = false;
|
||||
|
||||
for (size_t i = 0; i < (len + 1) / 2; i++) {
|
||||
fingerprint = fingerprint * 27 + string[i];
|
||||
fingerprint = fingerprint * 27 + string[len - 1 - i];
|
||||
}
|
||||
|
||||
while (*atomp != XKB_ATOM_NONE) {
|
||||
struct atom_node *node = &darray_item(table->table, *atomp);
|
||||
|
||||
if (fingerprint < node->fingerprint) {
|
||||
atomp = &node->left;
|
||||
}
|
||||
else if (fingerprint > node->fingerprint) {
|
||||
atomp = &node->right;
|
||||
}
|
||||
else {
|
||||
/* Now start testing the strings. */
|
||||
const int cmp = strncmp(string, node->string, len);
|
||||
if (cmp < 0 || (cmp == 0 && len < strlen(node->string))) {
|
||||
atomp = &node->left;
|
||||
}
|
||||
else if (cmp > 0) {
|
||||
atomp = &node->right;
|
||||
}
|
||||
else {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fingerprint_out)
|
||||
*fingerprint_out = fingerprint;
|
||||
if (atomp_out)
|
||||
*atomp_out = atomp;
|
||||
return found;
|
||||
}
|
||||
|
||||
xkb_atom_t
|
||||
atom_lookup(struct atom_table *table, const char *string, size_t len)
|
||||
{
|
||||
xkb_atom_t *atomp;
|
||||
|
||||
if (!string)
|
||||
return XKB_ATOM_NONE;
|
||||
|
||||
if (!find_atom_pointer(table, string, len, &atomp, NULL))
|
||||
return XKB_ATOM_NONE;
|
||||
|
||||
return *atomp;
|
||||
}
|
||||
|
||||
/*
|
||||
* If steal is true, we do not strdup @string; therefore it must be
|
||||
* dynamically allocated, NUL-terminated, not be free'd by the caller
|
||||
* and not be used afterwards. Use to avoid some redundant allocations.
|
||||
*/
|
||||
xkb_atom_t
|
||||
atom_intern(struct atom_table *table, const char *string, size_t len,
|
||||
bool steal)
|
||||
{
|
||||
xkb_atom_t *atomp;
|
||||
struct atom_node node;
|
||||
unsigned int fingerprint;
|
||||
|
||||
if (!string)
|
||||
return XKB_ATOM_NONE;
|
||||
|
||||
if (find_atom_pointer(table, string, len, &atomp, &fingerprint)) {
|
||||
if (steal)
|
||||
free(UNCONSTIFY(string));
|
||||
return *atomp;
|
||||
}
|
||||
|
||||
if (steal) {
|
||||
node.string = UNCONSTIFY(string);
|
||||
}
|
||||
else {
|
||||
node.string = strndup(string, len);
|
||||
if (!node.string)
|
||||
return XKB_ATOM_NONE;
|
||||
}
|
||||
|
||||
node.left = node.right = XKB_ATOM_NONE;
|
||||
node.fingerprint = fingerprint;
|
||||
node.atom = darray_size(table->table);
|
||||
/* Do this before the append, as it may realloc and change the offsets. */
|
||||
*atomp = node.atom;
|
||||
darray_append(table->table, node);
|
||||
|
||||
return node.atom;
|
||||
}
|
49
src/3rdparty/xkbcommon/src/atom.h
vendored
49
src/3rdparty/xkbcommon/src/atom.h
vendored
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 Dan Nicholson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ATOM_H
|
||||
#define ATOM_H
|
||||
|
||||
typedef uint32_t xkb_atom_t;
|
||||
|
||||
#define XKB_ATOM_NONE 0
|
||||
|
||||
struct atom_table;
|
||||
|
||||
struct atom_table *
|
||||
atom_table_new(void);
|
||||
|
||||
void
|
||||
atom_table_free(struct atom_table *table);
|
||||
|
||||
xkb_atom_t
|
||||
atom_lookup(struct atom_table *table, const char *string, size_t len);
|
||||
|
||||
xkb_atom_t
|
||||
atom_intern(struct atom_table *table, const char *string, size_t len,
|
||||
bool steal);
|
||||
|
||||
const char *
|
||||
atom_text(struct atom_table *table, xkb_atom_t atom);
|
||||
|
||||
#endif /* ATOM_H */
|
196
src/3rdparty/xkbcommon/src/compose/compose-state.c
vendored
196
src/3rdparty/xkbcommon/src/compose/compose-state.c
vendored
@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "table.h"
|
||||
#include "utils.h"
|
||||
#include "keysym.h"
|
||||
|
||||
struct xkb_compose_state {
|
||||
int refcnt;
|
||||
enum xkb_compose_state_flags flags;
|
||||
struct xkb_compose_table *table;
|
||||
|
||||
/*
|
||||
* Offsets into xkb_compose_table::nodes.
|
||||
*
|
||||
* They maintain the current and previous position in the trie; see
|
||||
* xkb_compose_state_feed().
|
||||
*
|
||||
* This is also sufficient for inferring the current status; see
|
||||
* xkb_compose_state_get_status().
|
||||
*/
|
||||
uint32_t prev_context;
|
||||
uint32_t context;
|
||||
};
|
||||
|
||||
XKB_EXPORT struct xkb_compose_state *
|
||||
xkb_compose_state_new(struct xkb_compose_table *table,
|
||||
enum xkb_compose_state_flags flags)
|
||||
{
|
||||
struct xkb_compose_state *state;
|
||||
|
||||
state = calloc(1, sizeof(*state));
|
||||
if (!state)
|
||||
return NULL;
|
||||
|
||||
state->refcnt = 1;
|
||||
state->table = xkb_compose_table_ref(table);
|
||||
|
||||
state->flags = flags;
|
||||
state->prev_context = 0;
|
||||
state->context = 0;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_compose_state *
|
||||
xkb_compose_state_ref(struct xkb_compose_state *state)
|
||||
{
|
||||
state->refcnt++;
|
||||
return state;
|
||||
}
|
||||
|
||||
XKB_EXPORT void
|
||||
xkb_compose_state_unref(struct xkb_compose_state *state)
|
||||
{
|
||||
if (!state || --state->refcnt > 0)
|
||||
return;
|
||||
|
||||
xkb_compose_table_unref(state->table);
|
||||
free(state);
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_compose_table *
|
||||
xkb_compose_state_get_compose_table(struct xkb_compose_state *state)
|
||||
{
|
||||
return state->table;
|
||||
}
|
||||
|
||||
XKB_EXPORT enum xkb_compose_feed_result
|
||||
xkb_compose_state_feed(struct xkb_compose_state *state, xkb_keysym_t keysym)
|
||||
{
|
||||
uint32_t context;
|
||||
const struct compose_node *node;
|
||||
|
||||
/*
|
||||
* Modifiers do not affect the sequence directly. In particular,
|
||||
* they do not cancel a sequence; otherwise it'd be impossible to
|
||||
* have a sequence like <dead_acute><A> (needs Shift in the middle).
|
||||
*
|
||||
* The following test is not really accurate - in order to test if
|
||||
* a key is "modifier key", we really need the keymap, but we don't
|
||||
* have it here. However, this is (approximately) what libX11 does
|
||||
* as well.
|
||||
*/
|
||||
if (xkb_keysym_is_modifier(keysym))
|
||||
return XKB_COMPOSE_FEED_IGNORED;
|
||||
|
||||
node = &darray_item(state->table->nodes, state->context);
|
||||
|
||||
context = (node->is_leaf ? 0 : node->u.successor);
|
||||
node = &darray_item(state->table->nodes, context);
|
||||
|
||||
while (node->keysym != keysym && node->next != 0) {
|
||||
context = node->next;
|
||||
node = &darray_item(state->table->nodes, context);
|
||||
}
|
||||
|
||||
if (node->keysym != keysym)
|
||||
context = 0;
|
||||
|
||||
state->prev_context = state->context;
|
||||
state->context = context;
|
||||
return XKB_COMPOSE_FEED_ACCEPTED;
|
||||
}
|
||||
|
||||
XKB_EXPORT void
|
||||
xkb_compose_state_reset(struct xkb_compose_state *state)
|
||||
{
|
||||
state->prev_context = 0;
|
||||
state->context = 0;
|
||||
}
|
||||
|
||||
XKB_EXPORT enum xkb_compose_status
|
||||
xkb_compose_state_get_status(struct xkb_compose_state *state)
|
||||
{
|
||||
const struct compose_node *prev_node, *node;
|
||||
|
||||
prev_node = &darray_item(state->table->nodes, state->prev_context);
|
||||
node = &darray_item(state->table->nodes, state->context);
|
||||
|
||||
if (state->context == 0 && !prev_node->is_leaf)
|
||||
return XKB_COMPOSE_CANCELLED;
|
||||
|
||||
if (state->context == 0)
|
||||
return XKB_COMPOSE_NOTHING;
|
||||
|
||||
if (!node->is_leaf)
|
||||
return XKB_COMPOSE_COMPOSING;
|
||||
|
||||
return XKB_COMPOSE_COMPOSED;
|
||||
}
|
||||
|
||||
XKB_EXPORT int
|
||||
xkb_compose_state_get_utf8(struct xkb_compose_state *state,
|
||||
char *buffer, size_t size)
|
||||
{
|
||||
const struct compose_node *node =
|
||||
&darray_item(state->table->nodes, state->context);
|
||||
|
||||
if (!node->is_leaf)
|
||||
goto fail;
|
||||
|
||||
/* If there's no string specified, but only a keysym, try to do the
|
||||
* most helpful thing. */
|
||||
if (node->u.leaf.utf8 == 0 && node->u.leaf.keysym != XKB_KEY_NoSymbol) {
|
||||
char name[64];
|
||||
int ret;
|
||||
|
||||
ret = xkb_keysym_to_utf8(node->u.leaf.keysym, name, sizeof(name));
|
||||
if (ret < 0 || ret == 0) {
|
||||
/* ret < 0 is impossible.
|
||||
* ret == 0 means the keysym has no string representation. */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return snprintf(buffer, size, "%s", name);
|
||||
}
|
||||
|
||||
return snprintf(buffer, size, "%s",
|
||||
&darray_item(state->table->utf8, node->u.leaf.utf8));
|
||||
|
||||
fail:
|
||||
if (size > 0)
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keysym_t
|
||||
xkb_compose_state_get_one_sym(struct xkb_compose_state *state)
|
||||
{
|
||||
const struct compose_node *node =
|
||||
&darray_item(state->table->nodes, state->context);
|
||||
if (!node->is_leaf)
|
||||
return XKB_KEY_NoSymbol;
|
||||
return node->u.leaf.keysym;
|
||||
}
|
737
src/3rdparty/xkbcommon/src/compose/parser.c
vendored
737
src/3rdparty/xkbcommon/src/compose/parser.c
vendored
@ -1,737 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/******************************************************************
|
||||
|
||||
Copyright 1992 by Oki Technosystems Laboratory, Inc.
|
||||
Copyright 1992 by Fuji Xerox Co., Ltd.
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software
|
||||
and its documentation for any purpose is hereby granted without fee,
|
||||
provided that the above copyright notice appear in all copies and
|
||||
that both that copyright notice and this permission notice appear
|
||||
in supporting documentation, and that the name of Oki Technosystems
|
||||
Laboratory and Fuji Xerox not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific, written
|
||||
prior permission.
|
||||
Oki Technosystems Laboratory and Fuji Xerox make no representations
|
||||
about the suitability of this software for any purpose. It is provided
|
||||
"as is" without express or implied warranty.
|
||||
|
||||
OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS
|
||||
LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||
OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
Author: Yasuhiro Kawai Oki Technosystems Laboratory
|
||||
Author: Kazunori Nishihara Fuji Xerox
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "scanner-utils.h"
|
||||
#include "table.h"
|
||||
#include "paths.h"
|
||||
#include "utf8.h"
|
||||
#include "parser.h"
|
||||
|
||||
#define MAX_LHS_LEN 10
|
||||
#define MAX_INCLUDE_DEPTH 5
|
||||
|
||||
/*
|
||||
* Grammar adapted from libX11/modules/im/ximcp/imLcPrs.c.
|
||||
* See also the XCompose(5) manpage.
|
||||
*
|
||||
* FILE ::= { [PRODUCTION] [COMMENT] "\n" | INCLUDE }
|
||||
* INCLUDE ::= "include" '"' INCLUDE_STRING '"'
|
||||
* PRODUCTION ::= LHS ":" RHS [ COMMENT ]
|
||||
* COMMENT ::= "#" {<any character except null or newline>}
|
||||
* LHS ::= EVENT { EVENT }
|
||||
* EVENT ::= [MODIFIER_LIST] "<" keysym ">"
|
||||
* MODIFIER_LIST ::= (["!"] {MODIFIER} ) | "None"
|
||||
* MODIFIER ::= ["~"] MODIFIER_NAME
|
||||
* MODIFIER_NAME ::= ("Ctrl"|"Lock"|"Caps"|"Shift"|"Alt"|"Meta")
|
||||
* RHS ::= ( STRING | keysym | STRING keysym )
|
||||
* STRING ::= '"' { CHAR } '"'
|
||||
* CHAR ::= GRAPHIC_CHAR | ESCAPED_CHAR
|
||||
* GRAPHIC_CHAR ::= locale (codeset) dependent code
|
||||
* ESCAPED_CHAR ::= ('\\' | '\"' | OCTAL | HEX )
|
||||
* OCTAL ::= '\' OCTAL_CHAR [OCTAL_CHAR [OCTAL_CHAR]]
|
||||
* OCTAL_CHAR ::= (0|1|2|3|4|5|6|7)
|
||||
* HEX ::= '\' (x|X) HEX_CHAR [HEX_CHAR]]
|
||||
* HEX_CHAR ::= (0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|a|b|c|d|e|f)
|
||||
*
|
||||
* INCLUDE_STRING is a filesystem path, with the following %-expansions:
|
||||
* %% - '%'.
|
||||
* %H - The user's home directory (the $HOME environment variable).
|
||||
* %L - The name of the locale specific Compose file (e.g.,
|
||||
* "/usr/share/X11/locale/<localename>/Compose").
|
||||
* %S - The name of the system directory for Compose files (e.g.,
|
||||
* "/usr/share/X11/locale").
|
||||
*/
|
||||
|
||||
enum rules_token {
|
||||
TOK_END_OF_FILE = 0,
|
||||
TOK_END_OF_LINE,
|
||||
TOK_INCLUDE,
|
||||
TOK_INCLUDE_STRING,
|
||||
TOK_LHS_KEYSYM,
|
||||
TOK_COLON,
|
||||
TOK_BANG,
|
||||
TOK_TILDE,
|
||||
TOK_STRING,
|
||||
TOK_IDENT,
|
||||
TOK_ERROR
|
||||
};
|
||||
|
||||
/* Values returned with some tokens, like yylval. */
|
||||
union lvalue {
|
||||
struct {
|
||||
/* Still \0-terminated. */
|
||||
const char *str;
|
||||
size_t len;
|
||||
} string;
|
||||
};
|
||||
|
||||
static enum rules_token
|
||||
lex(struct scanner *s, union lvalue *val)
|
||||
{
|
||||
skip_more_whitespace_and_comments:
|
||||
/* Skip spaces. */
|
||||
while (is_space(peek(s)))
|
||||
if (next(s) == '\n')
|
||||
return TOK_END_OF_LINE;
|
||||
|
||||
/* Skip comments. */
|
||||
if (chr(s, '#')) {
|
||||
skip_to_eol(s);
|
||||
goto skip_more_whitespace_and_comments;
|
||||
}
|
||||
|
||||
/* See if we're done. */
|
||||
if (eof(s)) return TOK_END_OF_FILE;
|
||||
|
||||
/* New token. */
|
||||
s->token_line = s->line;
|
||||
s->token_column = s->column;
|
||||
s->buf_pos = 0;
|
||||
|
||||
/* LHS Keysym. */
|
||||
if (chr(s, '<')) {
|
||||
while (peek(s) != '>' && !eol(s) && !eof(s))
|
||||
buf_append(s, next(s));
|
||||
if (!chr(s, '>')) {
|
||||
scanner_err(s, "unterminated keysym literal");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
if (!buf_append(s, '\0')) {
|
||||
scanner_err(s, "keysym literal is too long");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
val->string.str = s->buf;
|
||||
val->string.len = s->buf_pos;
|
||||
return TOK_LHS_KEYSYM;
|
||||
}
|
||||
|
||||
/* Colon. */
|
||||
if (chr(s, ':'))
|
||||
return TOK_COLON;
|
||||
if (chr(s, '!'))
|
||||
return TOK_BANG;
|
||||
if (chr(s, '~'))
|
||||
return TOK_TILDE;
|
||||
|
||||
/* String literal. */
|
||||
if (chr(s, '\"')) {
|
||||
while (!eof(s) && !eol(s) && peek(s) != '\"') {
|
||||
if (chr(s, '\\')) {
|
||||
uint8_t o;
|
||||
if (chr(s, '\\')) {
|
||||
buf_append(s, '\\');
|
||||
}
|
||||
else if (chr(s, '"')) {
|
||||
buf_append(s, '"');
|
||||
}
|
||||
else if (chr(s, 'x') || chr(s, 'X')) {
|
||||
if (hex(s, &o))
|
||||
buf_append(s, (char) o);
|
||||
else
|
||||
scanner_warn(s, "illegal hexadecimal escape sequence in string literal");
|
||||
}
|
||||
else if (oct(s, &o)) {
|
||||
buf_append(s, (char) o);
|
||||
}
|
||||
else {
|
||||
scanner_warn(s, "unknown escape sequence (%c) in string literal", peek(s));
|
||||
/* Ignore. */
|
||||
}
|
||||
} else {
|
||||
buf_append(s, next(s));
|
||||
}
|
||||
}
|
||||
if (!chr(s, '\"')) {
|
||||
scanner_err(s, "unterminated string literal");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
if (!buf_append(s, '\0')) {
|
||||
scanner_err(s, "string literal is too long");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
if (!is_valid_utf8(s->buf, s->buf_pos - 1)) {
|
||||
scanner_err(s, "string literal is not a valid UTF-8 string");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
val->string.str = s->buf;
|
||||
val->string.len = s->buf_pos;
|
||||
return TOK_STRING;
|
||||
}
|
||||
|
||||
/* Identifier or include. */
|
||||
if (is_alpha(peek(s)) || peek(s) == '_') {
|
||||
s->buf_pos = 0;
|
||||
while (is_alnum(peek(s)) || peek(s) == '_')
|
||||
buf_append(s, next(s));
|
||||
if (!buf_append(s, '\0')) {
|
||||
scanner_err(s, "identifier is too long");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
|
||||
if (streq(s->buf, "include"))
|
||||
return TOK_INCLUDE;
|
||||
|
||||
val->string.str = s->buf;
|
||||
val->string.len = s->buf_pos;
|
||||
return TOK_IDENT;
|
||||
}
|
||||
|
||||
/* Discard rest of line. */
|
||||
skip_to_eol(s);
|
||||
|
||||
scanner_err(s, "unrecognized token");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
|
||||
static enum rules_token
|
||||
lex_include_string(struct scanner *s, struct xkb_compose_table *table,
|
||||
union lvalue *val_out)
|
||||
{
|
||||
while (is_space(peek(s)))
|
||||
if (next(s) == '\n')
|
||||
return TOK_END_OF_LINE;
|
||||
|
||||
s->token_line = s->line;
|
||||
s->token_column = s->column;
|
||||
s->buf_pos = 0;
|
||||
|
||||
if (!chr(s, '\"')) {
|
||||
scanner_err(s, "include statement must be followed by a path");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
|
||||
while (!eof(s) && !eol(s) && peek(s) != '\"') {
|
||||
if (chr(s, '%')) {
|
||||
if (chr(s, '%')) {
|
||||
buf_append(s, '%');
|
||||
}
|
||||
else if (chr(s, 'H')) {
|
||||
const char *home = secure_getenv("HOME");
|
||||
if (!home) {
|
||||
scanner_err(s, "%%H was used in an include statement, but the HOME environment variable is not set");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
if (!buf_appends(s, home)) {
|
||||
scanner_err(s, "include path after expanding %%H is too long");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
}
|
||||
else if (chr(s, 'L')) {
|
||||
char *path = get_locale_compose_file_path(table->locale);
|
||||
if (!path) {
|
||||
scanner_err(s, "failed to expand %%L to the locale Compose file");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
if (!buf_appends(s, path)) {
|
||||
free(path);
|
||||
scanner_err(s, "include path after expanding %%L is too long");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
else if (chr(s, 'S')) {
|
||||
const char *xlocaledir = get_xlocaledir_path();
|
||||
if (!buf_appends(s, xlocaledir)) {
|
||||
scanner_err(s, "include path after expanding %%S is too long");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
scanner_err(s, "unknown %% format (%c) in include statement", peek(s));
|
||||
return TOK_ERROR;
|
||||
}
|
||||
} else {
|
||||
buf_append(s, next(s));
|
||||
}
|
||||
}
|
||||
if (!chr(s, '\"')) {
|
||||
scanner_err(s, "unterminated include statement");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
if (!buf_append(s, '\0')) {
|
||||
scanner_err(s, "include path is too long");
|
||||
return TOK_ERROR;
|
||||
}
|
||||
val_out->string.str = s->buf;
|
||||
val_out->string.len = s->buf_pos;
|
||||
return TOK_INCLUDE_STRING;
|
||||
}
|
||||
|
||||
struct production {
|
||||
xkb_keysym_t lhs[MAX_LHS_LEN];
|
||||
unsigned int len;
|
||||
xkb_keysym_t keysym;
|
||||
char string[256];
|
||||
/* At least one of these is true. */
|
||||
bool has_keysym;
|
||||
bool has_string;
|
||||
|
||||
/* The matching is as follows: (active_mods & modmask) == mods. */
|
||||
xkb_mod_mask_t modmask;
|
||||
xkb_mod_mask_t mods;
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
add_node(struct xkb_compose_table *table, xkb_keysym_t keysym)
|
||||
{
|
||||
struct compose_node new = {
|
||||
.keysym = keysym,
|
||||
.next = 0,
|
||||
.is_leaf = true,
|
||||
};
|
||||
darray_append(table->nodes, new);
|
||||
return darray_size(table->nodes) - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
add_production(struct xkb_compose_table *table, struct scanner *s,
|
||||
const struct production *production)
|
||||
{
|
||||
unsigned lhs_pos;
|
||||
uint32_t curr;
|
||||
struct compose_node *node;
|
||||
|
||||
curr = 0;
|
||||
node = &darray_item(table->nodes, curr);
|
||||
|
||||
/*
|
||||
* Insert the sequence to the trie, creating new nodes as needed.
|
||||
*
|
||||
* TODO: This can be sped up a bit by first trying the path that the
|
||||
* previous production took, and only then doing the linear search
|
||||
* through the trie levels. This will work because sequences in the
|
||||
* Compose files are often clustered by a common prefix; especially
|
||||
* in the 1st and 2nd keysyms, which is where the largest variation
|
||||
* (thus, longest search) is.
|
||||
*/
|
||||
for (lhs_pos = 0; lhs_pos < production->len; lhs_pos++) {
|
||||
while (production->lhs[lhs_pos] != node->keysym) {
|
||||
if (node->next == 0) {
|
||||
uint32_t next = add_node(table, production->lhs[lhs_pos]);
|
||||
/* Refetch since add_node could have realloc()ed. */
|
||||
node = &darray_item(table->nodes, curr);
|
||||
node->next = next;
|
||||
}
|
||||
|
||||
curr = node->next;
|
||||
node = &darray_item(table->nodes, curr);
|
||||
}
|
||||
|
||||
if (lhs_pos + 1 == production->len)
|
||||
break;
|
||||
|
||||
if (node->is_leaf) {
|
||||
if (node->u.leaf.utf8 != 0 ||
|
||||
node->u.leaf.keysym != XKB_KEY_NoSymbol) {
|
||||
scanner_warn(s, "a sequence already exists which is a prefix of this sequence; overriding");
|
||||
node->u.leaf.utf8 = 0;
|
||||
node->u.leaf.keysym = XKB_KEY_NoSymbol;
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t successor = add_node(table, production->lhs[lhs_pos + 1]);
|
||||
/* Refetch since add_node could have realloc()ed. */
|
||||
node = &darray_item(table->nodes, curr);
|
||||
node->is_leaf = false;
|
||||
node->u.successor = successor;
|
||||
}
|
||||
}
|
||||
|
||||
curr = node->u.successor;
|
||||
node = &darray_item(table->nodes, curr);
|
||||
}
|
||||
|
||||
if (!node->is_leaf) {
|
||||
scanner_warn(s, "this compose sequence is a prefix of another; skipping line");
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->u.leaf.utf8 != 0 || node->u.leaf.keysym != XKB_KEY_NoSymbol) {
|
||||
bool same_string =
|
||||
(node->u.leaf.utf8 == 0 && !production->has_string) ||
|
||||
(
|
||||
node->u.leaf.utf8 != 0 && production->has_string &&
|
||||
streq(&darray_item(table->utf8, node->u.leaf.utf8),
|
||||
production->string)
|
||||
);
|
||||
bool same_keysym =
|
||||
(node->u.leaf.keysym == XKB_KEY_NoSymbol && !production->has_keysym) ||
|
||||
(
|
||||
node->u.leaf.keysym != XKB_KEY_NoSymbol && production->has_keysym &&
|
||||
node->u.leaf.keysym == production->keysym
|
||||
);
|
||||
if (same_string && same_keysym) {
|
||||
scanner_warn(s, "this compose sequence is a duplicate of another; skipping line");
|
||||
return;
|
||||
}
|
||||
scanner_warn(s, "this compose sequence already exists; overriding");
|
||||
}
|
||||
|
||||
if (production->has_string) {
|
||||
node->u.leaf.utf8 = darray_size(table->utf8);
|
||||
darray_append_items(table->utf8, production->string,
|
||||
strlen(production->string) + 1);
|
||||
}
|
||||
if (production->has_keysym) {
|
||||
node->u.leaf.keysym = production->keysym;
|
||||
}
|
||||
}
|
||||
|
||||
/* Should match resolve_modifier(). */
|
||||
#define ALL_MODS_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
|
||||
|
||||
static xkb_mod_index_t
|
||||
resolve_modifier(const char *name)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
xkb_mod_index_t mod;
|
||||
} mods[] = {
|
||||
{ "Shift", 0 },
|
||||
{ "Ctrl", 2 },
|
||||
{ "Alt", 3 },
|
||||
{ "Meta", 3 },
|
||||
{ "Lock", 1 },
|
||||
{ "Caps", 1 },
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(mods); i++)
|
||||
if (streq(name, mods[i].name))
|
||||
return mods[i].mod;
|
||||
|
||||
return XKB_MOD_INVALID;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse(struct xkb_compose_table *table, struct scanner *s,
|
||||
unsigned include_depth);
|
||||
|
||||
static bool
|
||||
do_include(struct xkb_compose_table *table, struct scanner *s,
|
||||
const char *path, unsigned include_depth)
|
||||
{
|
||||
FILE *file;
|
||||
bool ok;
|
||||
char *string;
|
||||
size_t size;
|
||||
struct scanner new_s;
|
||||
|
||||
if (include_depth >= MAX_INCLUDE_DEPTH) {
|
||||
scanner_err(s, "maximum include depth (%d) exceeded; maybe there is an include loop?",
|
||||
MAX_INCLUDE_DEPTH);
|
||||
return false;
|
||||
}
|
||||
|
||||
file = fopen(path, "r");
|
||||
if (!file) {
|
||||
scanner_err(s, "failed to open included Compose file \"%s\": %s",
|
||||
path, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = map_file(file, &string, &size);
|
||||
if (!ok) {
|
||||
scanner_err(s, "failed to read included Compose file \"%s\": %s",
|
||||
path, strerror(errno));
|
||||
goto err_file;
|
||||
}
|
||||
|
||||
scanner_init(&new_s, table->ctx, string, size, path, s->priv);
|
||||
|
||||
ok = parse(table, &new_s, include_depth + 1);
|
||||
if (!ok)
|
||||
goto err_unmap;
|
||||
|
||||
err_unmap:
|
||||
unmap_file(string, size);
|
||||
err_file:
|
||||
fclose(file);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse(struct xkb_compose_table *table, struct scanner *s,
|
||||
unsigned include_depth)
|
||||
{
|
||||
enum rules_token tok;
|
||||
union lvalue val;
|
||||
xkb_keysym_t keysym;
|
||||
struct production production;
|
||||
enum { MAX_ERRORS = 10 };
|
||||
int num_errors = 0;
|
||||
|
||||
initial:
|
||||
production.len = 0;
|
||||
production.has_keysym = false;
|
||||
production.has_string = false;
|
||||
production.mods = 0;
|
||||
production.modmask = 0;
|
||||
|
||||
/* fallthrough */
|
||||
|
||||
initial_eol:
|
||||
switch (tok = lex(s, &val)) {
|
||||
case TOK_END_OF_LINE:
|
||||
goto initial_eol;
|
||||
case TOK_END_OF_FILE:
|
||||
goto finished;
|
||||
case TOK_INCLUDE:
|
||||
goto include;
|
||||
default:
|
||||
goto lhs_tok;
|
||||
}
|
||||
|
||||
include:
|
||||
switch (tok = lex_include_string(s, table, &val)) {
|
||||
case TOK_INCLUDE_STRING:
|
||||
goto include_eol;
|
||||
default:
|
||||
goto unexpected;
|
||||
}
|
||||
|
||||
include_eol:
|
||||
switch (tok = lex(s, &val)) {
|
||||
case TOK_END_OF_LINE:
|
||||
if (!do_include(table, s, val.string.str, include_depth))
|
||||
goto fail;
|
||||
goto initial;
|
||||
default:
|
||||
goto unexpected;
|
||||
}
|
||||
|
||||
lhs:
|
||||
tok = lex(s, &val);
|
||||
lhs_tok:
|
||||
switch (tok) {
|
||||
case TOK_COLON:
|
||||
if (production.len <= 0) {
|
||||
scanner_warn(s, "expected at least one keysym on left-hand side; skipping line");
|
||||
goto skip;
|
||||
}
|
||||
goto rhs;
|
||||
case TOK_IDENT:
|
||||
if (streq(val.string.str, "None")) {
|
||||
production.mods = 0;
|
||||
production.modmask = ALL_MODS_MASK;
|
||||
goto lhs_keysym;
|
||||
}
|
||||
goto lhs_mod_list_tok;
|
||||
case TOK_TILDE:
|
||||
goto lhs_mod_list_tok;
|
||||
case TOK_BANG:
|
||||
production.modmask = ALL_MODS_MASK;
|
||||
goto lhs_mod_list;
|
||||
default:
|
||||
goto lhs_keysym_tok;
|
||||
}
|
||||
|
||||
lhs_keysym:
|
||||
tok = lex(s, &val);
|
||||
lhs_keysym_tok:
|
||||
switch (tok) {
|
||||
case TOK_LHS_KEYSYM:
|
||||
keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS);
|
||||
if (keysym == XKB_KEY_NoSymbol) {
|
||||
scanner_err(s, "unrecognized keysym \"%s\" on left-hand side",
|
||||
val.string.str);
|
||||
goto error;
|
||||
}
|
||||
if (production.len + 1 > MAX_LHS_LEN) {
|
||||
scanner_warn(s, "too many keysyms (%d) on left-hand side; skipping line",
|
||||
MAX_LHS_LEN + 1);
|
||||
goto skip;
|
||||
}
|
||||
production.lhs[production.len++] = keysym;
|
||||
production.mods = 0;
|
||||
production.modmask = 0;
|
||||
goto lhs;
|
||||
default:
|
||||
goto unexpected;
|
||||
}
|
||||
|
||||
lhs_mod_list:
|
||||
tok = lex(s, &val);
|
||||
lhs_mod_list_tok: {
|
||||
bool tilde = false;
|
||||
xkb_mod_index_t mod;
|
||||
|
||||
if (tok != TOK_TILDE && tok != TOK_IDENT)
|
||||
goto lhs_keysym_tok;
|
||||
|
||||
if (tok == TOK_TILDE) {
|
||||
tilde = true;
|
||||
tok = lex(s, &val);
|
||||
}
|
||||
|
||||
if (tok != TOK_IDENT)
|
||||
goto unexpected;
|
||||
|
||||
mod = resolve_modifier(val.string.str);
|
||||
if (mod == XKB_MOD_INVALID) {
|
||||
scanner_err(s, "unrecognized modifier \"%s\"",
|
||||
val.string.str);
|
||||
goto error;
|
||||
}
|
||||
|
||||
production.modmask |= 1 << mod;
|
||||
if (tilde)
|
||||
production.mods &= ~(1 << mod);
|
||||
else
|
||||
production.mods |= 1 << mod;
|
||||
|
||||
goto lhs_mod_list;
|
||||
}
|
||||
|
||||
rhs:
|
||||
switch (tok = lex(s, &val)) {
|
||||
case TOK_STRING:
|
||||
if (production.has_string) {
|
||||
scanner_warn(s, "right-hand side can have at most one string; skipping line");
|
||||
goto skip;
|
||||
}
|
||||
if (val.string.len <= 0) {
|
||||
scanner_warn(s, "right-hand side string must not be empty; skipping line");
|
||||
goto skip;
|
||||
}
|
||||
if (val.string.len >= sizeof(production.string)) {
|
||||
scanner_warn(s, "right-hand side string is too long; skipping line");
|
||||
goto skip;
|
||||
}
|
||||
strcpy(production.string, val.string.str);
|
||||
production.has_string = true;
|
||||
goto rhs;
|
||||
case TOK_IDENT:
|
||||
keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS);
|
||||
if (keysym == XKB_KEY_NoSymbol) {
|
||||
scanner_err(s, "unrecognized keysym \"%s\" on right-hand side",
|
||||
val.string.str);
|
||||
goto error;
|
||||
}
|
||||
if (production.has_keysym) {
|
||||
scanner_warn(s, "right-hand side can have at most one keysym; skipping line");
|
||||
goto skip;
|
||||
}
|
||||
production.keysym = keysym;
|
||||
production.has_keysym = true;
|
||||
/* fallthrough */
|
||||
case TOK_END_OF_LINE:
|
||||
if (!production.has_string && !production.has_keysym) {
|
||||
scanner_warn(s, "right-hand side must have at least one of string or keysym; skipping line");
|
||||
goto skip;
|
||||
}
|
||||
add_production(table, s, &production);
|
||||
goto initial;
|
||||
default:
|
||||
goto unexpected;
|
||||
}
|
||||
|
||||
unexpected:
|
||||
if (tok != TOK_ERROR)
|
||||
scanner_err(s, "unexpected token");
|
||||
error:
|
||||
num_errors++;
|
||||
if (num_errors <= MAX_ERRORS)
|
||||
goto skip;
|
||||
|
||||
scanner_err(s, "too many errors");
|
||||
goto fail;
|
||||
|
||||
fail:
|
||||
scanner_err(s, "failed to parse file");
|
||||
return false;
|
||||
|
||||
skip:
|
||||
while (tok != TOK_END_OF_LINE && tok != TOK_END_OF_FILE)
|
||||
tok = lex(s, &val);
|
||||
goto initial;
|
||||
|
||||
finished:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parse_string(struct xkb_compose_table *table, const char *string, size_t len,
|
||||
const char *file_name)
|
||||
{
|
||||
struct scanner s;
|
||||
scanner_init(&s, table->ctx, string, len, file_name, NULL);
|
||||
if (!parse(table, &s, 0))
|
||||
return false;
|
||||
/* Maybe the allocator can use the excess space. */
|
||||
darray_shrink(table->nodes);
|
||||
darray_shrink(table->utf8);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
parse_file(struct xkb_compose_table *table, FILE *file, const char *file_name)
|
||||
{
|
||||
bool ok;
|
||||
char *string;
|
||||
size_t size;
|
||||
|
||||
ok = map_file(file, &string, &size);
|
||||
if (!ok) {
|
||||
log_err(table->ctx, "Couldn't read Compose file %s: %s\n",
|
||||
file_name, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = parse_string(table, string, size, file_name);
|
||||
unmap_file(string, size);
|
||||
return ok;
|
||||
}
|
36
src/3rdparty/xkbcommon/src/compose/parser.h
vendored
36
src/3rdparty/xkbcommon/src/compose/parser.h
vendored
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef COMPOSE_PARSER_H
|
||||
#define COMPOSE_PARSER_H
|
||||
|
||||
bool
|
||||
parse_string(struct xkb_compose_table *table,
|
||||
const char *string, size_t len,
|
||||
const char *file_name);
|
||||
|
||||
bool
|
||||
parse_file(struct xkb_compose_table *table,
|
||||
FILE *file, const char *file_name);
|
||||
|
||||
#endif
|
203
src/3rdparty/xkbcommon/src/compose/paths.c
vendored
203
src/3rdparty/xkbcommon/src/compose/paths.c
vendored
@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2014 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "paths.h"
|
||||
|
||||
enum resolve_name_direction {
|
||||
LEFT_TO_RIGHT,
|
||||
RIGHT_TO_LEFT,
|
||||
};
|
||||
|
||||
const char *
|
||||
get_xlocaledir_path(void)
|
||||
{
|
||||
const char *dir = secure_getenv("XLOCALEDIR");
|
||||
if (!dir)
|
||||
dir = XLOCALEDIR;
|
||||
return dir;
|
||||
}
|
||||
|
||||
/*
|
||||
* Files like compose.dir have the format LEFT: RIGHT. Lookup @name in
|
||||
* such a file and return its matching value, according to @direction.
|
||||
* @filename is relative to the xlocaledir.
|
||||
*/
|
||||
static char *
|
||||
resolve_name(const char *filename, enum resolve_name_direction direction,
|
||||
const char *name)
|
||||
{
|
||||
int ret;
|
||||
bool ok;
|
||||
const char *xlocaledir;
|
||||
char path[512];
|
||||
FILE *file;
|
||||
char *string;
|
||||
size_t string_size;
|
||||
const char *end;
|
||||
const char *s, *left, *right;
|
||||
char *match;
|
||||
size_t left_len, right_len, name_len;
|
||||
|
||||
xlocaledir = get_xlocaledir_path();
|
||||
|
||||
ret = snprintf(path, sizeof(path), "%s/%s", xlocaledir, filename);
|
||||
if (ret < 0 || (size_t) ret >= sizeof(path))
|
||||
return false;
|
||||
|
||||
file = fopen(path, "r");
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
ok = map_file(file, &string, &string_size);
|
||||
fclose(file);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
s = string;
|
||||
end = string + string_size;
|
||||
name_len = strlen(name);
|
||||
match = NULL;
|
||||
|
||||
while (s < end) {
|
||||
/* Skip spaces. */
|
||||
while (s < end && is_space(*s))
|
||||
s++;
|
||||
|
||||
/* Skip comments. */
|
||||
if (s < end && *s == '#') {
|
||||
while (s < end && *s != '\n')
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the left value. */
|
||||
left = s;
|
||||
while (s < end && !is_space(*s) && *s != ':')
|
||||
s++;
|
||||
left_len = s - left;
|
||||
|
||||
/* There's an optional colon between left and right. */
|
||||
if (s < end && *s == ':')
|
||||
s++;
|
||||
|
||||
/* Skip spaces. */
|
||||
while (s < end && is_space(*s))
|
||||
s++;
|
||||
|
||||
/* Get the right value. */
|
||||
right = s;
|
||||
while (s < end && !is_space(*s))
|
||||
s++;
|
||||
right_len = s - right;
|
||||
|
||||
/* Discard rest of line. */
|
||||
while (s < end && *s != '\n')
|
||||
s++;
|
||||
|
||||
if (direction == LEFT_TO_RIGHT) {
|
||||
if (left_len == name_len && memcmp(left, name, left_len) == 0) {
|
||||
match = strndup(right, right_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (direction == RIGHT_TO_LEFT) {
|
||||
if (right_len == name_len && memcmp(right, name, right_len) == 0) {
|
||||
match = strndup(left, left_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unmap_file(string, string_size);
|
||||
return match;
|
||||
}
|
||||
|
||||
char *
|
||||
resolve_locale(const char *locale)
|
||||
{
|
||||
char *alias = resolve_name("locale.alias", LEFT_TO_RIGHT, locale);
|
||||
return alias ? alias : strdup(locale);
|
||||
}
|
||||
|
||||
const char *
|
||||
get_xcomposefile_path(void)
|
||||
{
|
||||
return secure_getenv("XCOMPOSEFILE");
|
||||
}
|
||||
|
||||
char *
|
||||
get_home_xcompose_file_path(void)
|
||||
{
|
||||
int ret;
|
||||
const char *home;
|
||||
char *path;
|
||||
|
||||
home = secure_getenv("HOME");
|
||||
if (!home)
|
||||
return NULL;
|
||||
|
||||
ret = asprintf(&path, "%s/.XCompose", home);
|
||||
if (ret <0)
|
||||
return NULL;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
char *
|
||||
get_locale_compose_file_path(const char *locale)
|
||||
{
|
||||
char *resolved;
|
||||
char *path;
|
||||
|
||||
/*
|
||||
* WARNING: Random workaround ahead.
|
||||
*
|
||||
* We currently do not support non-UTF-8 Compose files. The C/POSIX
|
||||
* locale is specified to be the default fallback locale with an
|
||||
* ASCII charset. But for some reason the compose.dir points the C
|
||||
* locale to the iso8859-1/Compose file, which is not ASCII but
|
||||
* ISO8859-1. Since this is bound to happen a lot, and since our API
|
||||
* is UTF-8 based, and since 99% of the time a C locale is really just
|
||||
* a misconfiguration for UTF-8, let's do the most helpful thing.
|
||||
*/
|
||||
if (streq(locale, "C"))
|
||||
locale = "en_US.UTF-8";
|
||||
|
||||
resolved = resolve_name("compose.dir", RIGHT_TO_LEFT, locale);
|
||||
if (!resolved)
|
||||
return NULL;
|
||||
|
||||
if (resolved[0] == '/') {
|
||||
path = resolved;
|
||||
}
|
||||
else {
|
||||
const char *xlocaledir = get_xlocaledir_path();
|
||||
int ret = asprintf(&path, "%s/%s", xlocaledir, resolved);
|
||||
free(resolved);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
42
src/3rdparty/xkbcommon/src/compose/paths.h
vendored
42
src/3rdparty/xkbcommon/src/compose/paths.h
vendored
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2014 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef COMPOSE_RESOLVE_H
|
||||
#define COMPOSE_RESOLVE_H
|
||||
|
||||
char *
|
||||
resolve_locale(const char *locale);
|
||||
|
||||
const char *
|
||||
get_xlocaledir_path(void);
|
||||
|
||||
const char *
|
||||
get_xcomposefile_path(void);
|
||||
|
||||
char *
|
||||
get_home_xcompose_file_path(void);
|
||||
|
||||
char *
|
||||
get_locale_compose_file_path(const char *locale);
|
||||
|
||||
#endif
|
219
src/3rdparty/xkbcommon/src/compose/table.c
vendored
219
src/3rdparty/xkbcommon/src/compose/table.c
vendored
@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "table.h"
|
||||
#include "parser.h"
|
||||
#include "paths.h"
|
||||
|
||||
static struct xkb_compose_table *
|
||||
xkb_compose_table_new(struct xkb_context *ctx,
|
||||
const char *locale,
|
||||
enum xkb_compose_format format,
|
||||
enum xkb_compose_compile_flags flags)
|
||||
{
|
||||
char *resolved_locale;
|
||||
struct xkb_compose_table *table;
|
||||
struct compose_node root;
|
||||
|
||||
resolved_locale = resolve_locale(locale);
|
||||
if (!resolved_locale)
|
||||
return NULL;
|
||||
|
||||
table = calloc(1, sizeof(*table));
|
||||
if (!table) {
|
||||
free(resolved_locale);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
table->refcnt = 1;
|
||||
table->ctx = xkb_context_ref(ctx);
|
||||
|
||||
table->locale = resolved_locale;
|
||||
table->format = format;
|
||||
table->flags = flags;
|
||||
|
||||
darray_init(table->nodes);
|
||||
darray_init(table->utf8);
|
||||
|
||||
root.keysym = XKB_KEY_NoSymbol;
|
||||
root.next = 0;
|
||||
root.is_leaf = true;
|
||||
root.u.leaf.utf8 = 0;
|
||||
root.u.leaf.keysym = XKB_KEY_NoSymbol;
|
||||
darray_append(table->nodes, root);
|
||||
|
||||
darray_append(table->utf8, '\0');
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_compose_table *
|
||||
xkb_compose_table_ref(struct xkb_compose_table *table)
|
||||
{
|
||||
table->refcnt++;
|
||||
return table;
|
||||
}
|
||||
|
||||
XKB_EXPORT void
|
||||
xkb_compose_table_unref(struct xkb_compose_table *table)
|
||||
{
|
||||
if (!table || --table->refcnt > 0)
|
||||
return;
|
||||
free(table->locale);
|
||||
darray_free(table->nodes);
|
||||
darray_free(table->utf8);
|
||||
xkb_context_unref(table->ctx);
|
||||
free(table);
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_compose_table *
|
||||
xkb_compose_table_new_from_file(struct xkb_context *ctx,
|
||||
FILE *file,
|
||||
const char *locale,
|
||||
enum xkb_compose_format format,
|
||||
enum xkb_compose_compile_flags flags)
|
||||
{
|
||||
struct xkb_compose_table *table;
|
||||
bool ok;
|
||||
|
||||
if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) {
|
||||
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (format != XKB_COMPOSE_FORMAT_TEXT_V1) {
|
||||
log_err_func(ctx, "unsupported compose format: %d\n", format);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
table = xkb_compose_table_new(ctx, locale, format, flags);
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
ok = parse_file(table, file, "(unknown file)");
|
||||
if (!ok) {
|
||||
xkb_compose_table_unref(table);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_compose_table *
|
||||
xkb_compose_table_new_from_buffer(struct xkb_context *ctx,
|
||||
const char *buffer, size_t length,
|
||||
const char *locale,
|
||||
enum xkb_compose_format format,
|
||||
enum xkb_compose_compile_flags flags)
|
||||
{
|
||||
struct xkb_compose_table *table;
|
||||
bool ok;
|
||||
|
||||
if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) {
|
||||
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (format != XKB_COMPOSE_FORMAT_TEXT_V1) {
|
||||
log_err_func(ctx, "unsupported compose format: %d\n", format);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
table = xkb_compose_table_new(ctx, locale, format, flags);
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
ok = parse_string(table, buffer, length, "(input string)");
|
||||
if (!ok) {
|
||||
xkb_compose_table_unref(table);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_compose_table *
|
||||
xkb_compose_table_new_from_locale(struct xkb_context *ctx,
|
||||
const char *locale,
|
||||
enum xkb_compose_compile_flags flags)
|
||||
{
|
||||
struct xkb_compose_table *table;
|
||||
char *path = NULL;
|
||||
const char *cpath;
|
||||
FILE *file;
|
||||
bool ok;
|
||||
|
||||
if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) {
|
||||
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
table = xkb_compose_table_new(ctx, locale, XKB_COMPOSE_FORMAT_TEXT_V1,
|
||||
flags);
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
cpath = get_xcomposefile_path();
|
||||
if (cpath) {
|
||||
file = fopen(cpath, "r");
|
||||
if (file)
|
||||
goto found_path;
|
||||
}
|
||||
|
||||
cpath = path = get_home_xcompose_file_path();
|
||||
if (path) {
|
||||
file = fopen(path, "r");
|
||||
if (file)
|
||||
goto found_path;
|
||||
}
|
||||
free(path);
|
||||
path = NULL;
|
||||
|
||||
cpath = path = get_locale_compose_file_path(table->locale);
|
||||
if (path) {
|
||||
file = fopen(path, "r");
|
||||
if (file)
|
||||
goto found_path;
|
||||
}
|
||||
free(path);
|
||||
path = NULL;
|
||||
|
||||
log_err(ctx, "couldn't find a Compose file for locale \"%s\"\n", locale);
|
||||
xkb_compose_table_unref(table);
|
||||
return NULL;
|
||||
|
||||
found_path:
|
||||
ok = parse_file(table, file, cpath);
|
||||
fclose(file);
|
||||
if (!ok) {
|
||||
xkb_compose_table_unref(table);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
log_dbg(ctx, "created compose table from locale %s with path %s\n",
|
||||
table->locale, path);
|
||||
|
||||
free(path);
|
||||
return table;
|
||||
}
|
100
src/3rdparty/xkbcommon/src/compose/table.h
vendored
100
src/3rdparty/xkbcommon/src/compose/table.h
vendored
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef COMPOSE_COMPOSE_H
|
||||
#define COMPOSE_COMPOSE_H
|
||||
|
||||
#include "xkbcommon/xkbcommon-compose.h"
|
||||
#include "utils.h"
|
||||
#include "context.h"
|
||||
|
||||
/*
|
||||
* The compose table data structure is a simple trie. An example will
|
||||
* help. Given these sequences:
|
||||
*
|
||||
* <A> <B> : "first" dead_a
|
||||
* <A> <C> <D> : "second" dead_b
|
||||
* <E> <F> : "third" dead_c
|
||||
*
|
||||
* the trie would look like:
|
||||
*
|
||||
* [root] ---> [<A>] -----------------> [<E>] -#
|
||||
* | | |
|
||||
* # v v
|
||||
* [<B>] ---> [<C>] -# [<F>] -#
|
||||
* | | -
|
||||
* # v #
|
||||
* [<D>] -#
|
||||
* |
|
||||
* #
|
||||
* where:
|
||||
* - [root] is a special empty root node.
|
||||
* - [<X>] is a node for a sequence keysym <X>.
|
||||
* - right arrows are `next` pointers.
|
||||
* - down arrows are `successor` pointers.
|
||||
* - # is a nil pointer.
|
||||
*
|
||||
* The nodes are all kept in a contiguous array. Pointers are represented
|
||||
* as integer offsets into this array. A nil pointer is represented as 0
|
||||
* (which, helpfully, is the offset of the empty root node).
|
||||
*
|
||||
* Nodes without a successor are leaf nodes. Since a sequence cannot be a
|
||||
* prefix of another, these are exactly the nodes which terminate the
|
||||
* sequences (in a bijective manner).
|
||||
*
|
||||
* A leaf contains the result data of its sequence. The result keysym is
|
||||
* contained in the node struct itself; the result UTF-8 string is a byte
|
||||
* offset into an array of the form "\0first\0second\0third" (the initial
|
||||
* \0 is so offset 0 points to an empty string).
|
||||
*/
|
||||
|
||||
struct compose_node {
|
||||
xkb_keysym_t keysym;
|
||||
/* Offset into xkb_compose_table::nodes. */
|
||||
unsigned int next:31;
|
||||
bool is_leaf:1;
|
||||
|
||||
union {
|
||||
/* Offset into xkb_compose_table::nodes. */
|
||||
uint32_t successor;
|
||||
struct {
|
||||
/* Offset into xkb_compose_table::utf8. */
|
||||
uint32_t utf8;
|
||||
xkb_keysym_t keysym;
|
||||
} leaf;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct xkb_compose_table {
|
||||
int refcnt;
|
||||
enum xkb_compose_format format;
|
||||
enum xkb_compose_compile_flags flags;
|
||||
struct xkb_context *ctx;
|
||||
|
||||
char *locale;
|
||||
|
||||
darray_char utf8;
|
||||
darray(struct compose_node) nodes;
|
||||
};
|
||||
|
||||
#endif
|
190
src/3rdparty/xkbcommon/src/context-priv.c
vendored
190
src/3rdparty/xkbcommon/src/context-priv.c
vendored
@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2012 Ran Benita
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "utils.h"
|
||||
#include "context.h"
|
||||
|
||||
unsigned int
|
||||
xkb_context_num_failed_include_paths(struct xkb_context *ctx)
|
||||
{
|
||||
return darray_size(ctx->failed_includes);
|
||||
}
|
||||
|
||||
const char *
|
||||
xkb_context_failed_include_path_get(struct xkb_context *ctx,
|
||||
unsigned int idx)
|
||||
{
|
||||
if (idx >= xkb_context_num_failed_include_paths(ctx))
|
||||
return NULL;
|
||||
|
||||
return darray_item(ctx->failed_includes, idx);
|
||||
}
|
||||
|
||||
xkb_atom_t
|
||||
xkb_atom_lookup(struct xkb_context *ctx, const char *string)
|
||||
{
|
||||
return atom_lookup(ctx->atom_table, string, strlen(string));
|
||||
}
|
||||
|
||||
xkb_atom_t
|
||||
xkb_atom_intern(struct xkb_context *ctx, const char *string, size_t len)
|
||||
{
|
||||
return atom_intern(ctx->atom_table, string, len, false);
|
||||
}
|
||||
|
||||
xkb_atom_t
|
||||
xkb_atom_steal(struct xkb_context *ctx, char *string)
|
||||
{
|
||||
return atom_intern(ctx->atom_table, string, strlen(string), true);
|
||||
}
|
||||
|
||||
const char *
|
||||
xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom)
|
||||
{
|
||||
return atom_text(ctx->atom_table, atom);
|
||||
}
|
||||
|
||||
void
|
||||
xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (ctx->log_level < level || ctx->log_verbosity < verbosity)
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
ctx->log_fn(ctx, level, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
char *
|
||||
xkb_context_get_buffer(struct xkb_context *ctx, size_t size)
|
||||
{
|
||||
char *rtrn;
|
||||
|
||||
if (size >= sizeof(ctx->text_buffer))
|
||||
return NULL;
|
||||
|
||||
if (sizeof(ctx->text_buffer) - ctx->text_next <= size)
|
||||
ctx->text_next = 0;
|
||||
|
||||
rtrn = &ctx->text_buffer[ctx->text_next];
|
||||
ctx->text_next += size;
|
||||
|
||||
return rtrn;
|
||||
}
|
||||
|
||||
#ifndef DEFAULT_XKB_VARIANT
|
||||
#define DEFAULT_XKB_VARIANT NULL
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_XKB_OPTIONS
|
||||
#define DEFAULT_XKB_OPTIONS NULL
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
xkb_context_get_default_rules(struct xkb_context *ctx)
|
||||
{
|
||||
const char *env = NULL;
|
||||
|
||||
if (ctx->use_environment_names)
|
||||
env = secure_getenv("XKB_DEFAULT_RULES");
|
||||
|
||||
return env ? env : DEFAULT_XKB_RULES;
|
||||
}
|
||||
|
||||
static const char *
|
||||
xkb_context_get_default_model(struct xkb_context *ctx)
|
||||
{
|
||||
const char *env = NULL;
|
||||
|
||||
if (ctx->use_environment_names)
|
||||
env = secure_getenv("XKB_DEFAULT_MODEL");
|
||||
|
||||
return env ? env : DEFAULT_XKB_MODEL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
xkb_context_get_default_layout(struct xkb_context *ctx)
|
||||
{
|
||||
const char *env = NULL;
|
||||
|
||||
if (ctx->use_environment_names)
|
||||
env = secure_getenv("XKB_DEFAULT_LAYOUT");
|
||||
|
||||
return env ? env : DEFAULT_XKB_LAYOUT;
|
||||
}
|
||||
|
||||
static const char *
|
||||
xkb_context_get_default_variant(struct xkb_context *ctx)
|
||||
{
|
||||
const char *env = NULL;
|
||||
const char *layout = secure_getenv("XKB_DEFAULT_LAYOUT");
|
||||
|
||||
/* We don't want to inherit the variant if they haven't also set a
|
||||
* layout, since they're so closely paired. */
|
||||
if (layout && ctx->use_environment_names)
|
||||
env = secure_getenv("XKB_DEFAULT_VARIANT");
|
||||
|
||||
return env ? env : DEFAULT_XKB_VARIANT;
|
||||
}
|
||||
|
||||
static const char *
|
||||
xkb_context_get_default_options(struct xkb_context *ctx)
|
||||
{
|
||||
const char *env = NULL;
|
||||
|
||||
if (ctx->use_environment_names)
|
||||
env = secure_getenv("XKB_DEFAULT_OPTIONS");
|
||||
|
||||
return env ? env : DEFAULT_XKB_OPTIONS;
|
||||
}
|
||||
|
||||
void
|
||||
xkb_context_sanitize_rule_names(struct xkb_context *ctx,
|
||||
struct xkb_rule_names *rmlvo)
|
||||
{
|
||||
if (isempty(rmlvo->rules))
|
||||
rmlvo->rules = xkb_context_get_default_rules(ctx);
|
||||
if (isempty(rmlvo->model))
|
||||
rmlvo->model = xkb_context_get_default_model(ctx);
|
||||
/* Layout and variant are tied together, so don't try to use one from
|
||||
* the caller and one from the environment. */
|
||||
if (isempty(rmlvo->layout)) {
|
||||
rmlvo->layout = xkb_context_get_default_layout(ctx);
|
||||
rmlvo->variant = xkb_context_get_default_variant(ctx);
|
||||
}
|
||||
/* Options can be empty, so respect that if passed in. */
|
||||
if (rmlvo->options == NULL)
|
||||
rmlvo->options = xkb_context_get_default_options(ctx);
|
||||
}
|
331
src/3rdparty/xkbcommon/src/context.c
vendored
331
src/3rdparty/xkbcommon/src/context.c
vendored
@ -1,331 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2012 Ran Benita
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "utils.h"
|
||||
#include "context.h"
|
||||
|
||||
/**
|
||||
* Append one directory to the context's include path.
|
||||
*/
|
||||
XKB_EXPORT int
|
||||
xkb_context_include_path_append(struct xkb_context *ctx, const char *path)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
int err;
|
||||
char *tmp;
|
||||
|
||||
tmp = strdup(path);
|
||||
if (!tmp)
|
||||
goto err;
|
||||
|
||||
err = stat(path, &stat_buf);
|
||||
if (err != 0)
|
||||
goto err;
|
||||
if (!S_ISDIR(stat_buf.st_mode))
|
||||
goto err;
|
||||
|
||||
#if defined(HAVE_EACCESS)
|
||||
if (eaccess(path, R_OK | X_OK) != 0)
|
||||
goto err;
|
||||
#elif defined(HAVE_EUIDACCESS)
|
||||
if (euidaccess(path, R_OK | X_OK) != 0)
|
||||
goto err;
|
||||
#endif
|
||||
|
||||
darray_append(ctx->includes, tmp);
|
||||
return 1;
|
||||
|
||||
err:
|
||||
darray_append(ctx->failed_includes, tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the default include directories to the context.
|
||||
*/
|
||||
XKB_EXPORT int
|
||||
xkb_context_include_path_append_default(struct xkb_context *ctx)
|
||||
{
|
||||
const char *home, *root;
|
||||
char *user_path;
|
||||
int err;
|
||||
int ret = 0;
|
||||
|
||||
root = secure_getenv("XKB_CONFIG_ROOT");
|
||||
if (root != NULL)
|
||||
ret |= xkb_context_include_path_append(ctx, root);
|
||||
else
|
||||
ret |= xkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_ROOT);
|
||||
|
||||
home = secure_getenv("HOME");
|
||||
if (!home)
|
||||
return ret;
|
||||
err = asprintf(&user_path, "%s/.xkb", home);
|
||||
if (err <= 0)
|
||||
return ret;
|
||||
ret |= xkb_context_include_path_append(ctx, user_path);
|
||||
free(user_path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries in the context's include path.
|
||||
*/
|
||||
XKB_EXPORT void
|
||||
xkb_context_include_path_clear(struct xkb_context *ctx)
|
||||
{
|
||||
char **path;
|
||||
|
||||
darray_foreach(path, ctx->includes)
|
||||
free(*path);
|
||||
darray_free(ctx->includes);
|
||||
|
||||
darray_foreach(path, ctx->failed_includes)
|
||||
free(*path);
|
||||
darray_free(ctx->failed_includes);
|
||||
}
|
||||
|
||||
/**
|
||||
* xkb_context_include_path_clear() + xkb_context_include_path_append_default()
|
||||
*/
|
||||
XKB_EXPORT int
|
||||
xkb_context_include_path_reset_defaults(struct xkb_context *ctx)
|
||||
{
|
||||
xkb_context_include_path_clear(ctx);
|
||||
return xkb_context_include_path_append_default(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of entries in the context's include path.
|
||||
*/
|
||||
XKB_EXPORT unsigned int
|
||||
xkb_context_num_include_paths(struct xkb_context *ctx)
|
||||
{
|
||||
return darray_size(ctx->includes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given entry in the context's include path, or NULL if an
|
||||
* invalid index is passed.
|
||||
*/
|
||||
XKB_EXPORT const char *
|
||||
xkb_context_include_path_get(struct xkb_context *ctx, unsigned int idx)
|
||||
{
|
||||
if (idx >= xkb_context_num_include_paths(ctx))
|
||||
return NULL;
|
||||
|
||||
return darray_item(ctx->includes, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a new reference on the context.
|
||||
*/
|
||||
XKB_EXPORT struct xkb_context *
|
||||
xkb_context_ref(struct xkb_context *ctx)
|
||||
{
|
||||
ctx->refcnt++;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop an existing reference on the context, and free it if the refcnt is
|
||||
* now 0.
|
||||
*/
|
||||
XKB_EXPORT void
|
||||
xkb_context_unref(struct xkb_context *ctx)
|
||||
{
|
||||
if (!ctx || --ctx->refcnt > 0)
|
||||
return;
|
||||
|
||||
xkb_context_include_path_clear(ctx);
|
||||
atom_table_free(ctx->atom_table);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static const char *
|
||||
log_level_to_prefix(enum xkb_log_level level)
|
||||
{
|
||||
switch (level) {
|
||||
case XKB_LOG_LEVEL_DEBUG:
|
||||
return "xkbcommon: DEBUG: ";
|
||||
case XKB_LOG_LEVEL_INFO:
|
||||
return "xkbcommon: INFO: ";
|
||||
case XKB_LOG_LEVEL_WARNING:
|
||||
return "xkbcommon: WARNING: ";
|
||||
case XKB_LOG_LEVEL_ERROR:
|
||||
return "xkbcommon: ERROR: ";
|
||||
case XKB_LOG_LEVEL_CRITICAL:
|
||||
return "xkbcommon: CRITICAL: ";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_PRINTF(3, 0) static void
|
||||
default_log_fn(struct xkb_context *ctx, enum xkb_log_level level,
|
||||
const char *fmt, va_list args)
|
||||
{
|
||||
const char *prefix = log_level_to_prefix(level);
|
||||
|
||||
if (prefix)
|
||||
fprintf(stderr, "%s", prefix);
|
||||
vfprintf(stderr, fmt, args);
|
||||
}
|
||||
|
||||
static enum xkb_log_level
|
||||
log_level(const char *level) {
|
||||
char *endptr;
|
||||
enum xkb_log_level lvl;
|
||||
|
||||
errno = 0;
|
||||
lvl = strtol(level, &endptr, 10);
|
||||
if (errno == 0 && (endptr[0] == '\0' || is_space(endptr[0])))
|
||||
return lvl;
|
||||
if (istreq_prefix("crit", level))
|
||||
return XKB_LOG_LEVEL_CRITICAL;
|
||||
if (istreq_prefix("err", level))
|
||||
return XKB_LOG_LEVEL_ERROR;
|
||||
if (istreq_prefix("warn", level))
|
||||
return XKB_LOG_LEVEL_WARNING;
|
||||
if (istreq_prefix("info", level))
|
||||
return XKB_LOG_LEVEL_INFO;
|
||||
if (istreq_prefix("debug", level) || istreq_prefix("dbg", level))
|
||||
return XKB_LOG_LEVEL_DEBUG;
|
||||
|
||||
return XKB_LOG_LEVEL_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
log_verbosity(const char *verbosity) {
|
||||
char *endptr;
|
||||
int v;
|
||||
|
||||
errno = 0;
|
||||
v = strtol(verbosity, &endptr, 10);
|
||||
if (errno == 0)
|
||||
return v;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new context.
|
||||
*/
|
||||
XKB_EXPORT struct xkb_context *
|
||||
xkb_context_new(enum xkb_context_flags flags)
|
||||
{
|
||||
const char *env;
|
||||
struct xkb_context *ctx = calloc(1, sizeof(*ctx));
|
||||
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
ctx->refcnt = 1;
|
||||
ctx->log_fn = default_log_fn;
|
||||
ctx->log_level = XKB_LOG_LEVEL_ERROR;
|
||||
ctx->log_verbosity = 0;
|
||||
|
||||
/* Environment overwrites defaults. */
|
||||
env = secure_getenv("XKB_LOG_LEVEL");
|
||||
if (env)
|
||||
xkb_context_set_log_level(ctx, log_level(env));
|
||||
|
||||
env = secure_getenv("XKB_LOG_VERBOSITY");
|
||||
if (env)
|
||||
xkb_context_set_log_verbosity(ctx, log_verbosity(env));
|
||||
|
||||
if (!(flags & XKB_CONTEXT_NO_DEFAULT_INCLUDES) &&
|
||||
!xkb_context_include_path_append_default(ctx)) {
|
||||
log_err(ctx, "failed to add default include path %s\n",
|
||||
DFLT_XKB_CONFIG_ROOT);
|
||||
xkb_context_unref(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
|
||||
|
||||
ctx->atom_table = atom_table_new();
|
||||
if (!ctx->atom_table) {
|
||||
xkb_context_unref(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
XKB_EXPORT void
|
||||
xkb_context_set_log_fn(struct xkb_context *ctx,
|
||||
void (*log_fn)(struct xkb_context *ctx,
|
||||
enum xkb_log_level level,
|
||||
const char *fmt, va_list args))
|
||||
{
|
||||
ctx->log_fn = (log_fn ? log_fn : default_log_fn);
|
||||
}
|
||||
|
||||
XKB_EXPORT enum xkb_log_level
|
||||
xkb_context_get_log_level(struct xkb_context *ctx)
|
||||
{
|
||||
return ctx->log_level;
|
||||
}
|
||||
|
||||
XKB_EXPORT void
|
||||
xkb_context_set_log_level(struct xkb_context *ctx, enum xkb_log_level level)
|
||||
{
|
||||
ctx->log_level = level;
|
||||
}
|
||||
|
||||
XKB_EXPORT int
|
||||
xkb_context_get_log_verbosity(struct xkb_context *ctx)
|
||||
{
|
||||
return ctx->log_verbosity;
|
||||
}
|
||||
|
||||
XKB_EXPORT void
|
||||
xkb_context_set_log_verbosity(struct xkb_context *ctx, int verbosity)
|
||||
{
|
||||
ctx->log_verbosity = verbosity;
|
||||
}
|
||||
|
||||
XKB_EXPORT void *
|
||||
xkb_context_get_user_data(struct xkb_context *ctx)
|
||||
{
|
||||
if (ctx)
|
||||
return ctx->user_data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XKB_EXPORT void
|
||||
xkb_context_set_user_data(struct xkb_context *ctx, void *user_data)
|
||||
{
|
||||
ctx->user_data = user_data;
|
||||
}
|
127
src/3rdparty/xkbcommon/src/context.h
vendored
127
src/3rdparty/xkbcommon/src/context.h
vendored
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#ifndef CONTEXT_H
|
||||
#define CONTEXT_H
|
||||
|
||||
#include "atom.h"
|
||||
|
||||
struct xkb_context {
|
||||
int refcnt;
|
||||
|
||||
ATTR_PRINTF(3, 0) void (*log_fn)(struct xkb_context *ctx,
|
||||
enum xkb_log_level level,
|
||||
const char *fmt, va_list args);
|
||||
enum xkb_log_level log_level;
|
||||
int log_verbosity;
|
||||
void *user_data;
|
||||
|
||||
struct xkb_rule_names names_dflt;
|
||||
|
||||
darray(char *) includes;
|
||||
darray(char *) failed_includes;
|
||||
|
||||
struct atom_table *atom_table;
|
||||
|
||||
/* Buffer for the *Text() functions. */
|
||||
char text_buffer[2048];
|
||||
size_t text_next;
|
||||
|
||||
unsigned int use_environment_names : 1;
|
||||
};
|
||||
|
||||
unsigned int
|
||||
xkb_context_num_failed_include_paths(struct xkb_context *ctx);
|
||||
|
||||
const char *
|
||||
xkb_context_failed_include_path_get(struct xkb_context *ctx,
|
||||
unsigned int idx);
|
||||
|
||||
/*
|
||||
* Returns XKB_ATOM_NONE if @string was not previously interned,
|
||||
* otherwise returns the atom.
|
||||
*/
|
||||
xkb_atom_t
|
||||
xkb_atom_lookup(struct xkb_context *ctx, const char *string);
|
||||
|
||||
xkb_atom_t
|
||||
xkb_atom_intern(struct xkb_context *ctx, const char *string, size_t len);
|
||||
|
||||
#define xkb_atom_intern_literal(ctx, literal) \
|
||||
xkb_atom_intern((ctx), (literal), sizeof(literal) - 1)
|
||||
|
||||
/**
|
||||
* If @string is dynamically allocated, NUL-terminated, free'd immediately
|
||||
* after being interned, and not used afterwards, use this function
|
||||
* instead of xkb_atom_intern to avoid some unnecessary allocations.
|
||||
* The caller should not use or free the passed in string afterwards.
|
||||
*/
|
||||
xkb_atom_t
|
||||
xkb_atom_steal(struct xkb_context *ctx, char *string);
|
||||
|
||||
const char *
|
||||
xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom);
|
||||
|
||||
char *
|
||||
xkb_context_get_buffer(struct xkb_context *ctx, size_t size);
|
||||
|
||||
ATTR_PRINTF(4, 5) void
|
||||
xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity,
|
||||
const char *fmt, ...);
|
||||
|
||||
void
|
||||
xkb_context_sanitize_rule_names(struct xkb_context *ctx,
|
||||
struct xkb_rule_names *rmlvo);
|
||||
|
||||
/*
|
||||
* The format is not part of the argument list in order to avoid the
|
||||
* "ISO C99 requires rest arguments to be used" warning when only the
|
||||
* format is supplied without arguments. Not supplying it would still
|
||||
* result in an error, though.
|
||||
*/
|
||||
#define log_dbg(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_DEBUG, 0, __VA_ARGS__)
|
||||
#define log_info(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_INFO, 0, __VA_ARGS__)
|
||||
#define log_warn(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_WARNING, 0, __VA_ARGS__)
|
||||
#define log_err(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_ERROR, 0, __VA_ARGS__)
|
||||
#define log_wsgo(ctx, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_CRITICAL, 0, __VA_ARGS__)
|
||||
#define log_vrb(ctx, vrb, ...) \
|
||||
xkb_log((ctx), XKB_LOG_LEVEL_WARNING, (vrb), __VA_ARGS__)
|
||||
|
||||
/*
|
||||
* Variants which are prefixed by the name of the function they're
|
||||
* called from.
|
||||
* Here we must have the silly 1 variant.
|
||||
*/
|
||||
#define log_err_func(ctx, fmt, ...) \
|
||||
log_err(ctx, "%s: " fmt, __func__, __VA_ARGS__)
|
||||
#define log_err_func1(ctx, fmt) \
|
||||
log_err(ctx, "%s: " fmt, __func__)
|
||||
|
||||
#endif
|
209
src/3rdparty/xkbcommon/src/darray.h
vendored
209
src/3rdparty/xkbcommon/src/darray.h
vendored
@ -1,209 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Joseph Adams <joeyadams3.14159@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CCAN_DARRAY_H
|
||||
#define CCAN_DARRAY_H
|
||||
|
||||
/* Originally taken from: https://ccodearchive.net/info/darray.html
|
||||
* But modified for libxkbcommon. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define darray(type) struct { type *item; unsigned size; unsigned alloc; }
|
||||
|
||||
#define darray_new() { 0, 0, 0 }
|
||||
|
||||
#define darray_init(arr) do { \
|
||||
(arr).item = 0; (arr).size = 0; (arr).alloc = 0; \
|
||||
} while (0)
|
||||
|
||||
#define darray_free(arr) do { \
|
||||
free((arr).item); \
|
||||
darray_init(arr); \
|
||||
} while (0)
|
||||
|
||||
#define darray_steal(arr, to, to_size) do { \
|
||||
*(to) = (arr).item; \
|
||||
if (to_size) \
|
||||
*(unsigned int *) (to_size) = (arr).size; \
|
||||
darray_init(arr); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Typedefs for darrays of common types. These are useful
|
||||
* when you want to pass a pointer to an darray(T) around.
|
||||
*
|
||||
* The following will produce an incompatible pointer warning:
|
||||
*
|
||||
* void foo(darray(int) *arr);
|
||||
* darray(int) arr = darray_new();
|
||||
* foo(&arr);
|
||||
*
|
||||
* The workaround:
|
||||
*
|
||||
* void foo(darray_int *arr);
|
||||
* darray_int arr = darray_new();
|
||||
* foo(&arr);
|
||||
*/
|
||||
|
||||
typedef darray (char) darray_char;
|
||||
typedef darray (signed char) darray_schar;
|
||||
typedef darray (unsigned char) darray_uchar;
|
||||
|
||||
typedef darray (short) darray_short;
|
||||
typedef darray (int) darray_int;
|
||||
typedef darray (long) darray_long;
|
||||
|
||||
typedef darray (unsigned short) darray_ushort;
|
||||
typedef darray (unsigned int) darray_uint;
|
||||
typedef darray (unsigned long) darray_ulong;
|
||||
|
||||
/*** Access ***/
|
||||
|
||||
#define darray_item(arr, i) ((arr).item[i])
|
||||
#define darray_size(arr) ((arr).size)
|
||||
#define darray_empty(arr) ((arr).size == 0)
|
||||
|
||||
/*** Insertion (single item) ***/
|
||||
|
||||
#define darray_append(arr, ...) do { \
|
||||
darray_resize(arr, (arr).size + 1); \
|
||||
(arr).item[(arr).size - 1] = (__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/*** Insertion (multiple items) ***/
|
||||
|
||||
#define darray_append_items(arr, items, count) do { \
|
||||
unsigned __count = (count), __oldSize = (arr).size; \
|
||||
darray_resize(arr, __oldSize + __count); \
|
||||
memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
|
||||
} while (0)
|
||||
|
||||
#define darray_from_items(arr, items, count) do { \
|
||||
unsigned __count = (count); \
|
||||
darray_resize(arr, __count); \
|
||||
if (__count != 0) \
|
||||
memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
|
||||
} while (0)
|
||||
|
||||
#define darray_copy(arr_to, arr_from) \
|
||||
darray_from_items((arr_to), (arr_from).item, (arr_from).size)
|
||||
|
||||
#define darray_concat(arr_to, arr_from) \
|
||||
darray_append_items((arr_to), (arr_from).item, (arr_from).size)
|
||||
|
||||
/*** String buffer ***/
|
||||
|
||||
#define darray_append_string(arr, str) do { \
|
||||
const char *__str = (str); \
|
||||
darray_append_items(arr, __str, strlen(__str) + 1); \
|
||||
(arr).size--; \
|
||||
} while (0)
|
||||
|
||||
#define darray_append_lit(arr, stringLiteral) do { \
|
||||
darray_append_items(arr, stringLiteral, sizeof(stringLiteral)); \
|
||||
(arr).size--; \
|
||||
} while (0)
|
||||
|
||||
#define darray_appends_nullterminate(arr, items, count) do { \
|
||||
unsigned __count = (count), __oldSize = (arr).size; \
|
||||
darray_resize(arr, __oldSize + __count + 1); \
|
||||
memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
|
||||
(arr).item[--(arr).size] = 0; \
|
||||
} while (0)
|
||||
|
||||
#define darray_prepends_nullterminate(arr, items, count) do { \
|
||||
unsigned __count = (count), __oldSize = (arr).size; \
|
||||
darray_resize(arr, __count + __oldSize + 1); \
|
||||
memmove((arr).item + __count, (arr).item, \
|
||||
__oldSize * sizeof(*(arr).item)); \
|
||||
memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
|
||||
(arr).item[--(arr).size] = 0; \
|
||||
} while (0)
|
||||
|
||||
/*** Size management ***/
|
||||
|
||||
#define darray_resize(arr, newSize) \
|
||||
darray_growalloc(arr, (arr).size = (newSize))
|
||||
|
||||
#define darray_resize0(arr, newSize) do { \
|
||||
unsigned __oldSize = (arr).size, __newSize = (newSize); \
|
||||
(arr).size = __newSize; \
|
||||
if (__newSize > __oldSize) { \
|
||||
darray_growalloc(arr, __newSize); \
|
||||
memset(&(arr).item[__oldSize], 0, \
|
||||
(__newSize - __oldSize) * sizeof(*(arr).item)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define darray_realloc(arr, newAlloc) do { \
|
||||
(arr).item = realloc((arr).item, \
|
||||
((arr).alloc = (newAlloc)) * sizeof(*(arr).item)); \
|
||||
} while (0)
|
||||
|
||||
#define darray_growalloc(arr, need) do { \
|
||||
unsigned __need = (need); \
|
||||
if (__need > (arr).alloc) \
|
||||
darray_realloc(arr, darray_next_alloc((arr).alloc, __need, \
|
||||
sizeof(*(arr).item))); \
|
||||
} while (0)
|
||||
|
||||
#define darray_shrink(arr) do { \
|
||||
if ((arr).size > 0) \
|
||||
(arr).item = realloc((arr).item, \
|
||||
((arr).alloc = (arr).size) * sizeof(*(arr).item)); \
|
||||
} while (0)
|
||||
|
||||
static inline unsigned
|
||||
darray_next_alloc(unsigned alloc, unsigned need, unsigned itemSize)
|
||||
{
|
||||
assert(need < UINT_MAX / itemSize / 2); /* Overflow. */
|
||||
if (alloc == 0)
|
||||
alloc = 4;
|
||||
while (alloc < need)
|
||||
alloc *= 2;
|
||||
return alloc;
|
||||
}
|
||||
|
||||
/*** Traversal ***/
|
||||
|
||||
#define darray_foreach(i, arr) \
|
||||
for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++)
|
||||
|
||||
#define darray_foreach_from(i, arr, from) \
|
||||
for ((i) = &(arr).item[from]; (i) < &(arr).item[(arr).size]; (i)++)
|
||||
|
||||
/* Iterate on index and value at the same time, like Python's enumerate. */
|
||||
#define darray_enumerate(idx, val, arr) \
|
||||
for ((idx) = 0, (val) = &(arr).item[0]; \
|
||||
(idx) < (arr).size; \
|
||||
(idx)++, (val)++)
|
||||
|
||||
#define darray_enumerate_from(idx, val, arr, from) \
|
||||
for ((idx) = (from), (val) = &(arr).item[0]; \
|
||||
(idx) < (arr).size; \
|
||||
(idx)++, (val)++)
|
||||
|
||||
#endif /* CCAN_DARRAY_H */
|
150
src/3rdparty/xkbcommon/src/keymap-priv.c
vendored
150
src/3rdparty/xkbcommon/src/keymap-priv.c
vendored
@ -1,150 +0,0 @@
|
||||
/**
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#include "keymap.h"
|
||||
|
||||
static void
|
||||
update_builtin_keymap_fields(struct xkb_keymap *keymap)
|
||||
{
|
||||
/* Predefined (AKA real, core, X11) modifiers. The order is important! */
|
||||
static const char *const builtin_mods[] = {
|
||||
[0] = "Shift",
|
||||
[1] = "Lock",
|
||||
[2] = "Control",
|
||||
[3] = "Mod1",
|
||||
[4] = "Mod2",
|
||||
[5] = "Mod3",
|
||||
[6] = "Mod4",
|
||||
[7] = "Mod5"
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(builtin_mods); i++) {
|
||||
keymap->mods.mods[i].name = xkb_atom_intern(keymap->ctx,
|
||||
builtin_mods[i],
|
||||
strlen(builtin_mods[i]));
|
||||
keymap->mods.mods[i].type = MOD_REAL;
|
||||
}
|
||||
keymap->mods.num_mods = ARRAY_SIZE(builtin_mods);
|
||||
}
|
||||
|
||||
struct xkb_keymap *
|
||||
xkb_keymap_new(struct xkb_context *ctx,
|
||||
enum xkb_keymap_format format,
|
||||
enum xkb_keymap_compile_flags flags)
|
||||
{
|
||||
struct xkb_keymap *keymap;
|
||||
|
||||
keymap = calloc(1, sizeof(*keymap));
|
||||
if (!keymap)
|
||||
return NULL;
|
||||
|
||||
keymap->refcnt = 1;
|
||||
keymap->ctx = xkb_context_ref(ctx);
|
||||
|
||||
keymap->format = format;
|
||||
keymap->flags = flags;
|
||||
|
||||
update_builtin_keymap_fields(keymap);
|
||||
|
||||
return keymap;
|
||||
}
|
||||
|
||||
struct xkb_key *
|
||||
XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases)
|
||||
{
|
||||
struct xkb_key *key;
|
||||
|
||||
xkb_keys_foreach(key, keymap)
|
||||
if (key->name == name)
|
||||
return key;
|
||||
|
||||
if (use_aliases) {
|
||||
xkb_atom_t new_name = XkbResolveKeyAlias(keymap, name);
|
||||
if (new_name != XKB_ATOM_NONE)
|
||||
return XkbKeyByName(keymap, new_name, false);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xkb_atom_t
|
||||
XkbResolveKeyAlias(const struct xkb_keymap *keymap, xkb_atom_t name)
|
||||
{
|
||||
for (unsigned i = 0; i < keymap->num_key_aliases; i++)
|
||||
if (keymap->key_aliases[i].alias == name)
|
||||
return keymap->key_aliases[i].real;
|
||||
|
||||
return XKB_ATOM_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
XkbEscapeMapName(char *name)
|
||||
{
|
||||
/*
|
||||
* All latin-1 alphanumerics, plus parens, slash, minus, underscore and
|
||||
* wildcards.
|
||||
*/
|
||||
static const unsigned char legal[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
|
||||
0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
|
||||
};
|
||||
|
||||
if (!name)
|
||||
return;
|
||||
|
||||
while (*name) {
|
||||
unsigned char c = *name;
|
||||
if (!(legal[c / 8] & (1 << (c % 8))))
|
||||
*name = '_';
|
||||
name++;
|
||||
}
|
||||
}
|
||||
|
||||
xkb_mod_index_t
|
||||
XkbModNameToIndex(const struct xkb_mod_set *mods, xkb_atom_t name,
|
||||
enum mod_type type)
|
||||
{
|
||||
xkb_mod_index_t i;
|
||||
const struct xkb_mod *mod;
|
||||
|
||||
xkb_mods_enumerate(i, mod, mods)
|
||||
if ((mod->type & type) && name == mod->name)
|
||||
return i;
|
||||
|
||||
return XKB_MOD_INVALID;
|
||||
}
|
||||
|
||||
bool
|
||||
XkbLevelsSameSyms(const struct xkb_level *a, const struct xkb_level *b)
|
||||
{
|
||||
if (a->num_syms != b->num_syms)
|
||||
return false;
|
||||
if (a->num_syms <= 1)
|
||||
return a->u.sym == b->u.sym;
|
||||
return memcmp(a->u.syms, b->u.syms, sizeof(*a->u.syms) * a->num_syms) == 0;
|
||||
}
|
519
src/3rdparty/xkbcommon/src/keymap.c
vendored
519
src/3rdparty/xkbcommon/src/keymap.c
vendored
@ -1,519 +0,0 @@
|
||||
/**
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
/************************************************************
|
||||
* Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ********************************************************/
|
||||
|
||||
#include "keymap.h"
|
||||
#include "text.h"
|
||||
|
||||
XKB_EXPORT struct xkb_keymap *
|
||||
xkb_keymap_ref(struct xkb_keymap *keymap)
|
||||
{
|
||||
keymap->refcnt++;
|
||||
return keymap;
|
||||
}
|
||||
|
||||
XKB_EXPORT void
|
||||
xkb_keymap_unref(struct xkb_keymap *keymap)
|
||||
{
|
||||
if (!keymap || --keymap->refcnt > 0)
|
||||
return;
|
||||
|
||||
if (keymap->keys) {
|
||||
struct xkb_key *key;
|
||||
xkb_keys_foreach(key, keymap) {
|
||||
if (key->groups) {
|
||||
for (unsigned i = 0; i < key->num_groups; i++) {
|
||||
if (key->groups[i].levels) {
|
||||
for (unsigned j = 0; j < XkbKeyNumLevels(key, i); j++)
|
||||
if (key->groups[i].levels[j].num_syms > 1)
|
||||
free(key->groups[i].levels[j].u.syms);
|
||||
free(key->groups[i].levels);
|
||||
}
|
||||
}
|
||||
free(key->groups);
|
||||
}
|
||||
}
|
||||
free(keymap->keys);
|
||||
}
|
||||
if (keymap->types) {
|
||||
for (unsigned i = 0; i < keymap->num_types; i++) {
|
||||
free(keymap->types[i].entries);
|
||||
free(keymap->types[i].level_names);
|
||||
}
|
||||
free(keymap->types);
|
||||
}
|
||||
free(keymap->sym_interprets);
|
||||
free(keymap->key_aliases);
|
||||
free(keymap->group_names);
|
||||
free(keymap->keycodes_section_name);
|
||||
free(keymap->symbols_section_name);
|
||||
free(keymap->types_section_name);
|
||||
free(keymap->compat_section_name);
|
||||
xkb_context_unref(keymap->ctx);
|
||||
free(keymap);
|
||||
}
|
||||
|
||||
static const struct xkb_keymap_format_ops *
|
||||
get_keymap_format_ops(enum xkb_keymap_format format)
|
||||
{
|
||||
static const struct xkb_keymap_format_ops *keymap_format_ops[] = {
|
||||
[XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops,
|
||||
};
|
||||
|
||||
if ((int) format < 0 || (int) format >= (int) ARRAY_SIZE(keymap_format_ops))
|
||||
return NULL;
|
||||
|
||||
return keymap_format_ops[(int) format];
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_keymap *
|
||||
xkb_keymap_new_from_names(struct xkb_context *ctx,
|
||||
const struct xkb_rule_names *rmlvo_in,
|
||||
enum xkb_keymap_compile_flags flags)
|
||||
{
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_rule_names rmlvo;
|
||||
const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1;
|
||||
const struct xkb_keymap_format_ops *ops;
|
||||
|
||||
ops = get_keymap_format_ops(format);
|
||||
if (!ops || !ops->keymap_new_from_names) {
|
||||
log_err_func(ctx, "unsupported keymap format: %d\n", format);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
|
||||
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
keymap = xkb_keymap_new(ctx, format, flags);
|
||||
if (!keymap)
|
||||
return NULL;
|
||||
|
||||
if (rmlvo_in)
|
||||
rmlvo = *rmlvo_in;
|
||||
else
|
||||
memset(&rmlvo, 0, sizeof(rmlvo));
|
||||
xkb_context_sanitize_rule_names(ctx, &rmlvo);
|
||||
|
||||
if (!ops->keymap_new_from_names(keymap, &rmlvo)) {
|
||||
xkb_keymap_unref(keymap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return keymap;
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_keymap *
|
||||
xkb_keymap_new_from_string(struct xkb_context *ctx,
|
||||
const char *string,
|
||||
enum xkb_keymap_format format,
|
||||
enum xkb_keymap_compile_flags flags)
|
||||
{
|
||||
return xkb_keymap_new_from_buffer(ctx, string, strlen(string),
|
||||
format, flags);
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_keymap *
|
||||
xkb_keymap_new_from_buffer(struct xkb_context *ctx,
|
||||
const char *buffer, size_t length,
|
||||
enum xkb_keymap_format format,
|
||||
enum xkb_keymap_compile_flags flags)
|
||||
{
|
||||
struct xkb_keymap *keymap;
|
||||
const struct xkb_keymap_format_ops *ops;
|
||||
|
||||
ops = get_keymap_format_ops(format);
|
||||
if (!ops || !ops->keymap_new_from_string) {
|
||||
log_err_func(ctx, "unsupported keymap format: %d\n", format);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
|
||||
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!buffer) {
|
||||
log_err_func1(ctx, "no buffer specified\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
keymap = xkb_keymap_new(ctx, format, flags);
|
||||
if (!keymap)
|
||||
return NULL;
|
||||
|
||||
if (!ops->keymap_new_from_string(keymap, buffer, length)) {
|
||||
xkb_keymap_unref(keymap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return keymap;
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_keymap *
|
||||
xkb_keymap_new_from_file(struct xkb_context *ctx,
|
||||
FILE *file,
|
||||
enum xkb_keymap_format format,
|
||||
enum xkb_keymap_compile_flags flags)
|
||||
{
|
||||
struct xkb_keymap *keymap;
|
||||
const struct xkb_keymap_format_ops *ops;
|
||||
|
||||
ops = get_keymap_format_ops(format);
|
||||
if (!ops || !ops->keymap_new_from_file) {
|
||||
log_err_func(ctx, "unsupported keymap format: %d\n", format);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
|
||||
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
log_err_func1(ctx, "no file specified\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
keymap = xkb_keymap_new(ctx, format, flags);
|
||||
if (!keymap)
|
||||
return NULL;
|
||||
|
||||
if (!ops->keymap_new_from_file(keymap, file)) {
|
||||
xkb_keymap_unref(keymap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return keymap;
|
||||
}
|
||||
|
||||
XKB_EXPORT char *
|
||||
xkb_keymap_get_as_string(struct xkb_keymap *keymap,
|
||||
enum xkb_keymap_format format)
|
||||
{
|
||||
const struct xkb_keymap_format_ops *ops;
|
||||
|
||||
if (format == XKB_KEYMAP_USE_ORIGINAL_FORMAT)
|
||||
format = keymap->format;
|
||||
|
||||
ops = get_keymap_format_ops(format);
|
||||
if (!ops || !ops->keymap_get_as_string) {
|
||||
log_err_func(keymap->ctx, "unsupported keymap format: %d\n", format);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ops->keymap_get_as_string(keymap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of modifiers active in the keymap.
|
||||
*/
|
||||
XKB_EXPORT xkb_mod_index_t
|
||||
xkb_keymap_num_mods(struct xkb_keymap *keymap)
|
||||
{
|
||||
return keymap->mods.num_mods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name for a given modifier.
|
||||
*/
|
||||
XKB_EXPORT const char *
|
||||
xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx)
|
||||
{
|
||||
if (idx >= keymap->mods.num_mods)
|
||||
return NULL;
|
||||
|
||||
return xkb_atom_text(keymap->ctx, keymap->mods.mods[idx].name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index for a named modifier.
|
||||
*/
|
||||
XKB_EXPORT xkb_mod_index_t
|
||||
xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name)
|
||||
{
|
||||
xkb_atom_t atom;
|
||||
|
||||
atom = xkb_atom_lookup(keymap->ctx, name);
|
||||
if (atom == XKB_ATOM_NONE)
|
||||
return XKB_MOD_INVALID;
|
||||
|
||||
return XkbModNameToIndex(&keymap->mods, atom, MOD_BOTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total number of active groups in the keymap.
|
||||
*/
|
||||
XKB_EXPORT xkb_layout_index_t
|
||||
xkb_keymap_num_layouts(struct xkb_keymap *keymap)
|
||||
{
|
||||
return keymap->num_groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name for a given group.
|
||||
*/
|
||||
XKB_EXPORT const char *
|
||||
xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx)
|
||||
{
|
||||
if (idx >= keymap->num_group_names)
|
||||
return NULL;
|
||||
|
||||
return xkb_atom_text(keymap->ctx, keymap->group_names[idx]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index for a named layout.
|
||||
*/
|
||||
XKB_EXPORT xkb_layout_index_t
|
||||
xkb_keymap_layout_get_index(struct xkb_keymap *keymap, const char *name)
|
||||
{
|
||||
xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
|
||||
xkb_layout_index_t i;
|
||||
|
||||
if (atom == XKB_ATOM_NONE)
|
||||
return XKB_LAYOUT_INVALID;
|
||||
|
||||
for (i = 0; i < keymap->num_group_names; i++)
|
||||
if (keymap->group_names[i] == atom)
|
||||
return i;
|
||||
|
||||
return XKB_LAYOUT_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of layouts active for a particular key.
|
||||
*/
|
||||
XKB_EXPORT xkb_layout_index_t
|
||||
xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc)
|
||||
{
|
||||
const struct xkb_key *key = XkbKey(keymap, kc);
|
||||
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
return key->num_groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of levels active for a particular key and layout.
|
||||
*/
|
||||
XKB_EXPORT xkb_level_index_t
|
||||
xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc,
|
||||
xkb_layout_index_t layout)
|
||||
{
|
||||
const struct xkb_key *key = XkbKey(keymap, kc);
|
||||
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
layout = XkbWrapGroupIntoRange(layout, key->num_groups,
|
||||
key->out_of_range_group_action,
|
||||
key->out_of_range_group_number);
|
||||
if (layout == XKB_LAYOUT_INVALID)
|
||||
return 0;
|
||||
|
||||
return XkbKeyNumLevels(key, layout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total number of LEDs in the keymap.
|
||||
*/
|
||||
XKB_EXPORT xkb_led_index_t
|
||||
xkb_keymap_num_leds(struct xkb_keymap *keymap)
|
||||
{
|
||||
return keymap->num_leds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name for a given LED.
|
||||
*/
|
||||
XKB_EXPORT const char *
|
||||
xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx)
|
||||
{
|
||||
if (idx >= keymap->num_leds)
|
||||
return NULL;
|
||||
|
||||
return xkb_atom_text(keymap->ctx, keymap->leds[idx].name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index for a named LED.
|
||||
*/
|
||||
XKB_EXPORT xkb_led_index_t
|
||||
xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name)
|
||||
{
|
||||
xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
|
||||
xkb_led_index_t i;
|
||||
const struct xkb_led *led;
|
||||
|
||||
if (atom == XKB_ATOM_NONE)
|
||||
return XKB_LED_INVALID;
|
||||
|
||||
xkb_leds_enumerate(i, led, keymap)
|
||||
if (led->name == atom)
|
||||
return i;
|
||||
|
||||
return XKB_LED_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* As below, but takes an explicit layout/level rather than state.
|
||||
*/
|
||||
XKB_EXPORT int
|
||||
xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap,
|
||||
xkb_keycode_t kc,
|
||||
xkb_layout_index_t layout,
|
||||
xkb_level_index_t level,
|
||||
const xkb_keysym_t **syms_out)
|
||||
{
|
||||
const struct xkb_key *key = XkbKey(keymap, kc);
|
||||
int num_syms;
|
||||
|
||||
if (!key)
|
||||
goto err;
|
||||
|
||||
layout = XkbWrapGroupIntoRange(layout, key->num_groups,
|
||||
key->out_of_range_group_action,
|
||||
key->out_of_range_group_number);
|
||||
if (layout == XKB_LAYOUT_INVALID)
|
||||
goto err;
|
||||
|
||||
if (level >= XkbKeyNumLevels(key, layout))
|
||||
goto err;
|
||||
|
||||
num_syms = key->groups[layout].levels[level].num_syms;
|
||||
if (num_syms == 0)
|
||||
goto err;
|
||||
|
||||
if (num_syms == 1)
|
||||
*syms_out = &key->groups[layout].levels[level].u.sym;
|
||||
else
|
||||
*syms_out = key->groups[layout].levels[level].u.syms;
|
||||
|
||||
return num_syms;
|
||||
|
||||
err:
|
||||
*syms_out = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keycode_t
|
||||
xkb_keymap_min_keycode(struct xkb_keymap *keymap)
|
||||
{
|
||||
return keymap->min_key_code;
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keycode_t
|
||||
xkb_keymap_max_keycode(struct xkb_keymap *keymap)
|
||||
{
|
||||
return keymap->max_key_code;
|
||||
}
|
||||
|
||||
XKB_EXPORT void
|
||||
xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
|
||||
void *data)
|
||||
{
|
||||
struct xkb_key *key;
|
||||
|
||||
xkb_keys_foreach(key, keymap)
|
||||
iter(keymap, key->keycode, data);
|
||||
}
|
||||
|
||||
XKB_EXPORT const char *
|
||||
xkb_keymap_key_get_name(struct xkb_keymap *keymap, xkb_keycode_t kc)
|
||||
{
|
||||
const struct xkb_key *key = XkbKey(keymap, kc);
|
||||
|
||||
if (!key)
|
||||
return NULL;
|
||||
|
||||
return xkb_atom_text(keymap->ctx, key->name);
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keycode_t
|
||||
xkb_keymap_key_by_name(struct xkb_keymap *keymap, const char *name)
|
||||
{
|
||||
struct xkb_key *key;
|
||||
xkb_atom_t atom;
|
||||
|
||||
atom = xkb_atom_lookup(keymap->ctx, name);
|
||||
if (atom) {
|
||||
xkb_atom_t ratom = XkbResolveKeyAlias(keymap, atom);
|
||||
if (ratom)
|
||||
atom = ratom;
|
||||
}
|
||||
if (!atom)
|
||||
return XKB_KEYCODE_INVALID;
|
||||
|
||||
xkb_keys_foreach(key, keymap) {
|
||||
if (key->name == atom)
|
||||
return key->keycode;
|
||||
}
|
||||
|
||||
return XKB_KEYCODE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple boolean specifying whether or not the key should repeat.
|
||||
*/
|
||||
XKB_EXPORT int
|
||||
xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
|
||||
{
|
||||
const struct xkb_key *key = XkbKey(keymap, kc);
|
||||
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
return key->repeats;
|
||||
}
|
482
src/3rdparty/xkbcommon/src/keymap.h
vendored
482
src/3rdparty/xkbcommon/src/keymap.h
vendored
@ -1,482 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1987, 1990, 1998 The Open Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the names of the authors or their
|
||||
* institutions shall not be used in advertising or otherwise to promote the
|
||||
* sale, use or other dealings in this Software without prior written
|
||||
* authorization from the authors.
|
||||
*/
|
||||
|
||||
/************************************************************
|
||||
* Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* Copyright © 2009 Dan Nicholson
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2012 Ran Benita
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
* Dan Nicholson <dbn.lists@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef KEYMAP_H
|
||||
#define KEYMAP_H
|
||||
|
||||
/* Don't use compat names in internal code. */
|
||||
#define _XKBCOMMON_COMPAT_H
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "context.h"
|
||||
|
||||
/* This limit is artificially enforced, we do not depend on it any where.
|
||||
* The reason it's still here is that the rules file format does not
|
||||
* support multiple groups very well, and the rules shipped with
|
||||
* xkeyboard-config (see rules/evdev) depend on this limit extensively.
|
||||
* So just lifting this limit would cause problems for people who will use
|
||||
* more than 4 layouts.
|
||||
* TODO: Fix the group index syntax in the rules format, preferably in a
|
||||
* backwards compatible way.
|
||||
* See e.g. https://bugs.freedesktop.org/show_bug.cgi?id=14372
|
||||
* Note: A limit on the number of groups we *do* depend on is imposed by
|
||||
* the size of the xkb_layout_mask_t type (32). This is more than enough
|
||||
* though.
|
||||
*/
|
||||
#define XKB_MAX_GROUPS 4
|
||||
|
||||
/* Don't allow more modifiers than we can hold in xkb_mod_mask_t. */
|
||||
#define XKB_MAX_MODS ((xkb_mod_index_t) (sizeof(xkb_mod_mask_t) * 8))
|
||||
|
||||
/* Don't allow more leds than we can hold in xkb_led_mask_t. */
|
||||
#define XKB_MAX_LEDS ((xkb_led_index_t) (sizeof(xkb_led_mask_t) * 8))
|
||||
|
||||
/* These should all go away. */
|
||||
enum mod_type {
|
||||
MOD_REAL = (1 << 0),
|
||||
MOD_VIRT = (1 << 1),
|
||||
MOD_BOTH = (MOD_REAL | MOD_VIRT),
|
||||
};
|
||||
#define MOD_REAL_MASK_ALL ((xkb_mod_mask_t) 0x000000ff)
|
||||
|
||||
enum xkb_action_type {
|
||||
ACTION_TYPE_NONE = 0,
|
||||
ACTION_TYPE_MOD_SET,
|
||||
ACTION_TYPE_MOD_LATCH,
|
||||
ACTION_TYPE_MOD_LOCK,
|
||||
ACTION_TYPE_GROUP_SET,
|
||||
ACTION_TYPE_GROUP_LATCH,
|
||||
ACTION_TYPE_GROUP_LOCK,
|
||||
ACTION_TYPE_PTR_MOVE,
|
||||
ACTION_TYPE_PTR_BUTTON,
|
||||
ACTION_TYPE_PTR_LOCK,
|
||||
ACTION_TYPE_PTR_DEFAULT,
|
||||
ACTION_TYPE_TERMINATE,
|
||||
ACTION_TYPE_SWITCH_VT,
|
||||
ACTION_TYPE_CTRL_SET,
|
||||
ACTION_TYPE_CTRL_LOCK,
|
||||
ACTION_TYPE_PRIVATE,
|
||||
_ACTION_TYPE_NUM_ENTRIES
|
||||
};
|
||||
|
||||
enum xkb_action_flags {
|
||||
ACTION_LOCK_CLEAR = (1 << 0),
|
||||
ACTION_LATCH_TO_LOCK = (1 << 1),
|
||||
ACTION_LOCK_NO_LOCK = (1 << 2),
|
||||
ACTION_LOCK_NO_UNLOCK = (1 << 3),
|
||||
ACTION_MODS_LOOKUP_MODMAP = (1 << 4),
|
||||
ACTION_ABSOLUTE_SWITCH = (1 << 5),
|
||||
ACTION_ABSOLUTE_X = (1 << 6),
|
||||
ACTION_ABSOLUTE_Y = (1 << 7),
|
||||
ACTION_ACCEL = (1 << 8),
|
||||
ACTION_SAME_SCREEN = (1 << 9),
|
||||
};
|
||||
|
||||
enum xkb_action_controls {
|
||||
CONTROL_REPEAT = (1 << 0),
|
||||
CONTROL_SLOW = (1 << 1),
|
||||
CONTROL_DEBOUNCE = (1 << 2),
|
||||
CONTROL_STICKY = (1 << 3),
|
||||
CONTROL_MOUSEKEYS = (1 << 4),
|
||||
CONTROL_MOUSEKEYS_ACCEL = (1 << 5),
|
||||
CONTROL_AX = (1 << 6),
|
||||
CONTROL_AX_TIMEOUT = (1 << 7),
|
||||
CONTROL_AX_FEEDBACK = (1 << 8),
|
||||
CONTROL_BELL = (1 << 9),
|
||||
CONTROL_IGNORE_GROUP_LOCK = (1 << 10),
|
||||
CONTROL_ALL = \
|
||||
(CONTROL_REPEAT | CONTROL_SLOW | CONTROL_DEBOUNCE | CONTROL_STICKY | \
|
||||
CONTROL_MOUSEKEYS | CONTROL_MOUSEKEYS_ACCEL | CONTROL_AX | \
|
||||
CONTROL_AX_TIMEOUT | CONTROL_AX_FEEDBACK | CONTROL_BELL | \
|
||||
CONTROL_IGNORE_GROUP_LOCK)
|
||||
};
|
||||
|
||||
enum xkb_match_operation {
|
||||
MATCH_NONE,
|
||||
MATCH_ANY_OR_NONE,
|
||||
MATCH_ANY,
|
||||
MATCH_ALL,
|
||||
MATCH_EXACTLY,
|
||||
};
|
||||
|
||||
struct xkb_mods {
|
||||
xkb_mod_mask_t mods; /* original real+virtual mods in definition */
|
||||
xkb_mod_mask_t mask; /* computed effective mask */
|
||||
};
|
||||
|
||||
struct xkb_mod_action {
|
||||
enum xkb_action_type type;
|
||||
enum xkb_action_flags flags;
|
||||
struct xkb_mods mods;
|
||||
};
|
||||
|
||||
struct xkb_group_action {
|
||||
enum xkb_action_type type;
|
||||
enum xkb_action_flags flags;
|
||||
int32_t group;
|
||||
};
|
||||
|
||||
struct xkb_controls_action {
|
||||
enum xkb_action_type type;
|
||||
enum xkb_action_flags flags;
|
||||
enum xkb_action_controls ctrls;
|
||||
};
|
||||
|
||||
struct xkb_pointer_default_action {
|
||||
enum xkb_action_type type;
|
||||
enum xkb_action_flags flags;
|
||||
int8_t value;
|
||||
};
|
||||
|
||||
struct xkb_switch_screen_action {
|
||||
enum xkb_action_type type;
|
||||
enum xkb_action_flags flags;
|
||||
int8_t screen;
|
||||
};
|
||||
|
||||
struct xkb_pointer_action {
|
||||
enum xkb_action_type type;
|
||||
enum xkb_action_flags flags;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
};
|
||||
|
||||
struct xkb_pointer_button_action {
|
||||
enum xkb_action_type type;
|
||||
enum xkb_action_flags flags;
|
||||
uint8_t count;
|
||||
uint8_t button;
|
||||
};
|
||||
|
||||
struct xkb_private_action {
|
||||
enum xkb_action_type type;
|
||||
uint8_t data[7];
|
||||
};
|
||||
|
||||
union xkb_action {
|
||||
enum xkb_action_type type;
|
||||
struct xkb_mod_action mods;
|
||||
struct xkb_group_action group;
|
||||
struct xkb_controls_action ctrls;
|
||||
struct xkb_pointer_default_action dflt;
|
||||
struct xkb_switch_screen_action screen;
|
||||
struct xkb_pointer_action ptr;
|
||||
struct xkb_pointer_button_action btn;
|
||||
struct xkb_private_action priv;
|
||||
};
|
||||
|
||||
struct xkb_key_type_entry {
|
||||
xkb_level_index_t level;
|
||||
struct xkb_mods mods;
|
||||
struct xkb_mods preserve;
|
||||
};
|
||||
|
||||
struct xkb_key_type {
|
||||
xkb_atom_t name;
|
||||
struct xkb_mods mods;
|
||||
xkb_level_index_t num_levels;
|
||||
unsigned int num_level_names;
|
||||
xkb_atom_t *level_names;
|
||||
unsigned int num_entries;
|
||||
struct xkb_key_type_entry *entries;
|
||||
};
|
||||
|
||||
struct xkb_sym_interpret {
|
||||
xkb_keysym_t sym;
|
||||
enum xkb_match_operation match;
|
||||
xkb_mod_mask_t mods;
|
||||
xkb_mod_index_t virtual_mod;
|
||||
union xkb_action action;
|
||||
bool level_one_only;
|
||||
bool repeat;
|
||||
};
|
||||
|
||||
struct xkb_led {
|
||||
xkb_atom_t name;
|
||||
enum xkb_state_component which_groups;
|
||||
xkb_layout_mask_t groups;
|
||||
enum xkb_state_component which_mods;
|
||||
struct xkb_mods mods;
|
||||
enum xkb_action_controls ctrls;
|
||||
};
|
||||
|
||||
struct xkb_key_alias {
|
||||
xkb_atom_t real;
|
||||
xkb_atom_t alias;
|
||||
};
|
||||
|
||||
struct xkb_controls {
|
||||
unsigned char groups_wrap;
|
||||
struct xkb_mods internal;
|
||||
struct xkb_mods ignore_lock;
|
||||
unsigned short repeat_delay;
|
||||
unsigned short repeat_interval;
|
||||
unsigned short slow_keys_delay;
|
||||
unsigned short debounce_delay;
|
||||
unsigned short ax_options;
|
||||
unsigned short ax_timeout;
|
||||
unsigned short axt_opts_mask;
|
||||
unsigned short axt_opts_values;
|
||||
unsigned int axt_ctrls_mask;
|
||||
unsigned int axt_ctrls_values;
|
||||
};
|
||||
|
||||
/* Such an awkward name. Oh well. */
|
||||
enum xkb_range_exceed_type {
|
||||
RANGE_WRAP = 0,
|
||||
RANGE_SATURATE,
|
||||
RANGE_REDIRECT,
|
||||
};
|
||||
|
||||
enum xkb_explicit_components {
|
||||
EXPLICIT_INTERP = (1 << 0),
|
||||
EXPLICIT_VMODMAP = (1 << 1),
|
||||
EXPLICIT_REPEAT = (1 << 2),
|
||||
};
|
||||
|
||||
struct xkb_level {
|
||||
union xkb_action action;
|
||||
unsigned int num_syms;
|
||||
union {
|
||||
xkb_keysym_t sym; /* num_syms == 1 */
|
||||
xkb_keysym_t *syms; /* num_syms > 1 */
|
||||
} u;
|
||||
};
|
||||
|
||||
struct xkb_group {
|
||||
bool explicit_type;
|
||||
/* Points to a type in keymap->types. */
|
||||
const struct xkb_key_type *type;
|
||||
/* Use XkbKeyNumLevels for the number of levels. */
|
||||
struct xkb_level *levels;
|
||||
};
|
||||
|
||||
struct xkb_key {
|
||||
xkb_keycode_t keycode;
|
||||
xkb_atom_t name;
|
||||
|
||||
enum xkb_explicit_components explicit;
|
||||
|
||||
xkb_mod_mask_t modmap;
|
||||
xkb_mod_mask_t vmodmap;
|
||||
|
||||
bool repeats;
|
||||
|
||||
enum xkb_range_exceed_type out_of_range_group_action;
|
||||
xkb_layout_index_t out_of_range_group_number;
|
||||
|
||||
xkb_layout_index_t num_groups;
|
||||
struct xkb_group *groups;
|
||||
};
|
||||
|
||||
struct xkb_mod {
|
||||
xkb_atom_t name;
|
||||
enum mod_type type;
|
||||
xkb_mod_mask_t mapping; /* vmod -> real mod mapping */
|
||||
};
|
||||
|
||||
struct xkb_mod_set {
|
||||
struct xkb_mod mods[XKB_MAX_MODS];
|
||||
unsigned int num_mods;
|
||||
};
|
||||
|
||||
/* Common keyboard description structure */
|
||||
struct xkb_keymap {
|
||||
struct xkb_context *ctx;
|
||||
|
||||
int refcnt;
|
||||
enum xkb_keymap_compile_flags flags;
|
||||
enum xkb_keymap_format format;
|
||||
|
||||
enum xkb_action_controls enabled_ctrls;
|
||||
|
||||
xkb_keycode_t min_key_code;
|
||||
xkb_keycode_t max_key_code;
|
||||
struct xkb_key *keys;
|
||||
|
||||
/* aliases in no particular order */
|
||||
unsigned int num_key_aliases;
|
||||
struct xkb_key_alias *key_aliases;
|
||||
|
||||
struct xkb_key_type *types;
|
||||
unsigned int num_types;
|
||||
|
||||
unsigned int num_sym_interprets;
|
||||
struct xkb_sym_interpret *sym_interprets;
|
||||
|
||||
struct xkb_mod_set mods;
|
||||
|
||||
/* Number of groups in the key with the most groups. */
|
||||
xkb_layout_index_t num_groups;
|
||||
/* Not all groups must have names. */
|
||||
xkb_layout_index_t num_group_names;
|
||||
xkb_atom_t *group_names;
|
||||
|
||||
struct xkb_led leds[XKB_MAX_LEDS];
|
||||
unsigned int num_leds;
|
||||
|
||||
char *keycodes_section_name;
|
||||
char *symbols_section_name;
|
||||
char *types_section_name;
|
||||
char *compat_section_name;
|
||||
};
|
||||
|
||||
#define xkb_keys_foreach(iter, keymap) \
|
||||
for ((iter) = (keymap)->keys + (keymap)->min_key_code; \
|
||||
(iter) <= (keymap)->keys + (keymap)->max_key_code; \
|
||||
(iter)++)
|
||||
|
||||
#define xkb_mods_foreach(iter, mods_) \
|
||||
for ((iter) = (mods_)->mods; \
|
||||
(iter) < (mods_)->mods + (mods_)->num_mods; \
|
||||
(iter)++)
|
||||
|
||||
#define xkb_mods_enumerate(idx, iter, mods_) \
|
||||
for ((idx) = 0, (iter) = (mods_)->mods; \
|
||||
(idx) < (mods_)->num_mods; \
|
||||
(idx)++, (iter)++)
|
||||
|
||||
#define xkb_leds_foreach(iter, keymap) \
|
||||
for ((iter) = (keymap)->leds; \
|
||||
(iter) < (keymap)->leds + (keymap)->num_leds; \
|
||||
(iter)++)
|
||||
|
||||
#define xkb_leds_enumerate(idx, iter, keymap) \
|
||||
for ((idx) = 0, (iter) = (keymap)->leds; \
|
||||
(idx) < (keymap)->num_leds; \
|
||||
(idx)++, (iter)++)
|
||||
|
||||
static inline const struct xkb_key *
|
||||
XkbKey(struct xkb_keymap *keymap, xkb_keycode_t kc)
|
||||
{
|
||||
if (kc < keymap->min_key_code || kc > keymap->max_key_code)
|
||||
return NULL;
|
||||
return &keymap->keys[kc];
|
||||
}
|
||||
|
||||
static inline xkb_level_index_t
|
||||
XkbKeyNumLevels(const struct xkb_key *key, xkb_layout_index_t layout)
|
||||
{
|
||||
return key->groups[layout].type->num_levels;
|
||||
}
|
||||
|
||||
struct xkb_keymap *
|
||||
xkb_keymap_new(struct xkb_context *ctx,
|
||||
enum xkb_keymap_format format,
|
||||
enum xkb_keymap_compile_flags flags);
|
||||
|
||||
struct xkb_key *
|
||||
XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases);
|
||||
|
||||
xkb_atom_t
|
||||
XkbResolveKeyAlias(const struct xkb_keymap *keymap, xkb_atom_t name);
|
||||
|
||||
void
|
||||
XkbEscapeMapName(char *name);
|
||||
|
||||
xkb_mod_index_t
|
||||
XkbModNameToIndex(const struct xkb_mod_set *mods, xkb_atom_t name,
|
||||
enum mod_type type);
|
||||
|
||||
bool
|
||||
XkbLevelsSameSyms(const struct xkb_level *a, const struct xkb_level *b);
|
||||
|
||||
xkb_layout_index_t
|
||||
XkbWrapGroupIntoRange(int32_t group,
|
||||
xkb_layout_index_t num_groups,
|
||||
enum xkb_range_exceed_type out_of_range_group_action,
|
||||
xkb_layout_index_t out_of_range_group_number);
|
||||
|
||||
xkb_mod_mask_t
|
||||
mod_mask_get_effective(struct xkb_keymap *keymap, xkb_mod_mask_t mods);
|
||||
|
||||
struct xkb_keymap_format_ops {
|
||||
bool (*keymap_new_from_names)(struct xkb_keymap *keymap,
|
||||
const struct xkb_rule_names *names);
|
||||
bool (*keymap_new_from_string)(struct xkb_keymap *keymap,
|
||||
const char *string, size_t length);
|
||||
bool (*keymap_new_from_file)(struct xkb_keymap *keymap, FILE *file);
|
||||
char *(*keymap_get_as_string)(struct xkb_keymap *keymap);
|
||||
};
|
||||
|
||||
extern const struct xkb_keymap_format_ops text_v1_keymap_format_ops;
|
||||
|
||||
#endif
|
937
src/3rdparty/xkbcommon/src/keysym-utf.c
vendored
937
src/3rdparty/xkbcommon/src/keysym-utf.c
vendored
@ -1,937 +0,0 @@
|
||||
/* The table and comments below along with the function xkb_keysym_to_ucs4
|
||||
* are under the public domain and are derived as described below.
|
||||
*/
|
||||
/* This module converts keysym values into the corresponding ISO 10646
|
||||
* (UCS, Unicode) values.
|
||||
*
|
||||
* The array keysymtab[] contains pairs of X11 keysym values for graphical
|
||||
* characters and the corresponding Unicode value. The function
|
||||
* keysym2ucs() maps a keysym onto a Unicode value using a binary search,
|
||||
* therefore keysymtab[] must remain SORTED by keysym value.
|
||||
*
|
||||
* The keysym -> UTF-8 conversion will hopefully one day be provided
|
||||
* by Xlib via XmbLookupString() and should ideally not have to be
|
||||
* done in X applications. But we are not there yet.
|
||||
*
|
||||
* We allow to represent any UCS character in the range U-00000000 to
|
||||
* U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
|
||||
* This admittedly does not cover the entire 31-bit space of UCS, but
|
||||
* it does cover all of the characters up to U-10FFFF, which can be
|
||||
* represented by UTF-16, and more, and it is very unlikely that higher
|
||||
* UCS codes will ever be assigned by ISO. So to get Unicode character
|
||||
* U+ABCD you can directly use keysym 0x0100abcd.
|
||||
*
|
||||
* NOTE: The comments in the table below contain the actual character
|
||||
* encoded in UTF-8, so for viewing and editing best use an editor in
|
||||
* UTF-8 mode.
|
||||
*
|
||||
* Author: Markus G. Kuhn <http://www.cl.cam.ac.uk/~mgk25/>,
|
||||
* University of Cambridge, April 2001
|
||||
*
|
||||
* Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing
|
||||
* an initial draft of the mapping table.
|
||||
*
|
||||
* This software is in the public domain. Share and enjoy!
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "utils.h"
|
||||
#include "utf8.h"
|
||||
|
||||
/* We don't use the uint32_t types here, to save some space. */
|
||||
struct codepair {
|
||||
uint16_t keysym;
|
||||
uint16_t ucs;
|
||||
};
|
||||
|
||||
static const struct codepair keysymtab[] = {
|
||||
{ 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */
|
||||
{ 0x01a2, 0x02d8 }, /* breve ˘ BREVE */
|
||||
{ 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */
|
||||
{ 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */
|
||||
{ 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */
|
||||
{ 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */
|
||||
{ 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */
|
||||
{ 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */
|
||||
{ 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */
|
||||
{ 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */
|
||||
{ 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */
|
||||
{ 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */
|
||||
{ 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */
|
||||
{ 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */
|
||||
{ 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */
|
||||
{ 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */
|
||||
{ 0x01b7, 0x02c7 }, /* caron ˇ CARON */
|
||||
{ 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */
|
||||
{ 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */
|
||||
{ 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */
|
||||
{ 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */
|
||||
{ 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */
|
||||
{ 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */
|
||||
{ 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */
|
||||
{ 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */
|
||||
{ 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */
|
||||
{ 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */
|
||||
{ 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */
|
||||
{ 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */
|
||||
{ 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */
|
||||
{ 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */
|
||||
{ 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */
|
||||
{ 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */
|
||||
{ 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */
|
||||
{ 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */
|
||||
{ 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
|
||||
{ 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */
|
||||
{ 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */
|
||||
{ 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
|
||||
{ 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */
|
||||
{ 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */
|
||||
{ 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */
|
||||
{ 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */
|
||||
{ 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */
|
||||
{ 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */
|
||||
{ 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */
|
||||
{ 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */
|
||||
{ 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */
|
||||
{ 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */
|
||||
{ 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */
|
||||
{ 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */
|
||||
{ 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */
|
||||
{ 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */
|
||||
{ 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */
|
||||
{ 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */
|
||||
{ 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */
|
||||
{ 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */
|
||||
{ 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */
|
||||
{ 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
|
||||
{ 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */
|
||||
{ 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */
|
||||
{ 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
|
||||
{ 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */
|
||||
{ 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */
|
||||
{ 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */
|
||||
{ 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */
|
||||
{ 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */
|
||||
{ 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */
|
||||
{ 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
|
||||
{ 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */
|
||||
{ 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
|
||||
{ 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */
|
||||
{ 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
|
||||
{ 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */
|
||||
{ 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */
|
||||
{ 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */
|
||||
{ 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */
|
||||
{ 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */
|
||||
{ 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */
|
||||
{ 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */
|
||||
{ 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */
|
||||
{ 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */
|
||||
{ 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */
|
||||
{ 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */
|
||||
{ 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */
|
||||
{ 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */
|
||||
{ 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */
|
||||
{ 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */
|
||||
{ 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */
|
||||
{ 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */
|
||||
{ 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */
|
||||
{ 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */
|
||||
{ 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */
|
||||
{ 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */
|
||||
{ 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */
|
||||
{ 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */
|
||||
{ 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */
|
||||
{ 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */
|
||||
{ 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */
|
||||
{ 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */
|
||||
{ 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */
|
||||
{ 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */
|
||||
{ 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */
|
||||
{ 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */
|
||||
{ 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */
|
||||
{ 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */
|
||||
{ 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */
|
||||
{ 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */
|
||||
{ 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */
|
||||
{ 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */
|
||||
{ 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */
|
||||
{ 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */
|
||||
{ 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */
|
||||
{ 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */
|
||||
{ 0x047e, 0x203e }, /* overline ‾ OVERLINE */
|
||||
{ 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
|
||||
{ 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */
|
||||
{ 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */
|
||||
{ 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */
|
||||
{ 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */
|
||||
{ 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */
|
||||
{ 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */
|
||||
{ 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */
|
||||
{ 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */
|
||||
{ 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */
|
||||
{ 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */
|
||||
{ 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */
|
||||
{ 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */
|
||||
{ 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */
|
||||
{ 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */
|
||||
{ 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */
|
||||
{ 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */
|
||||
{ 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */
|
||||
{ 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */
|
||||
{ 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */
|
||||
{ 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */
|
||||
{ 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */
|
||||
{ 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */
|
||||
{ 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */
|
||||
{ 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */
|
||||
{ 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */
|
||||
{ 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */
|
||||
{ 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */
|
||||
{ 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */
|
||||
{ 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */
|
||||
{ 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */
|
||||
{ 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */
|
||||
{ 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */
|
||||
{ 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */
|
||||
{ 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */
|
||||
{ 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */
|
||||
{ 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */
|
||||
{ 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */
|
||||
{ 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */
|
||||
{ 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */
|
||||
{ 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */
|
||||
{ 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */
|
||||
{ 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */
|
||||
{ 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */
|
||||
{ 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */
|
||||
{ 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */
|
||||
{ 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */
|
||||
{ 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */
|
||||
{ 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */
|
||||
{ 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */
|
||||
{ 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */
|
||||
{ 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */
|
||||
{ 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */
|
||||
{ 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */
|
||||
{ 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */
|
||||
{ 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */
|
||||
{ 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */
|
||||
{ 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */
|
||||
{ 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */
|
||||
{ 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */
|
||||
{ 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */
|
||||
{ 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */
|
||||
{ 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
|
||||
{ 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */
|
||||
{ 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */
|
||||
{ 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */
|
||||
{ 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */
|
||||
{ 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */
|
||||
{ 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */
|
||||
{ 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */
|
||||
{ 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */
|
||||
{ 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */
|
||||
{ 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */
|
||||
{ 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */
|
||||
{ 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */
|
||||
{ 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */
|
||||
{ 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */
|
||||
{ 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */
|
||||
{ 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */
|
||||
{ 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */
|
||||
{ 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */
|
||||
{ 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */
|
||||
{ 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */
|
||||
{ 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */
|
||||
{ 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */
|
||||
{ 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */
|
||||
{ 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */
|
||||
{ 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */
|
||||
{ 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */
|
||||
{ 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */
|
||||
{ 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */
|
||||
{ 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */
|
||||
{ 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */
|
||||
{ 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */
|
||||
{ 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */
|
||||
{ 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */
|
||||
{ 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */
|
||||
{ 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */
|
||||
{ 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */
|
||||
{ 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */
|
||||
{ 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */
|
||||
{ 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */
|
||||
{ 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */
|
||||
{ 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */
|
||||
{ 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */
|
||||
{ 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */
|
||||
{ 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */
|
||||
{ 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */
|
||||
{ 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */
|
||||
{ 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */
|
||||
{ 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */
|
||||
{ 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */
|
||||
{ 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */
|
||||
{ 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */
|
||||
{ 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */
|
||||
{ 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */
|
||||
{ 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
|
||||
{ 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */
|
||||
{ 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */
|
||||
{ 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */
|
||||
{ 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */
|
||||
{ 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */
|
||||
{ 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */
|
||||
{ 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN */
|
||||
{ 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */
|
||||
{ 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */
|
||||
{ 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */
|
||||
{ 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */
|
||||
{ 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */
|
||||
{ 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */
|
||||
{ 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */
|
||||
{ 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */
|
||||
{ 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
|
||||
{ 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */
|
||||
{ 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */
|
||||
{ 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */
|
||||
{ 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */
|
||||
{ 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */
|
||||
{ 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */
|
||||
{ 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
|
||||
{ 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */
|
||||
{ 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */
|
||||
{ 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */
|
||||
{ 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */
|
||||
{ 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */
|
||||
{ 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */
|
||||
{ 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */
|
||||
{ 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */
|
||||
{ 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */
|
||||
{ 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */
|
||||
{ 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */
|
||||
{ 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */
|
||||
{ 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */
|
||||
{ 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */
|
||||
{ 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */
|
||||
{ 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */
|
||||
{ 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */
|
||||
{ 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */
|
||||
{ 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */
|
||||
{ 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */
|
||||
{ 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */
|
||||
{ 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */
|
||||
{ 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */
|
||||
{ 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */
|
||||
{ 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */
|
||||
{ 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */
|
||||
{ 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */
|
||||
{ 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */
|
||||
{ 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */
|
||||
{ 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */
|
||||
{ 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */
|
||||
{ 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */
|
||||
{ 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */
|
||||
{ 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */
|
||||
{ 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */
|
||||
{ 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */
|
||||
{ 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */
|
||||
{ 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */
|
||||
{ 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */
|
||||
{ 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */
|
||||
{ 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */
|
||||
{ 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */
|
||||
{ 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */
|
||||
{ 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */
|
||||
{ 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */
|
||||
{ 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */
|
||||
{ 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */
|
||||
{ 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */
|
||||
{ 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */
|
||||
{ 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */
|
||||
{ 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */
|
||||
{ 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */
|
||||
{ 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */
|
||||
{ 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */
|
||||
{ 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */
|
||||
{ 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */
|
||||
{ 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */
|
||||
{ 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */
|
||||
{ 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */
|
||||
{ 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */
|
||||
{ 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */
|
||||
{ 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */
|
||||
{ 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */
|
||||
{ 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */
|
||||
{ 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */
|
||||
{ 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */
|
||||
{ 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */
|
||||
{ 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
|
||||
{ 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
|
||||
{ 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
|
||||
{ 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
|
||||
{ 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */
|
||||
{ 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
|
||||
{ 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */
|
||||
{ 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */
|
||||
{ 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */
|
||||
{ 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
|
||||
{ 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
|
||||
{ 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */
|
||||
{ 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */
|
||||
{ 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
|
||||
{ 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */
|
||||
{ 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */
|
||||
{ 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
|
||||
{ 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
|
||||
{ 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */
|
||||
{ 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */
|
||||
{ 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */
|
||||
{ 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */
|
||||
{ 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */
|
||||
{ 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */
|
||||
{ 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */
|
||||
{ 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */
|
||||
{ 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */
|
||||
{ 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */
|
||||
{ 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */
|
||||
{ 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */
|
||||
{ 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */
|
||||
{ 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */
|
||||
{ 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */
|
||||
{ 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */
|
||||
{ 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */
|
||||
{ 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */
|
||||
{ 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */
|
||||
{ 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */
|
||||
{ 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */
|
||||
{ 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */
|
||||
{ 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
|
||||
{ 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
|
||||
{ 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
|
||||
{ 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */
|
||||
{ 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */
|
||||
{ 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */
|
||||
{ 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */
|
||||
{ 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */
|
||||
{ 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */
|
||||
{ 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */
|
||||
{ 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */
|
||||
{ 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */
|
||||
{ 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */
|
||||
{ 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */
|
||||
{ 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */
|
||||
{ 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */
|
||||
{ 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */
|
||||
{ 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */
|
||||
{ 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */
|
||||
{ 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */
|
||||
{ 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */
|
||||
{ 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */
|
||||
{ 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */
|
||||
{ 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */
|
||||
{ 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */
|
||||
{ 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */
|
||||
{ 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */
|
||||
{ 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
|
||||
{ 0x08a1, 0x23b7 }, /* leftradical ⎷ ??? */
|
||||
{ 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
|
||||
{ 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */
|
||||
{ 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
|
||||
{ 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
|
||||
{ 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
|
||||
{ 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ ??? */
|
||||
{ 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ ??? */
|
||||
{ 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ ??? */
|
||||
{ 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ ??? */
|
||||
{ 0x08ab, 0x239b }, /* topleftparens ⎛ ??? */
|
||||
{ 0x08ac, 0x239d }, /* botleftparens ⎝ ??? */
|
||||
{ 0x08ad, 0x239e }, /* toprightparens ⎞ ??? */
|
||||
{ 0x08ae, 0x23a0 }, /* botrightparens ⎠ ??? */
|
||||
{ 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ ??? */
|
||||
{ 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ ??? */
|
||||
/* 0x08b1 topleftsummation ? ??? */
|
||||
/* 0x08b2 botleftsummation ? ??? */
|
||||
/* 0x08b3 topvertsummationconnector ? ??? */
|
||||
/* 0x08b4 botvertsummationconnector ? ??? */
|
||||
/* 0x08b5 toprightsummation ? ??? */
|
||||
/* 0x08b6 botrightsummation ? ??? */
|
||||
/* 0x08b7 rightmiddlesummation ? ??? */
|
||||
{ 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
|
||||
{ 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */
|
||||
{ 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */
|
||||
{ 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */
|
||||
{ 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */
|
||||
{ 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */
|
||||
{ 0x08c2, 0x221e }, /* infinity ∞ INFINITY */
|
||||
{ 0x08c5, 0x2207 }, /* nabla ∇ NABLA */
|
||||
{ 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */
|
||||
{ 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */
|
||||
{ 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
|
||||
{ 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
|
||||
{ 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
|
||||
{ 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */
|
||||
{ 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */
|
||||
{ 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */
|
||||
{ 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */
|
||||
{ 0x08dd, 0x222a }, /* union ∪ UNION */
|
||||
{ 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */
|
||||
{ 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */
|
||||
{ 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */
|
||||
{ 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */
|
||||
{ 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */
|
||||
{ 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */
|
||||
{ 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */
|
||||
{ 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */
|
||||
/* 0x09df blank ? ??? */
|
||||
{ 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */
|
||||
{ 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */
|
||||
{ 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
|
||||
{ 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */
|
||||
{ 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */
|
||||
{ 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */
|
||||
{ 0x09e8, 0x2424 }, /* nl  SYMBOL FOR NEWLINE */
|
||||
{ 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */
|
||||
{ 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */
|
||||
{ 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */
|
||||
{ 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
|
||||
{ 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */
|
||||
{ 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
|
||||
{ 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */
|
||||
{ 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */
|
||||
{ 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
|
||||
{ 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */
|
||||
{ 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */
|
||||
{ 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
|
||||
{ 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
|
||||
{ 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
|
||||
{ 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
|
||||
{ 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */
|
||||
{ 0x0aa1, 0x2003 }, /* emspace EM SPACE */
|
||||
{ 0x0aa2, 0x2002 }, /* enspace EN SPACE */
|
||||
{ 0x0aa3, 0x2004 }, /* em3space THREE-PER-EM SPACE */
|
||||
{ 0x0aa4, 0x2005 }, /* em4space FOUR-PER-EM SPACE */
|
||||
{ 0x0aa5, 0x2007 }, /* digitspace FIGURE SPACE */
|
||||
{ 0x0aa6, 0x2008 }, /* punctspace PUNCTUATION SPACE */
|
||||
{ 0x0aa7, 0x2009 }, /* thinspace THIN SPACE */
|
||||
{ 0x0aa8, 0x200a }, /* hairspace HAIR SPACE */
|
||||
{ 0x0aa9, 0x2014 }, /* emdash — EM DASH */
|
||||
{ 0x0aaa, 0x2013 }, /* endash – EN DASH */
|
||||
{ 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */
|
||||
{ 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
|
||||
{ 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */
|
||||
{ 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */
|
||||
{ 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */
|
||||
{ 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */
|
||||
{ 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */
|
||||
{ 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */
|
||||
{ 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */
|
||||
{ 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */
|
||||
{ 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */
|
||||
{ 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */
|
||||
{ 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */
|
||||
{ 0x0abc, 0x27e8 }, /* leftanglebracket ⟨ MATHEMATICAL LEFT ANGLE BRACKET */
|
||||
{ 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
|
||||
{ 0x0abe, 0x27e9 }, /* rightanglebracket ⟩ MATHEMATICAL RIGHT ANGLE BRACKET */
|
||||
/* 0x0abf marker ? ??? */
|
||||
{ 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */
|
||||
{ 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
|
||||
{ 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */
|
||||
{ 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */
|
||||
{ 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */
|
||||
{ 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */
|
||||
/* 0x0acb trademarkincircle ? ??? */
|
||||
{ 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */
|
||||
{ 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */
|
||||
{ 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */
|
||||
{ 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */
|
||||
{ 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
|
||||
{ 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
|
||||
{ 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
|
||||
{ 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */
|
||||
{ 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */
|
||||
{ 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */
|
||||
{ 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
|
||||
{ 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
|
||||
{ 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */
|
||||
/* 0x0ada hexagram ? ??? */
|
||||
{ 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */
|
||||
{ 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */
|
||||
{ 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
|
||||
{ 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */
|
||||
{ 0x0adf, 0x25ae }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */
|
||||
{ 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */
|
||||
{ 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */
|
||||
{ 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */
|
||||
{ 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */
|
||||
{ 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */
|
||||
{ 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */
|
||||
{ 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */
|
||||
{ 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */
|
||||
{ 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */
|
||||
{ 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */
|
||||
{ 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */
|
||||
{ 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */
|
||||
{ 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */
|
||||
{ 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */
|
||||
{ 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */
|
||||
{ 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */
|
||||
{ 0x0af1, 0x2020 }, /* dagger † DAGGER */
|
||||
{ 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */
|
||||
{ 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */
|
||||
{ 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */
|
||||
{ 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */
|
||||
{ 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */
|
||||
{ 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */
|
||||
{ 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */
|
||||
{ 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */
|
||||
{ 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */
|
||||
{ 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */
|
||||
{ 0x0afc, 0x2038 }, /* caret ‸ CARET */
|
||||
{ 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */
|
||||
{ 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */
|
||||
/* 0x0aff cursor ? ??? */
|
||||
{ 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */
|
||||
{ 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */
|
||||
{ 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */
|
||||
{ 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */
|
||||
{ 0x0bc0, 0x00af }, /* overbar ¯ MACRON */
|
||||
{ 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */
|
||||
{ 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */
|
||||
{ 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */
|
||||
{ 0x0bc6, 0x005f }, /* underbar _ LOW LINE */
|
||||
{ 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */
|
||||
{ 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
|
||||
{ 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */
|
||||
{ 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */
|
||||
{ 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */
|
||||
{ 0x0bd6, 0x222a }, /* downshoe ∪ UNION */
|
||||
{ 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */
|
||||
{ 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */
|
||||
{ 0x0bdc, 0x22a2 }, /* lefttack ⊢ RIGHT TACK */
|
||||
{ 0x0bfc, 0x22a3 }, /* righttack ⊣ LEFT TACK */
|
||||
{ 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */
|
||||
{ 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */
|
||||
{ 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */
|
||||
{ 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */
|
||||
{ 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */
|
||||
{ 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */
|
||||
{ 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */
|
||||
{ 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */
|
||||
{ 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */
|
||||
{ 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */
|
||||
{ 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */
|
||||
{ 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */
|
||||
{ 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */
|
||||
{ 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */
|
||||
{ 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */
|
||||
{ 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */
|
||||
{ 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */
|
||||
{ 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */
|
||||
{ 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */
|
||||
{ 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */
|
||||
{ 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */
|
||||
{ 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */
|
||||
{ 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */
|
||||
{ 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */
|
||||
{ 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */
|
||||
{ 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */
|
||||
{ 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */
|
||||
{ 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */
|
||||
{ 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */
|
||||
{ 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */
|
||||
{ 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */
|
||||
{ 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */
|
||||
{ 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */
|
||||
{ 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */
|
||||
{ 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */
|
||||
{ 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */
|
||||
{ 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */
|
||||
{ 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */
|
||||
{ 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */
|
||||
{ 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */
|
||||
{ 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */
|
||||
{ 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */
|
||||
{ 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */
|
||||
{ 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */
|
||||
{ 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */
|
||||
{ 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */
|
||||
{ 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */
|
||||
{ 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */
|
||||
{ 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */
|
||||
{ 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */
|
||||
{ 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */
|
||||
{ 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */
|
||||
{ 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */
|
||||
{ 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */
|
||||
{ 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */
|
||||
{ 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */
|
||||
{ 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */
|
||||
{ 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */
|
||||
{ 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */
|
||||
{ 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */
|
||||
{ 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */
|
||||
{ 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */
|
||||
{ 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */
|
||||
{ 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */
|
||||
{ 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */
|
||||
{ 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */
|
||||
{ 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */
|
||||
{ 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */
|
||||
{ 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */
|
||||
{ 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */
|
||||
{ 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */
|
||||
{ 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */
|
||||
{ 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */
|
||||
{ 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */
|
||||
{ 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */
|
||||
{ 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */
|
||||
{ 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */
|
||||
{ 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */
|
||||
{ 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */
|
||||
{ 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */
|
||||
{ 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */
|
||||
{ 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */
|
||||
{ 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */
|
||||
{ 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */
|
||||
{ 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */
|
||||
{ 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */
|
||||
{ 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ??? */
|
||||
{ 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */
|
||||
{ 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */
|
||||
{ 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */
|
||||
{ 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */
|
||||
{ 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */
|
||||
{ 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */
|
||||
{ 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */
|
||||
{ 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */
|
||||
{ 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */
|
||||
{ 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */
|
||||
{ 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */
|
||||
{ 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */
|
||||
{ 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */
|
||||
{ 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */
|
||||
{ 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */
|
||||
{ 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */
|
||||
{ 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */
|
||||
{ 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */
|
||||
{ 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */
|
||||
{ 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */
|
||||
{ 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */
|
||||
{ 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */
|
||||
{ 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */
|
||||
{ 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */
|
||||
{ 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */
|
||||
{ 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */
|
||||
{ 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */
|
||||
{ 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */
|
||||
{ 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */
|
||||
{ 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */
|
||||
{ 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */
|
||||
{ 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */
|
||||
{ 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */
|
||||
{ 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */
|
||||
{ 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */
|
||||
{ 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */
|
||||
{ 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */
|
||||
{ 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */
|
||||
{ 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */
|
||||
{ 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */
|
||||
{ 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */
|
||||
{ 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */
|
||||
{ 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */
|
||||
{ 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */
|
||||
{ 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */
|
||||
{ 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */
|
||||
{ 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */
|
||||
{ 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */
|
||||
{ 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */
|
||||
{ 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */
|
||||
{ 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */
|
||||
{ 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */
|
||||
{ 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */
|
||||
{ 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */
|
||||
{ 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */
|
||||
{ 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */
|
||||
{ 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */
|
||||
{ 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */
|
||||
{ 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */
|
||||
{ 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */
|
||||
{ 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */
|
||||
{ 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */
|
||||
{ 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */
|
||||
{ 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */
|
||||
{ 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */
|
||||
{ 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */
|
||||
{ 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */
|
||||
{ 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */
|
||||
{ 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */
|
||||
{ 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */
|
||||
{ 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */
|
||||
{ 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */
|
||||
{ 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */
|
||||
{ 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */
|
||||
{ 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */
|
||||
{ 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */
|
||||
{ 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */
|
||||
{ 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */
|
||||
{ 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */
|
||||
{ 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */
|
||||
{ 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */
|
||||
{ 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */
|
||||
{ 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */
|
||||
{ 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */
|
||||
{ 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */
|
||||
{ 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */
|
||||
{ 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */
|
||||
{ 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */
|
||||
{ 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */
|
||||
{ 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */
|
||||
{ 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */
|
||||
{ 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */
|
||||
{ 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */
|
||||
{ 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */
|
||||
{ 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */
|
||||
{ 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */
|
||||
{ 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */
|
||||
{ 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */
|
||||
{ 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */
|
||||
{ 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */
|
||||
{ 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */
|
||||
{ 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */
|
||||
{ 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
|
||||
{ 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */
|
||||
{ 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
|
||||
{ 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
|
||||
{ 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
|
||||
/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */
|
||||
{ 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
|
||||
{ 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
|
||||
{ 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
|
||||
{ 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
|
||||
{ 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
|
||||
{ 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */
|
||||
{ 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
|
||||
{ 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */
|
||||
{ 0x13a4, 0x20ac }, /* Euro € EURO SIGN */
|
||||
{ 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */
|
||||
{ 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */
|
||||
{ 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
|
||||
{ 0x20a0, 0x20a0 }, /* EcuSign ₠ EURO-CURRENCY SIGN */
|
||||
{ 0x20a1, 0x20a1 }, /* ColonSign ₡ COLON SIGN */
|
||||
{ 0x20a2, 0x20a2 }, /* CruzeiroSign ₢ CRUZEIRO SIGN */
|
||||
{ 0x20a3, 0x20a3 }, /* FFrancSign ₣ FRENCH FRANC SIGN */
|
||||
{ 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */
|
||||
{ 0x20a5, 0x20a5 }, /* MillSign ₥ MILL SIGN */
|
||||
{ 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */
|
||||
{ 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */
|
||||
{ 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */
|
||||
{ 0x20a9, 0x20a9 }, /* WonSign ₩ WON SIGN */
|
||||
{ 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */
|
||||
{ 0x20ab, 0x20ab }, /* DongSign ₫ DONG SIGN */
|
||||
{ 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */
|
||||
};
|
||||
|
||||
/* binary search with range check */
|
||||
static uint32_t
|
||||
bin_search(const struct codepair *table, size_t length, xkb_keysym_t keysym)
|
||||
{
|
||||
size_t first = 0;
|
||||
size_t last = length;
|
||||
|
||||
if (keysym < table[0].keysym || keysym > table[length].keysym)
|
||||
return 0;
|
||||
|
||||
/* binary search in table */
|
||||
while (last >= first) {
|
||||
size_t mid = (first + last) / 2;
|
||||
if (table[mid].keysym < keysym)
|
||||
first = mid + 1;
|
||||
else if (table[mid].keysym > keysym)
|
||||
last = mid - 1;
|
||||
else /* found it */
|
||||
return table[mid].ucs;
|
||||
}
|
||||
|
||||
/* no matching Unicode value found in table */
|
||||
return 0;
|
||||
}
|
||||
|
||||
XKB_EXPORT uint32_t
|
||||
xkb_keysym_to_utf32(xkb_keysym_t keysym)
|
||||
{
|
||||
/* first check for Latin-1 characters (1:1 mapping) */
|
||||
if ((keysym >= 0x0020 && keysym <= 0x007e) ||
|
||||
(keysym >= 0x00a0 && keysym <= 0x00ff))
|
||||
return keysym;
|
||||
|
||||
/* patch encoding botch */
|
||||
if (keysym == XKB_KEY_KP_Space)
|
||||
return XKB_KEY_space & 0x7f;
|
||||
|
||||
/* special keysyms */
|
||||
if ((keysym >= XKB_KEY_BackSpace && keysym <= XKB_KEY_Clear) ||
|
||||
(keysym >= XKB_KEY_KP_Multiply && keysym <= XKB_KEY_KP_9) ||
|
||||
keysym == XKB_KEY_Return || keysym == XKB_KEY_Escape ||
|
||||
keysym == XKB_KEY_Delete || keysym == XKB_KEY_KP_Tab ||
|
||||
keysym == XKB_KEY_KP_Enter || keysym == XKB_KEY_KP_Equal)
|
||||
return keysym & 0x7f;
|
||||
|
||||
/* also check for directly encoded Unicode codepoints */
|
||||
/*
|
||||
* In theory, this is supposed to start from 0x100100, such that the ASCII
|
||||
* range, which is already covered by 0x00-0xff, can't be encoded in two
|
||||
* ways. However, changing this after a couple of decades probably won't
|
||||
* go well, so it stays as it is.
|
||||
*/
|
||||
if (0x01000000 <= keysym && keysym <= 0x0110ffff)
|
||||
return keysym - 0x01000000;
|
||||
|
||||
/* search main table */
|
||||
return bin_search(keysymtab, ARRAY_SIZE(keysymtab) - 1, keysym);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Rob Bradford <rob@linux.intel.com>
|
||||
*/
|
||||
|
||||
XKB_EXPORT int
|
||||
xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size)
|
||||
{
|
||||
uint32_t codepoint;
|
||||
|
||||
if (size < 7)
|
||||
return -1;
|
||||
|
||||
codepoint = xkb_keysym_to_utf32(keysym);
|
||||
|
||||
if (codepoint == 0)
|
||||
return 0;
|
||||
|
||||
return utf32_to_utf8(codepoint, buffer);
|
||||
}
|
762
src/3rdparty/xkbcommon/src/keysym.c
vendored
762
src/3rdparty/xkbcommon/src/keysym.c
vendored
@ -1,762 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1987, 1990, 1998 The Open Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the names of the authors or their
|
||||
* institutions shall not be used in advertising or otherwise to promote the
|
||||
* sale, use or other dealings in this Software without prior written
|
||||
* authorization from the authors.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright © 2009 Dan Nicholson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "utils.h"
|
||||
#include "keysym.h"
|
||||
#include "ks_tables.h"
|
||||
|
||||
static inline const char *
|
||||
get_name(const struct name_keysym *entry)
|
||||
{
|
||||
return keysym_names + entry->offset;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_by_keysym(const void *a, const void *b)
|
||||
{
|
||||
const xkb_keysym_t *key = a;
|
||||
const struct name_keysym *entry = b;
|
||||
if (*key < entry->keysym)
|
||||
return -1;
|
||||
if (*key > entry->keysym)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_by_name(const void *a, const void *b)
|
||||
{
|
||||
const char *key = a;
|
||||
const struct name_keysym *entry = b;
|
||||
return istrcmp(key, get_name(entry));
|
||||
}
|
||||
|
||||
XKB_EXPORT int
|
||||
xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
|
||||
{
|
||||
const struct name_keysym *entry;
|
||||
|
||||
if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
|
||||
snprintf(buffer, size, "Invalid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry = bsearch(&ks, keysym_to_name,
|
||||
ARRAY_SIZE(keysym_to_name),
|
||||
sizeof(*keysym_to_name),
|
||||
compare_by_keysym);
|
||||
if (entry)
|
||||
return snprintf(buffer, size, "%s", get_name(entry));
|
||||
|
||||
/* Unnamed Unicode codepoint. */
|
||||
if (ks >= 0x01000100 && ks <= 0x0110ffff) {
|
||||
const int width = (ks & 0xff0000UL) ? 8 : 4;
|
||||
return snprintf(buffer, size, "U%0*lX", width, ks & 0xffffffUL);
|
||||
}
|
||||
|
||||
/* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
|
||||
return snprintf(buffer, size, "0x%08x", ks);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the correct keysym if one case-insensitive match is given.
|
||||
*
|
||||
* The name_to_keysym table is sorted by istrcmp(). So bsearch() may return
|
||||
* _any_ of all possible case-insensitive duplicates. This function searches the
|
||||
* returned entry @entry, all previous and all next entries that match by
|
||||
* case-insensitive comparison and returns the exact match to @name. If @icase
|
||||
* is true, then this returns the best case-insensitive match instead of a
|
||||
* correct match.
|
||||
* The "best" case-insensitive match is the lower-case keysym which we find with
|
||||
* the help of xkb_keysym_is_lower().
|
||||
* The only keysyms that only differ by letter-case are keysyms that are
|
||||
* available as lower-case and upper-case variant (like KEY_a and KEY_A). So
|
||||
* returning the first lower-case match is enough in this case.
|
||||
*/
|
||||
static const struct name_keysym *
|
||||
find_sym(const struct name_keysym *entry, const char *name, bool icase)
|
||||
{
|
||||
const struct name_keysym *iter, *last;
|
||||
size_t len = ARRAY_SIZE(name_to_keysym);
|
||||
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
if (!icase && strcmp(get_name(entry), name) == 0)
|
||||
return entry;
|
||||
if (icase && xkb_keysym_is_lower(entry->keysym))
|
||||
return entry;
|
||||
|
||||
for (iter = entry - 1; iter >= name_to_keysym; --iter) {
|
||||
if (!icase && strcmp(get_name(iter), name) == 0)
|
||||
return iter;
|
||||
if (istrcmp(get_name(iter), get_name(entry)) != 0)
|
||||
break;
|
||||
if (icase && xkb_keysym_is_lower(iter->keysym))
|
||||
return iter;
|
||||
}
|
||||
|
||||
last = name_to_keysym + len;
|
||||
for (iter = entry + 1; iter < last; ++iter) {
|
||||
if (!icase && strcmp(get_name(iter), name) == 0)
|
||||
return iter;
|
||||
if (istrcmp(get_name(iter), get_name(entry)) != 0)
|
||||
break;
|
||||
if (icase && xkb_keysym_is_lower(iter->keysym))
|
||||
return iter;
|
||||
}
|
||||
|
||||
if (icase)
|
||||
return entry;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keysym_t
|
||||
xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags)
|
||||
{
|
||||
const struct name_keysym *entry;
|
||||
char *tmp;
|
||||
xkb_keysym_t val;
|
||||
bool icase = (flags & XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
|
||||
if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE)
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
entry = bsearch(s, name_to_keysym,
|
||||
ARRAY_SIZE(name_to_keysym),
|
||||
sizeof(*name_to_keysym),
|
||||
compare_by_name);
|
||||
entry = find_sym(entry, s, icase);
|
||||
if (entry)
|
||||
return entry->keysym;
|
||||
|
||||
if (*s == 'U' || (icase && *s == 'u')) {
|
||||
val = strtoul(&s[1], &tmp, 16);
|
||||
if (tmp && *tmp != '\0')
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
if (val < 0x20 || (val > 0x7e && val < 0xa0))
|
||||
return XKB_KEY_NoSymbol;
|
||||
if (val < 0x100)
|
||||
return val;
|
||||
if (val > 0x10ffff)
|
||||
return XKB_KEY_NoSymbol;
|
||||
return val | 0x01000000;
|
||||
}
|
||||
else if (s[0] == '0' && (s[1] == 'x' || (icase && s[1] == 'X'))) {
|
||||
val = strtoul(&s[2], &tmp, 16);
|
||||
if (tmp && *tmp != '\0')
|
||||
return XKB_KEY_NoSymbol;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Stupid inconsistency between the headers and XKeysymDB: the former has
|
||||
* no separating underscore, while some XF86* syms in the latter did.
|
||||
* As a last ditch effort, try without. */
|
||||
if (strncmp(s, "XF86_", 5) == 0 ||
|
||||
(icase && strncasecmp(s, "XF86_", 5) == 0)) {
|
||||
xkb_keysym_t ret;
|
||||
tmp = strdup(s);
|
||||
if (!tmp)
|
||||
return XKB_KEY_NoSymbol;
|
||||
memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1);
|
||||
ret = xkb_keysym_from_name(tmp, flags);
|
||||
free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return XKB_KEY_NoSymbol;
|
||||
}
|
||||
|
||||
bool
|
||||
xkb_keysym_is_keypad(xkb_keysym_t keysym)
|
||||
{
|
||||
return keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_Equal;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
xkb_keysym_is_modifier(xkb_keysym_t keysym)
|
||||
{
|
||||
return
|
||||
(keysym >= XKB_KEY_Shift_L && keysym <= XKB_KEY_Hyper_R) ||
|
||||
/* libX11 only goes upto XKB_KEY_ISO_Level5_Lock. */
|
||||
(keysym >= XKB_KEY_ISO_Lock && keysym <= XKB_KEY_ISO_Last_Group_Lock) ||
|
||||
keysym == XKB_KEY_Mode_switch ||
|
||||
keysym == XKB_KEY_Num_Lock;
|
||||
}
|
||||
|
||||
static void
|
||||
XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper);
|
||||
|
||||
bool
|
||||
xkb_keysym_is_lower(xkb_keysym_t ks)
|
||||
{
|
||||
xkb_keysym_t lower, upper;
|
||||
|
||||
XConvertCase(ks, &lower, &upper);
|
||||
|
||||
if (lower == upper)
|
||||
return false;
|
||||
|
||||
return (ks == lower ? true : false);
|
||||
}
|
||||
|
||||
bool
|
||||
xkb_keysym_is_upper(xkb_keysym_t ks)
|
||||
{
|
||||
xkb_keysym_t lower, upper;
|
||||
|
||||
XConvertCase(ks, &lower, &upper);
|
||||
|
||||
if (lower == upper)
|
||||
return false;
|
||||
|
||||
return (ks == upper ? true : false);
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keysym_t
|
||||
xkb_keysym_to_lower(xkb_keysym_t ks)
|
||||
{
|
||||
xkb_keysym_t lower, upper;
|
||||
|
||||
XConvertCase(ks, &lower, &upper);
|
||||
|
||||
return lower;
|
||||
}
|
||||
|
||||
XKB_EXPORT xkb_keysym_t
|
||||
xkb_keysym_to_upper(xkb_keysym_t ks)
|
||||
{
|
||||
xkb_keysym_t lower, upper;
|
||||
|
||||
XConvertCase(ks, &lower, &upper);
|
||||
|
||||
return upper;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following is copied verbatim from libX11:src/KeyBind.c, commit
|
||||
* d45b3fc19fbe95c41afc4e51d768df6d42332010, with the following changes:
|
||||
* - unsigned -> uint32_t
|
||||
* - unsigend short -> uint16_t
|
||||
* - s/XK_/XKB_KEY_
|
||||
*
|
||||
* XXX: If newlocale() and iswlower_l()/iswupper_l() interface ever
|
||||
* become portable, we should use that in conjunction with
|
||||
* xkb_keysym_to_utf32(), instead of all this stuff. We should
|
||||
* be sure to give the same results as libX11, though, and be
|
||||
* locale independent; this information is used by xkbcomp to
|
||||
* find the automatic type to assign to key groups.
|
||||
*/
|
||||
|
||||
static void
|
||||
UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper)
|
||||
{
|
||||
/* Case conversion for UCS, as in Unicode Data version 4.0.0 */
|
||||
/* NB: Only converts simple one-to-one mappings. */
|
||||
|
||||
/* Tables are used where they take less space than */
|
||||
/* the code to work out the mappings. Zero values mean */
|
||||
/* undefined code points. */
|
||||
|
||||
static uint16_t const IPAExt_upper_mapping[] = { /* part only */
|
||||
0x0181, 0x0186, 0x0255, 0x0189, 0x018A,
|
||||
0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F,
|
||||
0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267,
|
||||
0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C,
|
||||
0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277,
|
||||
0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F,
|
||||
0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287,
|
||||
0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F,
|
||||
0x0290, 0x0291, 0x01B7
|
||||
};
|
||||
|
||||
static uint16_t const LatinExtB_upper_mapping[] = { /* first part only */
|
||||
0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187,
|
||||
0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F,
|
||||
0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197,
|
||||
0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F,
|
||||
0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7,
|
||||
0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF,
|
||||
0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7,
|
||||
0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7,
|
||||
0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7,
|
||||
0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA
|
||||
};
|
||||
|
||||
static uint16_t const LatinExtB_lower_mapping[] = { /* first part only */
|
||||
0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
|
||||
0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
|
||||
0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
|
||||
0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
|
||||
0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8,
|
||||
0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0,
|
||||
0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
|
||||
0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
|
||||
0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
|
||||
0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC
|
||||
};
|
||||
|
||||
static uint16_t const Greek_upper_mapping[] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387,
|
||||
0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F,
|
||||
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
|
||||
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
|
||||
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
|
||||
0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A,
|
||||
0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
|
||||
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
|
||||
0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
|
||||
0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000,
|
||||
0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7,
|
||||
0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE,
|
||||
0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6,
|
||||
0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE,
|
||||
0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7,
|
||||
0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
static uint16_t const Greek_lower_mapping[] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387,
|
||||
0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE,
|
||||
0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
|
||||
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
|
||||
0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
|
||||
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
|
||||
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
|
||||
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
|
||||
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000,
|
||||
0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
|
||||
0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF,
|
||||
0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
|
||||
0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
|
||||
0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8,
|
||||
0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
static uint16_t const GreekExt_lower_mapping[] = {
|
||||
0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
|
||||
0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
|
||||
0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
|
||||
0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
|
||||
0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
|
||||
0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
|
||||
0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
|
||||
0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
|
||||
0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
|
||||
0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
|
||||
0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57,
|
||||
0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57,
|
||||
0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
|
||||
0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
|
||||
0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77,
|
||||
0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000,
|
||||
0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
|
||||
0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
|
||||
0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
|
||||
0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
|
||||
0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
|
||||
0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
|
||||
0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
|
||||
0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF,
|
||||
0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
|
||||
0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF,
|
||||
0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
|
||||
0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
|
||||
0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7,
|
||||
0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF,
|
||||
0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
|
||||
0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000
|
||||
};
|
||||
|
||||
static uint16_t const GreekExt_upper_mapping[] = {
|
||||
0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
|
||||
0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
|
||||
0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
|
||||
0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
|
||||
0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
|
||||
0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
|
||||
0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
|
||||
0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
|
||||
0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
|
||||
0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
|
||||
0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F,
|
||||
0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F,
|
||||
0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
|
||||
0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
|
||||
0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB,
|
||||
0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000,
|
||||
0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
|
||||
0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
|
||||
0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
|
||||
0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
|
||||
0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
|
||||
0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
|
||||
0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
|
||||
0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF,
|
||||
0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
|
||||
0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF,
|
||||
0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
|
||||
0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
|
||||
0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7,
|
||||
0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF,
|
||||
0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
|
||||
0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000
|
||||
};
|
||||
|
||||
*lower = code;
|
||||
*upper = code;
|
||||
|
||||
/* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */
|
||||
if (code <= 0x00ff) {
|
||||
if (code >= 0x0041 && code <= 0x005a) /* A-Z */
|
||||
*lower += 0x20;
|
||||
else if (code >= 0x0061 && code <= 0x007a) /* a-z */
|
||||
*upper -= 0x20;
|
||||
else if ( (code >= 0x00c0 && code <= 0x00d6) ||
|
||||
(code >= 0x00d8 && code <= 0x00de) )
|
||||
*lower += 0x20;
|
||||
else if ( (code >= 0x00e0 && code <= 0x00f6) ||
|
||||
(code >= 0x00f8 && code <= 0x00fe) )
|
||||
*upper -= 0x20;
|
||||
else if (code == 0x00ff) /* y with diaeresis */
|
||||
*upper = 0x0178;
|
||||
else if (code == 0x00b5) /* micro sign */
|
||||
*upper = 0x039c;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Latin Extended-A, U+0100 to U+017F */
|
||||
if (code >= 0x0100 && code <= 0x017f) {
|
||||
if ( (code >= 0x0100 && code <= 0x012f) ||
|
||||
(code >= 0x0132 && code <= 0x0137) ||
|
||||
(code >= 0x014a && code <= 0x0177) ) {
|
||||
*upper = code & ~1;
|
||||
*lower = code | 1;
|
||||
}
|
||||
else if ( (code >= 0x0139 && code <= 0x0148) ||
|
||||
(code >= 0x0179 && code <= 0x017e) ) {
|
||||
if (code & 1)
|
||||
*lower += 1;
|
||||
else
|
||||
*upper -= 1;
|
||||
}
|
||||
else if (code == 0x0130)
|
||||
*lower = 0x0069;
|
||||
else if (code == 0x0131)
|
||||
*upper = 0x0049;
|
||||
else if (code == 0x0178)
|
||||
*lower = 0x00ff;
|
||||
else if (code == 0x017f)
|
||||
*upper = 0x0053;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Latin Extended-B, U+0180 to U+024F */
|
||||
if (code >= 0x0180 && code <= 0x024f) {
|
||||
if (code >= 0x01cd && code <= 0x01dc) {
|
||||
if (code & 1)
|
||||
*lower += 1;
|
||||
else
|
||||
*upper -= 1;
|
||||
}
|
||||
else if ( (code >= 0x01de && code <= 0x01ef) ||
|
||||
(code >= 0x01f4 && code <= 0x01f5) ||
|
||||
(code >= 0x01f8 && code <= 0x021f) ||
|
||||
(code >= 0x0222 && code <= 0x0233) ) {
|
||||
*lower |= 1;
|
||||
*upper &= ~1;
|
||||
}
|
||||
else if (code >= 0x0180 && code <= 0x01cc) {
|
||||
*lower = LatinExtB_lower_mapping[code - 0x0180];
|
||||
*upper = LatinExtB_upper_mapping[code - 0x0180];
|
||||
}
|
||||
else if (code == 0x01dd)
|
||||
*upper = 0x018e;
|
||||
else if (code == 0x01f1 || code == 0x01f2) {
|
||||
*lower = 0x01f3;
|
||||
*upper = 0x01f1;
|
||||
}
|
||||
else if (code == 0x01f3)
|
||||
*upper = 0x01f1;
|
||||
else if (code == 0x01f6)
|
||||
*lower = 0x0195;
|
||||
else if (code == 0x01f7)
|
||||
*lower = 0x01bf;
|
||||
else if (code == 0x0220)
|
||||
*lower = 0x019e;
|
||||
return;
|
||||
}
|
||||
|
||||
/* IPA Extensions, U+0250 to U+02AF */
|
||||
if (code >= 0x0253 && code <= 0x0292) {
|
||||
*upper = IPAExt_upper_mapping[code - 0x0253];
|
||||
}
|
||||
|
||||
/* Combining Diacritical Marks, U+0300 to U+036F */
|
||||
if (code == 0x0345) {
|
||||
*upper = 0x0399;
|
||||
}
|
||||
|
||||
/* Greek and Coptic, U+0370 to U+03FF */
|
||||
if (code >= 0x0370 && code <= 0x03ff) {
|
||||
*lower = Greek_lower_mapping[code - 0x0370];
|
||||
*upper = Greek_upper_mapping[code - 0x0370];
|
||||
if (*upper == 0)
|
||||
*upper = code;
|
||||
if (*lower == 0)
|
||||
*lower = code;
|
||||
}
|
||||
|
||||
/* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */
|
||||
if ( (code >= 0x0400 && code <= 0x04ff) ||
|
||||
(code >= 0x0500 && code <= 0x052f) ) {
|
||||
if (code >= 0x0400 && code <= 0x040f)
|
||||
*lower += 0x50;
|
||||
else if (code >= 0x0410 && code <= 0x042f)
|
||||
*lower += 0x20;
|
||||
else if (code >= 0x0430 && code <= 0x044f)
|
||||
*upper -= 0x20;
|
||||
else if (code >= 0x0450 && code <= 0x045f)
|
||||
*upper -= 0x50;
|
||||
else if ( (code >= 0x0460 && code <= 0x0481) ||
|
||||
(code >= 0x048a && code <= 0x04bf) ||
|
||||
(code >= 0x04d0 && code <= 0x04f5) ||
|
||||
(code >= 0x04f8 && code <= 0x04f9) ||
|
||||
(code >= 0x0500 && code <= 0x050f) ) {
|
||||
*upper &= ~1;
|
||||
*lower |= 1;
|
||||
}
|
||||
else if (code >= 0x04c1 && code <= 0x04ce) {
|
||||
if (code & 1)
|
||||
*lower += 1;
|
||||
else
|
||||
*upper -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Armenian, U+0530 to U+058F */
|
||||
if (code >= 0x0530 && code <= 0x058f) {
|
||||
if (code >= 0x0531 && code <= 0x0556)
|
||||
*lower += 0x30;
|
||||
else if (code >=0x0561 && code <= 0x0586)
|
||||
*upper -= 0x30;
|
||||
}
|
||||
|
||||
/* Latin Extended Additional, U+1E00 to U+1EFF */
|
||||
if (code >= 0x1e00 && code <= 0x1eff) {
|
||||
if ( (code >= 0x1e00 && code <= 0x1e95) ||
|
||||
(code >= 0x1ea0 && code <= 0x1ef9) ) {
|
||||
*upper &= ~1;
|
||||
*lower |= 1;
|
||||
}
|
||||
else if (code == 0x1e9b)
|
||||
*upper = 0x1e60;
|
||||
}
|
||||
|
||||
/* Greek Extended, U+1F00 to U+1FFF */
|
||||
if (code >= 0x1f00 && code <= 0x1fff) {
|
||||
*lower = GreekExt_lower_mapping[code - 0x1f00];
|
||||
*upper = GreekExt_upper_mapping[code - 0x1f00];
|
||||
if (*upper == 0)
|
||||
*upper = code;
|
||||
if (*lower == 0)
|
||||
*lower = code;
|
||||
}
|
||||
|
||||
/* Letterlike Symbols, U+2100 to U+214F */
|
||||
if (code >= 0x2100 && code <= 0x214f) {
|
||||
switch (code) {
|
||||
case 0x2126: *lower = 0x03c9; break;
|
||||
case 0x212a: *lower = 0x006b; break;
|
||||
case 0x212b: *lower = 0x00e5; break;
|
||||
}
|
||||
}
|
||||
/* Number Forms, U+2150 to U+218F */
|
||||
else if (code >= 0x2160 && code <= 0x216f)
|
||||
*lower += 0x10;
|
||||
else if (code >= 0x2170 && code <= 0x217f)
|
||||
*upper -= 0x10;
|
||||
/* Enclosed Alphanumerics, U+2460 to U+24FF */
|
||||
else if (code >= 0x24b6 && code <= 0x24cf)
|
||||
*lower += 0x1a;
|
||||
else if (code >= 0x24d0 && code <= 0x24e9)
|
||||
*upper -= 0x1a;
|
||||
/* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */
|
||||
else if (code >= 0xff21 && code <= 0xff3a)
|
||||
*lower += 0x20;
|
||||
else if (code >= 0xff41 && code <= 0xff5a)
|
||||
*upper -= 0x20;
|
||||
/* Deseret, U+10400 to U+104FF */
|
||||
else if (code >= 0x10400 && code <= 0x10427)
|
||||
*lower += 0x28;
|
||||
else if (code >= 0x10428 && code <= 0x1044f)
|
||||
*upper -= 0x28;
|
||||
}
|
||||
|
||||
static void
|
||||
XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
|
||||
{
|
||||
/* Latin 1 keysym */
|
||||
if (sym < 0x100) {
|
||||
UCSConvertCase(sym, lower, upper);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unicode keysym */
|
||||
if ((sym & 0xff000000) == 0x01000000) {
|
||||
UCSConvertCase((sym & 0x00ffffff), lower, upper);
|
||||
*upper |= 0x01000000;
|
||||
*lower |= 0x01000000;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Legacy keysym */
|
||||
|
||||
*lower = sym;
|
||||
*upper = sym;
|
||||
|
||||
switch(sym >> 8) {
|
||||
case 1: /* Latin 2 */
|
||||
/* Assume the KeySym is a legal value (ignore discontinuities) */
|
||||
if (sym == XKB_KEY_Aogonek)
|
||||
*lower = XKB_KEY_aogonek;
|
||||
else if (sym >= XKB_KEY_Lstroke && sym <= XKB_KEY_Sacute)
|
||||
*lower += (XKB_KEY_lstroke - XKB_KEY_Lstroke);
|
||||
else if (sym >= XKB_KEY_Scaron && sym <= XKB_KEY_Zacute)
|
||||
*lower += (XKB_KEY_scaron - XKB_KEY_Scaron);
|
||||
else if (sym >= XKB_KEY_Zcaron && sym <= XKB_KEY_Zabovedot)
|
||||
*lower += (XKB_KEY_zcaron - XKB_KEY_Zcaron);
|
||||
else if (sym == XKB_KEY_aogonek)
|
||||
*upper = XKB_KEY_Aogonek;
|
||||
else if (sym >= XKB_KEY_lstroke && sym <= XKB_KEY_sacute)
|
||||
*upper -= (XKB_KEY_lstroke - XKB_KEY_Lstroke);
|
||||
else if (sym >= XKB_KEY_scaron && sym <= XKB_KEY_zacute)
|
||||
*upper -= (XKB_KEY_scaron - XKB_KEY_Scaron);
|
||||
else if (sym >= XKB_KEY_zcaron && sym <= XKB_KEY_zabovedot)
|
||||
*upper -= (XKB_KEY_zcaron - XKB_KEY_Zcaron);
|
||||
else if (sym >= XKB_KEY_Racute && sym <= XKB_KEY_Tcedilla)
|
||||
*lower += (XKB_KEY_racute - XKB_KEY_Racute);
|
||||
else if (sym >= XKB_KEY_racute && sym <= XKB_KEY_tcedilla)
|
||||
*upper -= (XKB_KEY_racute - XKB_KEY_Racute);
|
||||
break;
|
||||
case 2: /* Latin 3 */
|
||||
/* Assume the KeySym is a legal value (ignore discontinuities) */
|
||||
if (sym >= XKB_KEY_Hstroke && sym <= XKB_KEY_Hcircumflex)
|
||||
*lower += (XKB_KEY_hstroke - XKB_KEY_Hstroke);
|
||||
else if (sym >= XKB_KEY_Gbreve && sym <= XKB_KEY_Jcircumflex)
|
||||
*lower += (XKB_KEY_gbreve - XKB_KEY_Gbreve);
|
||||
else if (sym >= XKB_KEY_hstroke && sym <= XKB_KEY_hcircumflex)
|
||||
*upper -= (XKB_KEY_hstroke - XKB_KEY_Hstroke);
|
||||
else if (sym >= XKB_KEY_gbreve && sym <= XKB_KEY_jcircumflex)
|
||||
*upper -= (XKB_KEY_gbreve - XKB_KEY_Gbreve);
|
||||
else if (sym >= XKB_KEY_Cabovedot && sym <= XKB_KEY_Scircumflex)
|
||||
*lower += (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
|
||||
else if (sym >= XKB_KEY_cabovedot && sym <= XKB_KEY_scircumflex)
|
||||
*upper -= (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
|
||||
break;
|
||||
case 3: /* Latin 4 */
|
||||
/* Assume the KeySym is a legal value (ignore discontinuities) */
|
||||
if (sym >= XKB_KEY_Rcedilla && sym <= XKB_KEY_Tslash)
|
||||
*lower += (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
|
||||
else if (sym >= XKB_KEY_rcedilla && sym <= XKB_KEY_tslash)
|
||||
*upper -= (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
|
||||
else if (sym == XKB_KEY_ENG)
|
||||
*lower = XKB_KEY_eng;
|
||||
else if (sym == XKB_KEY_eng)
|
||||
*upper = XKB_KEY_ENG;
|
||||
else if (sym >= XKB_KEY_Amacron && sym <= XKB_KEY_Umacron)
|
||||
*lower += (XKB_KEY_amacron - XKB_KEY_Amacron);
|
||||
else if (sym >= XKB_KEY_amacron && sym <= XKB_KEY_umacron)
|
||||
*upper -= (XKB_KEY_amacron - XKB_KEY_Amacron);
|
||||
break;
|
||||
case 6: /* Cyrillic */
|
||||
/* Assume the KeySym is a legal value (ignore discontinuities) */
|
||||
if (sym >= XKB_KEY_Serbian_DJE && sym <= XKB_KEY_Serbian_DZE)
|
||||
*lower -= (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
|
||||
else if (sym >= XKB_KEY_Serbian_dje && sym <= XKB_KEY_Serbian_dze)
|
||||
*upper += (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
|
||||
else if (sym >= XKB_KEY_Cyrillic_YU && sym <= XKB_KEY_Cyrillic_HARDSIGN)
|
||||
*lower -= (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
|
||||
else if (sym >= XKB_KEY_Cyrillic_yu && sym <= XKB_KEY_Cyrillic_hardsign)
|
||||
*upper += (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
|
||||
break;
|
||||
case 7: /* Greek */
|
||||
/* Assume the KeySym is a legal value (ignore discontinuities) */
|
||||
if (sym >= XKB_KEY_Greek_ALPHAaccent && sym <= XKB_KEY_Greek_OMEGAaccent)
|
||||
*lower += (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
|
||||
else if (sym >= XKB_KEY_Greek_alphaaccent && sym <= XKB_KEY_Greek_omegaaccent &&
|
||||
sym != XKB_KEY_Greek_iotaaccentdieresis &&
|
||||
sym != XKB_KEY_Greek_upsilonaccentdieresis)
|
||||
*upper -= (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
|
||||
else if (sym >= XKB_KEY_Greek_ALPHA && sym <= XKB_KEY_Greek_OMEGA)
|
||||
*lower += (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
|
||||
else if (sym >= XKB_KEY_Greek_alpha && sym <= XKB_KEY_Greek_omega &&
|
||||
sym != XKB_KEY_Greek_finalsmallsigma)
|
||||
*upper -= (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
|
||||
break;
|
||||
case 0x13: /* Latin 9 */
|
||||
if (sym == XKB_KEY_OE)
|
||||
*lower = XKB_KEY_oe;
|
||||
else if (sym == XKB_KEY_oe)
|
||||
*upper = XKB_KEY_OE;
|
||||
else if (sym == XKB_KEY_Ydiaeresis)
|
||||
*lower = XKB_KEY_ydiaeresis;
|
||||
break;
|
||||
}
|
||||
}
|
65
src/3rdparty/xkbcommon/src/keysym.h
vendored
65
src/3rdparty/xkbcommon/src/keysym.h
vendored
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 1985, 1987, 1990, 1998 The Open Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the names of the authors or their
|
||||
* institutions shall not be used in advertising or otherwise to promote the
|
||||
* sale, use or other dealings in this Software without prior written
|
||||
* authorization from the authors.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright © 2009 Dan Nicholson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef KEYSYM_H
|
||||
#define KEYSYM_H
|
||||
|
||||
bool
|
||||
xkb_keysym_is_lower(xkb_keysym_t keysym);
|
||||
|
||||
bool
|
||||
xkb_keysym_is_upper(xkb_keysym_t keysym);
|
||||
|
||||
bool
|
||||
xkb_keysym_is_keypad(xkb_keysym_t keysym);
|
||||
|
||||
bool
|
||||
xkb_keysym_is_modifier(xkb_keysym_t keysym);
|
||||
|
||||
#endif
|
7116
src/3rdparty/xkbcommon/src/ks_tables.h
vendored
7116
src/3rdparty/xkbcommon/src/ks_tables.h
vendored
File diff suppressed because it is too large
Load Diff
195
src/3rdparty/xkbcommon/src/scanner-utils.h
vendored
195
src/3rdparty/xkbcommon/src/scanner-utils.h
vendored
@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XKBCOMP_SCANNER_UTILS_H
|
||||
#define XKBCOMP_SCANNER_UTILS_H
|
||||
|
||||
/* Point to some substring in the file; used to avoid copying. */
|
||||
struct sval {
|
||||
const char *start;
|
||||
unsigned int len;
|
||||
};
|
||||
typedef darray(struct sval) darray_sval;
|
||||
|
||||
static inline bool
|
||||
svaleq(struct sval s1, struct sval s2)
|
||||
{
|
||||
return s1.len == s2.len && memcmp(s1.start, s2.start, s1.len) == 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
svaleq_prefix(struct sval s1, struct sval s2)
|
||||
{
|
||||
return s1.len <= s2.len && memcmp(s1.start, s2.start, s1.len) == 0;
|
||||
}
|
||||
|
||||
struct scanner {
|
||||
const char *s;
|
||||
size_t pos;
|
||||
size_t len;
|
||||
char buf[1024];
|
||||
size_t buf_pos;
|
||||
unsigned line, column;
|
||||
/* The line/column of the start of the current token. */
|
||||
unsigned token_line, token_column;
|
||||
const char *file_name;
|
||||
struct xkb_context *ctx;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
#define scanner_log(scanner, level, fmt, ...) \
|
||||
xkb_log((scanner)->ctx, (level), 0, \
|
||||
"%s:%u:%u: " fmt "\n", \
|
||||
(scanner)->file_name, \
|
||||
(scanner)->token_line, (scanner)->token_column, ##__VA_ARGS__)
|
||||
|
||||
#define scanner_err(scanner, fmt, ...) \
|
||||
scanner_log(scanner, XKB_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define scanner_warn(scanner, fmt, ...) \
|
||||
scanner_log(scanner, XKB_LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__)
|
||||
|
||||
static inline void
|
||||
scanner_init(struct scanner *s, struct xkb_context *ctx,
|
||||
const char *string, size_t len, const char *file_name,
|
||||
void *priv)
|
||||
{
|
||||
s->s = string;
|
||||
s->len = len;
|
||||
s->pos = 0;
|
||||
s->line = s->column = 1;
|
||||
s->token_line = s->token_column = 1;
|
||||
s->file_name = file_name;
|
||||
s->ctx = ctx;
|
||||
s->priv = priv;
|
||||
}
|
||||
|
||||
static inline char
|
||||
peek(struct scanner *s)
|
||||
{
|
||||
if (unlikely(s->pos >= s->len))
|
||||
return '\0';
|
||||
return s->s[s->pos];
|
||||
}
|
||||
|
||||
static inline bool
|
||||
eof(struct scanner *s)
|
||||
{
|
||||
return s->pos >= s->len;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
eol(struct scanner *s)
|
||||
{
|
||||
return peek(s) == '\n';
|
||||
}
|
||||
|
||||
static inline void
|
||||
skip_to_eol(struct scanner *s)
|
||||
{
|
||||
const char *nl = memchr(s->s + s->pos, '\n', s->len - s->pos);
|
||||
const size_t new_pos = nl ? (size_t) (nl - s->s) : s->len;
|
||||
s->column += new_pos - s->pos;
|
||||
s->pos = new_pos;
|
||||
}
|
||||
|
||||
static inline char
|
||||
next(struct scanner *s)
|
||||
{
|
||||
if (unlikely(eof(s)))
|
||||
return '\0';
|
||||
if (unlikely(eol(s))) {
|
||||
s->line++;
|
||||
s->column = 1;
|
||||
}
|
||||
else {
|
||||
s->column++;
|
||||
}
|
||||
return s->s[s->pos++];
|
||||
}
|
||||
|
||||
static inline bool
|
||||
chr(struct scanner *s, char ch)
|
||||
{
|
||||
if (likely(peek(s) != ch))
|
||||
return false;
|
||||
s->pos++; s->column++;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
str(struct scanner *s, const char *string, size_t len)
|
||||
{
|
||||
if (s->len - s->pos < len)
|
||||
return false;
|
||||
if (memcmp(s->s + s->pos, string, len) != 0)
|
||||
return false;
|
||||
s->pos += len; s->column += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define lit(s, literal) str(s, literal, sizeof(literal) - 1)
|
||||
|
||||
static inline bool
|
||||
buf_append(struct scanner *s, char ch)
|
||||
{
|
||||
if (s->buf_pos + 1 >= sizeof(s->buf))
|
||||
return false;
|
||||
s->buf[s->buf_pos++] = ch;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
buf_appends(struct scanner *s, const char *str)
|
||||
{
|
||||
int ret;
|
||||
ret = snprintf(s->buf + s->buf_pos, sizeof(s->buf) - s->buf_pos, "%s", str);
|
||||
if (ret < 0 || (size_t) ret >= sizeof(s->buf) - s->buf_pos)
|
||||
return false;
|
||||
s->buf_pos += ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
oct(struct scanner *s, uint8_t *out)
|
||||
{
|
||||
int i;
|
||||
for (i = 0, *out = 0; peek(s) >= '0' && peek(s) <= '7' && i < 3; i++)
|
||||
*out = *out * 8 + next(s) - '0';
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hex(struct scanner *s, uint8_t *out)
|
||||
{
|
||||
int i;
|
||||
for (i = 0, *out = 0; is_xdigit(peek(s)) && i < 2; i++) {
|
||||
const char c = next(s);
|
||||
const char offset = (c >= '0' && c <= '9' ? '0' :
|
||||
c >= 'a' && c <= 'f' ? 'a' - 10 : 'A' - 10);
|
||||
*out = *out * 16 + c - offset;
|
||||
}
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
#endif
|
1446
src/3rdparty/xkbcommon/src/state.c
vendored
1446
src/3rdparty/xkbcommon/src/state.c
vendored
File diff suppressed because it is too large
Load Diff
346
src/3rdparty/xkbcommon/src/text.c
vendored
346
src/3rdparty/xkbcommon/src/text.c
vendored
@ -1,346 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#include "keymap.h"
|
||||
#include "text.h"
|
||||
|
||||
bool
|
||||
LookupString(const LookupEntry tab[], const char *string,
|
||||
unsigned int *value_rtrn)
|
||||
{
|
||||
if (!string)
|
||||
return false;
|
||||
|
||||
for (const LookupEntry *entry = tab; entry->name; entry++) {
|
||||
if (istreq(entry->name, string)) {
|
||||
*value_rtrn = entry->value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *
|
||||
LookupValue(const LookupEntry tab[], unsigned int value)
|
||||
{
|
||||
for (const LookupEntry *entry = tab; entry->name; entry++)
|
||||
if (entry->value == value)
|
||||
return entry->name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LookupEntry ctrlMaskNames[] = {
|
||||
{ "RepeatKeys", CONTROL_REPEAT },
|
||||
{ "Repeat", CONTROL_REPEAT },
|
||||
{ "AutoRepeat", CONTROL_REPEAT },
|
||||
{ "SlowKeys", CONTROL_SLOW },
|
||||
{ "BounceKeys", CONTROL_DEBOUNCE },
|
||||
{ "StickyKeys", CONTROL_STICKY },
|
||||
{ "MouseKeys", CONTROL_MOUSEKEYS },
|
||||
{ "MouseKeysAccel", CONTROL_MOUSEKEYS_ACCEL },
|
||||
{ "AccessXKeys", CONTROL_AX },
|
||||
{ "AccessXTimeout", CONTROL_AX_TIMEOUT },
|
||||
{ "AccessXFeedback", CONTROL_AX_FEEDBACK },
|
||||
{ "AudibleBell", CONTROL_BELL },
|
||||
{ "IgnoreGroupLock", CONTROL_IGNORE_GROUP_LOCK },
|
||||
{ "all", CONTROL_ALL },
|
||||
{ "none", 0 },
|
||||
{ "Overlay1", 0 },
|
||||
{ "Overlay2", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const LookupEntry modComponentMaskNames[] = {
|
||||
{ "base", XKB_STATE_MODS_DEPRESSED },
|
||||
{ "latched", XKB_STATE_MODS_LATCHED },
|
||||
{ "locked", XKB_STATE_MODS_LOCKED },
|
||||
{ "effective", XKB_STATE_MODS_EFFECTIVE },
|
||||
{ "compat", XKB_STATE_MODS_EFFECTIVE },
|
||||
{ "any", XKB_STATE_MODS_EFFECTIVE },
|
||||
{ "none", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const LookupEntry groupComponentMaskNames[] = {
|
||||
{ "base", XKB_STATE_LAYOUT_DEPRESSED },
|
||||
{ "latched", XKB_STATE_LAYOUT_LATCHED },
|
||||
{ "locked", XKB_STATE_LAYOUT_LOCKED },
|
||||
{ "effective", XKB_STATE_LAYOUT_EFFECTIVE },
|
||||
{ "any", XKB_STATE_LAYOUT_EFFECTIVE },
|
||||
{ "none", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const LookupEntry groupMaskNames[] = {
|
||||
{ "Group1", 0x01 },
|
||||
{ "Group2", 0x02 },
|
||||
{ "Group3", 0x04 },
|
||||
{ "Group4", 0x08 },
|
||||
{ "Group5", 0x10 },
|
||||
{ "Group6", 0x20 },
|
||||
{ "Group7", 0x40 },
|
||||
{ "Group8", 0x80 },
|
||||
{ "none", 0x00 },
|
||||
{ "all", 0xff },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const LookupEntry groupNames[] = {
|
||||
{ "Group1", 1 },
|
||||
{ "Group2", 2 },
|
||||
{ "Group3", 3 },
|
||||
{ "Group4", 4 },
|
||||
{ "Group5", 5 },
|
||||
{ "Group6", 6 },
|
||||
{ "Group7", 7 },
|
||||
{ "Group8", 8 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const LookupEntry levelNames[] = {
|
||||
{ "Level1", 1 },
|
||||
{ "Level2", 2 },
|
||||
{ "Level3", 3 },
|
||||
{ "Level4", 4 },
|
||||
{ "Level5", 5 },
|
||||
{ "Level6", 6 },
|
||||
{ "Level7", 7 },
|
||||
{ "Level8", 8 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const LookupEntry buttonNames[] = {
|
||||
{ "Button1", 1 },
|
||||
{ "Button2", 2 },
|
||||
{ "Button3", 3 },
|
||||
{ "Button4", 4 },
|
||||
{ "Button5", 5 },
|
||||
{ "default", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const LookupEntry useModMapValueNames[] = {
|
||||
{ "LevelOne", 1 },
|
||||
{ "Level1", 1 },
|
||||
{ "AnyLevel", 0 },
|
||||
{ "any", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const LookupEntry actionTypeNames[] = {
|
||||
{ "NoAction", ACTION_TYPE_NONE },
|
||||
{ "SetMods", ACTION_TYPE_MOD_SET },
|
||||
{ "LatchMods", ACTION_TYPE_MOD_LATCH },
|
||||
{ "LockMods", ACTION_TYPE_MOD_LOCK },
|
||||
{ "SetGroup", ACTION_TYPE_GROUP_SET },
|
||||
{ "LatchGroup", ACTION_TYPE_GROUP_LATCH },
|
||||
{ "LockGroup", ACTION_TYPE_GROUP_LOCK },
|
||||
{ "MovePtr", ACTION_TYPE_PTR_MOVE },
|
||||
{ "MovePointer", ACTION_TYPE_PTR_MOVE },
|
||||
{ "PtrBtn", ACTION_TYPE_PTR_BUTTON },
|
||||
{ "PointerButton", ACTION_TYPE_PTR_BUTTON },
|
||||
{ "LockPtrBtn", ACTION_TYPE_PTR_LOCK },
|
||||
{ "LockPtrButton", ACTION_TYPE_PTR_LOCK },
|
||||
{ "LockPointerButton", ACTION_TYPE_PTR_LOCK },
|
||||
{ "LockPointerBtn", ACTION_TYPE_PTR_LOCK },
|
||||
{ "SetPtrDflt", ACTION_TYPE_PTR_DEFAULT },
|
||||
{ "SetPointerDefault", ACTION_TYPE_PTR_DEFAULT },
|
||||
{ "Terminate", ACTION_TYPE_TERMINATE },
|
||||
{ "TerminateServer", ACTION_TYPE_TERMINATE },
|
||||
{ "SwitchScreen", ACTION_TYPE_SWITCH_VT },
|
||||
{ "SetControls", ACTION_TYPE_CTRL_SET },
|
||||
{ "LockControls", ACTION_TYPE_CTRL_LOCK },
|
||||
{ "Private", ACTION_TYPE_PRIVATE },
|
||||
/* deprecated actions below here - unused */
|
||||
{ "RedirectKey", ACTION_TYPE_NONE },
|
||||
{ "Redirect", ACTION_TYPE_NONE },
|
||||
{ "ISOLock", ACTION_TYPE_NONE },
|
||||
{ "ActionMessage", ACTION_TYPE_NONE },
|
||||
{ "MessageAction", ACTION_TYPE_NONE },
|
||||
{ "Message", ACTION_TYPE_NONE },
|
||||
{ "DeviceBtn", ACTION_TYPE_NONE },
|
||||
{ "DevBtn", ACTION_TYPE_NONE },
|
||||
{ "DevButton", ACTION_TYPE_NONE },
|
||||
{ "DeviceButton", ACTION_TYPE_NONE },
|
||||
{ "LockDeviceBtn", ACTION_TYPE_NONE },
|
||||
{ "LockDevBtn", ACTION_TYPE_NONE },
|
||||
{ "LockDevButton", ACTION_TYPE_NONE },
|
||||
{ "LockDeviceButton", ACTION_TYPE_NONE },
|
||||
{ "DeviceValuator", ACTION_TYPE_NONE },
|
||||
{ "DevVal", ACTION_TYPE_NONE },
|
||||
{ "DeviceVal", ACTION_TYPE_NONE },
|
||||
{ "DevValuator", ACTION_TYPE_NONE },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
const LookupEntry symInterpretMatchMaskNames[] = {
|
||||
{ "NoneOf", MATCH_NONE },
|
||||
{ "AnyOfOrNone", MATCH_ANY_OR_NONE },
|
||||
{ "AnyOf", MATCH_ANY },
|
||||
{ "AllOf", MATCH_ALL },
|
||||
{ "Exactly", MATCH_EXACTLY },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
const char *
|
||||
ModIndexText(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
xkb_mod_index_t ndx)
|
||||
{
|
||||
if (ndx == XKB_MOD_INVALID)
|
||||
return "none";
|
||||
|
||||
if (ndx >= mods->num_mods)
|
||||
return NULL;
|
||||
|
||||
return xkb_atom_text(ctx, mods->mods[ndx].name);
|
||||
}
|
||||
|
||||
const char *
|
||||
ActionTypeText(enum xkb_action_type type)
|
||||
{
|
||||
const char *name = LookupValue(actionTypeNames, type);
|
||||
return name ? name : "Private";
|
||||
}
|
||||
|
||||
const char *
|
||||
KeysymText(struct xkb_context *ctx, xkb_keysym_t sym)
|
||||
{
|
||||
char *buffer = xkb_context_get_buffer(ctx, 64);
|
||||
xkb_keysym_get_name(sym, buffer, 64);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const char *
|
||||
KeyNameText(struct xkb_context *ctx, xkb_atom_t name)
|
||||
{
|
||||
const char *sname = xkb_atom_text(ctx, name);
|
||||
size_t len = strlen_safe(sname) + 3;
|
||||
char *buf = xkb_context_get_buffer(ctx, len);
|
||||
snprintf(buf, len, "<%s>", strempty(sname));
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *
|
||||
SIMatchText(enum xkb_match_operation type)
|
||||
{
|
||||
return LookupValue(symInterpretMatchMaskNames, type);
|
||||
}
|
||||
|
||||
const char *
|
||||
ModMaskText(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
xkb_mod_mask_t mask)
|
||||
{
|
||||
char buf[1024] = {0};
|
||||
size_t pos = 0;
|
||||
xkb_mod_index_t i;
|
||||
const struct xkb_mod *mod;
|
||||
|
||||
if (mask == 0)
|
||||
return "none";
|
||||
|
||||
if (mask == MOD_REAL_MASK_ALL)
|
||||
return "all";
|
||||
|
||||
xkb_mods_enumerate(i, mod, mods) {
|
||||
int ret;
|
||||
|
||||
if (!(mask & (1u << i)))
|
||||
continue;
|
||||
|
||||
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
|
||||
pos == 0 ? "" : "+",
|
||||
xkb_atom_text(ctx, mod->name));
|
||||
if (ret <= 0 || pos + ret >= sizeof(buf))
|
||||
break;
|
||||
else
|
||||
pos += ret;
|
||||
}
|
||||
|
||||
return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf);
|
||||
}
|
||||
|
||||
const char *
|
||||
LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask)
|
||||
{
|
||||
char buf[1024];
|
||||
size_t pos = 0;
|
||||
|
||||
if (mask == 0)
|
||||
return "0";
|
||||
|
||||
for (unsigned i = 0; mask; i++) {
|
||||
int ret;
|
||||
|
||||
if (!(mask & (1u << i)))
|
||||
continue;
|
||||
|
||||
mask &= ~(1u << i);
|
||||
|
||||
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
|
||||
pos == 0 ? "" : "+",
|
||||
LookupValue(modComponentMaskNames, 1u << i));
|
||||
if (ret <= 0 || pos + ret >= sizeof(buf))
|
||||
break;
|
||||
else
|
||||
pos += ret;
|
||||
}
|
||||
|
||||
return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf);
|
||||
}
|
||||
|
||||
const char *
|
||||
ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask)
|
||||
{
|
||||
char buf[1024];
|
||||
size_t pos = 0;
|
||||
|
||||
if (mask == 0)
|
||||
return "none";
|
||||
|
||||
if (mask == CONTROL_ALL)
|
||||
return "all";
|
||||
|
||||
for (unsigned i = 0; mask; i++) {
|
||||
int ret;
|
||||
|
||||
if (!(mask & (1u << i)))
|
||||
continue;
|
||||
|
||||
mask &= ~(1u << i);
|
||||
|
||||
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
|
||||
pos == 0 ? "" : "+",
|
||||
LookupValue(ctrlMaskNames, 1u << i));
|
||||
if (ret <= 0 || pos + ret >= sizeof(buf))
|
||||
break;
|
||||
else
|
||||
pos += ret;
|
||||
}
|
||||
|
||||
return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf);
|
||||
}
|
76
src/3rdparty/xkbcommon/src/text.h
vendored
76
src/3rdparty/xkbcommon/src/text.h
vendored
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 Dan Nicholson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TEXT_H
|
||||
#define TEXT_H
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
unsigned int value;
|
||||
} LookupEntry;
|
||||
|
||||
bool
|
||||
LookupString(const LookupEntry tab[], const char *string,
|
||||
unsigned int *value_rtrn);
|
||||
|
||||
const char *
|
||||
LookupValue(const LookupEntry tab[], unsigned int value);
|
||||
|
||||
extern const LookupEntry ctrlMaskNames[];
|
||||
extern const LookupEntry modComponentMaskNames[];
|
||||
extern const LookupEntry groupComponentMaskNames[];
|
||||
extern const LookupEntry groupMaskNames[];
|
||||
extern const LookupEntry groupNames[];
|
||||
extern const LookupEntry levelNames[];
|
||||
extern const LookupEntry buttonNames[];
|
||||
extern const LookupEntry useModMapValueNames[];
|
||||
extern const LookupEntry actionTypeNames[];
|
||||
extern const LookupEntry symInterpretMatchMaskNames[];
|
||||
|
||||
const char *
|
||||
ModMaskText(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
xkb_mod_mask_t mask);
|
||||
|
||||
const char *
|
||||
ModIndexText(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
xkb_mod_index_t ndx);
|
||||
|
||||
const char *
|
||||
ActionTypeText(enum xkb_action_type type);
|
||||
|
||||
const char *
|
||||
KeysymText(struct xkb_context *ctx, xkb_keysym_t sym);
|
||||
|
||||
const char *
|
||||
KeyNameText(struct xkb_context *ctx, xkb_atom_t name);
|
||||
|
||||
const char *
|
||||
SIMatchText(enum xkb_match_operation type);
|
||||
|
||||
const char *
|
||||
LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask);
|
||||
|
||||
const char *
|
||||
ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask);
|
||||
|
||||
#endif /* TEXT_H */
|
138
src/3rdparty/xkbcommon/src/utf8.c
vendored
138
src/3rdparty/xkbcommon/src/utf8.c
vendored
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2014 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Rob Bradford <rob@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "utf8.h"
|
||||
|
||||
int
|
||||
utf32_to_utf8(uint32_t unichar, char *buffer)
|
||||
{
|
||||
int count, shift, length;
|
||||
uint8_t head;
|
||||
|
||||
if (unichar <= 0x007f) {
|
||||
buffer[0] = unichar;
|
||||
buffer[1] = '\0';
|
||||
return 2;
|
||||
}
|
||||
else if (unichar <= 0x07FF) {
|
||||
length = 2;
|
||||
head = 0xc0;
|
||||
}
|
||||
else if (unichar <= 0xffff) {
|
||||
length = 3;
|
||||
head = 0xe0;
|
||||
}
|
||||
else if (unichar <= 0x10ffff) {
|
||||
length = 4;
|
||||
head = 0xf0;
|
||||
}
|
||||
else {
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (count = length - 1, shift = 0; count > 0; count--, shift += 6)
|
||||
buffer[count] = 0x80 | ((unichar >> shift) & 0x3f);
|
||||
|
||||
buffer[0] = head | ((unichar >> shift) & 0x3f);
|
||||
buffer[length] = '\0';
|
||||
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
bool
|
||||
is_valid_utf8(const char *ss, size_t len)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t tail_bytes = 0;
|
||||
const uint8_t *s = (const uint8_t *) ss;
|
||||
|
||||
/* This beauty is from:
|
||||
* The Unicode Standard Version 6.2 - Core Specification, Table 3.7
|
||||
* https://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G7404
|
||||
* We can optimize if needed. */
|
||||
while (i < len)
|
||||
{
|
||||
if (s[i] <= 0x7F) {
|
||||
tail_bytes = 0;
|
||||
}
|
||||
else if (s[i] >= 0xC2 && s[i] <= 0xDF) {
|
||||
tail_bytes = 1;
|
||||
}
|
||||
else if (s[i] == 0xE0) {
|
||||
i++;
|
||||
if (i >= len || !(s[i] >= 0xA0 && s[i] <= 0xBF))
|
||||
return false;
|
||||
tail_bytes = 1;
|
||||
}
|
||||
else if (s[i] >= 0xE1 && s[i] <= 0xEC) {
|
||||
tail_bytes = 2;
|
||||
}
|
||||
else if (s[i] == 0xED) {
|
||||
i++;
|
||||
if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x9F))
|
||||
return false;
|
||||
tail_bytes = 1;
|
||||
}
|
||||
else if (s[i] >= 0xEE && s[i] <= 0xEF) {
|
||||
tail_bytes = 2;
|
||||
}
|
||||
else if (s[i] == 0xF0) {
|
||||
i++;
|
||||
if (i >= len || !(s[i] >= 0x90 && s[i] <= 0xBF))
|
||||
return false;
|
||||
tail_bytes = 2;
|
||||
}
|
||||
else if (s[i] >= 0xF1 && s[i] <= 0xF3) {
|
||||
tail_bytes = 3;
|
||||
}
|
||||
else if (s[i] == 0xF4) {
|
||||
i++;
|
||||
if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x8F))
|
||||
return false;
|
||||
tail_bytes = 2;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
while (i < len && tail_bytes > 0 && s[i] >= 0x80 && s[i] <= 0xBF) {
|
||||
i++;
|
||||
tail_bytes--;
|
||||
}
|
||||
|
||||
if (tail_bytes != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
36
src/3rdparty/xkbcommon/src/utf8.h
vendored
36
src/3rdparty/xkbcommon/src/utf8.h
vendored
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2014 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Rob Bradford <rob@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef XKBCOMMON_UTF8_H
|
||||
#define XKBCOMMON_UTF8_H
|
||||
|
||||
int
|
||||
utf32_to_utf8(uint32_t unichar, char *buffer);
|
||||
|
||||
bool
|
||||
is_valid_utf8(const char *ss, size_t len);
|
||||
|
||||
#endif
|
163
src/3rdparty/xkbcommon/src/utils.c
vendored
163
src/3rdparty/xkbcommon/src/utils.c
vendored
@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
bool
|
||||
map_file(FILE *file, char **string_out, size_t *size_out)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
int fd;
|
||||
char *string;
|
||||
|
||||
/* Make sure to keep the errno on failure! */
|
||||
fd = fileno(file);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
if (fstat(fd, &stat_buf) != 0)
|
||||
return false;
|
||||
|
||||
string = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (string == MAP_FAILED)
|
||||
return false;
|
||||
|
||||
*string_out = string;
|
||||
*size_out = stat_buf.st_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
unmap_file(char *str, size_t size)
|
||||
{
|
||||
munmap(str, size);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool
|
||||
map_file(FILE *file, char **string_out, size_t *size_out)
|
||||
{
|
||||
long ret;
|
||||
size_t ret_s;
|
||||
char *string;
|
||||
size_t size;
|
||||
|
||||
/* Make sure to keep the errno on failure! */
|
||||
|
||||
ret = fseek(file, 0, SEEK_END);
|
||||
if (ret != 0)
|
||||
return false;
|
||||
|
||||
ret = ftell(file);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
size = (size_t) ret;
|
||||
|
||||
ret = fseek(file, 0, SEEK_SET);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
string = malloc(size);
|
||||
if (!string)
|
||||
return false;
|
||||
|
||||
ret_s = fread(string, 1, size, file);
|
||||
if (ret_s < size) {
|
||||
free(string);
|
||||
return false;
|
||||
}
|
||||
|
||||
*string_out = string;
|
||||
*size_out = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
unmap_file(char *str, size_t size)
|
||||
{
|
||||
free(str);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ASCII lower-case map.
|
||||
static const unsigned char lower_map[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
|
||||
59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
|
||||
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
|
||||
91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
|
||||
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
|
||||
123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
|
||||
138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
|
||||
153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
|
||||
168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
|
||||
183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
|
||||
198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
|
||||
213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
|
||||
228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
|
||||
243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
|
||||
};
|
||||
|
||||
// ASCII tolower (to avoid locale issues).
|
||||
char
|
||||
to_lower(char c)
|
||||
{
|
||||
return (char) lower_map[(unsigned char) c];
|
||||
}
|
||||
|
||||
// ASCII strcasecmp (to avoid locale issues).
|
||||
int
|
||||
istrcmp(const char *a, const char *b)
|
||||
{
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (to_lower(a[i]) != to_lower(b[i]))
|
||||
return (int) to_lower(a[i]) - (int) to_lower(b[i]);
|
||||
if (!a[i])
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ASCII strncasecmp (to avoid locale issues).
|
||||
int
|
||||
istrncmp(const char *a, const char *b, size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (to_lower(a[i]) != to_lower(b[i]))
|
||||
return (int) to_lower(a[i]) - (int) to_lower(b[i]);
|
||||
if (!a[i])
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
276
src/3rdparty/xkbcommon/src/utils.h
vendored
276
src/3rdparty/xkbcommon/src/utils.h
vendored
@ -1,276 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H 1
|
||||
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "darray.h"
|
||||
|
||||
/*
|
||||
* We sometimes malloc strings and then expose them as const char*'s. This
|
||||
* macro is used when we free these strings in order to avoid -Wcast-qual
|
||||
* errors.
|
||||
*/
|
||||
#define UNCONSTIFY(const_ptr) ((void *) (uintptr_t) (const_ptr))
|
||||
|
||||
#define STATIC_ASSERT(expr, message) do { \
|
||||
switch (0) { case 0: case (expr): ; } \
|
||||
} while (0)
|
||||
|
||||
char
|
||||
to_lower(char c);
|
||||
|
||||
int
|
||||
istrcmp(const char *a, const char *b);
|
||||
|
||||
int
|
||||
istrncmp(const char *a, const char *b, size_t n);
|
||||
|
||||
static inline bool
|
||||
streq(const char *s1, const char *s2)
|
||||
{
|
||||
return strcmp(s1, s2) == 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
streq_not_null(const char *s1, const char *s2)
|
||||
{
|
||||
if (!s1 || !s2)
|
||||
return false;
|
||||
return streq(s1, s2);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
istreq(const char *s1, const char *s2)
|
||||
{
|
||||
return istrcmp(s1, s2) == 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
istreq_prefix(const char *s1, const char *s2)
|
||||
{
|
||||
return istrncmp(s1, s2, strlen(s1)) == 0;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
strdup_safe(const char *s)
|
||||
{
|
||||
return s ? strdup(s) : NULL;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
strlen_safe(const char *s)
|
||||
{
|
||||
return s ? strlen(s) : 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
isempty(const char *s)
|
||||
{
|
||||
return s == NULL || s[0] == '\0';
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
strnull(const char *s)
|
||||
{
|
||||
return s ? s : "(null)";
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
strempty(const char *s)
|
||||
{
|
||||
return s ? s : "";
|
||||
}
|
||||
|
||||
static inline void *
|
||||
memdup(const void *mem, size_t nmemb, size_t size)
|
||||
{
|
||||
void *p = calloc(nmemb, size);
|
||||
if (p)
|
||||
memcpy(p, mem, nmemb * size);
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline int
|
||||
min(int misc, int other)
|
||||
{
|
||||
return (misc < other) ? misc : other;
|
||||
}
|
||||
|
||||
static inline int
|
||||
max(int misc, int other)
|
||||
{
|
||||
return (misc > other) ? misc : other;
|
||||
}
|
||||
|
||||
/* ctype.h is locale-dependent and has other oddities. */
|
||||
static inline bool
|
||||
is_space(char ch)
|
||||
{
|
||||
return ch == ' ' || (ch >= '\t' && ch <= '\r');
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_alpha(char ch)
|
||||
{
|
||||
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_digit(char ch)
|
||||
{
|
||||
return ch >= '0' && ch <= '9';
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_alnum(char ch)
|
||||
{
|
||||
return is_alpha(ch) || is_digit(ch);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_xdigit(char ch)
|
||||
{
|
||||
return
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
(ch >= 'a' && ch <= 'f') ||
|
||||
(ch >= 'A' && ch <= 'F');
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_graph(char ch)
|
||||
{
|
||||
/* See table in ascii(7). */
|
||||
return ch >= '!' && ch <= '~';
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the bit position of the most significant bit.
|
||||
* Note: this is 1-based! It's more useful this way, and returns 0 when
|
||||
* mask is all 0s.
|
||||
*/
|
||||
static inline unsigned
|
||||
msb_pos(uint32_t mask)
|
||||
{
|
||||
unsigned pos = 0;
|
||||
while (mask) {
|
||||
pos++;
|
||||
mask >>= 1u;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Avoid conflict with other popcount()s.
|
||||
static inline int
|
||||
my_popcount(uint32_t x)
|
||||
{
|
||||
int count;
|
||||
#if defined(HAVE___BUILTIN_POPCOUNT)
|
||||
count = __builtin_popcount(x);
|
||||
#else
|
||||
for (count = 0; x; count++)
|
||||
x &= x - 1;
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
bool
|
||||
map_file(FILE *file, char **string_out, size_t *size_out);
|
||||
|
||||
void
|
||||
unmap_file(char *string, size_t size);
|
||||
|
||||
#define ARRAY_SIZE(arr) ((sizeof(arr) / sizeof(*(arr))))
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MIN3(a, b, c) MIN(MIN((a), (b)), (c))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MAX3(a, b, c) MAX(MAX((a), (b)), (c))
|
||||
|
||||
/* Round up @a so it's divisible by @b. */
|
||||
#define ROUNDUP(a, b) (((a) + (b) - 1) / (b) * (b))
|
||||
|
||||
#if defined(HAVE_SECURE_GETENV)
|
||||
# define secure_getenv secure_getenv
|
||||
#elif defined(HAVE___SECURE_GETENV)
|
||||
# define secure_getenv __secure_getenv
|
||||
#else
|
||||
# define secure_getenv getenv
|
||||
#endif
|
||||
|
||||
#if defined(HAVE___BUILTIN_EXPECT)
|
||||
# define likely(x) __builtin_expect(!!(x), 1)
|
||||
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
# define likely(x) (x)
|
||||
# define unlikely(x) (x)
|
||||
#endif
|
||||
|
||||
/* Compiler Attributes */
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__)
|
||||
# define XKB_EXPORT __attribute__((visibility("default")))
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
|
||||
# define XKB_EXPORT __global
|
||||
#else /* not gcc >= 4 and not Sun Studio >= 8 */
|
||||
# define XKB_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
|
||||
# define ATTR_PRINTF(x,y) __attribute__((__format__(__printf__, x, y)))
|
||||
#else /* not gcc >= 2.3 */
|
||||
# define ATTR_PRINTF(x,y)
|
||||
#endif
|
||||
|
||||
#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
|
||||
|| (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
|
||||
# define ATTR_NORETURN __attribute__((__noreturn__))
|
||||
#else
|
||||
# define ATTR_NORETURN
|
||||
#endif /* GNUC */
|
||||
|
||||
#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 296)
|
||||
#define ATTR_MALLOC __attribute__((__malloc__))
|
||||
#else
|
||||
#define ATTR_MALLOC
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
# define ATTR_NULL_SENTINEL __attribute__((__sentinel__))
|
||||
#else
|
||||
# define ATTR_NULL_SENTINEL
|
||||
#endif /* GNUC >= 4 */
|
||||
|
||||
#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 295)
|
||||
#define ATTR_PACKED __attribute__((__packed__))
|
||||
#else
|
||||
#define ATTR_PACKED
|
||||
#endif
|
||||
|
||||
#endif /* UTILS_H */
|
217
src/3rdparty/xkbcommon/src/x11/util.c
vendored
217
src/3rdparty/xkbcommon/src/x11/util.c
vendored
@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "x11-priv.h"
|
||||
|
||||
XKB_EXPORT int
|
||||
xkb_x11_setup_xkb_extension(xcb_connection_t *conn,
|
||||
uint16_t major_xkb_version,
|
||||
uint16_t minor_xkb_version,
|
||||
enum xkb_x11_setup_xkb_extension_flags flags,
|
||||
uint16_t *major_xkb_version_out,
|
||||
uint16_t *minor_xkb_version_out,
|
||||
uint8_t *base_event_out,
|
||||
uint8_t *base_error_out)
|
||||
{
|
||||
uint8_t base_event, base_error;
|
||||
uint16_t server_major, server_minor;
|
||||
|
||||
if (flags & ~(XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS)) {
|
||||
/* log_err_func(ctx, "unrecognized flags: %#x\n", flags); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
const xcb_query_extension_reply_t *reply =
|
||||
xcb_get_extension_data(conn, &xcb_xkb_id);
|
||||
if (!reply) {
|
||||
/* log_err_func(ctx, "failed to query for XKB extension\n"); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!reply->present) {
|
||||
/* log_err_func(ctx, "failed to start using XKB extension: not available in server\n"); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
base_event = reply->first_event;
|
||||
base_error = reply->first_error;
|
||||
}
|
||||
|
||||
{
|
||||
xcb_generic_error_t *error = NULL;
|
||||
xcb_xkb_use_extension_cookie_t cookie =
|
||||
xcb_xkb_use_extension(conn, major_xkb_version, minor_xkb_version);
|
||||
xcb_xkb_use_extension_reply_t *reply =
|
||||
xcb_xkb_use_extension_reply(conn, cookie, &error);
|
||||
|
||||
if (!reply) {
|
||||
/* log_err_func(ctx, */
|
||||
/* "failed to start using XKB extension: error code %d\n", */
|
||||
/* error ? error->error_code : -1); */
|
||||
free(error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!reply->supported) {
|
||||
/* log_err_func(ctx, */
|
||||
/* "failed to start using XKB extension: server doesn't support version %d.%d\n", */
|
||||
/* major_xkb_version, minor_xkb_version); */
|
||||
free(reply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
server_major = reply->serverMajor;
|
||||
server_minor = reply->serverMinor;
|
||||
|
||||
free(reply);
|
||||
}
|
||||
|
||||
/*
|
||||
* The XkbUseExtension() in libX11 has a *bunch* of legacy stuff, but
|
||||
* it doesn't seem like any of it is useful to us.
|
||||
*/
|
||||
|
||||
if (major_xkb_version_out)
|
||||
*major_xkb_version_out = server_major;
|
||||
if (minor_xkb_version_out)
|
||||
*minor_xkb_version_out = server_minor;
|
||||
if (base_event_out)
|
||||
*base_event_out = base_event;
|
||||
if (base_error_out)
|
||||
*base_error_out = base_error;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
XKB_EXPORT int32_t
|
||||
xkb_x11_get_core_keyboard_device_id(xcb_connection_t *conn)
|
||||
{
|
||||
int32_t device_id;
|
||||
xcb_xkb_get_device_info_cookie_t cookie =
|
||||
xcb_xkb_get_device_info(conn, XCB_XKB_ID_USE_CORE_KBD,
|
||||
0, 0, 0, 0, 0, 0);
|
||||
xcb_xkb_get_device_info_reply_t *reply =
|
||||
xcb_xkb_get_device_info_reply(conn, cookie, NULL);
|
||||
|
||||
if (!reply)
|
||||
return -1;
|
||||
|
||||
device_id = reply->deviceID;
|
||||
free(reply);
|
||||
return device_id;
|
||||
}
|
||||
|
||||
bool
|
||||
get_atom_name(xcb_connection_t *conn, xcb_atom_t atom, char **out)
|
||||
{
|
||||
xcb_get_atom_name_cookie_t cookie;
|
||||
xcb_get_atom_name_reply_t *reply;
|
||||
int length;
|
||||
char *name;
|
||||
|
||||
if (atom == 0) {
|
||||
*out = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
cookie = xcb_get_atom_name(conn, atom);
|
||||
reply = xcb_get_atom_name_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
return false;
|
||||
|
||||
length = xcb_get_atom_name_name_length(reply);
|
||||
name = xcb_get_atom_name_name(reply);
|
||||
|
||||
*out = strndup(name, length);
|
||||
if (!*out) {
|
||||
free(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
free(reply);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn,
|
||||
const xcb_atom_t *from, xkb_atom_t *to, const size_t count)
|
||||
{
|
||||
enum { SIZE = 128 };
|
||||
xcb_get_atom_name_cookie_t cookies[SIZE];
|
||||
const size_t num_batches = ROUNDUP(count, SIZE) / SIZE;
|
||||
|
||||
/* Send and collect the atoms in batches of reasonable SIZE. */
|
||||
for (size_t batch = 0; batch < num_batches; batch++) {
|
||||
const size_t start = batch * SIZE;
|
||||
const size_t stop = min((batch + 1) * SIZE, count);
|
||||
|
||||
/* Send. */
|
||||
for (size_t i = start; i < stop; i++)
|
||||
if (from[i] != XCB_ATOM_NONE)
|
||||
cookies[i % SIZE] = xcb_get_atom_name(conn, from[i]);
|
||||
|
||||
/* Collect. */
|
||||
for (size_t i = start; i < stop; i++) {
|
||||
xcb_get_atom_name_reply_t *reply;
|
||||
|
||||
if (from[i] == XCB_ATOM_NONE) {
|
||||
to[i] = XKB_ATOM_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
reply = xcb_get_atom_name_reply(conn, cookies[i % SIZE], NULL);
|
||||
if (!reply)
|
||||
goto err_discard;
|
||||
|
||||
to[i] = xkb_atom_intern(ctx,
|
||||
xcb_get_atom_name_name(reply),
|
||||
xcb_get_atom_name_name_length(reply));
|
||||
free(reply);
|
||||
|
||||
if (to[i] == XKB_ATOM_NONE)
|
||||
goto err_discard;
|
||||
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If we don't discard the uncollected replies, they just
|
||||
* sit in the XCB queue waiting forever. Sad.
|
||||
*/
|
||||
err_discard:
|
||||
for (size_t j = i + 1; j < stop; j++)
|
||||
if (from[j] != XCB_ATOM_NONE)
|
||||
xcb_discard_reply(conn, cookies[j % SIZE].sequence);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
adopt_atom(struct xkb_context *ctx, xcb_connection_t *conn, xcb_atom_t atom,
|
||||
xkb_atom_t *out)
|
||||
{
|
||||
return adopt_atoms(ctx, conn, &atom, out, 1);
|
||||
}
|
1177
src/3rdparty/xkbcommon/src/x11/x11-keymap.c
vendored
1177
src/3rdparty/xkbcommon/src/x11/x11-keymap.c
vendored
File diff suppressed because it is too large
Load Diff
54
src/3rdparty/xkbcommon/src/x11/x11-priv.h
vendored
54
src/3rdparty/xkbcommon/src/x11/x11-priv.h
vendored
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _XKBCOMMON_X11_PRIV_H
|
||||
#define _XKBCOMMON_X11_PRIV_H
|
||||
|
||||
#include <xcb/xkb.h>
|
||||
|
||||
#include "keymap.h"
|
||||
#include "xkbcommon/xkbcommon-x11.h"
|
||||
|
||||
/* Get a strdup'd name of an X atom. */
|
||||
bool
|
||||
get_atom_name(xcb_connection_t *conn, xcb_atom_t atom, char **out);
|
||||
|
||||
/*
|
||||
* Make a xkb_atom_t's from X atoms (prefer to send as many as possible
|
||||
* at once, to avoid many roundtrips).
|
||||
*
|
||||
* TODO: We can make this more flexible, such that @to doesn't have to
|
||||
* be sequential. Then we can convert most adopt_atom() calls to
|
||||
* adopt_atoms().
|
||||
* Atom caching would also likely be useful for avoiding quite a
|
||||
* few requests.
|
||||
*/
|
||||
bool
|
||||
adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn,
|
||||
const xcb_atom_t *from, xkb_atom_t *to, size_t count);
|
||||
|
||||
bool
|
||||
adopt_atom(struct xkb_context *ctx, xcb_connection_t *conn, xcb_atom_t atom,
|
||||
xkb_atom_t *out);
|
||||
|
||||
#endif
|
71
src/3rdparty/xkbcommon/src/x11/x11-state.c
vendored
71
src/3rdparty/xkbcommon/src/x11/x11-state.c
vendored
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "x11-priv.h"
|
||||
|
||||
static bool
|
||||
update_initial_state(struct xkb_state *state, xcb_connection_t *conn,
|
||||
uint16_t device_id)
|
||||
{
|
||||
xcb_xkb_get_state_cookie_t cookie =
|
||||
xcb_xkb_get_state(conn, device_id);
|
||||
xcb_xkb_get_state_reply_t *reply =
|
||||
xcb_xkb_get_state_reply(conn, cookie, NULL);
|
||||
|
||||
if (!reply)
|
||||
return false;
|
||||
|
||||
xkb_state_update_mask(state,
|
||||
reply->baseMods,
|
||||
reply->latchedMods,
|
||||
reply->lockedMods,
|
||||
reply->baseGroup,
|
||||
reply->latchedGroup,
|
||||
reply->lockedGroup);
|
||||
|
||||
free(reply);
|
||||
return true;
|
||||
}
|
||||
|
||||
XKB_EXPORT struct xkb_state *
|
||||
xkb_x11_state_new_from_device(struct xkb_keymap *keymap,
|
||||
xcb_connection_t *conn, int32_t device_id)
|
||||
{
|
||||
struct xkb_state *state;
|
||||
|
||||
if (device_id < 0 || device_id > 255) {
|
||||
log_err_func(keymap->ctx, "illegal device ID: %d", device_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state = xkb_state_new(keymap);
|
||||
if (!state)
|
||||
return NULL;
|
||||
|
||||
if (!update_initial_state(state, conn, device_id)) {
|
||||
xkb_state_unref(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
871
src/3rdparty/xkbcommon/src/xkbcomp/action.c
vendored
871
src/3rdparty/xkbcommon/src/xkbcomp/action.c
vendored
@ -1,871 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
* Ran Benita <ran234@gmail.com>
|
||||
*/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "text.h"
|
||||
#include "expr.h"
|
||||
#include "action.h"
|
||||
|
||||
static const ExprBoolean constTrue = {
|
||||
.expr = {
|
||||
.common = { .type = STMT_EXPR, .next = NULL },
|
||||
.op = EXPR_VALUE,
|
||||
.value_type = EXPR_TYPE_BOOLEAN,
|
||||
},
|
||||
.set = true,
|
||||
};
|
||||
|
||||
static const ExprBoolean constFalse = {
|
||||
.expr = {
|
||||
.common = { .type = STMT_EXPR, .next = NULL },
|
||||
.op = EXPR_VALUE,
|
||||
.value_type = EXPR_TYPE_BOOLEAN,
|
||||
},
|
||||
.set = false,
|
||||
};
|
||||
|
||||
enum action_field {
|
||||
ACTION_FIELD_CLEAR_LOCKS,
|
||||
ACTION_FIELD_LATCH_TO_LOCK,
|
||||
ACTION_FIELD_GEN_KEY_EVENT,
|
||||
ACTION_FIELD_REPORT,
|
||||
ACTION_FIELD_DEFAULT,
|
||||
ACTION_FIELD_AFFECT,
|
||||
ACTION_FIELD_INCREMENT,
|
||||
ACTION_FIELD_MODIFIERS,
|
||||
ACTION_FIELD_GROUP,
|
||||
ACTION_FIELD_X,
|
||||
ACTION_FIELD_Y,
|
||||
ACTION_FIELD_ACCEL,
|
||||
ACTION_FIELD_BUTTON,
|
||||
ACTION_FIELD_VALUE,
|
||||
ACTION_FIELD_CONTROLS,
|
||||
ACTION_FIELD_TYPE,
|
||||
ACTION_FIELD_COUNT,
|
||||
ACTION_FIELD_SCREEN,
|
||||
ACTION_FIELD_SAME,
|
||||
ACTION_FIELD_DATA,
|
||||
ACTION_FIELD_DEVICE,
|
||||
ACTION_FIELD_KEYCODE,
|
||||
ACTION_FIELD_MODS_TO_CLEAR,
|
||||
};
|
||||
|
||||
ActionsInfo *
|
||||
NewActionsInfo(void)
|
||||
{
|
||||
enum xkb_action_type type;
|
||||
ActionsInfo *info;
|
||||
|
||||
info = calloc(1, sizeof(*info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
for (type = 0; type < _ACTION_TYPE_NUM_ENTRIES; type++)
|
||||
info->actions[type].type = type;
|
||||
|
||||
/* Apply some "factory defaults". */
|
||||
|
||||
/* Increment default button. */
|
||||
info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.flags = 0;
|
||||
info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.value = 1;
|
||||
info->actions[ACTION_TYPE_PTR_MOVE].ptr.flags = ACTION_ACCEL;
|
||||
info->actions[ACTION_TYPE_SWITCH_VT].screen.flags = ACTION_SAME_SCREEN;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void
|
||||
FreeActionsInfo(ActionsInfo *info)
|
||||
{
|
||||
free(info);
|
||||
}
|
||||
|
||||
static const LookupEntry fieldStrings[] = {
|
||||
{ "clearLocks", ACTION_FIELD_CLEAR_LOCKS },
|
||||
{ "latchToLock", ACTION_FIELD_LATCH_TO_LOCK },
|
||||
{ "genKeyEvent", ACTION_FIELD_GEN_KEY_EVENT },
|
||||
{ "generateKeyEvent", ACTION_FIELD_GEN_KEY_EVENT },
|
||||
{ "report", ACTION_FIELD_REPORT },
|
||||
{ "default", ACTION_FIELD_DEFAULT },
|
||||
{ "affect", ACTION_FIELD_AFFECT },
|
||||
{ "increment", ACTION_FIELD_INCREMENT },
|
||||
{ "modifiers", ACTION_FIELD_MODIFIERS },
|
||||
{ "mods", ACTION_FIELD_MODIFIERS },
|
||||
{ "group", ACTION_FIELD_GROUP },
|
||||
{ "x", ACTION_FIELD_X },
|
||||
{ "y", ACTION_FIELD_Y },
|
||||
{ "accel", ACTION_FIELD_ACCEL },
|
||||
{ "accelerate", ACTION_FIELD_ACCEL },
|
||||
{ "repeat", ACTION_FIELD_ACCEL },
|
||||
{ "button", ACTION_FIELD_BUTTON },
|
||||
{ "value", ACTION_FIELD_VALUE },
|
||||
{ "controls", ACTION_FIELD_CONTROLS },
|
||||
{ "ctrls", ACTION_FIELD_CONTROLS },
|
||||
{ "type", ACTION_FIELD_TYPE },
|
||||
{ "count", ACTION_FIELD_COUNT },
|
||||
{ "screen", ACTION_FIELD_SCREEN },
|
||||
{ "same", ACTION_FIELD_SAME },
|
||||
{ "sameServer", ACTION_FIELD_SAME },
|
||||
{ "data", ACTION_FIELD_DATA },
|
||||
{ "device", ACTION_FIELD_DEVICE },
|
||||
{ "dev", ACTION_FIELD_DEVICE },
|
||||
{ "key", ACTION_FIELD_KEYCODE },
|
||||
{ "keycode", ACTION_FIELD_KEYCODE },
|
||||
{ "kc", ACTION_FIELD_KEYCODE },
|
||||
{ "clearmods", ACTION_FIELD_MODS_TO_CLEAR },
|
||||
{ "clearmodifiers", ACTION_FIELD_MODS_TO_CLEAR },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static bool
|
||||
stringToAction(const char *str, enum xkb_action_type *type_rtrn)
|
||||
{
|
||||
return LookupString(actionTypeNames, str, type_rtrn);
|
||||
}
|
||||
|
||||
static bool
|
||||
stringToField(const char *str, enum action_field *field_rtrn)
|
||||
{
|
||||
return LookupString(fieldStrings, str, field_rtrn);
|
||||
}
|
||||
|
||||
static const char *
|
||||
fieldText(enum action_field field)
|
||||
{
|
||||
return LookupValue(fieldStrings, field);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static inline bool
|
||||
ReportMismatch(struct xkb_context *ctx, enum xkb_action_type action,
|
||||
enum action_field field, const char *type)
|
||||
{
|
||||
log_err(ctx,
|
||||
"Value of %s field must be of type %s; "
|
||||
"Action %s definition ignored\n",
|
||||
fieldText(field), type, ActionTypeText(action));
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportIllegal(struct xkb_context *ctx, enum xkb_action_type action,
|
||||
enum action_field field)
|
||||
{
|
||||
log_err(ctx,
|
||||
"Field %s is not defined for an action of type %s; "
|
||||
"Action definition ignored\n",
|
||||
fieldText(field), ActionTypeText(action));
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportActionNotArray(struct xkb_context *ctx, enum xkb_action_type action,
|
||||
enum action_field field)
|
||||
{
|
||||
log_err(ctx,
|
||||
"The %s field in the %s action is not an array; "
|
||||
"Action definition ignored\n",
|
||||
fieldText(field), ActionTypeText(action));
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleNoAction(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
union xkb_action *action, enum action_field field,
|
||||
const ExprDef *array_ndx, const ExprDef *value)
|
||||
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckBooleanFlag(struct xkb_context *ctx, enum xkb_action_type action,
|
||||
enum action_field field, enum xkb_action_flags flag,
|
||||
const ExprDef *array_ndx, const ExprDef *value,
|
||||
enum xkb_action_flags *flags_inout)
|
||||
{
|
||||
bool set;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action, field);
|
||||
|
||||
if (!ExprResolveBoolean(ctx, value, &set))
|
||||
return ReportMismatch(ctx, action, field, "boolean");
|
||||
|
||||
if (set)
|
||||
*flags_inout |= flag;
|
||||
else
|
||||
*flags_inout &= ~flag;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckModifierField(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
enum xkb_action_type action, const ExprDef *array_ndx,
|
||||
const ExprDef *value, enum xkb_action_flags *flags_inout,
|
||||
xkb_mod_mask_t *mods_rtrn)
|
||||
{
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action, ACTION_FIELD_MODIFIERS);
|
||||
|
||||
if (value->expr.op == EXPR_IDENT) {
|
||||
const char *valStr;
|
||||
valStr = xkb_atom_text(ctx, value->ident.ident);
|
||||
if (valStr && (istreq(valStr, "usemodmapmods") ||
|
||||
istreq(valStr, "modmapmods"))) {
|
||||
*mods_rtrn = 0;
|
||||
*flags_inout |= ACTION_MODS_LOOKUP_MODMAP;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ExprResolveModMask(ctx, value, MOD_BOTH, mods, mods_rtrn))
|
||||
return ReportMismatch(ctx, action,
|
||||
ACTION_FIELD_MODIFIERS, "modifier mask");
|
||||
|
||||
*flags_inout &= ~ACTION_MODS_LOOKUP_MODMAP;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const LookupEntry lockWhich[] = {
|
||||
{ "both", 0 },
|
||||
{ "lock", ACTION_LOCK_NO_UNLOCK },
|
||||
{ "neither", (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK) },
|
||||
{ "unlock", ACTION_LOCK_NO_LOCK },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static bool
|
||||
CheckAffectField(struct xkb_context *ctx, enum xkb_action_type action,
|
||||
const ExprDef *array_ndx, const ExprDef *value,
|
||||
enum xkb_action_flags *flags_inout)
|
||||
{
|
||||
enum xkb_action_flags flags;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action, ACTION_FIELD_AFFECT);
|
||||
|
||||
if (!ExprResolveEnum(ctx, value, &flags, lockWhich))
|
||||
return ReportMismatch(ctx, action, ACTION_FIELD_AFFECT,
|
||||
"lock, unlock, both, neither");
|
||||
|
||||
*flags_inout &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK);
|
||||
*flags_inout |= flags;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleSetLatchLockMods(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
union xkb_action *action, enum action_field field,
|
||||
const ExprDef *array_ndx, const ExprDef *value)
|
||||
{
|
||||
struct xkb_mod_action *act = &action->mods;
|
||||
const enum xkb_action_type type = action->type;
|
||||
|
||||
if (field == ACTION_FIELD_MODIFIERS)
|
||||
return CheckModifierField(ctx, mods, action->type, array_ndx, value,
|
||||
&act->flags, &act->mods.mods);
|
||||
if ((type == ACTION_TYPE_MOD_SET || type == ACTION_TYPE_MOD_LATCH) &&
|
||||
field == ACTION_FIELD_CLEAR_LOCKS)
|
||||
return CheckBooleanFlag(ctx, action->type, field,
|
||||
ACTION_LOCK_CLEAR, array_ndx, value,
|
||||
&act->flags);
|
||||
if (type == ACTION_TYPE_MOD_LATCH &&
|
||||
field == ACTION_FIELD_LATCH_TO_LOCK)
|
||||
return CheckBooleanFlag(ctx, action->type, field,
|
||||
ACTION_LATCH_TO_LOCK, array_ndx, value,
|
||||
&act->flags);
|
||||
if (type == ACTION_TYPE_MOD_LOCK &&
|
||||
field == ACTION_FIELD_AFFECT)
|
||||
return CheckAffectField(ctx, action->type, array_ndx, value,
|
||||
&act->flags);
|
||||
|
||||
return ReportIllegal(ctx, action->type, field);
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckGroupField(struct xkb_context *ctx, enum xkb_action_type action,
|
||||
const ExprDef *array_ndx, const ExprDef *value,
|
||||
enum xkb_action_flags *flags_inout, int32_t *group_rtrn)
|
||||
{
|
||||
const ExprDef *spec;
|
||||
xkb_layout_index_t idx;
|
||||
enum xkb_action_flags flags = *flags_inout;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action, ACTION_FIELD_GROUP);
|
||||
|
||||
if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) {
|
||||
flags &= ~ACTION_ABSOLUTE_SWITCH;
|
||||
spec = value->unary.child;
|
||||
}
|
||||
else {
|
||||
flags |= ACTION_ABSOLUTE_SWITCH;
|
||||
spec = value;
|
||||
}
|
||||
|
||||
if (!ExprResolveGroup(ctx, spec, &idx))
|
||||
return ReportMismatch(ctx, action, ACTION_FIELD_GROUP,
|
||||
"integer (range 1..8)");
|
||||
|
||||
/* +n, -n are relative, n is absolute. */
|
||||
if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) {
|
||||
*group_rtrn = (int32_t) idx;
|
||||
if (value->expr.op == EXPR_NEGATE)
|
||||
*group_rtrn = -*group_rtrn;
|
||||
}
|
||||
else {
|
||||
*group_rtrn = (int32_t) (idx - 1);
|
||||
}
|
||||
*flags_inout = flags;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleSetLatchLockGroup(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
union xkb_action *action, enum action_field field,
|
||||
const ExprDef *array_ndx, const ExprDef *value)
|
||||
{
|
||||
struct xkb_group_action *act = &action->group;
|
||||
const enum xkb_action_type type = action->type;
|
||||
|
||||
if (field == ACTION_FIELD_GROUP)
|
||||
return CheckGroupField(ctx, action->type, array_ndx, value,
|
||||
&act->flags, &act->group);
|
||||
if ((type == ACTION_TYPE_GROUP_SET || type == ACTION_TYPE_GROUP_LATCH) &&
|
||||
field == ACTION_FIELD_CLEAR_LOCKS)
|
||||
return CheckBooleanFlag(ctx, action->type, field,
|
||||
ACTION_LOCK_CLEAR, array_ndx, value,
|
||||
&act->flags);
|
||||
if (type == ACTION_TYPE_GROUP_LATCH &&
|
||||
field == ACTION_FIELD_LATCH_TO_LOCK)
|
||||
return CheckBooleanFlag(ctx, action->type, field,
|
||||
ACTION_LATCH_TO_LOCK, array_ndx, value,
|
||||
&act->flags);
|
||||
|
||||
return ReportIllegal(ctx, action->type, field);
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleMovePtr(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
union xkb_action *action, enum action_field field,
|
||||
const ExprDef *array_ndx, const ExprDef *value)
|
||||
{
|
||||
struct xkb_pointer_action *act = &action->ptr;
|
||||
|
||||
if (field == ACTION_FIELD_X || field == ACTION_FIELD_Y) {
|
||||
int val;
|
||||
const bool absolute = (value->expr.op != EXPR_NEGATE &&
|
||||
value->expr.op != EXPR_UNARY_PLUS);
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action->type, field);
|
||||
|
||||
if (!ExprResolveInteger(ctx, value, &val))
|
||||
return ReportMismatch(ctx, action->type, field, "integer");
|
||||
|
||||
if (val < INT16_MIN || val > INT16_MAX) {
|
||||
log_err(ctx,
|
||||
"The %s field in the %s action must be in range %d..%d; "
|
||||
"Action definition ignored\n",
|
||||
fieldText(field), ActionTypeText(action->type),
|
||||
INT16_MIN, INT16_MAX);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (field == ACTION_FIELD_X) {
|
||||
if (absolute)
|
||||
act->flags |= ACTION_ABSOLUTE_X;
|
||||
act->x = (int16_t) val;
|
||||
}
|
||||
else {
|
||||
if (absolute)
|
||||
act->flags |= ACTION_ABSOLUTE_Y;
|
||||
act->y = (int16_t) val;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (field == ACTION_FIELD_ACCEL) {
|
||||
return CheckBooleanFlag(ctx, action->type, field,
|
||||
ACTION_ACCEL, array_ndx, value, &act->flags);
|
||||
}
|
||||
|
||||
return ReportIllegal(ctx, action->type, field);
|
||||
}
|
||||
|
||||
static bool
|
||||
HandlePtrBtn(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
union xkb_action *action, enum action_field field,
|
||||
const ExprDef *array_ndx, const ExprDef *value)
|
||||
{
|
||||
struct xkb_pointer_button_action *act = &action->btn;
|
||||
|
||||
if (field == ACTION_FIELD_BUTTON) {
|
||||
int btn;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action->type, field);
|
||||
|
||||
if (!ExprResolveButton(ctx, value, &btn))
|
||||
return ReportMismatch(ctx, action->type, field,
|
||||
"integer (range 1..5)");
|
||||
|
||||
if (btn < 0 || btn > 5) {
|
||||
log_err(ctx,
|
||||
"Button must specify default or be in the range 1..5; "
|
||||
"Illegal button value %d ignored\n", btn);
|
||||
return false;
|
||||
}
|
||||
|
||||
act->button = btn;
|
||||
return true;
|
||||
}
|
||||
else if (action->type == ACTION_TYPE_PTR_LOCK &&
|
||||
field == ACTION_FIELD_AFFECT) {
|
||||
return CheckAffectField(ctx, action->type, array_ndx, value,
|
||||
&act->flags);
|
||||
}
|
||||
else if (field == ACTION_FIELD_COUNT) {
|
||||
int val;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action->type, field);
|
||||
|
||||
if (!ExprResolveInteger(ctx, value, &val))
|
||||
return ReportMismatch(ctx, action->type, field, "integer");
|
||||
|
||||
if (val < 0 || val > 255) {
|
||||
log_err(ctx,
|
||||
"The count field must have a value in the range 0..255; "
|
||||
"Illegal count %d ignored\n", val);
|
||||
return false;
|
||||
}
|
||||
|
||||
act->count = (uint8_t) val;
|
||||
return true;
|
||||
}
|
||||
|
||||
return ReportIllegal(ctx, action->type, field);
|
||||
}
|
||||
|
||||
static const LookupEntry ptrDflts[] = {
|
||||
{ "dfltbtn", 1 },
|
||||
{ "defaultbutton", 1 },
|
||||
{ "button", 1 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static bool
|
||||
HandleSetPtrDflt(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
union xkb_action *action, enum action_field field,
|
||||
const ExprDef *array_ndx, const ExprDef *value)
|
||||
{
|
||||
struct xkb_pointer_default_action *act = &action->dflt;
|
||||
|
||||
if (field == ACTION_FIELD_AFFECT) {
|
||||
unsigned int val;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action->type, field);
|
||||
|
||||
if (!ExprResolveEnum(ctx, value, &val, ptrDflts))
|
||||
return ReportMismatch(ctx, action->type, field,
|
||||
"pointer component");
|
||||
return true;
|
||||
}
|
||||
else if (field == ACTION_FIELD_BUTTON || field == ACTION_FIELD_VALUE) {
|
||||
const ExprDef *button;
|
||||
int btn;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action->type, field);
|
||||
|
||||
if (value->expr.op == EXPR_NEGATE ||
|
||||
value->expr.op == EXPR_UNARY_PLUS) {
|
||||
act->flags &= ~ACTION_ABSOLUTE_SWITCH;
|
||||
button = value->unary.child;
|
||||
}
|
||||
else {
|
||||
act->flags |= ACTION_ABSOLUTE_SWITCH;
|
||||
button = value;
|
||||
}
|
||||
|
||||
if (!ExprResolveButton(ctx, button, &btn))
|
||||
return ReportMismatch(ctx, action->type, field,
|
||||
"integer (range 1..5)");
|
||||
|
||||
if (btn < 0 || btn > 5) {
|
||||
log_err(ctx,
|
||||
"New default button value must be in the range 1..5; "
|
||||
"Illegal default button value %d ignored\n", btn);
|
||||
return false;
|
||||
}
|
||||
if (btn == 0) {
|
||||
log_err(ctx,
|
||||
"Cannot set default pointer button to \"default\"; "
|
||||
"Illegal default button setting ignored\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
act->value = (value->expr.op == EXPR_NEGATE ? -btn: btn);
|
||||
return true;
|
||||
}
|
||||
|
||||
return ReportIllegal(ctx, action->type, field);
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleSwitchScreen(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
union xkb_action *action, enum action_field field,
|
||||
const ExprDef *array_ndx, const ExprDef *value)
|
||||
{
|
||||
struct xkb_switch_screen_action *act = &action->screen;
|
||||
|
||||
if (field == ACTION_FIELD_SCREEN) {
|
||||
const ExprDef *scrn;
|
||||
int val;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action->type, field);
|
||||
|
||||
if (value->expr.op == EXPR_NEGATE ||
|
||||
value->expr.op == EXPR_UNARY_PLUS) {
|
||||
act->flags &= ~ACTION_ABSOLUTE_SWITCH;
|
||||
scrn = value->unary.child;
|
||||
}
|
||||
else {
|
||||
act->flags |= ACTION_ABSOLUTE_SWITCH;
|
||||
scrn = value;
|
||||
}
|
||||
|
||||
if (!ExprResolveInteger(ctx, scrn, &val))
|
||||
return ReportMismatch(ctx, action->type, field,
|
||||
"integer (0..255)");
|
||||
|
||||
if (val < 0 || val > 255) {
|
||||
log_err(ctx,
|
||||
"Screen index must be in the range 1..255; "
|
||||
"Illegal screen value %d ignored\n", val);
|
||||
return false;
|
||||
}
|
||||
|
||||
act->screen = (value->expr.op == EXPR_NEGATE ? -val : val);
|
||||
return true;
|
||||
}
|
||||
else if (field == ACTION_FIELD_SAME) {
|
||||
return CheckBooleanFlag(ctx, action->type, field,
|
||||
ACTION_SAME_SCREEN, array_ndx, value,
|
||||
&act->flags);
|
||||
}
|
||||
|
||||
return ReportIllegal(ctx, action->type, field);
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleSetLockControls(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
union xkb_action *action, enum action_field field,
|
||||
const ExprDef *array_ndx, const ExprDef *value)
|
||||
{
|
||||
struct xkb_controls_action *act = &action->ctrls;
|
||||
|
||||
if (field == ACTION_FIELD_CONTROLS) {
|
||||
enum xkb_action_controls mask;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action->type, field);
|
||||
|
||||
if (!ExprResolveMask(ctx, value, &mask, ctrlMaskNames))
|
||||
return ReportMismatch(ctx, action->type, field,
|
||||
"controls mask");
|
||||
|
||||
act->ctrls = mask;
|
||||
return true;
|
||||
}
|
||||
else if (field == ACTION_FIELD_AFFECT) {
|
||||
return CheckAffectField(ctx, action->type, array_ndx, value,
|
||||
&act->flags);
|
||||
}
|
||||
|
||||
return ReportIllegal(ctx, action->type, field);
|
||||
}
|
||||
|
||||
static bool
|
||||
HandlePrivate(struct xkb_context *ctx, const struct xkb_mod_set *mods,
|
||||
union xkb_action *action, enum action_field field,
|
||||
const ExprDef *array_ndx, const ExprDef *value)
|
||||
{
|
||||
struct xkb_private_action *act = &action->priv;
|
||||
|
||||
if (field == ACTION_FIELD_TYPE) {
|
||||
int type;
|
||||
|
||||
if (array_ndx)
|
||||
return ReportActionNotArray(ctx, action->type, field);
|
||||
|
||||
if (!ExprResolveInteger(ctx, value, &type))
|
||||
return ReportMismatch(ctx, ACTION_TYPE_PRIVATE, field, "integer");
|
||||
|
||||
if (type < 0 || type > 255) {
|
||||
log_err(ctx,
|
||||
"Private action type must be in the range 0..255; "
|
||||
"Illegal type %d ignored\n", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* It's possible for someone to write something like this:
|
||||
* actions = [ Private(type=3,data[0]=1,data[1]=3,data[2]=3) ]
|
||||
* where the type refers to some existing action type, e.g. LockMods.
|
||||
* This assumes that this action's struct is laid out in memory
|
||||
* exactly as described in the XKB specification and libraries.
|
||||
* We, however, have changed these structs in various ways, so this
|
||||
* assumption is no longer true. Since this is a lousy "feature", we
|
||||
* make actions like these no-ops for now.
|
||||
*/
|
||||
if (type < ACTION_TYPE_PRIVATE) {
|
||||
log_info(ctx,
|
||||
"Private actions of type %s are not supported; Ignored\n",
|
||||
ActionTypeText(type));
|
||||
act->type = ACTION_TYPE_NONE;
|
||||
}
|
||||
else {
|
||||
act->type = (enum xkb_action_type) type;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (field == ACTION_FIELD_DATA) {
|
||||
if (array_ndx == NULL) {
|
||||
xkb_atom_t val;
|
||||
const char *str;
|
||||
size_t len;
|
||||
|
||||
if (!ExprResolveString(ctx, value, &val))
|
||||
return ReportMismatch(ctx, action->type, field, "string");
|
||||
|
||||
str = xkb_atom_text(ctx, val);
|
||||
len = strlen(str);
|
||||
if (len < 1 || len > 7) {
|
||||
log_warn(ctx,
|
||||
"A private action has 7 data bytes; "
|
||||
"Illegal data ignored\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* act->data may not be null-terminated, this is intentional */
|
||||
strncpy((char *) act->data, str, sizeof(act->data));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
int ndx, datum;
|
||||
|
||||
if (!ExprResolveInteger(ctx, array_ndx, &ndx)) {
|
||||
log_err(ctx,
|
||||
"Array subscript must be integer; "
|
||||
"Illegal subscript ignored\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ndx < 0 || (size_t) ndx >= sizeof(act->data)) {
|
||||
log_err(ctx,
|
||||
"The data for a private action is %lu bytes long; "
|
||||
"Attempt to use data[%d] ignored\n",
|
||||
(unsigned long) sizeof(act->data), ndx);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ExprResolveInteger(ctx, value, &datum))
|
||||
return ReportMismatch(ctx, act->type, field, "integer");
|
||||
|
||||
if (datum < 0 || datum > 255) {
|
||||
log_err(ctx,
|
||||
"All data for a private action must be 0..255; "
|
||||
"Illegal datum %d ignored\n", datum);
|
||||
return false;
|
||||
}
|
||||
|
||||
act->data[ndx] = (uint8_t) datum;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return ReportIllegal(ctx, ACTION_TYPE_NONE, field);
|
||||
}
|
||||
|
||||
typedef bool (*actionHandler)(struct xkb_context *ctx,
|
||||
const struct xkb_mod_set *mods,
|
||||
union xkb_action *action,
|
||||
enum action_field field,
|
||||
const ExprDef *array_ndx,
|
||||
const ExprDef *value);
|
||||
|
||||
static const actionHandler handleAction[_ACTION_TYPE_NUM_ENTRIES] = {
|
||||
[ACTION_TYPE_NONE] = HandleNoAction,
|
||||
[ACTION_TYPE_MOD_SET] = HandleSetLatchLockMods,
|
||||
[ACTION_TYPE_MOD_LATCH] = HandleSetLatchLockMods,
|
||||
[ACTION_TYPE_MOD_LOCK] = HandleSetLatchLockMods,
|
||||
[ACTION_TYPE_GROUP_SET] = HandleSetLatchLockGroup,
|
||||
[ACTION_TYPE_GROUP_LATCH] = HandleSetLatchLockGroup,
|
||||
[ACTION_TYPE_GROUP_LOCK] = HandleSetLatchLockGroup,
|
||||
[ACTION_TYPE_PTR_MOVE] = HandleMovePtr,
|
||||
[ACTION_TYPE_PTR_BUTTON] = HandlePtrBtn,
|
||||
[ACTION_TYPE_PTR_LOCK] = HandlePtrBtn,
|
||||
[ACTION_TYPE_PTR_DEFAULT] = HandleSetPtrDflt,
|
||||
[ACTION_TYPE_TERMINATE] = HandleNoAction,
|
||||
[ACTION_TYPE_SWITCH_VT] = HandleSwitchScreen,
|
||||
[ACTION_TYPE_CTRL_SET] = HandleSetLockControls,
|
||||
[ACTION_TYPE_CTRL_LOCK] = HandleSetLockControls,
|
||||
[ACTION_TYPE_PRIVATE] = HandlePrivate,
|
||||
};
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
bool
|
||||
HandleActionDef(struct xkb_context *ctx, ActionsInfo *info,
|
||||
const struct xkb_mod_set *mods, ExprDef *def,
|
||||
union xkb_action *action)
|
||||
{
|
||||
ExprDef *arg;
|
||||
const char *str;
|
||||
enum xkb_action_type handler_type;
|
||||
|
||||
if (def->expr.op != EXPR_ACTION_DECL) {
|
||||
log_err(ctx, "Expected an action definition, found %s\n",
|
||||
expr_op_type_to_string(def->expr.op));
|
||||
return false;
|
||||
}
|
||||
|
||||
str = xkb_atom_text(ctx, def->action.name);
|
||||
if (!stringToAction(str, &handler_type)) {
|
||||
log_err(ctx, "Unknown action %s\n", str);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the default values for this action type, as modified by
|
||||
* statements such as:
|
||||
* latchMods.clearLocks = True;
|
||||
*/
|
||||
*action = info->actions[handler_type];
|
||||
|
||||
/*
|
||||
* Now change the action properties as specified for this
|
||||
* particular instance, e.g. "modifiers" and "clearLocks" in:
|
||||
* SetMods(modifiers=Alt,clearLocks);
|
||||
*/
|
||||
for (arg = def->action.args; arg != NULL;
|
||||
arg = (ExprDef *) arg->common.next) {
|
||||
const ExprDef *value;
|
||||
ExprDef *field, *arrayRtrn;
|
||||
const char *elemRtrn, *fieldRtrn;
|
||||
enum action_field fieldNdx;
|
||||
|
||||
if (arg->expr.op == EXPR_ASSIGN) {
|
||||
field = arg->binary.left;
|
||||
value = arg->binary.right;
|
||||
}
|
||||
else if (arg->expr.op == EXPR_NOT || arg->expr.op == EXPR_INVERT) {
|
||||
field = arg->unary.child;
|
||||
value = (const ExprDef *) &constFalse;
|
||||
}
|
||||
else {
|
||||
field = arg;
|
||||
value = (const ExprDef *) &constTrue;
|
||||
}
|
||||
|
||||
if (!ExprResolveLhs(ctx, field, &elemRtrn, &fieldRtrn, &arrayRtrn))
|
||||
return false;
|
||||
|
||||
if (elemRtrn) {
|
||||
log_err(ctx,
|
||||
"Cannot change defaults in an action definition; "
|
||||
"Ignoring attempt to change %s.%s\n",
|
||||
elemRtrn, fieldRtrn);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stringToField(fieldRtrn, &fieldNdx)) {
|
||||
log_err(ctx, "Unknown field name %s\n", fieldRtrn);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!handleAction[handler_type](ctx, mods, action, fieldNdx,
|
||||
arrayRtrn, value))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SetActionField(struct xkb_context *ctx, ActionsInfo *info,
|
||||
struct xkb_mod_set *mods, const char *elem,
|
||||
const char *field, ExprDef *array_ndx, ExprDef *value)
|
||||
{
|
||||
enum xkb_action_type action;
|
||||
enum action_field action_field;
|
||||
|
||||
if (!stringToAction(elem, &action))
|
||||
return false;
|
||||
|
||||
if (!stringToField(field, &action_field)) {
|
||||
log_err(ctx, "\"%s\" is not a legal field name\n", field);
|
||||
return false;
|
||||
}
|
||||
|
||||
return handleAction[action](ctx, mods, &info->actions[action],
|
||||
action_field, array_ndx, value);
|
||||
}
|
56
src/3rdparty/xkbcommon/src/xkbcomp/action.h
vendored
56
src/3rdparty/xkbcommon/src/xkbcomp/action.h
vendored
@ -1,56 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#ifndef XKBCOMP_ACTION_H
|
||||
#define XKBCOMP_ACTION_H
|
||||
|
||||
/*
|
||||
* This struct contains the default values which every new action
|
||||
* (e.g. in an interpret statement) starts off with. It can be
|
||||
* modified within the files (see calls to SetActionField).
|
||||
*/
|
||||
typedef struct {
|
||||
union xkb_action actions[_ACTION_TYPE_NUM_ENTRIES];
|
||||
} ActionsInfo;
|
||||
|
||||
ActionsInfo *
|
||||
NewActionsInfo(void);
|
||||
|
||||
void
|
||||
FreeActionsInfo(ActionsInfo *info);
|
||||
|
||||
bool
|
||||
HandleActionDef(struct xkb_context *ctx, ActionsInfo *info,
|
||||
const struct xkb_mod_set *mods, ExprDef *def,
|
||||
union xkb_action *action);
|
||||
|
||||
bool
|
||||
SetActionField(struct xkb_context *ctx, ActionsInfo *info,
|
||||
struct xkb_mod_set *mods, const char *elem,
|
||||
const char *field, ExprDef *array_ndx, ExprDef *value);
|
||||
|
||||
|
||||
#endif
|
806
src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
vendored
806
src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
vendored
@ -1,806 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
* Ran Benita <ran234@gmail.com>
|
||||
*/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "ast-build.h"
|
||||
#include "include.h"
|
||||
|
||||
ParseCommon *
|
||||
AppendStmt(ParseCommon *to, ParseCommon *append)
|
||||
{
|
||||
ParseCommon *iter;
|
||||
|
||||
if (!to)
|
||||
return append;
|
||||
|
||||
for (iter = to; iter->next; iter = iter->next);
|
||||
|
||||
iter->next = append;
|
||||
return to;
|
||||
}
|
||||
|
||||
static ExprDef *
|
||||
ExprCreate(enum expr_op_type op, enum expr_value_type type, size_t size)
|
||||
{
|
||||
ExprDef *expr = malloc(size);
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
expr->common.type = STMT_EXPR;
|
||||
expr->common.next = NULL;
|
||||
expr->expr.op = op;
|
||||
expr->expr.value_type = type;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
#define EXPR_CREATE(type_, name_, op_, value_type_) \
|
||||
ExprDef *name_ = ExprCreate(op_, value_type_, sizeof(type_)); \
|
||||
if (!name_) \
|
||||
return NULL;
|
||||
|
||||
ExprDef *
|
||||
ExprCreateString(xkb_atom_t str)
|
||||
{
|
||||
EXPR_CREATE(ExprString, expr, EXPR_VALUE, EXPR_TYPE_STRING);
|
||||
expr->string.str = str;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateInteger(int ival)
|
||||
{
|
||||
EXPR_CREATE(ExprInteger, expr, EXPR_VALUE, EXPR_TYPE_INT);
|
||||
expr->integer.ival = ival;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateFloat(void)
|
||||
{
|
||||
EXPR_CREATE(ExprFloat, expr, EXPR_VALUE, EXPR_TYPE_FLOAT);
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateBoolean(bool set)
|
||||
{
|
||||
EXPR_CREATE(ExprBoolean, expr, EXPR_VALUE, EXPR_TYPE_BOOLEAN);
|
||||
expr->boolean.set = set;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateKeyName(xkb_atom_t key_name)
|
||||
{
|
||||
EXPR_CREATE(ExprKeyName, expr, EXPR_VALUE, EXPR_TYPE_KEYNAME);
|
||||
expr->key_name.key_name = key_name;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateIdent(xkb_atom_t ident)
|
||||
{
|
||||
EXPR_CREATE(ExprIdent, expr, EXPR_IDENT, EXPR_TYPE_UNKNOWN);
|
||||
expr->ident.ident = ident;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
|
||||
ExprDef *child)
|
||||
{
|
||||
EXPR_CREATE(ExprUnary, expr, op, type);
|
||||
expr->unary.child = child;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
|
||||
{
|
||||
EXPR_CREATE(ExprBinary, expr, op, EXPR_TYPE_UNKNOWN);
|
||||
|
||||
if (op == EXPR_ASSIGN || left->expr.value_type == EXPR_TYPE_UNKNOWN)
|
||||
expr->expr.value_type = right->expr.value_type;
|
||||
else if (left->expr.value_type == right->expr.value_type ||
|
||||
right->expr.value_type == EXPR_TYPE_UNKNOWN)
|
||||
expr->expr.value_type = left->expr.value_type;
|
||||
expr->binary.left = left;
|
||||
expr->binary.right = right;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field)
|
||||
{
|
||||
EXPR_CREATE(ExprFieldRef, expr, EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN);
|
||||
expr->field_ref.element = element;
|
||||
expr->field_ref.field = field;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry)
|
||||
{
|
||||
EXPR_CREATE(ExprArrayRef, expr, EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
|
||||
expr->array_ref.element = element;
|
||||
expr->array_ref.field = field;
|
||||
expr->array_ref.entry = entry;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateAction(xkb_atom_t name, ExprDef *args)
|
||||
{
|
||||
EXPR_CREATE(ExprAction, expr, EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN);
|
||||
expr->action.name = name;
|
||||
expr->action.args = args;
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateKeysymList(xkb_keysym_t sym)
|
||||
{
|
||||
EXPR_CREATE(ExprKeysymList, expr, EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
|
||||
|
||||
darray_init(expr->keysym_list.syms);
|
||||
darray_init(expr->keysym_list.symsMapIndex);
|
||||
darray_init(expr->keysym_list.symsNumEntries);
|
||||
|
||||
darray_append(expr->keysym_list.syms, sym);
|
||||
darray_append(expr->keysym_list.symsMapIndex, 0);
|
||||
darray_append(expr->keysym_list.symsNumEntries, 1);
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprCreateMultiKeysymList(ExprDef *expr)
|
||||
{
|
||||
unsigned nLevels = darray_size(expr->keysym_list.symsMapIndex);
|
||||
|
||||
darray_resize(expr->keysym_list.symsMapIndex, 1);
|
||||
darray_resize(expr->keysym_list.symsNumEntries, 1);
|
||||
darray_item(expr->keysym_list.symsMapIndex, 0) = 0;
|
||||
darray_item(expr->keysym_list.symsNumEntries, 0) = nLevels;
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
|
||||
{
|
||||
unsigned nSyms = darray_size(expr->keysym_list.syms);
|
||||
|
||||
darray_append(expr->keysym_list.symsMapIndex, nSyms);
|
||||
darray_append(expr->keysym_list.symsNumEntries, 1);
|
||||
darray_append(expr->keysym_list.syms, sym);
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
ExprDef *
|
||||
ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append)
|
||||
{
|
||||
unsigned nSyms = darray_size(expr->keysym_list.syms);
|
||||
unsigned numEntries = darray_size(append->keysym_list.syms);
|
||||
|
||||
darray_append(expr->keysym_list.symsMapIndex, nSyms);
|
||||
darray_append(expr->keysym_list.symsNumEntries, numEntries);
|
||||
darray_concat(expr->keysym_list.syms, append->keysym_list.syms);
|
||||
|
||||
FreeStmt((ParseCommon *) append);
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
KeycodeDef *
|
||||
KeycodeCreate(xkb_atom_t name, int64_t value)
|
||||
{
|
||||
KeycodeDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_KEYCODE;
|
||||
def->common.next = NULL;
|
||||
def->name = name;
|
||||
def->value = value;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
KeyAliasDef *
|
||||
KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real)
|
||||
{
|
||||
KeyAliasDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_ALIAS;
|
||||
def->common.next = NULL;
|
||||
def->alias = alias;
|
||||
def->real = real;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
VModDef *
|
||||
VModCreate(xkb_atom_t name, ExprDef *value)
|
||||
{
|
||||
VModDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_VMOD;
|
||||
def->common.next = NULL;
|
||||
def->name = name;
|
||||
def->value = value;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
VarDef *
|
||||
VarCreate(ExprDef *name, ExprDef *value)
|
||||
{
|
||||
VarDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_VAR;
|
||||
def->common.next = NULL;
|
||||
def->name = name;
|
||||
def->value = value;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
VarDef *
|
||||
BoolVarCreate(xkb_atom_t ident, bool set)
|
||||
{
|
||||
ExprDef *name, *value;
|
||||
VarDef *def;
|
||||
if (!(name = ExprCreateIdent(ident))) {
|
||||
return NULL;
|
||||
}
|
||||
if (!(value = ExprCreateBoolean(set))) {
|
||||
FreeStmt((ParseCommon *) name);
|
||||
return NULL;
|
||||
}
|
||||
if (!(def = VarCreate(name, value))) {
|
||||
FreeStmt((ParseCommon *) name);
|
||||
FreeStmt((ParseCommon *) value);
|
||||
return NULL;
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
InterpDef *
|
||||
InterpCreate(xkb_keysym_t sym, ExprDef *match)
|
||||
{
|
||||
InterpDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_INTERP;
|
||||
def->common.next = NULL;
|
||||
def->sym = sym;
|
||||
def->match = match;
|
||||
def->def = NULL;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
KeyTypeDef *
|
||||
KeyTypeCreate(xkb_atom_t name, VarDef *body)
|
||||
{
|
||||
KeyTypeDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_TYPE;
|
||||
def->common.next = NULL;
|
||||
def->merge = MERGE_DEFAULT;
|
||||
def->name = name;
|
||||
def->body = body;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
SymbolsDef *
|
||||
SymbolsCreate(xkb_atom_t keyName, VarDef *symbols)
|
||||
{
|
||||
SymbolsDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_SYMBOLS;
|
||||
def->common.next = NULL;
|
||||
def->merge = MERGE_DEFAULT;
|
||||
def->keyName = keyName;
|
||||
def->symbols = symbols;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
GroupCompatDef *
|
||||
GroupCompatCreate(unsigned group, ExprDef *val)
|
||||
{
|
||||
GroupCompatDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_GROUP_COMPAT;
|
||||
def->common.next = NULL;
|
||||
def->merge = MERGE_DEFAULT;
|
||||
def->group = group;
|
||||
def->def = val;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
ModMapDef *
|
||||
ModMapCreate(xkb_atom_t modifier, ExprDef *keys)
|
||||
{
|
||||
ModMapDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_MODMAP;
|
||||
def->common.next = NULL;
|
||||
def->merge = MERGE_DEFAULT;
|
||||
def->modifier = modifier;
|
||||
def->keys = keys;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
LedMapDef *
|
||||
LedMapCreate(xkb_atom_t name, VarDef *body)
|
||||
{
|
||||
LedMapDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_LED_MAP;
|
||||
def->common.next = NULL;
|
||||
def->merge = MERGE_DEFAULT;
|
||||
def->name = name;
|
||||
def->body = body;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
LedNameDef *
|
||||
LedNameCreate(unsigned ndx, ExprDef *name, bool virtual)
|
||||
{
|
||||
LedNameDef *def = malloc(sizeof(*def));
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
def->common.type = STMT_LED_NAME;
|
||||
def->common.next = NULL;
|
||||
def->merge = MERGE_DEFAULT;
|
||||
def->ndx = ndx;
|
||||
def->name = name;
|
||||
def->virtual = virtual;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
static void
|
||||
FreeInclude(IncludeStmt *incl);
|
||||
|
||||
IncludeStmt *
|
||||
IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge)
|
||||
{
|
||||
IncludeStmt *incl, *first;
|
||||
char *file, *map, *stmt, *tmp, *extra_data;
|
||||
char nextop;
|
||||
|
||||
incl = first = NULL;
|
||||
file = map = NULL;
|
||||
tmp = str;
|
||||
stmt = strdup_safe(str);
|
||||
while (tmp && *tmp)
|
||||
{
|
||||
if (!ParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Given an RMLVO (here layout) like 'us,,fr', the rules parser
|
||||
* will give out something like 'pc+us+:2+fr:3+inet(evdev)'.
|
||||
* We should just skip the ':2' in this case and leave it to the
|
||||
* appropriate section to deal with the empty group.
|
||||
*/
|
||||
if (isempty(file)) {
|
||||
free(file);
|
||||
free(map);
|
||||
free(extra_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (first == NULL) {
|
||||
first = incl = malloc(sizeof(*first));
|
||||
} else {
|
||||
incl->next_incl = malloc(sizeof(*first));
|
||||
incl = incl->next_incl;
|
||||
}
|
||||
|
||||
if (!incl)
|
||||
break;
|
||||
|
||||
incl->common.type = STMT_INCLUDE;
|
||||
incl->common.next = NULL;
|
||||
incl->merge = merge;
|
||||
incl->stmt = NULL;
|
||||
incl->file = file;
|
||||
incl->map = map;
|
||||
incl->modifier = extra_data;
|
||||
incl->next_incl = NULL;
|
||||
|
||||
if (nextop == '|')
|
||||
merge = MERGE_AUGMENT;
|
||||
else
|
||||
merge = MERGE_OVERRIDE;
|
||||
}
|
||||
|
||||
if (first)
|
||||
first->stmt = stmt;
|
||||
else
|
||||
free(stmt);
|
||||
|
||||
return first;
|
||||
|
||||
err:
|
||||
log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt);
|
||||
FreeInclude(first);
|
||||
free(stmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XkbFile *
|
||||
XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs,
|
||||
enum xkb_map_flags flags)
|
||||
{
|
||||
XkbFile *file;
|
||||
|
||||
file = calloc(1, sizeof(*file));
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
XkbEscapeMapName(name);
|
||||
file->file_type = type;
|
||||
file->name = name ? name : strdup("(unnamed)");
|
||||
file->defs = defs;
|
||||
file->flags = flags;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
XkbFile *
|
||||
XkbFileFromComponents(struct xkb_context *ctx,
|
||||
const struct xkb_component_names *kkctgs)
|
||||
{
|
||||
char *const components[] = {
|
||||
kkctgs->keycodes, kkctgs->types,
|
||||
kkctgs->compat, kkctgs->symbols,
|
||||
};
|
||||
enum xkb_file_type type;
|
||||
IncludeStmt *include = NULL;
|
||||
XkbFile *file = NULL;
|
||||
ParseCommon *defs = NULL;
|
||||
|
||||
for (type = FIRST_KEYMAP_FILE_TYPE; type <= LAST_KEYMAP_FILE_TYPE; type++) {
|
||||
include = IncludeCreate(ctx, components[type], MERGE_DEFAULT);
|
||||
if (!include)
|
||||
goto err;
|
||||
|
||||
file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0);
|
||||
if (!file) {
|
||||
FreeInclude(include);
|
||||
goto err;
|
||||
}
|
||||
|
||||
defs = AppendStmt(defs, &file->common);
|
||||
}
|
||||
|
||||
file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0);
|
||||
if (!file)
|
||||
goto err;
|
||||
|
||||
return file;
|
||||
|
||||
err:
|
||||
FreeXkbFile((XkbFile *) defs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
FreeExpr(ExprDef *expr)
|
||||
{
|
||||
if (!expr)
|
||||
return;
|
||||
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_ACTION_LIST:
|
||||
case EXPR_NEGATE:
|
||||
case EXPR_UNARY_PLUS:
|
||||
case EXPR_NOT:
|
||||
case EXPR_INVERT:
|
||||
FreeStmt((ParseCommon *) expr->unary.child);
|
||||
break;
|
||||
|
||||
case EXPR_DIVIDE:
|
||||
case EXPR_ADD:
|
||||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_ASSIGN:
|
||||
FreeStmt((ParseCommon *) expr->binary.left);
|
||||
FreeStmt((ParseCommon *) expr->binary.right);
|
||||
break;
|
||||
|
||||
case EXPR_ACTION_DECL:
|
||||
FreeStmt((ParseCommon *) expr->action.args);
|
||||
break;
|
||||
|
||||
case EXPR_ARRAY_REF:
|
||||
FreeStmt((ParseCommon *) expr->array_ref.entry);
|
||||
break;
|
||||
|
||||
case EXPR_KEYSYM_LIST:
|
||||
darray_free(expr->keysym_list.syms);
|
||||
darray_free(expr->keysym_list.symsMapIndex);
|
||||
darray_free(expr->keysym_list.symsNumEntries);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FreeInclude(IncludeStmt *incl)
|
||||
{
|
||||
IncludeStmt *next;
|
||||
|
||||
while (incl)
|
||||
{
|
||||
next = incl->next_incl;
|
||||
|
||||
free(incl->file);
|
||||
free(incl->map);
|
||||
free(incl->modifier);
|
||||
free(incl->stmt);
|
||||
|
||||
free(incl);
|
||||
incl = next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FreeStmt(ParseCommon *stmt)
|
||||
{
|
||||
ParseCommon *next;
|
||||
|
||||
while (stmt)
|
||||
{
|
||||
next = stmt->next;
|
||||
|
||||
switch (stmt->type) {
|
||||
case STMT_INCLUDE:
|
||||
FreeInclude((IncludeStmt *) stmt);
|
||||
/* stmt is already free'd here. */
|
||||
stmt = NULL;
|
||||
break;
|
||||
case STMT_EXPR:
|
||||
FreeExpr((ExprDef *) stmt);
|
||||
break;
|
||||
case STMT_VAR:
|
||||
FreeStmt((ParseCommon *) ((VarDef *) stmt)->name);
|
||||
FreeStmt((ParseCommon *) ((VarDef *) stmt)->value);
|
||||
break;
|
||||
case STMT_TYPE:
|
||||
FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body);
|
||||
break;
|
||||
case STMT_INTERP:
|
||||
FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match);
|
||||
FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def);
|
||||
break;
|
||||
case STMT_VMOD:
|
||||
FreeStmt((ParseCommon *) ((VModDef *) stmt)->value);
|
||||
break;
|
||||
case STMT_SYMBOLS:
|
||||
FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols);
|
||||
break;
|
||||
case STMT_MODMAP:
|
||||
FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys);
|
||||
break;
|
||||
case STMT_GROUP_COMPAT:
|
||||
FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def);
|
||||
break;
|
||||
case STMT_LED_MAP:
|
||||
FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body);
|
||||
break;
|
||||
case STMT_LED_NAME:
|
||||
FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
free(stmt);
|
||||
stmt = next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FreeXkbFile(XkbFile *file)
|
||||
{
|
||||
XkbFile *next;
|
||||
|
||||
while (file)
|
||||
{
|
||||
next = (XkbFile *) file->common.next;
|
||||
|
||||
switch (file->file_type) {
|
||||
case FILE_TYPE_KEYMAP:
|
||||
FreeXkbFile((XkbFile *) file->defs);
|
||||
break;
|
||||
|
||||
case FILE_TYPE_TYPES:
|
||||
case FILE_TYPE_COMPAT:
|
||||
case FILE_TYPE_SYMBOLS:
|
||||
case FILE_TYPE_KEYCODES:
|
||||
case FILE_TYPE_GEOMETRY:
|
||||
FreeStmt(file->defs);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
free(file->name);
|
||||
free(file);
|
||||
file = next;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *xkb_file_type_strings[_FILE_TYPE_NUM_ENTRIES] = {
|
||||
[FILE_TYPE_KEYCODES] = "xkb_keycodes",
|
||||
[FILE_TYPE_TYPES] = "xkb_types",
|
||||
[FILE_TYPE_COMPAT] = "xkb_compatibility",
|
||||
[FILE_TYPE_SYMBOLS] = "xkb_symbols",
|
||||
[FILE_TYPE_GEOMETRY] = "xkb_geometry",
|
||||
[FILE_TYPE_KEYMAP] = "xkb_keymap",
|
||||
[FILE_TYPE_RULES] = "rules",
|
||||
};
|
||||
|
||||
const char *
|
||||
xkb_file_type_to_string(enum xkb_file_type type)
|
||||
{
|
||||
if (type >= _FILE_TYPE_NUM_ENTRIES)
|
||||
return "unknown";
|
||||
return xkb_file_type_strings[type];
|
||||
}
|
||||
|
||||
static const char *stmt_type_strings[_STMT_NUM_VALUES] = {
|
||||
[STMT_UNKNOWN] = "unknown statement",
|
||||
[STMT_INCLUDE] = "include statement",
|
||||
[STMT_KEYCODE] = "key name definition",
|
||||
[STMT_ALIAS] = "key alias definition",
|
||||
[STMT_EXPR] = "expression",
|
||||
[STMT_VAR] = "variable definition",
|
||||
[STMT_TYPE] = "key type definition",
|
||||
[STMT_INTERP] = "symbol interpretation definition",
|
||||
[STMT_VMOD] = "virtual modifiers definition",
|
||||
[STMT_SYMBOLS] = "key symbols definition",
|
||||
[STMT_MODMAP] = "modifier map declaration",
|
||||
[STMT_GROUP_COMPAT] = "group declaration",
|
||||
[STMT_LED_MAP] = "indicator map declaration",
|
||||
[STMT_LED_NAME] = "indicator name declaration",
|
||||
};
|
||||
|
||||
const char *
|
||||
stmt_type_to_string(enum stmt_type type)
|
||||
{
|
||||
if (type >= _STMT_NUM_VALUES)
|
||||
return NULL;
|
||||
return stmt_type_strings[type];
|
||||
}
|
||||
|
||||
static const char *expr_op_type_strings[_EXPR_NUM_VALUES] = {
|
||||
[EXPR_VALUE] = "literal",
|
||||
[EXPR_IDENT] = "identifier",
|
||||
[EXPR_ACTION_DECL] = "action declaration",
|
||||
[EXPR_FIELD_REF] = "field reference",
|
||||
[EXPR_ARRAY_REF] = "array reference",
|
||||
[EXPR_KEYSYM_LIST] = "list of keysyms",
|
||||
[EXPR_ACTION_LIST] = "list of actions",
|
||||
[EXPR_ADD] = "addition",
|
||||
[EXPR_SUBTRACT] = "subtraction",
|
||||
[EXPR_MULTIPLY] = "multiplication",
|
||||
[EXPR_DIVIDE] = "division",
|
||||
[EXPR_ASSIGN] = "assignment",
|
||||
[EXPR_NOT] = "logical negation",
|
||||
[EXPR_NEGATE] = "arithmetic negation",
|
||||
[EXPR_INVERT] = "bitwise inversion",
|
||||
[EXPR_UNARY_PLUS] = "unary plus",
|
||||
};
|
||||
|
||||
const char *
|
||||
expr_op_type_to_string(enum expr_op_type type)
|
||||
{
|
||||
if (type >= _EXPR_NUM_VALUES)
|
||||
return NULL;
|
||||
return expr_op_type_strings[type];
|
||||
}
|
||||
|
||||
static const char *expr_value_type_strings[_EXPR_TYPE_NUM_VALUES] = {
|
||||
[EXPR_TYPE_UNKNOWN] = "unknown",
|
||||
[EXPR_TYPE_BOOLEAN] = "boolean",
|
||||
[EXPR_TYPE_INT] = "int",
|
||||
[EXPR_TYPE_FLOAT] = "float",
|
||||
[EXPR_TYPE_STRING] = "string",
|
||||
[EXPR_TYPE_ACTION] = "action",
|
||||
[EXPR_TYPE_KEYNAME] = "keyname",
|
||||
[EXPR_TYPE_SYMBOLS] = "symbols",
|
||||
};
|
||||
|
||||
const char *
|
||||
expr_value_type_to_string(enum expr_value_type type)
|
||||
{
|
||||
if (type >= _EXPR_TYPE_NUM_VALUES)
|
||||
return NULL;
|
||||
return expr_value_type_strings[type];
|
||||
}
|
125
src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
vendored
125
src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
vendored
@ -1,125 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#ifndef XKBCOMP_AST_BUILD_H
|
||||
#define XKBCOMP_AST_BUILD_H
|
||||
|
||||
ParseCommon *
|
||||
AppendStmt(ParseCommon *to, ParseCommon *append);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateString(xkb_atom_t str);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateInteger(int ival);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateFloat(void);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateBoolean(bool set);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateKeyName(xkb_atom_t key_name);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateIdent(xkb_atom_t ident);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
|
||||
ExprDef *child);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateAction(xkb_atom_t name, ExprDef *args);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateMultiKeysymList(ExprDef *list);
|
||||
|
||||
ExprDef *
|
||||
ExprCreateKeysymList(xkb_keysym_t sym);
|
||||
|
||||
ExprDef *
|
||||
ExprAppendMultiKeysymList(ExprDef *list, ExprDef *append);
|
||||
|
||||
ExprDef *
|
||||
ExprAppendKeysymList(ExprDef *list, xkb_keysym_t sym);
|
||||
|
||||
KeycodeDef *
|
||||
KeycodeCreate(xkb_atom_t name, int64_t value);
|
||||
|
||||
KeyAliasDef *
|
||||
KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real);
|
||||
|
||||
VModDef *
|
||||
VModCreate(xkb_atom_t name, ExprDef *value);
|
||||
|
||||
VarDef *
|
||||
VarCreate(ExprDef *name, ExprDef *value);
|
||||
|
||||
VarDef *
|
||||
BoolVarCreate(xkb_atom_t ident, bool set);
|
||||
|
||||
InterpDef *
|
||||
InterpCreate(xkb_keysym_t sym, ExprDef *match);
|
||||
|
||||
KeyTypeDef *
|
||||
KeyTypeCreate(xkb_atom_t name, VarDef *body);
|
||||
|
||||
SymbolsDef *
|
||||
SymbolsCreate(xkb_atom_t keyName, VarDef *symbols);
|
||||
|
||||
GroupCompatDef *
|
||||
GroupCompatCreate(unsigned group, ExprDef *def);
|
||||
|
||||
ModMapDef *
|
||||
ModMapCreate(xkb_atom_t modifier, ExprDef *keys);
|
||||
|
||||
LedMapDef *
|
||||
LedMapCreate(xkb_atom_t name, VarDef *body);
|
||||
|
||||
LedNameDef *
|
||||
LedNameCreate(unsigned ndx, ExprDef *name, bool virtual);
|
||||
|
||||
IncludeStmt *
|
||||
IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge);
|
||||
|
||||
XkbFile *
|
||||
XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs,
|
||||
enum xkb_map_flags flags);
|
||||
|
||||
void
|
||||
FreeStmt(ParseCommon *stmt);
|
||||
|
||||
#endif
|
353
src/3rdparty/xkbcommon/src/xkbcomp/ast.h
vendored
353
src/3rdparty/xkbcommon/src/xkbcomp/ast.h
vendored
@ -1,353 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XKBCOMP_AST_H
|
||||
#define XKBCOMP_AST_H
|
||||
|
||||
enum xkb_file_type {
|
||||
/* Component files, by order of compilation. */
|
||||
FILE_TYPE_KEYCODES = 0,
|
||||
FILE_TYPE_TYPES = 1,
|
||||
FILE_TYPE_COMPAT = 2,
|
||||
FILE_TYPE_SYMBOLS = 3,
|
||||
/* Geometry is not compiled any more. */
|
||||
FILE_TYPE_GEOMETRY = 4,
|
||||
|
||||
/* A top level file which includes the above files. */
|
||||
FILE_TYPE_KEYMAP,
|
||||
|
||||
/* File types which must be found in a keymap file. */
|
||||
#define FIRST_KEYMAP_FILE_TYPE FILE_TYPE_KEYCODES
|
||||
#define LAST_KEYMAP_FILE_TYPE FILE_TYPE_SYMBOLS
|
||||
|
||||
/* This one doesn't mix with the others, but useful here as well. */
|
||||
FILE_TYPE_RULES,
|
||||
|
||||
_FILE_TYPE_NUM_ENTRIES
|
||||
};
|
||||
|
||||
enum stmt_type {
|
||||
STMT_UNKNOWN = 0,
|
||||
STMT_INCLUDE,
|
||||
STMT_KEYCODE,
|
||||
STMT_ALIAS,
|
||||
STMT_EXPR,
|
||||
STMT_VAR,
|
||||
STMT_TYPE,
|
||||
STMT_INTERP,
|
||||
STMT_VMOD,
|
||||
STMT_SYMBOLS,
|
||||
STMT_MODMAP,
|
||||
STMT_GROUP_COMPAT,
|
||||
STMT_LED_MAP,
|
||||
STMT_LED_NAME,
|
||||
|
||||
_STMT_NUM_VALUES
|
||||
};
|
||||
|
||||
enum expr_value_type {
|
||||
EXPR_TYPE_UNKNOWN = 0,
|
||||
EXPR_TYPE_BOOLEAN,
|
||||
EXPR_TYPE_INT,
|
||||
EXPR_TYPE_FLOAT,
|
||||
EXPR_TYPE_STRING,
|
||||
EXPR_TYPE_ACTION,
|
||||
EXPR_TYPE_KEYNAME,
|
||||
EXPR_TYPE_SYMBOLS,
|
||||
|
||||
_EXPR_TYPE_NUM_VALUES
|
||||
};
|
||||
|
||||
enum expr_op_type {
|
||||
EXPR_VALUE,
|
||||
EXPR_IDENT,
|
||||
EXPR_ACTION_DECL,
|
||||
EXPR_FIELD_REF,
|
||||
EXPR_ARRAY_REF,
|
||||
EXPR_KEYSYM_LIST,
|
||||
EXPR_ACTION_LIST,
|
||||
EXPR_ADD,
|
||||
EXPR_SUBTRACT,
|
||||
EXPR_MULTIPLY,
|
||||
EXPR_DIVIDE,
|
||||
EXPR_ASSIGN,
|
||||
EXPR_NOT,
|
||||
EXPR_NEGATE,
|
||||
EXPR_INVERT,
|
||||
EXPR_UNARY_PLUS,
|
||||
|
||||
_EXPR_NUM_VALUES
|
||||
};
|
||||
|
||||
enum merge_mode {
|
||||
MERGE_DEFAULT,
|
||||
MERGE_AUGMENT,
|
||||
MERGE_OVERRIDE,
|
||||
MERGE_REPLACE,
|
||||
};
|
||||
|
||||
const char *
|
||||
xkb_file_type_to_string(enum xkb_file_type type);
|
||||
|
||||
const char *
|
||||
stmt_type_to_string(enum stmt_type type);
|
||||
|
||||
const char *
|
||||
expr_op_type_to_string(enum expr_op_type type);
|
||||
|
||||
const char *
|
||||
expr_value_type_to_string(enum expr_value_type type);
|
||||
|
||||
typedef struct _ParseCommon {
|
||||
struct _ParseCommon *next;
|
||||
enum stmt_type type;
|
||||
} ParseCommon;
|
||||
|
||||
typedef struct _IncludeStmt {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
char *stmt;
|
||||
char *file;
|
||||
char *map;
|
||||
char *modifier;
|
||||
struct _IncludeStmt *next_incl;
|
||||
} IncludeStmt;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum expr_op_type op;
|
||||
enum expr_value_type value_type;
|
||||
} ExprCommon;
|
||||
|
||||
typedef union ExprDef ExprDef;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t ident;
|
||||
} ExprIdent;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t str;
|
||||
} ExprString;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
bool set;
|
||||
} ExprBoolean;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
int ival;
|
||||
} ExprInteger;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
/* We don't support floats, but we still represnt them in the AST, in
|
||||
* order to provide proper error messages. */
|
||||
} ExprFloat;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t key_name;
|
||||
} ExprKeyName;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
ExprDef *left;
|
||||
ExprDef *right;
|
||||
} ExprBinary;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
ExprDef *child;
|
||||
} ExprUnary;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t element;
|
||||
xkb_atom_t field;
|
||||
} ExprFieldRef;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t element;
|
||||
xkb_atom_t field;
|
||||
ExprDef *entry;
|
||||
} ExprArrayRef;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
xkb_atom_t name;
|
||||
ExprDef *args;
|
||||
} ExprAction;
|
||||
|
||||
typedef struct {
|
||||
ExprCommon expr;
|
||||
darray(xkb_keysym_t) syms;
|
||||
darray(unsigned int) symsMapIndex;
|
||||
darray(unsigned int) symsNumEntries;
|
||||
} ExprKeysymList;
|
||||
|
||||
union ExprDef {
|
||||
ParseCommon common;
|
||||
/* Maybe someday we can use C11 anonymous struct for ExprCommon here. */
|
||||
ExprCommon expr;
|
||||
ExprIdent ident;
|
||||
ExprString string;
|
||||
ExprBoolean boolean;
|
||||
ExprInteger integer;
|
||||
ExprKeyName key_name;
|
||||
ExprBinary binary;
|
||||
ExprUnary unary;
|
||||
ExprFieldRef field_ref;
|
||||
ExprArrayRef array_ref;
|
||||
ExprAction action;
|
||||
ExprKeysymList keysym_list;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
ExprDef *name;
|
||||
ExprDef *value;
|
||||
} VarDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
xkb_atom_t name;
|
||||
ExprDef *value;
|
||||
} VModDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
xkb_atom_t name;
|
||||
int64_t value;
|
||||
} KeycodeDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
xkb_atom_t alias;
|
||||
xkb_atom_t real;
|
||||
} KeyAliasDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
xkb_atom_t name;
|
||||
VarDef *body;
|
||||
} KeyTypeDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
xkb_atom_t keyName;
|
||||
VarDef *symbols;
|
||||
} SymbolsDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
xkb_atom_t modifier;
|
||||
ExprDef *keys;
|
||||
} ModMapDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
unsigned group;
|
||||
ExprDef *def;
|
||||
} GroupCompatDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
xkb_keysym_t sym;
|
||||
ExprDef *match;
|
||||
VarDef *def;
|
||||
} InterpDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
unsigned ndx;
|
||||
ExprDef *name;
|
||||
bool virtual;
|
||||
} LedNameDef;
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum merge_mode merge;
|
||||
xkb_atom_t name;
|
||||
VarDef *body;
|
||||
} LedMapDef;
|
||||
|
||||
enum xkb_map_flags {
|
||||
MAP_IS_DEFAULT = (1 << 0),
|
||||
MAP_IS_PARTIAL = (1 << 1),
|
||||
MAP_IS_HIDDEN = (1 << 2),
|
||||
MAP_HAS_ALPHANUMERIC = (1 << 3),
|
||||
MAP_HAS_MODIFIER = (1 << 4),
|
||||
MAP_HAS_KEYPAD = (1 << 5),
|
||||
MAP_HAS_FN = (1 << 6),
|
||||
MAP_IS_ALTGR = (1 << 7),
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ParseCommon common;
|
||||
enum xkb_file_type file_type;
|
||||
char *name;
|
||||
ParseCommon *defs;
|
||||
enum xkb_map_flags flags;
|
||||
} XkbFile;
|
||||
|
||||
#endif
|
932
src/3rdparty/xkbcommon/src/xkbcomp/compat.c
vendored
932
src/3rdparty/xkbcommon/src/xkbcomp/compat.c
vendored
@ -1,932 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "text.h"
|
||||
#include "expr.h"
|
||||
#include "action.h"
|
||||
#include "vmod.h"
|
||||
#include "include.h"
|
||||
|
||||
enum si_field {
|
||||
SI_FIELD_VIRTUAL_MOD = (1 << 0),
|
||||
SI_FIELD_ACTION = (1 << 1),
|
||||
SI_FIELD_AUTO_REPEAT = (1 << 2),
|
||||
SI_FIELD_LEVEL_ONE_ONLY = (1 << 3),
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum si_field defined;
|
||||
enum merge_mode merge;
|
||||
|
||||
struct xkb_sym_interpret interp;
|
||||
} SymInterpInfo;
|
||||
|
||||
enum led_field {
|
||||
LED_FIELD_MODS = (1 << 0),
|
||||
LED_FIELD_GROUPS = (1 << 1),
|
||||
LED_FIELD_CTRLS = (1 << 2),
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum led_field defined;
|
||||
enum merge_mode merge;
|
||||
|
||||
struct xkb_led led;
|
||||
} LedInfo;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int errorCount;
|
||||
SymInterpInfo default_interp;
|
||||
darray(SymInterpInfo) interps;
|
||||
LedInfo default_led;
|
||||
LedInfo leds[XKB_MAX_LEDS];
|
||||
unsigned int num_leds;
|
||||
ActionsInfo *actions;
|
||||
struct xkb_mod_set mods;
|
||||
|
||||
struct xkb_context *ctx;
|
||||
} CompatInfo;
|
||||
|
||||
static const char *
|
||||
siText(SymInterpInfo *si, CompatInfo *info)
|
||||
{
|
||||
char *buf = xkb_context_get_buffer(info->ctx, 128);
|
||||
|
||||
if (si == &info->default_interp)
|
||||
return "default";
|
||||
|
||||
snprintf(buf, 128, "%s+%s(%s)",
|
||||
KeysymText(info->ctx, si->interp.sym),
|
||||
SIMatchText(si->interp.match),
|
||||
ModMaskText(info->ctx, &info->mods, si->interp.mods));
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportSINotArray(CompatInfo *info, SymInterpInfo *si, const char *field)
|
||||
{
|
||||
return ReportNotArray(info->ctx, "symbol interpretation", field,
|
||||
siText(si, info));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportSIBadType(CompatInfo *info, SymInterpInfo *si, const char *field,
|
||||
const char *wanted)
|
||||
{
|
||||
return ReportBadType(info->ctx, "symbol interpretation", field,
|
||||
siText(si, info), wanted);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportLedBadType(CompatInfo *info, LedInfo *ledi, const char *field,
|
||||
const char *wanted)
|
||||
{
|
||||
return ReportBadType(info->ctx, "indicator map", field,
|
||||
xkb_atom_text(info->ctx, ledi->led.name),
|
||||
wanted);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportLedNotArray(CompatInfo *info, LedInfo *ledi, const char *field)
|
||||
{
|
||||
return ReportNotArray(info->ctx, "indicator map", field,
|
||||
xkb_atom_text(info->ctx, ledi->led.name));
|
||||
}
|
||||
|
||||
static void
|
||||
InitCompatInfo(CompatInfo *info, struct xkb_context *ctx,
|
||||
ActionsInfo *actions, const struct xkb_mod_set *mods)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->ctx = ctx;
|
||||
info->actions = actions;
|
||||
info->mods = *mods;
|
||||
info->default_interp.merge = MERGE_OVERRIDE;
|
||||
info->default_interp.interp.virtual_mod = XKB_MOD_INVALID;
|
||||
info->default_led.merge = MERGE_OVERRIDE;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearCompatInfo(CompatInfo *info)
|
||||
{
|
||||
free(info->name);
|
||||
darray_free(info->interps);
|
||||
}
|
||||
|
||||
static SymInterpInfo *
|
||||
FindMatchingInterp(CompatInfo *info, SymInterpInfo *new)
|
||||
{
|
||||
SymInterpInfo *old;
|
||||
|
||||
darray_foreach(old, info->interps)
|
||||
if (old->interp.sym == new->interp.sym &&
|
||||
old->interp.mods == new->interp.mods &&
|
||||
old->interp.match == new->interp.match)
|
||||
return old;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
UseNewInterpField(enum si_field field, SymInterpInfo *old, SymInterpInfo *new,
|
||||
bool report, enum si_field *collide)
|
||||
{
|
||||
if (!(old->defined & field))
|
||||
return true;
|
||||
|
||||
if (new->defined & field) {
|
||||
if (report)
|
||||
*collide |= field;
|
||||
|
||||
if (new->merge != MERGE_AUGMENT)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
AddInterp(CompatInfo *info, SymInterpInfo *new, bool same_file)
|
||||
{
|
||||
SymInterpInfo *old = FindMatchingInterp(info, new);
|
||||
if (old) {
|
||||
const int verbosity = xkb_context_get_log_verbosity(info->ctx);
|
||||
const bool report = (same_file && verbosity > 0) || verbosity > 9;
|
||||
enum si_field collide = 0;
|
||||
|
||||
if (new->merge == MERGE_REPLACE) {
|
||||
if (report)
|
||||
log_warn(info->ctx,
|
||||
"Multiple definitions for \"%s\"; "
|
||||
"Earlier interpretation ignored\n",
|
||||
siText(new, info));
|
||||
*old = *new;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (UseNewInterpField(SI_FIELD_VIRTUAL_MOD, old, new, report,
|
||||
&collide)) {
|
||||
old->interp.virtual_mod = new->interp.virtual_mod;
|
||||
old->defined |= SI_FIELD_VIRTUAL_MOD;
|
||||
}
|
||||
if (UseNewInterpField(SI_FIELD_ACTION, old, new, report,
|
||||
&collide)) {
|
||||
old->interp.action = new->interp.action;
|
||||
old->defined |= SI_FIELD_ACTION;
|
||||
}
|
||||
if (UseNewInterpField(SI_FIELD_AUTO_REPEAT, old, new, report,
|
||||
&collide)) {
|
||||
old->interp.repeat = new->interp.repeat;
|
||||
old->defined |= SI_FIELD_AUTO_REPEAT;
|
||||
}
|
||||
if (UseNewInterpField(SI_FIELD_LEVEL_ONE_ONLY, old, new, report,
|
||||
&collide)) {
|
||||
old->interp.level_one_only = new->interp.level_one_only;
|
||||
old->defined |= SI_FIELD_LEVEL_ONE_ONLY;
|
||||
}
|
||||
|
||||
if (collide) {
|
||||
log_warn(info->ctx,
|
||||
"Multiple interpretations of \"%s\"; "
|
||||
"Using %s definition for duplicate fields\n",
|
||||
siText(new, info),
|
||||
(new->merge != MERGE_AUGMENT ? "last" : "first"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
darray_append(info->interps, *new);
|
||||
return true;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
ResolveStateAndPredicate(ExprDef *expr, enum xkb_match_operation *pred_rtrn,
|
||||
xkb_mod_mask_t *mods_rtrn, CompatInfo *info)
|
||||
{
|
||||
if (expr == NULL) {
|
||||
*pred_rtrn = MATCH_ANY_OR_NONE;
|
||||
*mods_rtrn = MOD_REAL_MASK_ALL;
|
||||
return true;
|
||||
}
|
||||
|
||||
*pred_rtrn = MATCH_EXACTLY;
|
||||
if (expr->expr.op == EXPR_ACTION_DECL) {
|
||||
const char *pred_txt = xkb_atom_text(info->ctx, expr->action.name);
|
||||
if (!LookupString(symInterpretMatchMaskNames, pred_txt, pred_rtrn) ||
|
||||
!expr->action.args) {
|
||||
log_err(info->ctx,
|
||||
"Illegal modifier predicate \"%s\"; Ignored\n", pred_txt);
|
||||
return false;
|
||||
}
|
||||
expr = expr->action.args;
|
||||
}
|
||||
else if (expr->expr.op == EXPR_IDENT) {
|
||||
const char *pred_txt = xkb_atom_text(info->ctx, expr->ident.ident);
|
||||
if (pred_txt && istreq(pred_txt, "any")) {
|
||||
*pred_rtrn = MATCH_ANY;
|
||||
*mods_rtrn = MOD_REAL_MASK_ALL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return ExprResolveModMask(info->ctx, expr, MOD_REAL, &info->mods,
|
||||
mods_rtrn);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
UseNewLEDField(enum led_field field, LedInfo *old, LedInfo *new,
|
||||
bool report, enum led_field *collide)
|
||||
{
|
||||
if (!(old->defined & field))
|
||||
return true;
|
||||
|
||||
if (new->defined & field) {
|
||||
if (report)
|
||||
*collide |= field;
|
||||
|
||||
if (new->merge != MERGE_AUGMENT)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
AddLedMap(CompatInfo *info, LedInfo *new, bool same_file)
|
||||
{
|
||||
enum led_field collide;
|
||||
const int verbosity = xkb_context_get_log_verbosity(info->ctx);
|
||||
const bool report = (same_file && verbosity > 0) || verbosity > 9;
|
||||
|
||||
for (xkb_led_index_t i = 0; i < info->num_leds; i++) {
|
||||
LedInfo *old = &info->leds[i];
|
||||
|
||||
if (old->led.name != new->led.name)
|
||||
continue;
|
||||
|
||||
if (old->led.mods.mods == new->led.mods.mods &&
|
||||
old->led.groups == new->led.groups &&
|
||||
old->led.ctrls == new->led.ctrls &&
|
||||
old->led.which_mods == new->led.which_mods &&
|
||||
old->led.which_groups == new->led.which_groups) {
|
||||
old->defined |= new->defined;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (new->merge == MERGE_REPLACE) {
|
||||
if (report)
|
||||
log_warn(info->ctx,
|
||||
"Map for indicator %s redefined; "
|
||||
"Earlier definition ignored\n",
|
||||
xkb_atom_text(info->ctx, old->led.name));
|
||||
*old = *new;
|
||||
return true;
|
||||
}
|
||||
|
||||
collide = 0;
|
||||
if (UseNewLEDField(LED_FIELD_MODS, old, new, report, &collide)) {
|
||||
old->led.which_mods = new->led.which_mods;
|
||||
old->led.mods = new->led.mods;
|
||||
old->defined |= LED_FIELD_MODS;
|
||||
}
|
||||
if (UseNewLEDField(LED_FIELD_GROUPS, old, new, report, &collide)) {
|
||||
old->led.which_groups = new->led.which_groups;
|
||||
old->led.groups = new->led.groups;
|
||||
old->defined |= LED_FIELD_GROUPS;
|
||||
}
|
||||
if (UseNewLEDField(LED_FIELD_CTRLS, old, new, report, &collide)) {
|
||||
old->led.ctrls = new->led.ctrls;
|
||||
old->defined |= LED_FIELD_CTRLS;
|
||||
}
|
||||
|
||||
if (collide) {
|
||||
log_warn(info->ctx,
|
||||
"Map for indicator %s redefined; "
|
||||
"Using %s definition for duplicate fields\n",
|
||||
xkb_atom_text(info->ctx, old->led.name),
|
||||
(new->merge == MERGE_AUGMENT ? "first" : "last"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (info->num_leds >= XKB_MAX_LEDS) {
|
||||
log_err(info->ctx,
|
||||
"Too many LEDs defined (maximum %d)\n",
|
||||
XKB_MAX_LEDS);
|
||||
return false;
|
||||
}
|
||||
info->leds[info->num_leds++] = *new;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
MergeIncludedCompatMaps(CompatInfo *into, CompatInfo *from,
|
||||
enum merge_mode merge)
|
||||
{
|
||||
if (from->errorCount > 0) {
|
||||
into->errorCount += from->errorCount;
|
||||
return;
|
||||
}
|
||||
|
||||
into->mods = from->mods;
|
||||
|
||||
if (into->name == NULL) {
|
||||
into->name = from->name;
|
||||
from->name = NULL;
|
||||
}
|
||||
|
||||
if (darray_empty(into->interps)) {
|
||||
into->interps = from->interps;
|
||||
darray_init(from->interps);
|
||||
}
|
||||
else {
|
||||
SymInterpInfo *si;
|
||||
darray_foreach(si, from->interps) {
|
||||
si->merge = (merge == MERGE_DEFAULT ? si->merge : merge);
|
||||
if (!AddInterp(into, si, false))
|
||||
into->errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (into->num_leds == 0) {
|
||||
memcpy(into->leds, from->leds, sizeof(*from->leds) * from->num_leds);
|
||||
into->num_leds = from->num_leds;
|
||||
from->num_leds = 0;
|
||||
}
|
||||
else {
|
||||
for (xkb_led_index_t i = 0; i < from->num_leds; i++) {
|
||||
LedInfo *ledi = &from->leds[i];
|
||||
ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge);
|
||||
if (!AddLedMap(into, ledi, false))
|
||||
into->errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge);
|
||||
|
||||
static bool
|
||||
HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *include)
|
||||
{
|
||||
CompatInfo included;
|
||||
|
||||
InitCompatInfo(&included, info->ctx, info->actions, &info->mods);
|
||||
included.name = include->stmt;
|
||||
include->stmt = NULL;
|
||||
|
||||
for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
|
||||
CompatInfo next_incl;
|
||||
XkbFile *file;
|
||||
|
||||
file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_COMPAT);
|
||||
if (!file) {
|
||||
info->errorCount += 10;
|
||||
ClearCompatInfo(&included);
|
||||
return false;
|
||||
}
|
||||
|
||||
InitCompatInfo(&next_incl, info->ctx, info->actions, &included.mods);
|
||||
next_incl.default_interp = info->default_interp;
|
||||
next_incl.default_interp.merge = stmt->merge;
|
||||
next_incl.default_led = info->default_led;
|
||||
next_incl.default_led.merge = stmt->merge;
|
||||
|
||||
HandleCompatMapFile(&next_incl, file, MERGE_OVERRIDE);
|
||||
|
||||
MergeIncludedCompatMaps(&included, &next_incl, stmt->merge);
|
||||
|
||||
ClearCompatInfo(&next_incl);
|
||||
FreeXkbFile(file);
|
||||
}
|
||||
|
||||
MergeIncludedCompatMaps(info, &included, include->merge);
|
||||
ClearCompatInfo(&included);
|
||||
|
||||
return (info->errorCount == 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
SetInterpField(CompatInfo *info, SymInterpInfo *si, const char *field,
|
||||
ExprDef *arrayNdx, ExprDef *value)
|
||||
{
|
||||
xkb_mod_index_t ndx;
|
||||
|
||||
if (istreq(field, "action")) {
|
||||
if (arrayNdx)
|
||||
return ReportSINotArray(info, si, field);
|
||||
|
||||
if (!HandleActionDef(info->ctx, info->actions, &info->mods,
|
||||
value, &si->interp.action))
|
||||
return false;
|
||||
|
||||
si->defined |= SI_FIELD_ACTION;
|
||||
}
|
||||
else if (istreq(field, "virtualmodifier") ||
|
||||
istreq(field, "virtualmod")) {
|
||||
if (arrayNdx)
|
||||
return ReportSINotArray(info, si, field);
|
||||
|
||||
if (!ExprResolveMod(info->ctx, value, MOD_VIRT, &info->mods, &ndx))
|
||||
return ReportSIBadType(info, si, field, "virtual modifier");
|
||||
|
||||
si->interp.virtual_mod = ndx;
|
||||
si->defined |= SI_FIELD_VIRTUAL_MOD;
|
||||
}
|
||||
else if (istreq(field, "repeat")) {
|
||||
bool set;
|
||||
|
||||
if (arrayNdx)
|
||||
return ReportSINotArray(info, si, field);
|
||||
|
||||
if (!ExprResolveBoolean(info->ctx, value, &set))
|
||||
return ReportSIBadType(info, si, field, "boolean");
|
||||
|
||||
si->interp.repeat = set;
|
||||
|
||||
si->defined |= SI_FIELD_AUTO_REPEAT;
|
||||
}
|
||||
else if (istreq(field, "locking")) {
|
||||
log_dbg(info->ctx,
|
||||
"The \"locking\" field in symbol interpretation is unsupported; "
|
||||
"Ignored\n");
|
||||
}
|
||||
else if (istreq(field, "usemodmap") ||
|
||||
istreq(field, "usemodmapmods")) {
|
||||
unsigned int val;
|
||||
|
||||
if (arrayNdx)
|
||||
return ReportSINotArray(info, si, field);
|
||||
|
||||
if (!ExprResolveEnum(info->ctx, value, &val, useModMapValueNames))
|
||||
return ReportSIBadType(info, si, field, "level specification");
|
||||
|
||||
si->interp.level_one_only = val;
|
||||
si->defined |= SI_FIELD_LEVEL_ONE_ONLY;
|
||||
}
|
||||
else {
|
||||
return ReportBadField(info->ctx, "symbol interpretation", field,
|
||||
siText(si, info));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
SetLedMapField(CompatInfo *info, LedInfo *ledi, const char *field,
|
||||
ExprDef *arrayNdx, ExprDef *value)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
if (istreq(field, "modifiers") || istreq(field, "mods")) {
|
||||
if (arrayNdx)
|
||||
return ReportLedNotArray(info, ledi, field);
|
||||
|
||||
if (!ExprResolveModMask(info->ctx, value, MOD_BOTH,
|
||||
&info->mods, &ledi->led.mods.mods))
|
||||
return ReportLedBadType(info, ledi, field, "modifier mask");
|
||||
|
||||
ledi->defined |= LED_FIELD_MODS;
|
||||
}
|
||||
else if (istreq(field, "groups")) {
|
||||
unsigned int mask;
|
||||
|
||||
if (arrayNdx)
|
||||
return ReportLedNotArray(info, ledi, field);
|
||||
|
||||
if (!ExprResolveMask(info->ctx, value, &mask, groupMaskNames))
|
||||
return ReportLedBadType(info, ledi, field, "group mask");
|
||||
|
||||
ledi->led.groups = mask;
|
||||
ledi->defined |= LED_FIELD_GROUPS;
|
||||
}
|
||||
else if (istreq(field, "controls") || istreq(field, "ctrls")) {
|
||||
unsigned int mask;
|
||||
|
||||
if (arrayNdx)
|
||||
return ReportLedNotArray(info, ledi, field);
|
||||
|
||||
if (!ExprResolveMask(info->ctx, value, &mask, ctrlMaskNames))
|
||||
return ReportLedBadType(info, ledi, field, "controls mask");
|
||||
|
||||
ledi->led.ctrls = mask;
|
||||
ledi->defined |= LED_FIELD_CTRLS;
|
||||
}
|
||||
else if (istreq(field, "allowexplicit")) {
|
||||
log_dbg(info->ctx,
|
||||
"The \"allowExplicit\" field in indicator statements is unsupported; "
|
||||
"Ignored\n");
|
||||
}
|
||||
else if (istreq(field, "whichmodstate") ||
|
||||
istreq(field, "whichmodifierstate")) {
|
||||
unsigned int mask;
|
||||
|
||||
if (arrayNdx)
|
||||
return ReportLedNotArray(info, ledi, field);
|
||||
|
||||
if (!ExprResolveMask(info->ctx, value, &mask,
|
||||
modComponentMaskNames))
|
||||
return ReportLedBadType(info, ledi, field,
|
||||
"mask of modifier state components");
|
||||
|
||||
ledi->led.which_mods = mask;
|
||||
}
|
||||
else if (istreq(field, "whichgroupstate")) {
|
||||
unsigned mask;
|
||||
|
||||
if (arrayNdx)
|
||||
return ReportLedNotArray(info, ledi, field);
|
||||
|
||||
if (!ExprResolveMask(info->ctx, value, &mask,
|
||||
groupComponentMaskNames))
|
||||
return ReportLedBadType(info, ledi, field,
|
||||
"mask of group state components");
|
||||
|
||||
ledi->led.which_groups = mask;
|
||||
}
|
||||
else if (istreq(field, "driveskbd") ||
|
||||
istreq(field, "driveskeyboard") ||
|
||||
istreq(field, "leddriveskbd") ||
|
||||
istreq(field, "leddriveskeyboard") ||
|
||||
istreq(field, "indicatordriveskbd") ||
|
||||
istreq(field, "indicatordriveskeyboard")) {
|
||||
log_dbg(info->ctx,
|
||||
"The \"%s\" field in indicator statements is unsupported; "
|
||||
"Ignored\n", field);
|
||||
}
|
||||
else if (istreq(field, "index")) {
|
||||
/* Users should see this, it might cause unexpected behavior. */
|
||||
log_err(info->ctx,
|
||||
"The \"index\" field in indicator statements is unsupported; "
|
||||
"Ignored\n");
|
||||
}
|
||||
else {
|
||||
log_err(info->ctx,
|
||||
"Unknown field %s in map for %s indicator; "
|
||||
"Definition ignored\n",
|
||||
field, xkb_atom_text(info->ctx, ledi->led.name));
|
||||
ok = false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleGlobalVar(CompatInfo *info, VarDef *stmt)
|
||||
{
|
||||
const char *elem, *field;
|
||||
ExprDef *ndx;
|
||||
bool ret;
|
||||
|
||||
if (!ExprResolveLhs(info->ctx, stmt->name, &elem, &field, &ndx))
|
||||
ret = false;
|
||||
else if (elem && istreq(elem, "interpret"))
|
||||
ret = SetInterpField(info, &info->default_interp, field, ndx,
|
||||
stmt->value);
|
||||
else if (elem && istreq(elem, "indicator"))
|
||||
ret = SetLedMapField(info, &info->default_led, field, ndx,
|
||||
stmt->value);
|
||||
else
|
||||
ret = SetActionField(info->ctx, info->actions, &info->mods,
|
||||
elem, field, ndx, stmt->value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleInterpBody(CompatInfo *info, VarDef *def, SymInterpInfo *si)
|
||||
{
|
||||
bool ok = true;
|
||||
const char *elem, *field;
|
||||
ExprDef *arrayNdx;
|
||||
|
||||
for (; def; def = (VarDef *) def->common.next) {
|
||||
if (def->name && def->name->expr.op == EXPR_FIELD_REF) {
|
||||
log_err(info->ctx,
|
||||
"Cannot set a global default value from within an interpret statement; "
|
||||
"Move statements to the global file scope\n");
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
ok = ExprResolveLhs(info->ctx, def->name, &elem, &field, &arrayNdx);
|
||||
if (!ok)
|
||||
continue;
|
||||
|
||||
ok = SetInterpField(info, si, field, arrayNdx, def->value);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleInterpDef(CompatInfo *info, InterpDef *def, enum merge_mode merge)
|
||||
{
|
||||
enum xkb_match_operation pred;
|
||||
xkb_mod_mask_t mods;
|
||||
SymInterpInfo si;
|
||||
|
||||
if (!ResolveStateAndPredicate(def->match, &pred, &mods, info)) {
|
||||
log_err(info->ctx,
|
||||
"Couldn't determine matching modifiers; "
|
||||
"Symbol interpretation ignored\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
si = info->default_interp;
|
||||
si.merge = merge = (def->merge == MERGE_DEFAULT ? merge : def->merge);
|
||||
si.interp.sym = def->sym;
|
||||
si.interp.match = pred;
|
||||
si.interp.mods = mods;
|
||||
|
||||
if (!HandleInterpBody(info, def->def, &si)) {
|
||||
info->errorCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AddInterp(info, &si, true)) {
|
||||
info->errorCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleLedMapDef(CompatInfo *info, LedMapDef *def, enum merge_mode merge)
|
||||
{
|
||||
LedInfo ledi;
|
||||
VarDef *var;
|
||||
bool ok;
|
||||
|
||||
if (def->merge != MERGE_DEFAULT)
|
||||
merge = def->merge;
|
||||
|
||||
ledi = info->default_led;
|
||||
ledi.merge = merge;
|
||||
ledi.led.name = def->name;
|
||||
|
||||
ok = true;
|
||||
for (var = def->body; var != NULL; var = (VarDef *) var->common.next) {
|
||||
const char *elem, *field;
|
||||
ExprDef *arrayNdx;
|
||||
if (!ExprResolveLhs(info->ctx, var->name, &elem, &field, &arrayNdx)) {
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (elem) {
|
||||
log_err(info->ctx,
|
||||
"Cannot set defaults for \"%s\" element in indicator map; "
|
||||
"Assignment to %s.%s ignored\n", elem, elem, field);
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
ok = SetLedMapField(info, &ledi, field, arrayNdx, var->value) && ok;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
return AddLedMap(info, &ledi, true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
merge = (merge == MERGE_DEFAULT ? MERGE_AUGMENT : merge);
|
||||
|
||||
free(info->name);
|
||||
info->name = strdup_safe(file->name);
|
||||
|
||||
for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
|
||||
switch (stmt->type) {
|
||||
case STMT_INCLUDE:
|
||||
ok = HandleIncludeCompatMap(info, (IncludeStmt *) stmt);
|
||||
break;
|
||||
case STMT_INTERP:
|
||||
ok = HandleInterpDef(info, (InterpDef *) stmt, merge);
|
||||
break;
|
||||
case STMT_GROUP_COMPAT:
|
||||
log_dbg(info->ctx,
|
||||
"The \"group\" statement in compat is unsupported; "
|
||||
"Ignored\n");
|
||||
ok = true;
|
||||
break;
|
||||
case STMT_LED_MAP:
|
||||
ok = HandleLedMapDef(info, (LedMapDef *) stmt, merge);
|
||||
break;
|
||||
case STMT_VAR:
|
||||
ok = HandleGlobalVar(info, (VarDef *) stmt);
|
||||
break;
|
||||
case STMT_VMOD:
|
||||
ok = HandleVModDef(info->ctx, &info->mods, (VModDef *) stmt, merge);
|
||||
break;
|
||||
default:
|
||||
log_err(info->ctx,
|
||||
"Compat files may not include other types; "
|
||||
"Ignoring %s\n", stmt_type_to_string(stmt->type));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
info->errorCount++;
|
||||
|
||||
if (info->errorCount > 10) {
|
||||
log_err(info->ctx,
|
||||
"Abandoning compatibility map \"%s\"\n", file->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Temporary struct for CopyInterps. */
|
||||
struct collect {
|
||||
darray(struct xkb_sym_interpret) sym_interprets;
|
||||
};
|
||||
|
||||
static void
|
||||
CopyInterps(CompatInfo *info, bool needSymbol, enum xkb_match_operation pred,
|
||||
struct collect *collect)
|
||||
{
|
||||
SymInterpInfo *si;
|
||||
|
||||
darray_foreach(si, info->interps)
|
||||
if (si->interp.match == pred &&
|
||||
(si->interp.sym != XKB_KEY_NoSymbol) == needSymbol)
|
||||
darray_append(collect->sym_interprets, si->interp);
|
||||
}
|
||||
|
||||
static void
|
||||
CopyLedMapDefsToKeymap(struct xkb_keymap *keymap, CompatInfo *info)
|
||||
{
|
||||
for (xkb_led_index_t idx = 0; idx < info->num_leds; idx++) {
|
||||
LedInfo *ledi = &info->leds[idx];
|
||||
xkb_led_index_t i;
|
||||
struct xkb_led *led;
|
||||
|
||||
/*
|
||||
* Find the LED with the given name, if it was already declared
|
||||
* in keycodes.
|
||||
*/
|
||||
xkb_leds_enumerate(i, led, keymap)
|
||||
if (led->name == ledi->led.name)
|
||||
break;
|
||||
|
||||
/* Not previously declared; create it with next free index. */
|
||||
if (i >= keymap->num_leds) {
|
||||
log_dbg(keymap->ctx,
|
||||
"Indicator name \"%s\" was not declared in the keycodes section; "
|
||||
"Adding new indicator\n",
|
||||
xkb_atom_text(keymap->ctx, ledi->led.name));
|
||||
|
||||
xkb_leds_enumerate(i, led, keymap)
|
||||
if (led->name == XKB_ATOM_NONE)
|
||||
break;
|
||||
|
||||
if (i >= keymap->num_leds) {
|
||||
/* Not place to put it; ignore. */
|
||||
if (i >= XKB_MAX_LEDS) {
|
||||
log_err(keymap->ctx,
|
||||
"Too many indicators (maximum is %d); "
|
||||
"Indicator name \"%s\" ignored\n",
|
||||
XKB_MAX_LEDS,
|
||||
xkb_atom_text(keymap->ctx, ledi->led.name));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Add a new LED. */
|
||||
led = &keymap->leds[keymap->num_leds++];
|
||||
}
|
||||
}
|
||||
|
||||
*led = ledi->led;
|
||||
if (led->groups != 0 && led->which_groups == 0)
|
||||
led->which_groups = XKB_STATE_LAYOUT_EFFECTIVE;
|
||||
if (led->mods.mods != 0 && led->which_mods == 0)
|
||||
led->which_mods = XKB_STATE_MODS_EFFECTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
CopyCompatToKeymap(struct xkb_keymap *keymap, CompatInfo *info)
|
||||
{
|
||||
keymap->compat_section_name = strdup_safe(info->name);
|
||||
XkbEscapeMapName(keymap->compat_section_name);
|
||||
|
||||
keymap->mods = info->mods;
|
||||
|
||||
if (!darray_empty(info->interps)) {
|
||||
struct collect collect;
|
||||
darray_init(collect.sym_interprets);
|
||||
|
||||
/* Most specific to least specific. */
|
||||
CopyInterps(info, true, MATCH_EXACTLY, &collect);
|
||||
CopyInterps(info, true, MATCH_ALL, &collect);
|
||||
CopyInterps(info, true, MATCH_NONE, &collect);
|
||||
CopyInterps(info, true, MATCH_ANY, &collect);
|
||||
CopyInterps(info, true, MATCH_ANY_OR_NONE, &collect);
|
||||
CopyInterps(info, false, MATCH_EXACTLY, &collect);
|
||||
CopyInterps(info, false, MATCH_ALL, &collect);
|
||||
CopyInterps(info, false, MATCH_NONE, &collect);
|
||||
CopyInterps(info, false, MATCH_ANY, &collect);
|
||||
CopyInterps(info, false, MATCH_ANY_OR_NONE, &collect);
|
||||
|
||||
darray_steal(collect.sym_interprets,
|
||||
&keymap->sym_interprets, &keymap->num_sym_interprets);
|
||||
}
|
||||
|
||||
CopyLedMapDefsToKeymap(keymap, info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap,
|
||||
enum merge_mode merge)
|
||||
{
|
||||
CompatInfo info;
|
||||
ActionsInfo *actions;
|
||||
|
||||
actions = NewActionsInfo();
|
||||
if (!actions)
|
||||
return false;
|
||||
|
||||
InitCompatInfo(&info, keymap->ctx, actions, &keymap->mods);
|
||||
info.default_interp.merge = merge;
|
||||
info.default_led.merge = merge;
|
||||
|
||||
HandleCompatMapFile(&info, file, merge);
|
||||
if (info.errorCount != 0)
|
||||
goto err_info;
|
||||
|
||||
if (!CopyCompatToKeymap(keymap, &info))
|
||||
goto err_info;
|
||||
|
||||
ClearCompatInfo(&info);
|
||||
FreeActionsInfo(actions);
|
||||
return true;
|
||||
|
||||
err_info:
|
||||
ClearCompatInfo(&info);
|
||||
FreeActionsInfo(actions);
|
||||
return false;
|
||||
}
|
686
src/3rdparty/xkbcommon/src/xkbcomp/expr.c
vendored
686
src/3rdparty/xkbcommon/src/xkbcomp/expr.c
vendored
@ -1,686 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "text.h"
|
||||
#include "expr.h"
|
||||
|
||||
typedef bool (*IdentLookupFunc)(struct xkb_context *ctx, const void *priv,
|
||||
xkb_atom_t field, enum expr_value_type type,
|
||||
unsigned int *val_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr,
|
||||
const char **elem_rtrn, const char **field_rtrn,
|
||||
ExprDef **index_rtrn)
|
||||
{
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_IDENT:
|
||||
*elem_rtrn = NULL;
|
||||
*field_rtrn = xkb_atom_text(ctx, expr->ident.ident);
|
||||
*index_rtrn = NULL;
|
||||
return (*field_rtrn != NULL);
|
||||
case EXPR_FIELD_REF:
|
||||
*elem_rtrn = xkb_atom_text(ctx, expr->field_ref.element);
|
||||
*field_rtrn = xkb_atom_text(ctx, expr->field_ref.field);
|
||||
*index_rtrn = NULL;
|
||||
return (*elem_rtrn != NULL && *field_rtrn != NULL);
|
||||
case EXPR_ARRAY_REF:
|
||||
*elem_rtrn = xkb_atom_text(ctx, expr->array_ref.element);
|
||||
*field_rtrn = xkb_atom_text(ctx, expr->array_ref.field);
|
||||
*index_rtrn = expr->array_ref.entry;
|
||||
if (expr->array_ref.element != XKB_ATOM_NONE && *elem_rtrn == NULL)
|
||||
return false;
|
||||
if (*field_rtrn == NULL)
|
||||
return false;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->expr.op);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
SimpleLookup(struct xkb_context *ctx, const void *priv, xkb_atom_t field,
|
||||
enum expr_value_type type, unsigned int *val_rtrn)
|
||||
{
|
||||
const LookupEntry *entry;
|
||||
const char *str;
|
||||
|
||||
if (!priv || field == XKB_ATOM_NONE || type != EXPR_TYPE_INT)
|
||||
return false;
|
||||
|
||||
str = xkb_atom_text(ctx, field);
|
||||
for (entry = priv; entry && entry->name; entry++) {
|
||||
if (istreq(str, entry->name)) {
|
||||
*val_rtrn = entry->value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Data passed in the *priv argument for LookupModMask. */
|
||||
typedef struct {
|
||||
const struct xkb_mod_set *mods;
|
||||
enum mod_type mod_type;
|
||||
} LookupModMaskPriv;
|
||||
|
||||
static bool
|
||||
LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field,
|
||||
enum expr_value_type type, xkb_mod_mask_t *val_rtrn)
|
||||
{
|
||||
const char *str;
|
||||
xkb_mod_index_t ndx;
|
||||
const LookupModMaskPriv *arg = priv;
|
||||
const struct xkb_mod_set *mods = arg->mods;
|
||||
enum mod_type mod_type = arg->mod_type;
|
||||
|
||||
if (type != EXPR_TYPE_INT)
|
||||
return false;
|
||||
|
||||
str = xkb_atom_text(ctx, field);
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
if (istreq(str, "all")) {
|
||||
*val_rtrn = MOD_REAL_MASK_ALL;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (istreq(str, "none")) {
|
||||
*val_rtrn = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
ndx = XkbModNameToIndex(mods, field, mod_type);
|
||||
if (ndx == XKB_MOD_INVALID)
|
||||
return false;
|
||||
|
||||
*val_rtrn = (1u << ndx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
|
||||
bool *set_rtrn)
|
||||
{
|
||||
bool ok = false;
|
||||
const char *ident;
|
||||
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->expr.value_type != EXPR_TYPE_BOOLEAN) {
|
||||
log_err(ctx,
|
||||
"Found constant of type %s where boolean was expected\n",
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
*set_rtrn = expr->boolean.set;
|
||||
return true;
|
||||
|
||||
case EXPR_IDENT:
|
||||
ident = xkb_atom_text(ctx, expr->ident.ident);
|
||||
if (ident) {
|
||||
if (istreq(ident, "true") ||
|
||||
istreq(ident, "yes") ||
|
||||
istreq(ident, "on")) {
|
||||
*set_rtrn = true;
|
||||
return true;
|
||||
}
|
||||
else if (istreq(ident, "false") ||
|
||||
istreq(ident, "no") ||
|
||||
istreq(ident, "off")) {
|
||||
*set_rtrn = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n", ident);
|
||||
return false;
|
||||
|
||||
case EXPR_FIELD_REF:
|
||||
log_err(ctx, "Default \"%s.%s\" of type boolean is unknown\n",
|
||||
xkb_atom_text(ctx, expr->field_ref.element),
|
||||
xkb_atom_text(ctx, expr->field_ref.field));
|
||||
return false;
|
||||
|
||||
case EXPR_INVERT:
|
||||
case EXPR_NOT:
|
||||
ok = ExprResolveBoolean(ctx, expr->unary.child, set_rtrn);
|
||||
if (ok)
|
||||
*set_rtrn = !*set_rtrn;
|
||||
return ok;
|
||||
case EXPR_ADD:
|
||||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
case EXPR_ASSIGN:
|
||||
case EXPR_NEGATE:
|
||||
case EXPR_UNARY_PLUS:
|
||||
log_err(ctx, "%s of boolean values not permitted\n",
|
||||
expr_op_type_to_string(expr->expr.op));
|
||||
break;
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_keycode_t *kc)
|
||||
{
|
||||
xkb_keycode_t leftRtrn, rightRtrn;
|
||||
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->expr.value_type != EXPR_TYPE_INT) {
|
||||
log_err(ctx,
|
||||
"Found constant of type %s where an int was expected\n",
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
|
||||
*kc = (xkb_keycode_t) expr->integer.ival;
|
||||
return true;
|
||||
|
||||
case EXPR_ADD:
|
||||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
if (!ExprResolveKeyCode(ctx, expr->binary.left, &leftRtrn) ||
|
||||
!ExprResolveKeyCode(ctx, expr->binary.right, &rightRtrn))
|
||||
return false;
|
||||
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_ADD:
|
||||
*kc = leftRtrn + rightRtrn;
|
||||
break;
|
||||
case EXPR_SUBTRACT:
|
||||
*kc = leftRtrn - rightRtrn;
|
||||
break;
|
||||
case EXPR_MULTIPLY:
|
||||
*kc = leftRtrn * rightRtrn;
|
||||
break;
|
||||
case EXPR_DIVIDE:
|
||||
if (rightRtrn == 0) {
|
||||
log_err(ctx, "Cannot divide by zero: %d / %d\n",
|
||||
leftRtrn, rightRtrn);
|
||||
return false;
|
||||
}
|
||||
|
||||
*kc = leftRtrn / rightRtrn;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
case EXPR_NEGATE:
|
||||
if (!ExprResolveKeyCode(ctx, expr->unary.child, &leftRtrn))
|
||||
return false;
|
||||
|
||||
*kc = ~leftRtrn;
|
||||
return true;
|
||||
|
||||
case EXPR_UNARY_PLUS:
|
||||
return ExprResolveKeyCode(ctx, expr->unary.child, kc);
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns ... something. It's a bit of a guess, really.
|
||||
*
|
||||
* If an integer is given in value ctx, it will be returned in ival.
|
||||
* If an ident or field reference is given, the lookup function (if given)
|
||||
* will be called. At the moment, only SimpleLookup use this, and they both
|
||||
* return the results in uval. And don't support field references.
|
||||
*
|
||||
* Cool.
|
||||
*/
|
||||
static bool
|
||||
ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
|
||||
int *val_rtrn, IdentLookupFunc lookup,
|
||||
const void *lookupPriv)
|
||||
{
|
||||
bool ok = false;
|
||||
int l, r;
|
||||
unsigned u;
|
||||
ExprDef *left, *right;
|
||||
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->expr.value_type != EXPR_TYPE_INT) {
|
||||
log_err(ctx,
|
||||
"Found constant of type %s where an int was expected\n",
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
|
||||
*val_rtrn = expr->integer.ival;
|
||||
return true;
|
||||
|
||||
case EXPR_IDENT:
|
||||
if (lookup)
|
||||
ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT, &u);
|
||||
|
||||
if (!ok)
|
||||
log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
|
||||
xkb_atom_text(ctx, expr->ident.ident));
|
||||
else
|
||||
*val_rtrn = (int) u;
|
||||
|
||||
return ok;
|
||||
|
||||
case EXPR_FIELD_REF:
|
||||
log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
|
||||
xkb_atom_text(ctx, expr->field_ref.element),
|
||||
xkb_atom_text(ctx, expr->field_ref.field));
|
||||
return false;
|
||||
|
||||
case EXPR_ADD:
|
||||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
left = expr->binary.left;
|
||||
right = expr->binary.right;
|
||||
if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv) ||
|
||||
!ExprResolveIntegerLookup(ctx, right, &r, lookup, lookupPriv))
|
||||
return false;
|
||||
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_ADD:
|
||||
*val_rtrn = l + r;
|
||||
break;
|
||||
case EXPR_SUBTRACT:
|
||||
*val_rtrn = l - r;
|
||||
break;
|
||||
case EXPR_MULTIPLY:
|
||||
*val_rtrn = l * r;
|
||||
break;
|
||||
case EXPR_DIVIDE:
|
||||
if (r == 0) {
|
||||
log_err(ctx, "Cannot divide by zero: %d / %d\n", l, r);
|
||||
return false;
|
||||
}
|
||||
*val_rtrn = l / r;
|
||||
break;
|
||||
default:
|
||||
log_err(ctx, "%s of integers not permitted\n",
|
||||
expr_op_type_to_string(expr->expr.op));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
case EXPR_ASSIGN:
|
||||
log_wsgo(ctx, "Assignment operator not implemented yet\n");
|
||||
break;
|
||||
|
||||
case EXPR_NOT:
|
||||
log_err(ctx, "The ! operator cannot be applied to an integer\n");
|
||||
return false;
|
||||
|
||||
case EXPR_INVERT:
|
||||
case EXPR_NEGATE:
|
||||
left = expr->unary.child;
|
||||
if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv))
|
||||
return false;
|
||||
|
||||
*val_rtrn = (expr->expr.op == EXPR_NEGATE ? -l : ~l);
|
||||
return true;
|
||||
|
||||
case EXPR_UNARY_PLUS:
|
||||
left = expr->unary.child;
|
||||
return ExprResolveIntegerLookup(ctx, left, val_rtrn, lookup,
|
||||
lookupPriv);
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveInteger(struct xkb_context *ctx, const ExprDef *expr,
|
||||
int *val_rtrn)
|
||||
{
|
||||
return ExprResolveIntegerLookup(ctx, expr, val_rtrn, NULL, NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveGroup(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_layout_index_t *group_rtrn)
|
||||
{
|
||||
bool ok;
|
||||
int result;
|
||||
|
||||
ok = ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
|
||||
groupNames);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (result <= 0 || result > XKB_MAX_GROUPS) {
|
||||
log_err(ctx, "Group index %u is out of range (1..%d)\n",
|
||||
result, XKB_MAX_GROUPS);
|
||||
return false;
|
||||
}
|
||||
|
||||
*group_rtrn = (xkb_layout_index_t) result;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_level_index_t *level_rtrn)
|
||||
{
|
||||
bool ok;
|
||||
int result;
|
||||
|
||||
ok = ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
|
||||
levelNames);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (result < 1) {
|
||||
log_err(ctx, "Shift level %d is out of range\n", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Level is zero-indexed from now on. */
|
||||
*level_rtrn = (unsigned int) (result - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn)
|
||||
{
|
||||
return ExprResolveIntegerLookup(ctx, expr, btn_rtrn, SimpleLookup,
|
||||
buttonNames);
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_atom_t *val_rtrn)
|
||||
{
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->expr.value_type != EXPR_TYPE_STRING) {
|
||||
log_err(ctx, "Found constant of type %s, expected a string\n",
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
|
||||
*val_rtrn = expr->string.str;
|
||||
return true;
|
||||
|
||||
case EXPR_IDENT:
|
||||
log_err(ctx, "Identifier \"%s\" of type string not found\n",
|
||||
xkb_atom_text(ctx, expr->ident.ident));
|
||||
return false;
|
||||
|
||||
case EXPR_FIELD_REF:
|
||||
log_err(ctx, "Default \"%s.%s\" of type string not found\n",
|
||||
xkb_atom_text(ctx, expr->field_ref.element),
|
||||
xkb_atom_text(ctx, expr->field_ref.field));
|
||||
return false;
|
||||
|
||||
case EXPR_ADD:
|
||||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
case EXPR_ASSIGN:
|
||||
case EXPR_NEGATE:
|
||||
case EXPR_INVERT:
|
||||
case EXPR_NOT:
|
||||
case EXPR_UNARY_PLUS:
|
||||
log_err(ctx, "%s of strings not permitted\n",
|
||||
expr_op_type_to_string(expr->expr.op));
|
||||
return false;
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveString\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr,
|
||||
unsigned int *val_rtrn, const LookupEntry *values)
|
||||
{
|
||||
if (expr->expr.op != EXPR_IDENT) {
|
||||
log_err(ctx, "Found a %s where an enumerated value was expected\n",
|
||||
expr_op_type_to_string(expr->expr.op));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SimpleLookup(ctx, values, expr->ident.ident, EXPR_TYPE_INT,
|
||||
val_rtrn)) {
|
||||
log_err(ctx, "Illegal identifier %s; expected one of:\n",
|
||||
xkb_atom_text(ctx, expr->ident.ident));
|
||||
while (values && values->name)
|
||||
{
|
||||
log_err(ctx, "\t%s\n", values->name);
|
||||
values++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
|
||||
unsigned int *val_rtrn, IdentLookupFunc lookup,
|
||||
const void *lookupPriv)
|
||||
{
|
||||
bool ok = false;
|
||||
unsigned int l = 0, r = 0;
|
||||
int v;
|
||||
ExprDef *left, *right;
|
||||
const char *bogus = NULL;
|
||||
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_VALUE:
|
||||
if (expr->expr.value_type != EXPR_TYPE_INT) {
|
||||
log_err(ctx,
|
||||
"Found constant of type %s where a mask was expected\n",
|
||||
expr_value_type_to_string(expr->expr.value_type));
|
||||
return false;
|
||||
}
|
||||
*val_rtrn = (unsigned int) expr->integer.ival;
|
||||
return true;
|
||||
|
||||
case EXPR_IDENT:
|
||||
ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT,
|
||||
val_rtrn);
|
||||
if (!ok)
|
||||
log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
|
||||
xkb_atom_text(ctx, expr->ident.ident));
|
||||
return ok;
|
||||
|
||||
case EXPR_FIELD_REF:
|
||||
log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
|
||||
xkb_atom_text(ctx, expr->field_ref.element),
|
||||
xkb_atom_text(ctx, expr->field_ref.field));
|
||||
return false;
|
||||
|
||||
case EXPR_ARRAY_REF:
|
||||
bogus = "array reference";
|
||||
/* fallthrough */
|
||||
case EXPR_ACTION_DECL:
|
||||
if (bogus == NULL)
|
||||
bogus = "function use";
|
||||
log_err(ctx,
|
||||
"Unexpected %s in mask expression; Expression Ignored\n",
|
||||
bogus);
|
||||
return false;
|
||||
|
||||
case EXPR_ADD:
|
||||
case EXPR_SUBTRACT:
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
left = expr->binary.left;
|
||||
right = expr->binary.right;
|
||||
if (!ExprResolveMaskLookup(ctx, left, &l, lookup, lookupPriv) ||
|
||||
!ExprResolveMaskLookup(ctx, right, &r, lookup, lookupPriv))
|
||||
return false;
|
||||
|
||||
switch (expr->expr.op) {
|
||||
case EXPR_ADD:
|
||||
*val_rtrn = l | r;
|
||||
break;
|
||||
case EXPR_SUBTRACT:
|
||||
*val_rtrn = l & (~r);
|
||||
break;
|
||||
case EXPR_MULTIPLY:
|
||||
case EXPR_DIVIDE:
|
||||
log_err(ctx, "Cannot %s masks; Illegal operation ignored\n",
|
||||
(expr->expr.op == EXPR_DIVIDE ? "divide" : "multiply"));
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
case EXPR_ASSIGN:
|
||||
log_wsgo(ctx, "Assignment operator not implemented yet\n");
|
||||
break;
|
||||
|
||||
case EXPR_INVERT:
|
||||
left = expr->unary.child;
|
||||
if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
|
||||
return false;
|
||||
|
||||
*val_rtrn = ~v;
|
||||
return true;
|
||||
|
||||
case EXPR_UNARY_PLUS:
|
||||
case EXPR_NEGATE:
|
||||
case EXPR_NOT:
|
||||
left = expr->unary.child;
|
||||
if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
|
||||
log_err(ctx, "The %s operator cannot be used with a mask\n",
|
||||
(expr->expr.op == EXPR_NEGATE ? "-" : "!"));
|
||||
return false;
|
||||
|
||||
default:
|
||||
log_wsgo(ctx, "Unknown operator %d in ResolveMask\n",
|
||||
expr->expr.op);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveMask(struct xkb_context *ctx, const ExprDef *expr,
|
||||
unsigned int *mask_rtrn, const LookupEntry *values)
|
||||
{
|
||||
return ExprResolveMaskLookup(ctx, expr, mask_rtrn, SimpleLookup, values);
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveModMask(struct xkb_context *ctx, const ExprDef *expr,
|
||||
enum mod_type mod_type, const struct xkb_mod_set *mods,
|
||||
xkb_mod_mask_t *mask_rtrn)
|
||||
{
|
||||
LookupModMaskPriv priv = { .mods = mods, .mod_type = mod_type };
|
||||
return ExprResolveMaskLookup(ctx, expr, mask_rtrn, LookupModMask, &priv);
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_keysym_t *sym_rtrn)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (expr->expr.op == EXPR_IDENT) {
|
||||
const char *str = xkb_atom_text(ctx, expr->ident.ident);
|
||||
*sym_rtrn = xkb_keysym_from_name(str, 0);
|
||||
if (*sym_rtrn != XKB_KEY_NoSymbol)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ExprResolveInteger(ctx, expr, &val))
|
||||
return false;
|
||||
|
||||
if (val < 0 || val >= 10)
|
||||
return false;
|
||||
|
||||
*sym_rtrn = XKB_KEY_0 + (xkb_keysym_t) val;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ExprResolveMod(struct xkb_context *ctx, const ExprDef *def,
|
||||
enum mod_type mod_type, const struct xkb_mod_set *mods,
|
||||
xkb_mod_index_t *ndx_rtrn)
|
||||
{
|
||||
xkb_mod_index_t ndx;
|
||||
xkb_atom_t name;
|
||||
|
||||
if (def->expr.op != EXPR_IDENT) {
|
||||
log_err(ctx,
|
||||
"Cannot resolve virtual modifier: "
|
||||
"found %s where a virtual modifier name was expected\n",
|
||||
expr_op_type_to_string(def->expr.op));
|
||||
return false;
|
||||
}
|
||||
|
||||
name = def->ident.ident;
|
||||
ndx = XkbModNameToIndex(mods, name, mod_type);
|
||||
if (ndx == XKB_MOD_INVALID) {
|
||||
log_err(ctx,
|
||||
"Cannot resolve virtual modifier: "
|
||||
"\"%s\" was not previously declared\n",
|
||||
xkb_atom_text(ctx, name));
|
||||
return false;
|
||||
}
|
||||
|
||||
*ndx_rtrn = ndx;
|
||||
return true;
|
||||
}
|
85
src/3rdparty/xkbcommon/src/xkbcomp/expr.h
vendored
85
src/3rdparty/xkbcommon/src/xkbcomp/expr.h
vendored
@ -1,85 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#ifndef XKBCOMP_EXPR_H
|
||||
#define XKBCOMP_EXPR_H
|
||||
|
||||
bool
|
||||
ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr,
|
||||
const char **elem_rtrn, const char **field_rtrn,
|
||||
ExprDef **index_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveModMask(struct xkb_context *ctx, const ExprDef *expr,
|
||||
enum mod_type mod_type, const struct xkb_mod_set *mods,
|
||||
xkb_mod_mask_t *mask_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveMod(struct xkb_context *ctx, const ExprDef *def,
|
||||
enum mod_type mod_type, const struct xkb_mod_set *mods,
|
||||
xkb_mod_index_t *ndx_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
|
||||
bool *set_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_keycode_t *kc);
|
||||
|
||||
bool
|
||||
ExprResolveInteger(struct xkb_context *ctx, const ExprDef *expr,
|
||||
int *val_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_level_index_t *level_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveGroup(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_layout_index_t *group_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr,
|
||||
int *btn_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_atom_t *val_rtrn);
|
||||
|
||||
bool
|
||||
ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr,
|
||||
unsigned int *val_rtrn, const LookupEntry *values);
|
||||
|
||||
bool
|
||||
ExprResolveMask(struct xkb_context *ctx, const ExprDef *expr,
|
||||
unsigned int *mask_rtrn, const LookupEntry *values);
|
||||
|
||||
bool
|
||||
ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
|
||||
xkb_keysym_t *sym_rtrn);
|
||||
|
||||
#endif
|
309
src/3rdparty/xkbcommon/src/xkbcomp/include.c
vendored
309
src/3rdparty/xkbcommon/src/xkbcomp/include.c
vendored
@ -1,309 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "include.h"
|
||||
|
||||
/**
|
||||
* Parse an include statement. Each call returns a file name, along with
|
||||
* (possibly) a specific map in the file, an explicit group designator, and
|
||||
* the separator from the next file, used to determine the merge mode.
|
||||
*
|
||||
* @param str_inout Input statement, modified in-place. Should be passed in
|
||||
* repeatedly. If str_inout is NULL, the parsing has completed.
|
||||
*
|
||||
* @param file_rtrn Set to the name of the include file to be used. Combined
|
||||
* with an enum xkb_file_type, this determines which file to look for in the
|
||||
* include path.
|
||||
*
|
||||
* @param map_rtrn Set to the string between '(' and ')', if any. This will
|
||||
* result in the compilation of a specific named map within the file (e.g.
|
||||
* xkb_symbols "basic" { ... }) , as opposed to the default map of the file.
|
||||
*
|
||||
* @param nextop_rtrn Set to the next operation in the complete statement,
|
||||
* which is '\0' if it's the last file or '+' or '|' if there are more.
|
||||
* Separating the files with '+' sets the merge mode to MERGE_MODE_OVERRIDE,
|
||||
* while '|' sets the merge mode to MERGE_MODE_AUGMENT.
|
||||
*
|
||||
* @param extra_data Set to the string after ':', if any. Currently the
|
||||
* extra data is only used for setting an explicit group index for a symbols
|
||||
* file.
|
||||
*
|
||||
* @return true if parsing was successful, false for an illegal string.
|
||||
*
|
||||
* Example: "evdev+aliases(qwerty):2"
|
||||
* str_inout = "aliases(qwerty):2"
|
||||
* file_rtrn = "evdev"
|
||||
* map_rtrn = NULL
|
||||
* nextop_retrn = "+"
|
||||
* extra_data = NULL
|
||||
*
|
||||
* 2nd run with "aliases(qwerty):2"
|
||||
* str_inout = NULL
|
||||
* file_rtrn = "aliases"
|
||||
* map_rtrn = "qwerty"
|
||||
* nextop_retrn = ""
|
||||
* extra_data = "2"
|
||||
*
|
||||
*/
|
||||
bool
|
||||
ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
|
||||
char *nextop_rtrn, char **extra_data)
|
||||
{
|
||||
char *tmp, *str, *next;
|
||||
|
||||
str = *str_inout;
|
||||
|
||||
/*
|
||||
* Find the position in the string where the next file is included,
|
||||
* if there is more than one left in the statement.
|
||||
*/
|
||||
next = strpbrk(str, "|+");
|
||||
if (next) {
|
||||
/* Got more files, this function will be called again. */
|
||||
*nextop_rtrn = *next;
|
||||
/* Separate the string, for strchr etc. to work on this file only. */
|
||||
*next++ = '\0';
|
||||
}
|
||||
else {
|
||||
/* This is the last file in this statement, won't be called again. */
|
||||
*nextop_rtrn = '\0';
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for the explicit group designator, if any. If it's there,
|
||||
* it goes after the file name and map.
|
||||
*/
|
||||
tmp = strchr(str, ':');
|
||||
if (tmp != NULL) {
|
||||
*tmp++ = '\0';
|
||||
*extra_data = strdup(tmp);
|
||||
}
|
||||
else {
|
||||
*extra_data = NULL;
|
||||
}
|
||||
|
||||
/* Look for a map, if any. */
|
||||
tmp = strchr(str, '(');
|
||||
if (tmp == NULL) {
|
||||
/* No map. */
|
||||
*file_rtrn = strdup(str);
|
||||
*map_rtrn = NULL;
|
||||
}
|
||||
else if (str[0] == '(') {
|
||||
/* Map without file - invalid. */
|
||||
free(*extra_data);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
/* Got a map; separate the file and the map for the strdup's. */
|
||||
*tmp++ = '\0';
|
||||
*file_rtrn = strdup(str);
|
||||
str = tmp;
|
||||
tmp = strchr(str, ')');
|
||||
if (tmp == NULL || tmp[1] != '\0') {
|
||||
free(*file_rtrn);
|
||||
free(*extra_data);
|
||||
return false;
|
||||
}
|
||||
*tmp++ = '\0';
|
||||
*map_rtrn = strdup(str);
|
||||
}
|
||||
|
||||
/* Set up the next file for the next call, if any. */
|
||||
if (*nextop_rtrn == '\0')
|
||||
*str_inout = NULL;
|
||||
else if (*nextop_rtrn == '|' || *nextop_rtrn == '+')
|
||||
*str_inout = next;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *xkb_file_type_include_dirs[_FILE_TYPE_NUM_ENTRIES] = {
|
||||
[FILE_TYPE_KEYCODES] = "keycodes",
|
||||
[FILE_TYPE_TYPES] = "types",
|
||||
[FILE_TYPE_COMPAT] = "compat",
|
||||
[FILE_TYPE_SYMBOLS] = "symbols",
|
||||
[FILE_TYPE_GEOMETRY] = "geometry",
|
||||
[FILE_TYPE_KEYMAP] = "keymap",
|
||||
[FILE_TYPE_RULES] = "rules",
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the xkb directory based on the type.
|
||||
*/
|
||||
static const char *
|
||||
DirectoryForInclude(enum xkb_file_type type)
|
||||
{
|
||||
if (type >= _FILE_TYPE_NUM_ENTRIES)
|
||||
return "";
|
||||
return xkb_file_type_include_dirs[type];
|
||||
}
|
||||
|
||||
FILE *
|
||||
FindFileInXkbPath(struct xkb_context *ctx, const char *name,
|
||||
enum xkb_file_type type, char **pathRtrn)
|
||||
{
|
||||
unsigned int i;
|
||||
FILE *file = NULL;
|
||||
char *buf = NULL;
|
||||
const char *typeDir;
|
||||
size_t buf_size = 0, typeDirLen, name_len;
|
||||
|
||||
typeDir = DirectoryForInclude(type);
|
||||
typeDirLen = strlen(typeDir);
|
||||
name_len = strlen(name);
|
||||
|
||||
for (i = 0; i < xkb_context_num_include_paths(ctx); i++) {
|
||||
size_t new_buf_size = strlen(xkb_context_include_path_get(ctx, i)) +
|
||||
typeDirLen + name_len + 3;
|
||||
int ret;
|
||||
if (new_buf_size > buf_size) {
|
||||
void *buf_new = realloc(buf, new_buf_size);
|
||||
if (buf_new) {
|
||||
buf_size = new_buf_size;
|
||||
buf = buf_new;
|
||||
} else {
|
||||
log_err(ctx, "Cannot realloc for name (%s/%s/%s)\n",
|
||||
xkb_context_include_path_get(ctx, i), typeDir, name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ret = snprintf(buf, buf_size, "%s/%s/%s",
|
||||
xkb_context_include_path_get(ctx, i),
|
||||
typeDir, name);
|
||||
if (ret < 0) {
|
||||
log_err(ctx, "snprintf error (%s/%s/%s)\n",
|
||||
xkb_context_include_path_get(ctx, i), typeDir, name);
|
||||
continue;
|
||||
}
|
||||
|
||||
file = fopen(buf, "r");
|
||||
if (file)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
log_err(ctx, "Couldn't find file \"%s/%s\" in include paths\n",
|
||||
typeDir, name);
|
||||
|
||||
if (xkb_context_num_include_paths(ctx) > 0) {
|
||||
log_err(ctx, "%d include paths searched:\n",
|
||||
xkb_context_num_include_paths(ctx));
|
||||
for (i = 0; i < xkb_context_num_include_paths(ctx); i++)
|
||||
log_err(ctx, "\t%s\n",
|
||||
xkb_context_include_path_get(ctx, i));
|
||||
}
|
||||
else {
|
||||
log_err(ctx, "There are no include paths to search\n");
|
||||
}
|
||||
|
||||
if (xkb_context_num_failed_include_paths(ctx) > 0) {
|
||||
log_err(ctx, "%d include paths could not be added:\n",
|
||||
xkb_context_num_failed_include_paths(ctx));
|
||||
for (i = 0; i < xkb_context_num_failed_include_paths(ctx); i++)
|
||||
log_err(ctx, "\t%s\n",
|
||||
xkb_context_failed_include_path_get(ctx, i));
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pathRtrn)
|
||||
*pathRtrn = buf;
|
||||
else
|
||||
free(buf);
|
||||
return file;
|
||||
}
|
||||
|
||||
XkbFile *
|
||||
ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
|
||||
enum xkb_file_type file_type)
|
||||
{
|
||||
FILE *file;
|
||||
XkbFile *xkb_file;
|
||||
|
||||
file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
xkb_file = XkbParseFile(ctx, file, stmt->file, stmt->map);
|
||||
fclose(file);
|
||||
if (!xkb_file) {
|
||||
if (stmt->map)
|
||||
log_err(ctx, "Couldn't process include statement for '%s(%s)'\n",
|
||||
stmt->file, stmt->map);
|
||||
else
|
||||
log_err(ctx, "Couldn't process include statement for '%s'\n",
|
||||
stmt->file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xkb_file->file_type != file_type) {
|
||||
log_err(ctx,
|
||||
"Include file of wrong type (expected %s, got %s); "
|
||||
"Include file \"%s\" ignored\n",
|
||||
xkb_file_type_to_string(file_type),
|
||||
xkb_file_type_to_string(xkb_file->file_type), stmt->file);
|
||||
FreeXkbFile(xkb_file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* FIXME: we have to check recursive includes here (or somewhere) */
|
||||
|
||||
return xkb_file;
|
||||
}
|
42
src/3rdparty/xkbcommon/src/xkbcomp/include.h
vendored
42
src/3rdparty/xkbcommon/src/xkbcomp/include.h
vendored
@ -1,42 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#ifndef XKBCOMP_INCLUDE_H
|
||||
#define XKBCOMP_INCLUDE_H
|
||||
|
||||
bool
|
||||
ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
|
||||
char *nextop_rtrn, char **extra_data);
|
||||
|
||||
FILE *
|
||||
FindFileInXkbPath(struct xkb_context *ctx, const char *name,
|
||||
enum xkb_file_type type, char **pathRtrn);
|
||||
|
||||
XkbFile *
|
||||
ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
|
||||
enum xkb_file_type file_type);
|
||||
|
||||
#endif
|
668
src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
vendored
668
src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
vendored
@ -1,668 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "text.h"
|
||||
#include "expr.h"
|
||||
#include "include.h"
|
||||
|
||||
typedef struct {
|
||||
enum merge_mode merge;
|
||||
|
||||
xkb_atom_t alias;
|
||||
xkb_atom_t real;
|
||||
} AliasInfo;
|
||||
|
||||
typedef struct {
|
||||
enum merge_mode merge;
|
||||
|
||||
xkb_atom_t name;
|
||||
} LedNameInfo;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int errorCount;
|
||||
|
||||
xkb_keycode_t min_key_code;
|
||||
xkb_keycode_t max_key_code;
|
||||
darray(xkb_atom_t) key_names;
|
||||
LedNameInfo led_names[XKB_MAX_LEDS];
|
||||
unsigned int num_led_names;
|
||||
darray(AliasInfo) aliases;
|
||||
|
||||
struct xkb_context *ctx;
|
||||
} KeyNamesInfo;
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static void
|
||||
InitAliasInfo(AliasInfo *info, enum merge_mode merge,
|
||||
xkb_atom_t alias, xkb_atom_t real)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->merge = merge;
|
||||
info->alias = alias;
|
||||
info->real = real;
|
||||
}
|
||||
|
||||
static LedNameInfo *
|
||||
FindLedByName(KeyNamesInfo *info, xkb_atom_t name,
|
||||
xkb_led_index_t *idx_out)
|
||||
{
|
||||
for (xkb_led_index_t idx = 0; idx < info->num_led_names; idx++) {
|
||||
LedNameInfo *ledi = &info->led_names[idx];
|
||||
if (ledi->name == name) {
|
||||
*idx_out = idx;
|
||||
return ledi;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
AddLedName(KeyNamesInfo *info, enum merge_mode merge, bool same_file,
|
||||
LedNameInfo *new, xkb_led_index_t new_idx)
|
||||
{
|
||||
xkb_led_index_t old_idx;
|
||||
LedNameInfo *old;
|
||||
const int verbosity = xkb_context_get_log_verbosity(info->ctx);
|
||||
const bool report = (same_file && verbosity > 0) || verbosity > 9;
|
||||
const bool replace = (merge == MERGE_REPLACE || merge == MERGE_OVERRIDE);
|
||||
|
||||
/* LED with the same name already exists. */
|
||||
old = FindLedByName(info, new->name, &old_idx);
|
||||
if (old) {
|
||||
if (old_idx == new_idx) {
|
||||
log_warn(info->ctx,
|
||||
"Multiple indicators named \"%s\"; "
|
||||
"Identical definitions ignored\n",
|
||||
xkb_atom_text(info->ctx, new->name));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (report) {
|
||||
xkb_led_index_t use = (replace ? new_idx + 1 : old_idx + 1);
|
||||
xkb_led_index_t ignore = (replace ? old_idx + 1 : new_idx + 1);
|
||||
log_warn(info->ctx,
|
||||
"Multiple indicators named %s; Using %d, ignoring %d\n",
|
||||
xkb_atom_text(info->ctx, new->name), use, ignore);
|
||||
}
|
||||
|
||||
if (replace)
|
||||
*old = *new;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (new_idx >= info->num_led_names)
|
||||
info->num_led_names = new_idx + 1;
|
||||
|
||||
/* LED with the same index already exists. */
|
||||
old = &info->led_names[new_idx];
|
||||
if (old->name != XKB_ATOM_NONE) {
|
||||
if (report) {
|
||||
const xkb_atom_t use = (replace ? new->name : old->name);
|
||||
const xkb_atom_t ignore = (replace ? old->name : new->name);
|
||||
log_warn(info->ctx, "Multiple names for indicator %d; "
|
||||
"Using %s, ignoring %s\n", new_idx + 1,
|
||||
xkb_atom_text(info->ctx, use),
|
||||
xkb_atom_text(info->ctx, ignore));
|
||||
}
|
||||
|
||||
if (replace)
|
||||
*old = *new;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
*old = *new;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearKeyNamesInfo(KeyNamesInfo *info)
|
||||
{
|
||||
free(info->name);
|
||||
darray_free(info->key_names);
|
||||
darray_free(info->aliases);
|
||||
}
|
||||
|
||||
static void
|
||||
InitKeyNamesInfo(KeyNamesInfo *info, struct xkb_context *ctx)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->ctx = ctx;
|
||||
info->min_key_code = XKB_KEYCODE_INVALID;
|
||||
#if XKB_KEYCODE_INVALID < XKB_KEYCODE_MAX
|
||||
#error "Hey, you can't be changing stuff like that."
|
||||
#endif
|
||||
}
|
||||
|
||||
static xkb_keycode_t
|
||||
FindKeyByName(KeyNamesInfo *info, xkb_atom_t name)
|
||||
{
|
||||
xkb_keycode_t i;
|
||||
|
||||
for (i = info->min_key_code; i <= info->max_key_code; i++)
|
||||
if (darray_item(info->key_names, i) == name)
|
||||
return i;
|
||||
|
||||
return XKB_KEYCODE_INVALID;
|
||||
}
|
||||
|
||||
static bool
|
||||
AddKeyName(KeyNamesInfo *info, xkb_keycode_t kc, xkb_atom_t name,
|
||||
enum merge_mode merge, bool same_file, bool report)
|
||||
{
|
||||
xkb_atom_t old_name;
|
||||
xkb_keycode_t old_kc;
|
||||
const int verbosity = xkb_context_get_log_verbosity(info->ctx);
|
||||
|
||||
report = report && ((same_file && verbosity > 0) || verbosity > 7);
|
||||
|
||||
if (kc >= darray_size(info->key_names))
|
||||
darray_resize0(info->key_names, kc + 1);
|
||||
|
||||
info->min_key_code = MIN(info->min_key_code, kc);
|
||||
info->max_key_code = MAX(info->max_key_code, kc);
|
||||
|
||||
/* There's already a key with this keycode. */
|
||||
old_name = darray_item(info->key_names, kc);
|
||||
if (old_name != XKB_ATOM_NONE) {
|
||||
const char *lname = KeyNameText(info->ctx, old_name);
|
||||
const char *kname = KeyNameText(info->ctx, name);
|
||||
|
||||
if (old_name == name) {
|
||||
if (report)
|
||||
log_warn(info->ctx,
|
||||
"Multiple identical key name definitions; "
|
||||
"Later occurrences of \"%s = %d\" ignored\n",
|
||||
lname, kc);
|
||||
return true;
|
||||
}
|
||||
else if (merge == MERGE_AUGMENT) {
|
||||
if (report)
|
||||
log_warn(info->ctx,
|
||||
"Multiple names for keycode %d; "
|
||||
"Using %s, ignoring %s\n", kc, lname, kname);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (report)
|
||||
log_warn(info->ctx,
|
||||
"Multiple names for keycode %d; "
|
||||
"Using %s, ignoring %s\n", kc, kname, lname);
|
||||
darray_item(info->key_names, kc) = XKB_ATOM_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/* There's already a key with this name. */
|
||||
old_kc = FindKeyByName(info, name);
|
||||
if (old_kc != XKB_KEYCODE_INVALID && old_kc != kc) {
|
||||
const char *kname = KeyNameText(info->ctx, name);
|
||||
|
||||
if (merge == MERGE_OVERRIDE) {
|
||||
darray_item(info->key_names, old_kc) = XKB_ATOM_NONE;
|
||||
if (report)
|
||||
log_warn(info->ctx,
|
||||
"Key name %s assigned to multiple keys; "
|
||||
"Using %d, ignoring %d\n", kname, kc, old_kc);
|
||||
}
|
||||
else {
|
||||
if (report)
|
||||
log_vrb(info->ctx, 3,
|
||||
"Key name %s assigned to multiple keys; "
|
||||
"Using %d, ignoring %d\n", kname, old_kc, kc);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
darray_item(info->key_names, kc) = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge);
|
||||
|
||||
static void
|
||||
MergeIncludedKeycodes(KeyNamesInfo *into, KeyNamesInfo *from,
|
||||
enum merge_mode merge)
|
||||
{
|
||||
if (from->errorCount > 0) {
|
||||
into->errorCount += from->errorCount;
|
||||
return;
|
||||
}
|
||||
|
||||
if (into->name == NULL) {
|
||||
into->name = from->name;
|
||||
from->name = NULL;
|
||||
}
|
||||
|
||||
/* Merge key names. */
|
||||
if (darray_empty(into->key_names)) {
|
||||
into->key_names = from->key_names;
|
||||
darray_init(from->key_names);
|
||||
into->min_key_code = from->min_key_code;
|
||||
into->max_key_code = from->max_key_code;
|
||||
}
|
||||
else {
|
||||
if (darray_size(into->key_names) < darray_size(from->key_names))
|
||||
darray_resize0(into->key_names, darray_size(from->key_names));
|
||||
|
||||
for (unsigned i = from->min_key_code; i <= from->max_key_code; i++) {
|
||||
xkb_atom_t name = darray_item(from->key_names, i);
|
||||
if (name == XKB_ATOM_NONE)
|
||||
continue;
|
||||
|
||||
if (!AddKeyName(into, i, name, merge, true, false))
|
||||
into->errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge key aliases. */
|
||||
if (darray_empty(into->aliases)) {
|
||||
into->aliases = from->aliases;
|
||||
darray_init(from->aliases);
|
||||
}
|
||||
else {
|
||||
AliasInfo *alias;
|
||||
|
||||
darray_foreach(alias, from->aliases) {
|
||||
KeyAliasDef def;
|
||||
|
||||
def.merge = (merge == MERGE_DEFAULT ? alias->merge : merge);
|
||||
def.alias = alias->alias;
|
||||
def.real = alias->real;
|
||||
|
||||
if (!HandleAliasDef(into, &def, def.merge))
|
||||
into->errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge LED names. */
|
||||
if (into->num_led_names == 0) {
|
||||
memcpy(into->led_names, from->led_names,
|
||||
sizeof(*from->led_names) * from->num_led_names);
|
||||
into->num_led_names = from->num_led_names;
|
||||
from->num_led_names = 0;
|
||||
}
|
||||
else {
|
||||
for (xkb_led_index_t idx = 0; idx < from->num_led_names; idx++) {
|
||||
LedNameInfo *ledi = &from->led_names[idx];
|
||||
|
||||
if (ledi->name == XKB_ATOM_NONE)
|
||||
continue;
|
||||
|
||||
ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge);
|
||||
if (!AddLedName(into, ledi->merge, false, ledi, idx))
|
||||
into->errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge);
|
||||
|
||||
static bool
|
||||
HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *include)
|
||||
{
|
||||
KeyNamesInfo included;
|
||||
|
||||
InitKeyNamesInfo(&included, info->ctx);
|
||||
included.name = include->stmt;
|
||||
include->stmt = NULL;
|
||||
|
||||
for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
|
||||
KeyNamesInfo next_incl;
|
||||
XkbFile *file;
|
||||
|
||||
file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_KEYCODES);
|
||||
if (!file) {
|
||||
info->errorCount += 10;
|
||||
ClearKeyNamesInfo(&included);
|
||||
return false;
|
||||
}
|
||||
|
||||
InitKeyNamesInfo(&next_incl, info->ctx);
|
||||
|
||||
HandleKeycodesFile(&next_incl, file, MERGE_OVERRIDE);
|
||||
|
||||
MergeIncludedKeycodes(&included, &next_incl, stmt->merge);
|
||||
|
||||
ClearKeyNamesInfo(&next_incl);
|
||||
FreeXkbFile(file);
|
||||
}
|
||||
|
||||
MergeIncludedKeycodes(info, &included, include->merge);
|
||||
ClearKeyNamesInfo(&included);
|
||||
|
||||
return (info->errorCount == 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleKeycodeDef(KeyNamesInfo *info, KeycodeDef *stmt, enum merge_mode merge)
|
||||
{
|
||||
if (stmt->merge != MERGE_DEFAULT) {
|
||||
if (stmt->merge == MERGE_REPLACE)
|
||||
merge = MERGE_OVERRIDE;
|
||||
else
|
||||
merge = stmt->merge;
|
||||
}
|
||||
|
||||
if (stmt->value < 0 || stmt->value > XKB_KEYCODE_MAX) {
|
||||
log_err(info->ctx,
|
||||
"Illegal keycode %lld: must be between 0..%u; "
|
||||
"Key ignored\n", (long long) stmt->value, XKB_KEYCODE_MAX);
|
||||
return false;
|
||||
}
|
||||
|
||||
return AddKeyName(info, stmt->value, stmt->name, merge, false, true);
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge)
|
||||
{
|
||||
AliasInfo *old, new;
|
||||
|
||||
darray_foreach(old, info->aliases) {
|
||||
if (old->alias == def->alias) {
|
||||
if (def->real == old->real) {
|
||||
log_vrb(info->ctx, 1,
|
||||
"Alias of %s for %s declared more than once; "
|
||||
"First definition ignored\n",
|
||||
KeyNameText(info->ctx, def->alias),
|
||||
KeyNameText(info->ctx, def->real));
|
||||
}
|
||||
else {
|
||||
xkb_atom_t use, ignore;
|
||||
|
||||
use = (merge == MERGE_AUGMENT ? old->real : def->real);
|
||||
ignore = (merge == MERGE_AUGMENT ? def->real : old->real);
|
||||
|
||||
log_warn(info->ctx,
|
||||
"Multiple definitions for alias %s; "
|
||||
"Using %s, ignoring %s\n",
|
||||
KeyNameText(info->ctx, old->alias),
|
||||
KeyNameText(info->ctx, use),
|
||||
KeyNameText(info->ctx, ignore));
|
||||
|
||||
old->real = use;
|
||||
}
|
||||
|
||||
old->merge = merge;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
InitAliasInfo(&new, merge, def->alias, def->real);
|
||||
darray_append(info->aliases, new);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt)
|
||||
{
|
||||
const char *elem, *field;
|
||||
ExprDef *arrayNdx;
|
||||
|
||||
if (!ExprResolveLhs(info->ctx, stmt->name, &elem, &field, &arrayNdx))
|
||||
return false;
|
||||
|
||||
if (elem) {
|
||||
log_err(info->ctx, "Unknown element %s encountered; "
|
||||
"Default for field %s ignored\n", elem, field);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!istreq(field, "minimum") && !istreq(field, "maximum")) {
|
||||
log_err(info->ctx, "Unknown field encountered; "
|
||||
"Assignment to field %s ignored\n", field);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We ignore explicit min/max statements, we always use computed. */
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleLedNameDef(KeyNamesInfo *info, LedNameDef *def,
|
||||
enum merge_mode merge)
|
||||
{
|
||||
LedNameInfo ledi;
|
||||
xkb_atom_t name;
|
||||
|
||||
if (def->ndx < 1 || def->ndx > XKB_MAX_LEDS) {
|
||||
info->errorCount++;
|
||||
log_err(info->ctx,
|
||||
"Illegal indicator index (%d) specified; must be between 1 .. %d; "
|
||||
"Ignored\n", def->ndx, XKB_MAX_LEDS);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ExprResolveString(info->ctx, def->name, &name)) {
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "%u", def->ndx);
|
||||
info->errorCount++;
|
||||
return ReportBadType(info->ctx, "indicator", "name", buf, "string");
|
||||
}
|
||||
|
||||
ledi.merge = merge;
|
||||
ledi.name = name;
|
||||
return AddLedName(info, merge, true, &ledi, def->ndx - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
free(info->name);
|
||||
info->name = strdup_safe(file->name);
|
||||
|
||||
for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
|
||||
switch (stmt->type) {
|
||||
case STMT_INCLUDE:
|
||||
ok = HandleIncludeKeycodes(info, (IncludeStmt *) stmt);
|
||||
break;
|
||||
case STMT_KEYCODE:
|
||||
ok = HandleKeycodeDef(info, (KeycodeDef *) stmt, merge);
|
||||
break;
|
||||
case STMT_ALIAS:
|
||||
ok = HandleAliasDef(info, (KeyAliasDef *) stmt, merge);
|
||||
break;
|
||||
case STMT_VAR:
|
||||
ok = HandleKeyNameVar(info, (VarDef *) stmt);
|
||||
break;
|
||||
case STMT_LED_NAME:
|
||||
ok = HandleLedNameDef(info, (LedNameDef *) stmt, merge);
|
||||
break;
|
||||
default:
|
||||
log_err(info->ctx,
|
||||
"Keycode files may define key and indicator names only; "
|
||||
"Ignoring %s\n", stmt_type_to_string(stmt->type));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
info->errorCount++;
|
||||
|
||||
if (info->errorCount > 10) {
|
||||
log_err(info->ctx, "Abandoning keycodes file \"%s\"\n",
|
||||
file->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
|
||||
{
|
||||
struct xkb_key *keys;
|
||||
xkb_keycode_t min_key_code, max_key_code, kc;
|
||||
|
||||
min_key_code = info->min_key_code;
|
||||
max_key_code = info->max_key_code;
|
||||
/* If the keymap has no keys, let's just use the safest pair we know. */
|
||||
if (min_key_code == XKB_KEYCODE_INVALID) {
|
||||
min_key_code = 8;
|
||||
max_key_code = 255;
|
||||
}
|
||||
|
||||
keys = calloc(max_key_code + 1, sizeof(*keys));
|
||||
if (!keys)
|
||||
return false;
|
||||
|
||||
for (kc = min_key_code; kc <= max_key_code; kc++)
|
||||
keys[kc].keycode = kc;
|
||||
|
||||
for (kc = info->min_key_code; kc <= info->max_key_code; kc++)
|
||||
keys[kc].name = darray_item(info->key_names, kc);
|
||||
|
||||
keymap->min_key_code = min_key_code;
|
||||
keymap->max_key_code = max_key_code;
|
||||
keymap->keys = keys;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CopyKeyAliasesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
|
||||
{
|
||||
AliasInfo *alias;
|
||||
unsigned i, num_key_aliases;
|
||||
struct xkb_key_alias *key_aliases;
|
||||
|
||||
/*
|
||||
* Do some sanity checking on the aliases. We can't do it before
|
||||
* because keys and their aliases may be added out-of-order.
|
||||
*/
|
||||
num_key_aliases = 0;
|
||||
darray_foreach(alias, info->aliases) {
|
||||
/* Check that ->real is a key. */
|
||||
if (!XkbKeyByName(keymap, alias->real, false)) {
|
||||
log_vrb(info->ctx, 5,
|
||||
"Attempt to alias %s to non-existent key %s; Ignored\n",
|
||||
KeyNameText(info->ctx, alias->alias),
|
||||
KeyNameText(info->ctx, alias->real));
|
||||
alias->real = XKB_ATOM_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check that ->alias is not a key. */
|
||||
if (XkbKeyByName(keymap, alias->alias, false)) {
|
||||
log_vrb(info->ctx, 5,
|
||||
"Attempt to create alias with the name of a real key; "
|
||||
"Alias \"%s = %s\" ignored\n",
|
||||
KeyNameText(info->ctx, alias->alias),
|
||||
KeyNameText(info->ctx, alias->real));
|
||||
alias->real = XKB_ATOM_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
num_key_aliases++;
|
||||
}
|
||||
|
||||
/* Copy key aliases. */
|
||||
key_aliases = NULL;
|
||||
if (num_key_aliases > 0) {
|
||||
key_aliases = calloc(num_key_aliases, sizeof(*key_aliases));
|
||||
if (!key_aliases)
|
||||
return false;
|
||||
|
||||
i = 0;
|
||||
darray_foreach(alias, info->aliases) {
|
||||
if (alias->real != XKB_ATOM_NONE) {
|
||||
key_aliases[i].alias = alias->alias;
|
||||
key_aliases[i].real = alias->real;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keymap->num_key_aliases = num_key_aliases;
|
||||
keymap->key_aliases = key_aliases;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CopyLedNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
|
||||
{
|
||||
keymap->num_leds = info->num_led_names;
|
||||
for (xkb_led_index_t idx = 0; idx < info->num_led_names; idx++) {
|
||||
LedNameInfo *ledi = &info->led_names[idx];
|
||||
|
||||
if (ledi->name == XKB_ATOM_NONE)
|
||||
continue;
|
||||
|
||||
keymap->leds[idx].name = ledi->name;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CopyKeyNamesInfoToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
|
||||
{
|
||||
/* This function trashes keymap on error, but that's OK. */
|
||||
if (!CopyKeyNamesToKeymap(keymap, info) ||
|
||||
!CopyKeyAliasesToKeymap(keymap, info) ||
|
||||
!CopyLedNamesToKeymap(keymap, info))
|
||||
return false;
|
||||
|
||||
keymap->keycodes_section_name = strdup_safe(info->name);
|
||||
XkbEscapeMapName(keymap->keycodes_section_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
bool
|
||||
CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap,
|
||||
enum merge_mode merge)
|
||||
{
|
||||
KeyNamesInfo info;
|
||||
|
||||
InitKeyNamesInfo(&info, keymap->ctx);
|
||||
|
||||
HandleKeycodesFile(&info, file, merge);
|
||||
if (info.errorCount != 0)
|
||||
goto err_info;
|
||||
|
||||
if (!CopyKeyNamesInfoToKeymap(keymap, &info))
|
||||
goto err_info;
|
||||
|
||||
ClearKeyNamesInfo(&info);
|
||||
return true;
|
||||
|
||||
err_info:
|
||||
ClearKeyNamesInfo(&info);
|
||||
return false;
|
||||
}
|
664
src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
vendored
664
src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
vendored
@ -1,664 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "text.h"
|
||||
|
||||
#define BUF_CHUNK_SIZE 4096
|
||||
|
||||
struct buf {
|
||||
char *buf;
|
||||
size_t size;
|
||||
size_t alloc;
|
||||
};
|
||||
|
||||
static bool
|
||||
do_realloc(struct buf *buf, size_t at_least)
|
||||
{
|
||||
char *new;
|
||||
|
||||
buf->alloc += BUF_CHUNK_SIZE;
|
||||
if (at_least >= BUF_CHUNK_SIZE)
|
||||
buf->alloc += at_least;
|
||||
|
||||
new = realloc(buf->buf, buf->alloc);
|
||||
if (!new)
|
||||
return false;
|
||||
|
||||
buf->buf = new;
|
||||
return true;
|
||||
}
|
||||
|
||||
ATTR_PRINTF(2, 3) static bool
|
||||
check_write_buf(struct buf *buf, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int printed;
|
||||
size_t available;
|
||||
|
||||
available = buf->alloc - buf->size;
|
||||
va_start(args, fmt);
|
||||
printed = vsnprintf(buf->buf + buf->size, available, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (printed < 0)
|
||||
goto err;
|
||||
|
||||
if ((size_t) printed >= available)
|
||||
if (!do_realloc(buf, printed))
|
||||
goto err;
|
||||
|
||||
/* The buffer has enough space now. */
|
||||
|
||||
available = buf->alloc - buf->size;
|
||||
va_start(args, fmt);
|
||||
printed = vsnprintf(buf->buf + buf->size, available, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (printed < 0 || (size_t) printed >= available)
|
||||
goto err;
|
||||
|
||||
buf->size += printed;
|
||||
return true;
|
||||
|
||||
err:
|
||||
free(buf->buf);
|
||||
buf->buf = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#define write_buf(buf, ...) do { \
|
||||
if (!check_write_buf(buf, __VA_ARGS__)) \
|
||||
return false; \
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
write_vmods(struct xkb_keymap *keymap, struct buf *buf)
|
||||
{
|
||||
const struct xkb_mod *mod;
|
||||
xkb_mod_index_t num_vmods = 0;
|
||||
|
||||
xkb_mods_foreach(mod, &keymap->mods) {
|
||||
if (mod->type != MOD_VIRT)
|
||||
continue;
|
||||
|
||||
if (num_vmods == 0)
|
||||
write_buf(buf, "\tvirtual_modifiers ");
|
||||
else
|
||||
write_buf(buf, ",");
|
||||
write_buf(buf, "%s", xkb_atom_text(keymap->ctx, mod->name));
|
||||
num_vmods++;
|
||||
}
|
||||
|
||||
if (num_vmods > 0)
|
||||
write_buf(buf, ";\n\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
write_keycodes(struct xkb_keymap *keymap, struct buf *buf)
|
||||
{
|
||||
const struct xkb_key *key;
|
||||
xkb_led_index_t idx;
|
||||
const struct xkb_led *led;
|
||||
|
||||
if (keymap->keycodes_section_name)
|
||||
write_buf(buf, "xkb_keycodes \"%s\" {\n",
|
||||
keymap->keycodes_section_name);
|
||||
else
|
||||
write_buf(buf, "xkb_keycodes {\n");
|
||||
|
||||
/* xkbcomp and X11 really want to see keymaps with a minimum of 8, and
|
||||
* a maximum of at least 255, else XWayland really starts hating life.
|
||||
* If this is a problem and people really need strictly bounded keymaps,
|
||||
* we should probably control this with a flag. */
|
||||
write_buf(buf, "\tminimum = %u;\n", min(keymap->min_key_code, 8));
|
||||
write_buf(buf, "\tmaximum = %u;\n", max(keymap->max_key_code, 255));
|
||||
|
||||
xkb_keys_foreach(key, keymap) {
|
||||
if (key->name == XKB_ATOM_NONE)
|
||||
continue;
|
||||
|
||||
write_buf(buf, "\t%-20s = %u;\n",
|
||||
KeyNameText(keymap->ctx, key->name), key->keycode);
|
||||
}
|
||||
|
||||
xkb_leds_enumerate(idx, led, keymap)
|
||||
if (led->name != XKB_ATOM_NONE)
|
||||
write_buf(buf, "\tindicator %u = \"%s\";\n",
|
||||
idx + 1, xkb_atom_text(keymap->ctx, led->name));
|
||||
|
||||
|
||||
for (unsigned i = 0; i < keymap->num_key_aliases; i++)
|
||||
write_buf(buf, "\talias %-14s = %s;\n",
|
||||
KeyNameText(keymap->ctx, keymap->key_aliases[i].alias),
|
||||
KeyNameText(keymap->ctx, keymap->key_aliases[i].real));
|
||||
|
||||
write_buf(buf, "};\n\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
write_types(struct xkb_keymap *keymap, struct buf *buf)
|
||||
{
|
||||
if (keymap->types_section_name)
|
||||
write_buf(buf, "xkb_types \"%s\" {\n",
|
||||
keymap->types_section_name);
|
||||
else
|
||||
write_buf(buf, "xkb_types {\n");
|
||||
|
||||
write_vmods(keymap, buf);
|
||||
|
||||
for (unsigned i = 0; i < keymap->num_types; i++) {
|
||||
const struct xkb_key_type *type = &keymap->types[i];
|
||||
|
||||
write_buf(buf, "\ttype \"%s\" {\n",
|
||||
xkb_atom_text(keymap->ctx, type->name));
|
||||
|
||||
write_buf(buf, "\t\tmodifiers= %s;\n",
|
||||
ModMaskText(keymap->ctx, &keymap->mods, type->mods.mods));
|
||||
|
||||
for (unsigned j = 0; j < type->num_entries; j++) {
|
||||
const char *str;
|
||||
const struct xkb_key_type_entry *entry = &type->entries[j];
|
||||
|
||||
/*
|
||||
* Printing level 1 entries is redundant, it's the default,
|
||||
* unless there's preserve info.
|
||||
*/
|
||||
if (entry->level == 0 && entry->preserve.mods == 0)
|
||||
continue;
|
||||
|
||||
str = ModMaskText(keymap->ctx, &keymap->mods, entry->mods.mods);
|
||||
write_buf(buf, "\t\tmap[%s]= Level%u;\n",
|
||||
str, entry->level + 1);
|
||||
|
||||
if (entry->preserve.mods)
|
||||
write_buf(buf, "\t\tpreserve[%s]= %s;\n",
|
||||
str, ModMaskText(keymap->ctx, &keymap->mods,
|
||||
entry->preserve.mods));
|
||||
}
|
||||
|
||||
for (xkb_level_index_t n = 0; n < type->num_level_names; n++)
|
||||
if (type->level_names[n])
|
||||
write_buf(buf, "\t\tlevel_name[Level%u]= \"%s\";\n", n + 1,
|
||||
xkb_atom_text(keymap->ctx, type->level_names[n]));
|
||||
|
||||
write_buf(buf, "\t};\n");
|
||||
}
|
||||
|
||||
write_buf(buf, "};\n\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
write_led_map(struct xkb_keymap *keymap, struct buf *buf,
|
||||
const struct xkb_led *led)
|
||||
{
|
||||
write_buf(buf, "\tindicator \"%s\" {\n",
|
||||
xkb_atom_text(keymap->ctx, led->name));
|
||||
|
||||
if (led->which_groups) {
|
||||
if (led->which_groups != XKB_STATE_LAYOUT_EFFECTIVE) {
|
||||
write_buf(buf, "\t\twhichGroupState= %s;\n",
|
||||
LedStateMaskText(keymap->ctx, led->which_groups));
|
||||
}
|
||||
write_buf(buf, "\t\tgroups= 0x%02x;\n",
|
||||
led->groups);
|
||||
}
|
||||
|
||||
if (led->which_mods) {
|
||||
if (led->which_mods != XKB_STATE_MODS_EFFECTIVE) {
|
||||
write_buf(buf, "\t\twhichModState= %s;\n",
|
||||
LedStateMaskText(keymap->ctx, led->which_mods));
|
||||
}
|
||||
write_buf(buf, "\t\tmodifiers= %s;\n",
|
||||
ModMaskText(keymap->ctx, &keymap->mods, led->mods.mods));
|
||||
}
|
||||
|
||||
if (led->ctrls) {
|
||||
write_buf(buf, "\t\tcontrols= %s;\n",
|
||||
ControlMaskText(keymap->ctx, led->ctrls));
|
||||
}
|
||||
|
||||
write_buf(buf, "\t};\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *
|
||||
affect_lock_text(enum xkb_action_flags flags)
|
||||
{
|
||||
switch (flags & (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) {
|
||||
case ACTION_LOCK_NO_UNLOCK:
|
||||
return ",affect=lock";
|
||||
case ACTION_LOCK_NO_LOCK:
|
||||
return ",affect=unlock";
|
||||
case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK:
|
||||
return ",affect=neither";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static bool
|
||||
write_action(struct xkb_keymap *keymap, struct buf *buf,
|
||||
const union xkb_action *action,
|
||||
const char *prefix, const char *suffix)
|
||||
{
|
||||
const char *type;
|
||||
const char *args = NULL;
|
||||
|
||||
if (!prefix)
|
||||
prefix = "";
|
||||
if (!suffix)
|
||||
suffix = "";
|
||||
|
||||
type = ActionTypeText(action->type);
|
||||
|
||||
switch (action->type) {
|
||||
case ACTION_TYPE_MOD_SET:
|
||||
case ACTION_TYPE_MOD_LATCH:
|
||||
case ACTION_TYPE_MOD_LOCK:
|
||||
if (action->mods.flags & ACTION_MODS_LOOKUP_MODMAP)
|
||||
args = "modMapMods";
|
||||
else
|
||||
args = ModMaskText(keymap->ctx, &keymap->mods,
|
||||
action->mods.mods.mods);
|
||||
write_buf(buf, "%s%s(modifiers=%s%s%s%s)%s", prefix, type, args,
|
||||
(action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "",
|
||||
(action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "",
|
||||
(action->type == ACTION_TYPE_MOD_LOCK) ? affect_lock_text(action->mods.flags) : "",
|
||||
suffix);
|
||||
break;
|
||||
|
||||
case ACTION_TYPE_GROUP_SET:
|
||||
case ACTION_TYPE_GROUP_LATCH:
|
||||
case ACTION_TYPE_GROUP_LOCK:
|
||||
write_buf(buf, "%s%s(group=%s%d%s%s)%s", prefix, type,
|
||||
(!(action->group.flags & ACTION_ABSOLUTE_SWITCH) && action->group.group > 0) ? "+" : "",
|
||||
(action->group.flags & ACTION_ABSOLUTE_SWITCH) ? action->group.group + 1 : action->group.group,
|
||||
(action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "",
|
||||
(action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "",
|
||||
suffix);
|
||||
break;
|
||||
|
||||
case ACTION_TYPE_TERMINATE:
|
||||
write_buf(buf, "%s%s()%s", prefix, type, suffix);
|
||||
break;
|
||||
|
||||
case ACTION_TYPE_PTR_MOVE:
|
||||
write_buf(buf, "%s%s(x=%s%d,y=%s%d%s)%s", prefix, type,
|
||||
(!(action->ptr.flags & ACTION_ABSOLUTE_X) && action->ptr.x >= 0) ? "+" : "",
|
||||
action->ptr.x,
|
||||
(!(action->ptr.flags & ACTION_ABSOLUTE_Y) && action->ptr.y >= 0) ? "+" : "",
|
||||
action->ptr.y,
|
||||
(action->ptr.flags & ACTION_ACCEL) ? "" : ",!accel",
|
||||
suffix);
|
||||
break;
|
||||
|
||||
case ACTION_TYPE_PTR_LOCK:
|
||||
args = affect_lock_text(action->btn.flags);
|
||||
/* fallthrough */
|
||||
case ACTION_TYPE_PTR_BUTTON:
|
||||
write_buf(buf, "%s%s(button=", prefix, type);
|
||||
if (action->btn.button > 0 && action->btn.button <= 5)
|
||||
write_buf(buf, "%d", action->btn.button);
|
||||
else
|
||||
write_buf(buf, "default");
|
||||
if (action->btn.count)
|
||||
write_buf(buf, ",count=%d", action->btn.count);
|
||||
if (args)
|
||||
write_buf(buf, "%s", args);
|
||||
write_buf(buf, ")%s", suffix);
|
||||
break;
|
||||
|
||||
case ACTION_TYPE_PTR_DEFAULT:
|
||||
write_buf(buf, "%s%s(", prefix, type);
|
||||
write_buf(buf, "affect=button,button=%s%d",
|
||||
(!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) && action->dflt.value >= 0) ? "+" : "",
|
||||
action->dflt.value);
|
||||
write_buf(buf, ")%s", suffix);
|
||||
break;
|
||||
|
||||
case ACTION_TYPE_SWITCH_VT:
|
||||
write_buf(buf, "%s%s(screen=%s%d,%ssame)%s", prefix, type,
|
||||
(!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) && action->screen.screen >= 0) ? "+" : "",
|
||||
action->screen.screen,
|
||||
(action->screen.flags & ACTION_SAME_SCREEN) ? "" : "!",
|
||||
suffix);
|
||||
break;
|
||||
|
||||
case ACTION_TYPE_CTRL_SET:
|
||||
case ACTION_TYPE_CTRL_LOCK:
|
||||
write_buf(buf, "%s%s(controls=%s%s)%s", prefix, type,
|
||||
ControlMaskText(keymap->ctx, action->ctrls.ctrls),
|
||||
(action->type == ACTION_TYPE_CTRL_LOCK) ? affect_lock_text(action->ctrls.flags) : "",
|
||||
suffix);
|
||||
break;
|
||||
|
||||
case ACTION_TYPE_NONE:
|
||||
write_buf(buf, "%sNoAction()%s", prefix, suffix);
|
||||
break;
|
||||
|
||||
default:
|
||||
write_buf(buf,
|
||||
"%s%s(type=0x%02x,data[0]=0x%02x,data[1]=0x%02x,data[2]=0x%02x,data[3]=0x%02x,data[4]=0x%02x,data[5]=0x%02x,data[6]=0x%02x)%s",
|
||||
prefix, type, action->type, action->priv.data[0],
|
||||
action->priv.data[1], action->priv.data[2],
|
||||
action->priv.data[3], action->priv.data[4],
|
||||
action->priv.data[5], action->priv.data[6],
|
||||
suffix);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
write_compat(struct xkb_keymap *keymap, struct buf *buf)
|
||||
{
|
||||
const struct xkb_led *led;
|
||||
|
||||
if (keymap->compat_section_name)
|
||||
write_buf(buf, "xkb_compatibility \"%s\" {\n",
|
||||
keymap->compat_section_name);
|
||||
else
|
||||
write_buf(buf, "xkb_compatibility {\n");
|
||||
|
||||
write_vmods(keymap, buf);
|
||||
|
||||
write_buf(buf, "\tinterpret.useModMapMods= AnyLevel;\n");
|
||||
write_buf(buf, "\tinterpret.repeat= False;\n");
|
||||
|
||||
for (unsigned i = 0; i < keymap->num_sym_interprets; i++) {
|
||||
const struct xkb_sym_interpret *si = &keymap->sym_interprets[i];
|
||||
|
||||
write_buf(buf, "\tinterpret %s+%s(%s) {\n",
|
||||
si->sym ? KeysymText(keymap->ctx, si->sym) : "Any",
|
||||
SIMatchText(si->match),
|
||||
ModMaskText(keymap->ctx, &keymap->mods, si->mods));
|
||||
|
||||
if (si->virtual_mod != XKB_MOD_INVALID)
|
||||
write_buf(buf, "\t\tvirtualModifier= %s;\n",
|
||||
ModIndexText(keymap->ctx, &keymap->mods,
|
||||
si->virtual_mod));
|
||||
|
||||
if (si->level_one_only)
|
||||
write_buf(buf, "\t\tuseModMapMods=level1;\n");
|
||||
|
||||
if (si->repeat)
|
||||
write_buf(buf, "\t\trepeat= True;\n");
|
||||
|
||||
write_action(keymap, buf, &si->action, "\t\taction= ", ";\n");
|
||||
write_buf(buf, "\t};\n");
|
||||
}
|
||||
|
||||
xkb_leds_foreach(led, keymap)
|
||||
if (led->which_groups || led->groups || led->which_mods ||
|
||||
led->mods.mods || led->ctrls)
|
||||
write_led_map(keymap, buf, led);
|
||||
|
||||
write_buf(buf, "};\n\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
write_keysyms(struct xkb_keymap *keymap, struct buf *buf,
|
||||
const struct xkb_key *key, xkb_layout_index_t group)
|
||||
{
|
||||
for (xkb_level_index_t level = 0; level < XkbKeyNumLevels(key, group);
|
||||
level++) {
|
||||
const xkb_keysym_t *syms;
|
||||
int num_syms;
|
||||
|
||||
if (level != 0)
|
||||
write_buf(buf, ", ");
|
||||
|
||||
num_syms = xkb_keymap_key_get_syms_by_level(keymap, key->keycode,
|
||||
group, level, &syms);
|
||||
if (num_syms == 0) {
|
||||
write_buf(buf, "%15s", "NoSymbol");
|
||||
}
|
||||
else if (num_syms == 1) {
|
||||
write_buf(buf, "%15s", KeysymText(keymap->ctx, syms[0]));
|
||||
}
|
||||
else {
|
||||
write_buf(buf, "{ ");
|
||||
for (int s = 0; s < num_syms; s++) {
|
||||
if (s != 0)
|
||||
write_buf(buf, ", ");
|
||||
write_buf(buf, "%s", KeysymText(keymap->ctx, syms[s]));
|
||||
}
|
||||
write_buf(buf, " }");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
write_key(struct xkb_keymap *keymap, struct buf *buf,
|
||||
const struct xkb_key *key)
|
||||
{
|
||||
xkb_layout_index_t group;
|
||||
bool simple = true;
|
||||
bool explicit_types = false;
|
||||
bool multi_type = false;
|
||||
bool show_actions;
|
||||
|
||||
write_buf(buf, "\tkey %-20s {", KeyNameText(keymap->ctx, key->name));
|
||||
|
||||
for (group = 0; group < key->num_groups; group++) {
|
||||
if (key->groups[group].explicit_type)
|
||||
explicit_types = true;
|
||||
|
||||
if (group != 0 && key->groups[group].type != key->groups[0].type)
|
||||
multi_type = true;
|
||||
}
|
||||
|
||||
if (explicit_types) {
|
||||
const struct xkb_key_type *type;
|
||||
simple = false;
|
||||
|
||||
if (multi_type) {
|
||||
for (group = 0; group < key->num_groups; group++) {
|
||||
if (!key->groups[group].explicit_type)
|
||||
continue;
|
||||
|
||||
type = key->groups[group].type;
|
||||
write_buf(buf, "\n\t\ttype[group%u]= \"%s\",",
|
||||
group + 1,
|
||||
xkb_atom_text(keymap->ctx, type->name));
|
||||
}
|
||||
}
|
||||
else {
|
||||
type = key->groups[0].type;
|
||||
write_buf(buf, "\n\t\ttype= \"%s\",",
|
||||
xkb_atom_text(keymap->ctx, type->name));
|
||||
}
|
||||
}
|
||||
|
||||
if (key->explicit & EXPLICIT_REPEAT) {
|
||||
if (key->repeats)
|
||||
write_buf(buf, "\n\t\trepeat= Yes,");
|
||||
else
|
||||
write_buf(buf, "\n\t\trepeat= No,");
|
||||
simple = false;
|
||||
}
|
||||
|
||||
if (key->vmodmap && (key->explicit & EXPLICIT_VMODMAP))
|
||||
write_buf(buf, "\n\t\tvirtualMods= %s,",
|
||||
ModMaskText(keymap->ctx, &keymap->mods, key->vmodmap));
|
||||
|
||||
switch (key->out_of_range_group_action) {
|
||||
case RANGE_SATURATE:
|
||||
write_buf(buf, "\n\t\tgroupsClamp,");
|
||||
break;
|
||||
|
||||
case RANGE_REDIRECT:
|
||||
write_buf(buf, "\n\t\tgroupsRedirect= Group%u,",
|
||||
key->out_of_range_group_number + 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
show_actions = (key->explicit & EXPLICIT_INTERP);
|
||||
|
||||
if (key->num_groups > 1 || show_actions)
|
||||
simple = false;
|
||||
|
||||
if (simple) {
|
||||
write_buf(buf, "\t[ ");
|
||||
if (!write_keysyms(keymap, buf, key, 0))
|
||||
return false;
|
||||
write_buf(buf, " ] };\n");
|
||||
}
|
||||
else {
|
||||
xkb_level_index_t level;
|
||||
|
||||
for (group = 0; group < key->num_groups; group++) {
|
||||
if (group != 0)
|
||||
write_buf(buf, ",");
|
||||
write_buf(buf, "\n\t\tsymbols[Group%u]= [ ", group + 1);
|
||||
if (!write_keysyms(keymap, buf, key, group))
|
||||
return false;
|
||||
write_buf(buf, " ]");
|
||||
if (show_actions) {
|
||||
write_buf(buf, ",\n\t\tactions[Group%u]= [ ", group + 1);
|
||||
for (level = 0; level < XkbKeyNumLevels(key, group); level++) {
|
||||
if (level != 0)
|
||||
write_buf(buf, ", ");
|
||||
write_action(keymap, buf,
|
||||
&key->groups[group].levels[level].action,
|
||||
NULL, NULL);
|
||||
}
|
||||
write_buf(buf, " ]");
|
||||
}
|
||||
}
|
||||
write_buf(buf, "\n\t};\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
write_symbols(struct xkb_keymap *keymap, struct buf *buf)
|
||||
{
|
||||
const struct xkb_key *key;
|
||||
xkb_layout_index_t group;
|
||||
xkb_mod_index_t i;
|
||||
const struct xkb_mod *mod;
|
||||
|
||||
if (keymap->symbols_section_name)
|
||||
write_buf(buf, "xkb_symbols \"%s\" {\n",
|
||||
keymap->symbols_section_name);
|
||||
else
|
||||
write_buf(buf, "xkb_symbols {\n");
|
||||
|
||||
for (group = 0; group < keymap->num_group_names; group++)
|
||||
if (keymap->group_names[group])
|
||||
write_buf(buf,
|
||||
"\tname[group%u]=\"%s\";\n", group + 1,
|
||||
xkb_atom_text(keymap->ctx, keymap->group_names[group]));
|
||||
if (group > 0)
|
||||
write_buf(buf, "\n");
|
||||
|
||||
xkb_keys_foreach(key, keymap)
|
||||
if (key->num_groups > 0)
|
||||
write_key(keymap, buf, key);
|
||||
|
||||
xkb_mods_enumerate(i, mod, &keymap->mods) {
|
||||
bool had_any = false;
|
||||
xkb_keys_foreach(key, keymap) {
|
||||
if (key->modmap & (1u << i)) {
|
||||
if (!had_any)
|
||||
write_buf(buf, "\tmodifier_map %s { ",
|
||||
xkb_atom_text(keymap->ctx, mod->name));
|
||||
write_buf(buf, "%s%s",
|
||||
had_any ? ", " : "",
|
||||
KeyNameText(keymap->ctx, key->name));
|
||||
had_any = true;
|
||||
}
|
||||
}
|
||||
if (had_any)
|
||||
write_buf(buf, " };\n");
|
||||
}
|
||||
|
||||
write_buf(buf, "};\n\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
write_keymap(struct xkb_keymap *keymap, struct buf *buf)
|
||||
{
|
||||
return (check_write_buf(buf, "xkb_keymap {\n") &&
|
||||
write_keycodes(keymap, buf) &&
|
||||
write_types(keymap, buf) &&
|
||||
write_compat(keymap, buf) &&
|
||||
write_symbols(keymap, buf) &&
|
||||
check_write_buf(buf, "};\n"));
|
||||
}
|
||||
|
||||
char *
|
||||
text_v1_keymap_get_as_string(struct xkb_keymap *keymap)
|
||||
{
|
||||
struct buf buf = { NULL, 0, 0 };
|
||||
|
||||
if (!write_keymap(keymap, &buf)) {
|
||||
free(buf.buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buf.buf;
|
||||
}
|
348
src/3rdparty/xkbcommon/src/xkbcomp/keywords.c
vendored
348
src/3rdparty/xkbcommon/src/xkbcomp/keywords.c
vendored
@ -1,348 +0,0 @@
|
||||
/* ANSI-C code produced by gperf version 3.0.4 */
|
||||
/* Command-line: gperf */
|
||||
/* Computed positions: -k'1-2,5' */
|
||||
|
||||
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
||||
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
||||
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
||||
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
||||
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
||||
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
||||
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
||||
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
||||
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
||||
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
||||
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
||||
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
||||
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
||||
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
||||
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
||||
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
||||
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
||||
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
||||
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
||||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
|
||||
/* The character set is not based on ISO-646. */
|
||||
#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
|
||||
#endif
|
||||
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "parser-priv.h"
|
||||
|
||||
static unsigned int
|
||||
keyword_gperf_hash(const char *str, unsigned int len);
|
||||
|
||||
static const struct keyword_tok *
|
||||
keyword_gperf_lookup(const char *str, unsigned int len);
|
||||
struct keyword_tok { int name; int tok; };
|
||||
#include <string.h>
|
||||
/* maximum key range = 70, duplicates = 0 */
|
||||
|
||||
#ifndef GPERF_DOWNCASE
|
||||
#define GPERF_DOWNCASE 1
|
||||
static unsigned char gperf_downcase[256] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
|
||||
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
|
||||
107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
|
||||
122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
|
||||
105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
|
||||
120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
|
||||
135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
|
||||
150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
|
||||
165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
|
||||
180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
|
||||
195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
|
||||
210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
|
||||
225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
||||
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
|
||||
255
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef GPERF_CASE_STRCMP
|
||||
#define GPERF_CASE_STRCMP 1
|
||||
static int
|
||||
gperf_case_strcmp (register const char *s1, register const char *s2)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
unsigned char c1 = gperf_downcase[(unsigned char)*s1++];
|
||||
unsigned char c2 = gperf_downcase[(unsigned char)*s2++];
|
||||
if (c1 != 0 && c1 == c2)
|
||||
continue;
|
||||
return (int)c1 - (int)c2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
inline
|
||||
#endif
|
||||
#endif
|
||||
static unsigned int
|
||||
keyword_gperf_hash (register const char *str, register unsigned int len)
|
||||
{
|
||||
static const unsigned char asso_values[] =
|
||||
{
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 0, 73, 5, 36, 0,
|
||||
10, 1, 15, 15, 73, 0, 10, 20, 35, 20,
|
||||
50, 73, 10, 10, 5, 0, 15, 73, 0, 15,
|
||||
73, 73, 73, 73, 73, 73, 73, 0, 73, 5,
|
||||
36, 0, 10, 1, 15, 15, 73, 0, 10, 20,
|
||||
35, 20, 50, 73, 10, 10, 5, 0, 15, 73,
|
||||
0, 15, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
||||
73, 73, 73, 73, 73, 73
|
||||
};
|
||||
register int hval = len;
|
||||
|
||||
switch (hval)
|
||||
{
|
||||
default:
|
||||
hval += asso_values[(unsigned char)str[4]];
|
||||
/*FALLTHROUGH*/
|
||||
case 4:
|
||||
case 3:
|
||||
case 2:
|
||||
hval += asso_values[(unsigned char)str[1]];
|
||||
/*FALLTHROUGH*/
|
||||
case 1:
|
||||
hval += asso_values[(unsigned char)str[0]];
|
||||
break;
|
||||
}
|
||||
return hval;
|
||||
}
|
||||
|
||||
struct stringpool_t
|
||||
{
|
||||
char stringpool_str3[sizeof("key")];
|
||||
char stringpool_str4[sizeof("keys")];
|
||||
char stringpool_str7[sizeof("augment")];
|
||||
char stringpool_str9[sizeof("text")];
|
||||
char stringpool_str10[sizeof("xkb_keymap")];
|
||||
char stringpool_str11[sizeof("keypad_keys")];
|
||||
char stringpool_str12[sizeof("xkb_keycodes")];
|
||||
char stringpool_str13[sizeof("xkb_geometry")];
|
||||
char stringpool_str14[sizeof("xkb_types")];
|
||||
char stringpool_str15[sizeof("xkb_compat")];
|
||||
char stringpool_str17[sizeof("replace")];
|
||||
char stringpool_str19[sizeof("xkb_compat_map")];
|
||||
char stringpool_str20[sizeof("xkb_layout")];
|
||||
char stringpool_str21[sizeof("xkb_symbols")];
|
||||
char stringpool_str22[sizeof("xkb_compatibility")];
|
||||
char stringpool_str23[sizeof("xkb_semantics")];
|
||||
char stringpool_str24[sizeof("type")];
|
||||
char stringpool_str25[sizeof("alias")];
|
||||
char stringpool_str26[sizeof("xkb_compatibility_map")];
|
||||
char stringpool_str27[sizeof("alphanumeric_keys")];
|
||||
char stringpool_str28[sizeof("function_keys")];
|
||||
char stringpool_str29[sizeof("alternate")];
|
||||
char stringpool_str30[sizeof("shape")];
|
||||
char stringpool_str31[sizeof("action")];
|
||||
char stringpool_str32[sizeof("section")];
|
||||
char stringpool_str33[sizeof("row")];
|
||||
char stringpool_str34[sizeof("logo")];
|
||||
char stringpool_str35[sizeof("alternate_group")];
|
||||
char stringpool_str36[sizeof("hidden")];
|
||||
char stringpool_str37[sizeof("virtual")];
|
||||
char stringpool_str42[sizeof("outline")];
|
||||
char stringpool_str43[sizeof("default")];
|
||||
char stringpool_str46[sizeof("modmap")];
|
||||
char stringpool_str47[sizeof("virtual_modifiers")];
|
||||
char stringpool_str52[sizeof("overlay")];
|
||||
char stringpool_str53[sizeof("override")];
|
||||
char stringpool_str57[sizeof("include")];
|
||||
char stringpool_str62[sizeof("modifier_map")];
|
||||
char stringpool_str63[sizeof("modifier_keys")];
|
||||
char stringpool_str64[sizeof("indicator")];
|
||||
char stringpool_str66[sizeof("group")];
|
||||
char stringpool_str67[sizeof("mod_map")];
|
||||
char stringpool_str69[sizeof("interpret")];
|
||||
char stringpool_str71[sizeof("solid")];
|
||||
char stringpool_str72[sizeof("partial")];
|
||||
};
|
||||
static const struct stringpool_t stringpool_contents =
|
||||
{
|
||||
"key",
|
||||
"keys",
|
||||
"augment",
|
||||
"text",
|
||||
"xkb_keymap",
|
||||
"keypad_keys",
|
||||
"xkb_keycodes",
|
||||
"xkb_geometry",
|
||||
"xkb_types",
|
||||
"xkb_compat",
|
||||
"replace",
|
||||
"xkb_compat_map",
|
||||
"xkb_layout",
|
||||
"xkb_symbols",
|
||||
"xkb_compatibility",
|
||||
"xkb_semantics",
|
||||
"type",
|
||||
"alias",
|
||||
"xkb_compatibility_map",
|
||||
"alphanumeric_keys",
|
||||
"function_keys",
|
||||
"alternate",
|
||||
"shape",
|
||||
"action",
|
||||
"section",
|
||||
"row",
|
||||
"logo",
|
||||
"alternate_group",
|
||||
"hidden",
|
||||
"virtual",
|
||||
"outline",
|
||||
"default",
|
||||
"modmap",
|
||||
"virtual_modifiers",
|
||||
"overlay",
|
||||
"override",
|
||||
"include",
|
||||
"modifier_map",
|
||||
"modifier_keys",
|
||||
"indicator",
|
||||
"group",
|
||||
"mod_map",
|
||||
"interpret",
|
||||
"solid",
|
||||
"partial"
|
||||
};
|
||||
#define stringpool ((const char *) &stringpool_contents)
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
|
||||
__attribute__ ((__gnu_inline__))
|
||||
#endif
|
||||
#endif
|
||||
const struct keyword_tok *
|
||||
keyword_gperf_lookup (register const char *str, register unsigned int len)
|
||||
{
|
||||
enum
|
||||
{
|
||||
TOTAL_KEYWORDS = 45,
|
||||
MIN_WORD_LENGTH = 3,
|
||||
MAX_WORD_LENGTH = 21,
|
||||
MIN_HASH_VALUE = 3,
|
||||
MAX_HASH_VALUE = 72
|
||||
};
|
||||
|
||||
static const struct keyword_tok wordlist[] =
|
||||
{
|
||||
{-1}, {-1}, {-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str3, KEY},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str4, KEYS},
|
||||
{-1}, {-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str7, AUGMENT},
|
||||
{-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str9, TEXT},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str10, XKB_KEYMAP},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str11, KEYPAD_KEYS},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str12, XKB_KEYCODES},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str13, XKB_GEOMETRY},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str14, XKB_TYPES},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str15, XKB_COMPATMAP},
|
||||
{-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str17, REPLACE},
|
||||
{-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str19, XKB_COMPATMAP},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str20, XKB_LAYOUT},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str21, XKB_SYMBOLS},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str22, XKB_COMPATMAP},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str23, XKB_SEMANTICS},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str24, TYPE},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str25, ALIAS},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str26, XKB_COMPATMAP},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str27, ALPHANUMERIC_KEYS},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str28, FUNCTION_KEYS},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str29, ALTERNATE},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str30, SHAPE},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str31, ACTION_TOK},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str32, SECTION},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str33, ROW},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str34, LOGO},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str35, ALTERNATE_GROUP},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str36, HIDDEN},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str37, VIRTUAL},
|
||||
{-1}, {-1}, {-1}, {-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str42, OUTLINE},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str43, DEFAULT},
|
||||
{-1}, {-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str46, MODIFIER_MAP},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str47, VIRTUAL_MODS},
|
||||
{-1}, {-1}, {-1}, {-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str52, OVERLAY},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str53, OVERRIDE},
|
||||
{-1}, {-1}, {-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str57, INCLUDE},
|
||||
{-1}, {-1}, {-1}, {-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str62, MODIFIER_MAP},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str63, MODIFIER_KEYS},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str64, INDICATOR},
|
||||
{-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str66, GROUP},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str67, MODIFIER_MAP},
|
||||
{-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str69, INTERPRET},
|
||||
{-1},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str71, SOLID},
|
||||
{(int)(long)&((struct stringpool_t *)0)->stringpool_str72, PARTIAL}
|
||||
};
|
||||
|
||||
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
||||
{
|
||||
register int key = keyword_gperf_hash (str, len);
|
||||
|
||||
if (key <= MAX_HASH_VALUE && key >= 0)
|
||||
{
|
||||
register int o = wordlist[key].name;
|
||||
if (o >= 0)
|
||||
{
|
||||
register const char *s = o + stringpool;
|
||||
|
||||
if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strcmp (str, s))
|
||||
return &wordlist[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
keyword_to_token(const char *string, unsigned int len)
|
||||
{
|
||||
const struct keyword_tok *kt = keyword_gperf_lookup(string, len);
|
||||
if (!kt)
|
||||
return -1;
|
||||
return kt->tok;
|
||||
}
|
44
src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h
vendored
44
src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h
vendored
@ -1,44 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#ifndef XKBCOMP_PARSER_PRIV_H
|
||||
#define XKBCOMP_PARSER_PRIV_H
|
||||
|
||||
struct parser_param;
|
||||
struct scanner;
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
int
|
||||
_xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner);
|
||||
|
||||
XkbFile *
|
||||
parse(struct xkb_context *ctx, struct scanner *scanner, const char *map);
|
||||
|
||||
int
|
||||
keyword_to_token(const char *string, unsigned int len);
|
||||
|
||||
#endif
|
157
src/3rdparty/xkbcommon/src/xkbcomp/parser.h
vendored
157
src/3rdparty/xkbcommon/src/xkbcomp/parser.h
vendored
@ -1,157 +0,0 @@
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
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/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY__XKBCOMMON_XKBCOMMON_INTERNAL_STA_PARSER_H_INCLUDED
|
||||
# define YY__XKBCOMMON_XKBCOMMON_INTERNAL_STA_PARSER_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int _xkbcommon_debug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
END_OF_FILE = 0,
|
||||
ERROR_TOK = 255,
|
||||
XKB_KEYMAP = 1,
|
||||
XKB_KEYCODES = 2,
|
||||
XKB_TYPES = 3,
|
||||
XKB_SYMBOLS = 4,
|
||||
XKB_COMPATMAP = 5,
|
||||
XKB_GEOMETRY = 6,
|
||||
XKB_SEMANTICS = 7,
|
||||
XKB_LAYOUT = 8,
|
||||
INCLUDE = 10,
|
||||
OVERRIDE = 11,
|
||||
AUGMENT = 12,
|
||||
REPLACE = 13,
|
||||
ALTERNATE = 14,
|
||||
VIRTUAL_MODS = 20,
|
||||
TYPE = 21,
|
||||
INTERPRET = 22,
|
||||
ACTION_TOK = 23,
|
||||
KEY = 24,
|
||||
ALIAS = 25,
|
||||
GROUP = 26,
|
||||
MODIFIER_MAP = 27,
|
||||
INDICATOR = 28,
|
||||
SHAPE = 29,
|
||||
KEYS = 30,
|
||||
ROW = 31,
|
||||
SECTION = 32,
|
||||
OVERLAY = 33,
|
||||
TEXT = 34,
|
||||
OUTLINE = 35,
|
||||
SOLID = 36,
|
||||
LOGO = 37,
|
||||
VIRTUAL = 38,
|
||||
EQUALS = 40,
|
||||
PLUS = 41,
|
||||
MINUS = 42,
|
||||
DIVIDE = 43,
|
||||
TIMES = 44,
|
||||
OBRACE = 45,
|
||||
CBRACE = 46,
|
||||
OPAREN = 47,
|
||||
CPAREN = 48,
|
||||
OBRACKET = 49,
|
||||
CBRACKET = 50,
|
||||
DOT = 51,
|
||||
COMMA = 52,
|
||||
SEMI = 53,
|
||||
EXCLAM = 54,
|
||||
INVERT = 55,
|
||||
STRING = 60,
|
||||
INTEGER = 61,
|
||||
FLOAT = 62,
|
||||
IDENT = 63,
|
||||
KEYNAME = 64,
|
||||
PARTIAL = 70,
|
||||
DEFAULT = 71,
|
||||
HIDDEN = 72,
|
||||
ALPHANUMERIC_KEYS = 73,
|
||||
MODIFIER_KEYS = 74,
|
||||
KEYPAD_KEYS = 75,
|
||||
FUNCTION_KEYS = 76,
|
||||
ALTERNATE_GROUP = 77
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 162 "../src/xkbcomp/parser.y" /* yacc.c:1909 */
|
||||
|
||||
int ival;
|
||||
int64_t num;
|
||||
enum xkb_file_type file_type;
|
||||
char *str;
|
||||
xkb_atom_t atom;
|
||||
enum merge_mode merge;
|
||||
enum xkb_map_flags mapFlags;
|
||||
xkb_keysym_t keysym;
|
||||
ParseCommon *any;
|
||||
ExprDef *expr;
|
||||
VarDef *var;
|
||||
VModDef *vmod;
|
||||
InterpDef *interp;
|
||||
KeyTypeDef *keyType;
|
||||
SymbolsDef *syms;
|
||||
ModMapDef *modMask;
|
||||
GroupCompatDef *groupCompat;
|
||||
LedMapDef *ledMap;
|
||||
LedNameDef *ledName;
|
||||
KeycodeDef *keyCode;
|
||||
KeyAliasDef *keyAlias;
|
||||
void *geom;
|
||||
XkbFile *file;
|
||||
|
||||
#line 146 "xkbcommon-internal@sta/parser.h" /* yacc.c:1909 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int _xkbcommon_parse (struct parser_param *param);
|
||||
|
||||
#endif /* !YY__XKBCOMMON_XKBCOMMON_INTERNAL_STA_PARSER_H_INCLUDED */
|
1037
src/3rdparty/xkbcommon/src/xkbcomp/rules.c
vendored
1037
src/3rdparty/xkbcommon/src/xkbcomp/rules.c
vendored
File diff suppressed because it is too large
Load Diff
32
src/3rdparty/xkbcommon/src/xkbcomp/rules.h
vendored
32
src/3rdparty/xkbcommon/src/xkbcomp/rules.h
vendored
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 Dan Nicholson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XKBCOMP_RULES_H
|
||||
#define XKBCOMP_RULES_H
|
||||
|
||||
bool
|
||||
xkb_components_from_rules(struct xkb_context *ctx,
|
||||
const struct xkb_rule_names *rmlvo,
|
||||
struct xkb_component_names *out);
|
||||
|
||||
#endif
|
208
src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
vendored
208
src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
vendored
@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "parser-priv.h"
|
||||
#include "scanner-utils.h"
|
||||
|
||||
static bool
|
||||
number(struct scanner *s, int64_t *out, int *out_tok)
|
||||
{
|
||||
bool is_float = false, is_hex = false;
|
||||
const char *start = s->s + s->pos;
|
||||
char *end;
|
||||
|
||||
if (lit(s, "0x")) {
|
||||
while (is_xdigit(peek(s))) next(s);
|
||||
is_hex = true;
|
||||
}
|
||||
else {
|
||||
while (is_digit(peek(s))) next(s);
|
||||
is_float = chr(s, '.');
|
||||
while (is_digit(peek(s))) next(s);
|
||||
}
|
||||
if (s->s + s->pos == start)
|
||||
return false;
|
||||
|
||||
errno = 0;
|
||||
if (is_hex)
|
||||
*out = strtoul(start, &end, 16);
|
||||
else if (is_float)
|
||||
*out = strtod(start, &end);
|
||||
else
|
||||
*out = strtoul(start, &end, 10);
|
||||
if (errno != 0 || s->s + s->pos != end)
|
||||
*out_tok = ERROR_TOK;
|
||||
else
|
||||
*out_tok = (is_float ? FLOAT : INTEGER);
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
_xkbcommon_lex(YYSTYPE *yylval, struct scanner *s)
|
||||
{
|
||||
int tok;
|
||||
|
||||
skip_more_whitespace_and_comments:
|
||||
/* Skip spaces. */
|
||||
while (is_space(peek(s))) next(s);
|
||||
|
||||
/* Skip comments. */
|
||||
if (lit(s, "//") || chr(s, '#')) {
|
||||
skip_to_eol(s);
|
||||
goto skip_more_whitespace_and_comments;
|
||||
}
|
||||
|
||||
/* See if we're done. */
|
||||
if (eof(s)) return END_OF_FILE;
|
||||
|
||||
/* New token. */
|
||||
s->token_line = s->line;
|
||||
s->token_column = s->column;
|
||||
s->buf_pos = 0;
|
||||
|
||||
/* String literal. */
|
||||
if (chr(s, '\"')) {
|
||||
while (!eof(s) && !eol(s) && peek(s) != '\"') {
|
||||
if (chr(s, '\\')) {
|
||||
uint8_t o;
|
||||
if (chr(s, '\\')) buf_append(s, '\\');
|
||||
else if (chr(s, 'n')) buf_append(s, '\n');
|
||||
else if (chr(s, 't')) buf_append(s, '\t');
|
||||
else if (chr(s, 'r')) buf_append(s, '\r');
|
||||
else if (chr(s, 'b')) buf_append(s, '\b');
|
||||
else if (chr(s, 'f')) buf_append(s, '\f');
|
||||
else if (chr(s, 'v')) buf_append(s, '\v');
|
||||
else if (chr(s, 'e')) buf_append(s, '\033');
|
||||
else if (oct(s, &o)) buf_append(s, (char) o);
|
||||
else {
|
||||
scanner_warn(s, "unknown escape sequence in string literal");
|
||||
/* Ignore. */
|
||||
}
|
||||
} else {
|
||||
buf_append(s, next(s));
|
||||
}
|
||||
}
|
||||
if (!buf_append(s, '\0') || !chr(s, '\"')) {
|
||||
scanner_err(s, "unterminated string literal");
|
||||
return ERROR_TOK;
|
||||
}
|
||||
yylval->str = strdup(s->buf);
|
||||
if (!yylval->str)
|
||||
return ERROR_TOK;
|
||||
return STRING;
|
||||
}
|
||||
|
||||
/* Key name literal. */
|
||||
if (chr(s, '<')) {
|
||||
while (is_graph(peek(s)) && peek(s) != '>')
|
||||
buf_append(s, next(s));
|
||||
if (!buf_append(s, '\0') || !chr(s, '>')) {
|
||||
scanner_err(s, "unterminated key name literal");
|
||||
return ERROR_TOK;
|
||||
}
|
||||
/* Empty key name literals are allowed. */
|
||||
yylval->atom = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1);
|
||||
return KEYNAME;
|
||||
}
|
||||
|
||||
/* Operators and punctuation. */
|
||||
if (chr(s, ';')) return SEMI;
|
||||
if (chr(s, '{')) return OBRACE;
|
||||
if (chr(s, '}')) return CBRACE;
|
||||
if (chr(s, '=')) return EQUALS;
|
||||
if (chr(s, '[')) return OBRACKET;
|
||||
if (chr(s, ']')) return CBRACKET;
|
||||
if (chr(s, '(')) return OPAREN;
|
||||
if (chr(s, ')')) return CPAREN;
|
||||
if (chr(s, '.')) return DOT;
|
||||
if (chr(s, ',')) return COMMA;
|
||||
if (chr(s, '+')) return PLUS;
|
||||
if (chr(s, '-')) return MINUS;
|
||||
if (chr(s, '*')) return TIMES;
|
||||
if (chr(s, '/')) return DIVIDE;
|
||||
if (chr(s, '!')) return EXCLAM;
|
||||
if (chr(s, '~')) return INVERT;
|
||||
|
||||
/* Identifier. */
|
||||
if (is_alpha(peek(s)) || peek(s) == '_') {
|
||||
s->buf_pos = 0;
|
||||
while (is_alnum(peek(s)) || peek(s) == '_')
|
||||
buf_append(s, next(s));
|
||||
if (!buf_append(s, '\0')) {
|
||||
scanner_err(s, "identifier too long");
|
||||
return ERROR_TOK;
|
||||
}
|
||||
|
||||
/* Keyword. */
|
||||
tok = keyword_to_token(s->buf, s->buf_pos - 1);
|
||||
if (tok != -1) return tok;
|
||||
|
||||
yylval->str = strdup(s->buf);
|
||||
if (!yylval->str)
|
||||
return ERROR_TOK;
|
||||
return IDENT;
|
||||
}
|
||||
|
||||
/* Number literal (hexadecimal / decimal / float). */
|
||||
if (number(s, &yylval->num, &tok)) {
|
||||
if (tok == ERROR_TOK) {
|
||||
scanner_err(s, "malformed number literal");
|
||||
return ERROR_TOK;
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
|
||||
scanner_err(s, "unrecognized token");
|
||||
return ERROR_TOK;
|
||||
}
|
||||
|
||||
XkbFile *
|
||||
XkbParseString(struct xkb_context *ctx, const char *string, size_t len,
|
||||
const char *file_name, const char *map)
|
||||
{
|
||||
struct scanner scanner;
|
||||
scanner_init(&scanner, ctx, string, len, file_name, NULL);
|
||||
return parse(ctx, &scanner, map);
|
||||
}
|
||||
|
||||
XkbFile *
|
||||
XkbParseFile(struct xkb_context *ctx, FILE *file,
|
||||
const char *file_name, const char *map)
|
||||
{
|
||||
bool ok;
|
||||
XkbFile *xkb_file;
|
||||
char *string;
|
||||
size_t size;
|
||||
|
||||
ok = map_file(file, &string, &size);
|
||||
if (!ok) {
|
||||
log_err(ctx, "Couldn't read XKB file %s: %s\n",
|
||||
file_name, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xkb_file = XkbParseString(ctx, string, size, file_name, map);
|
||||
unmap_file(string, size);
|
||||
return xkb_file;
|
||||
}
|
1595
src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
vendored
1595
src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
vendored
File diff suppressed because it is too large
Load Diff
742
src/3rdparty/xkbcommon/src/xkbcomp/types.c
vendored
742
src/3rdparty/xkbcommon/src/xkbcomp/types.c
vendored
@ -1,742 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "text.h"
|
||||
#include "vmod.h"
|
||||
#include "expr.h"
|
||||
#include "include.h"
|
||||
|
||||
enum type_field {
|
||||
TYPE_FIELD_MASK = (1 << 0),
|
||||
TYPE_FIELD_MAP = (1 << 1),
|
||||
TYPE_FIELD_PRESERVE = (1 << 2),
|
||||
TYPE_FIELD_LEVEL_NAME = (1 << 3),
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum type_field defined;
|
||||
enum merge_mode merge;
|
||||
|
||||
xkb_atom_t name;
|
||||
xkb_mod_mask_t mods;
|
||||
xkb_level_index_t num_levels;
|
||||
darray(struct xkb_key_type_entry) entries;
|
||||
darray(xkb_atom_t) level_names;
|
||||
} KeyTypeInfo;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int errorCount;
|
||||
|
||||
darray(KeyTypeInfo) types;
|
||||
struct xkb_mod_set mods;
|
||||
|
||||
struct xkb_context *ctx;
|
||||
} KeyTypesInfo;
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static inline const char *
|
||||
MapEntryTxt(KeyTypesInfo *info, struct xkb_key_type_entry *entry)
|
||||
{
|
||||
return ModMaskText(info->ctx, &info->mods, entry->mods.mods);
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type)
|
||||
{
|
||||
return xkb_atom_text(info->ctx, type->name);
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
TypeMaskTxt(KeyTypesInfo *info, KeyTypeInfo *type)
|
||||
{
|
||||
return ModMaskText(info->ctx, &info->mods, type->mods);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportTypeShouldBeArray(KeyTypesInfo *info, KeyTypeInfo *type,
|
||||
const char *field)
|
||||
{
|
||||
return ReportShouldBeArray(info->ctx, "key type", field,
|
||||
TypeTxt(info, type));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type,
|
||||
const char *field, const char *wanted)
|
||||
{
|
||||
return ReportBadType(info->ctx, "key type", field,
|
||||
TypeTxt(info, type), wanted);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static void
|
||||
InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_context *ctx,
|
||||
const struct xkb_mod_set *mods)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->ctx = ctx;
|
||||
info->mods = *mods;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearKeyTypeInfo(KeyTypeInfo *type)
|
||||
{
|
||||
darray_free(type->entries);
|
||||
darray_free(type->level_names);
|
||||
}
|
||||
|
||||
static void
|
||||
ClearKeyTypesInfo(KeyTypesInfo *info)
|
||||
{
|
||||
free(info->name);
|
||||
darray_free(info->types);
|
||||
}
|
||||
|
||||
static KeyTypeInfo *
|
||||
FindMatchingKeyType(KeyTypesInfo *info, xkb_atom_t name)
|
||||
{
|
||||
KeyTypeInfo *old;
|
||||
|
||||
darray_foreach(old, info->types)
|
||||
if (old->name == name)
|
||||
return old;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new, bool same_file)
|
||||
{
|
||||
KeyTypeInfo *old;
|
||||
const int verbosity = xkb_context_get_log_verbosity(info->ctx);
|
||||
|
||||
old = FindMatchingKeyType(info, new->name);
|
||||
if (old) {
|
||||
if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) {
|
||||
if ((same_file && verbosity > 0) || verbosity > 9) {
|
||||
log_warn(info->ctx,
|
||||
"Multiple definitions of the %s key type; "
|
||||
"Earlier definition ignored\n",
|
||||
xkb_atom_text(info->ctx, new->name));
|
||||
}
|
||||
|
||||
ClearKeyTypeInfo(old);
|
||||
*old = *new;
|
||||
darray_init(new->entries);
|
||||
darray_init(new->level_names);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (same_file)
|
||||
log_vrb(info->ctx, 4,
|
||||
"Multiple definitions of the %s key type; "
|
||||
"Later definition ignored\n",
|
||||
xkb_atom_text(info->ctx, new->name));
|
||||
|
||||
ClearKeyTypeInfo(new);
|
||||
return true;
|
||||
}
|
||||
|
||||
darray_append(info->types, *new);
|
||||
return true;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static void
|
||||
MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
|
||||
enum merge_mode merge)
|
||||
{
|
||||
if (from->errorCount > 0) {
|
||||
into->errorCount += from->errorCount;
|
||||
return;
|
||||
}
|
||||
|
||||
into->mods = from->mods;
|
||||
|
||||
if (into->name == NULL) {
|
||||
into->name = from->name;
|
||||
from->name = NULL;
|
||||
}
|
||||
|
||||
if (darray_empty(into->types)) {
|
||||
into->types = from->types;
|
||||
darray_init(from->types);
|
||||
}
|
||||
else {
|
||||
KeyTypeInfo *type;
|
||||
darray_foreach(type, from->types) {
|
||||
type->merge = (merge == MERGE_DEFAULT ? type->merge : merge);
|
||||
if (!AddKeyType(into, type, false))
|
||||
into->errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge);
|
||||
|
||||
static bool
|
||||
HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *include)
|
||||
{
|
||||
KeyTypesInfo included;
|
||||
|
||||
InitKeyTypesInfo(&included, info->ctx, &info->mods);
|
||||
included.name = include->stmt;
|
||||
include->stmt = NULL;
|
||||
|
||||
for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
|
||||
KeyTypesInfo next_incl;
|
||||
XkbFile *file;
|
||||
|
||||
file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_TYPES);
|
||||
if (!file) {
|
||||
info->errorCount += 10;
|
||||
ClearKeyTypesInfo(&included);
|
||||
return false;
|
||||
}
|
||||
|
||||
InitKeyTypesInfo(&next_incl, info->ctx, &included.mods);
|
||||
|
||||
HandleKeyTypesFile(&next_incl, file, stmt->merge);
|
||||
|
||||
MergeIncludedKeyTypes(&included, &next_incl, stmt->merge);
|
||||
|
||||
ClearKeyTypesInfo(&next_incl);
|
||||
FreeXkbFile(file);
|
||||
}
|
||||
|
||||
MergeIncludedKeyTypes(info, &included, include->merge);
|
||||
ClearKeyTypesInfo(&included);
|
||||
|
||||
return (info->errorCount == 0);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
|
||||
ExprDef *value)
|
||||
{
|
||||
xkb_mod_mask_t mods;
|
||||
|
||||
if (arrayNdx)
|
||||
log_warn(info->ctx,
|
||||
"The modifiers field of a key type is not an array; "
|
||||
"Illegal array subscript ignored\n");
|
||||
|
||||
if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods, &mods)) {
|
||||
log_err(info->ctx,
|
||||
"Key type mask field must be a modifier mask; "
|
||||
"Key type definition ignored\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type->defined & TYPE_FIELD_MASK) {
|
||||
log_warn(info->ctx,
|
||||
"Multiple modifier mask definitions for key type %s; "
|
||||
"Using %s, ignoring %s\n",
|
||||
xkb_atom_text(info->ctx, type->name),
|
||||
TypeMaskTxt(info, type),
|
||||
ModMaskText(info->ctx, &info->mods, mods));
|
||||
return false;
|
||||
}
|
||||
|
||||
type->mods = mods;
|
||||
return true;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static struct xkb_key_type_entry *
|
||||
FindMatchingMapEntry(KeyTypeInfo *type, xkb_mod_mask_t mods)
|
||||
{
|
||||
struct xkb_key_type_entry *entry;
|
||||
|
||||
darray_foreach(entry, type->entries)
|
||||
if (entry->mods.mods == mods)
|
||||
return entry;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type,
|
||||
struct xkb_key_type_entry *new, bool clobber, bool report)
|
||||
{
|
||||
struct xkb_key_type_entry *old;
|
||||
|
||||
old = FindMatchingMapEntry(type, new->mods.mods);
|
||||
if (old) {
|
||||
if (report && old->level != new->level) {
|
||||
log_warn(info->ctx,
|
||||
"Multiple map entries for %s in %s; "
|
||||
"Using %d, ignoring %d\n",
|
||||
MapEntryTxt(info, new), TypeTxt(info, type),
|
||||
(clobber ? new->level : old->level) + 1,
|
||||
(clobber ? old->level : new->level) + 1);
|
||||
}
|
||||
else {
|
||||
log_vrb(info->ctx, 10,
|
||||
"Multiple occurrences of map[%s]= %d in %s; Ignored\n",
|
||||
MapEntryTxt(info, new), new->level + 1,
|
||||
TypeTxt(info, type));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (clobber) {
|
||||
if (new->level >= type->num_levels)
|
||||
type->num_levels = new->level + 1;
|
||||
old->level = new->level;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (new->level >= type->num_levels)
|
||||
type->num_levels = new->level + 1;
|
||||
|
||||
darray_append(type->entries, *new);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
|
||||
ExprDef *value)
|
||||
{
|
||||
struct xkb_key_type_entry entry;
|
||||
|
||||
if (arrayNdx == NULL)
|
||||
return ReportTypeShouldBeArray(info, type, "map entry");
|
||||
|
||||
if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods,
|
||||
&entry.mods.mods))
|
||||
return ReportTypeBadType(info, type, "map entry", "modifier mask");
|
||||
|
||||
if (entry.mods.mods & (~type->mods)) {
|
||||
log_vrb(info->ctx, 1,
|
||||
"Map entry for unused modifiers in %s; "
|
||||
"Using %s instead of %s\n",
|
||||
TypeTxt(info, type),
|
||||
ModMaskText(info->ctx, &info->mods,
|
||||
entry.mods.mods & type->mods),
|
||||
MapEntryTxt(info, &entry));
|
||||
entry.mods.mods &= type->mods;
|
||||
}
|
||||
|
||||
if (!ExprResolveLevel(info->ctx, value, &entry.level)) {
|
||||
log_err(info->ctx,
|
||||
"Level specifications in a key type must be integer; "
|
||||
"Ignoring malformed level specification\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
entry.preserve.mods = 0;
|
||||
|
||||
return AddMapEntry(info, type, &entry, true, true);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
|
||||
xkb_mod_mask_t mods, xkb_mod_mask_t preserve_mods)
|
||||
{
|
||||
struct xkb_key_type_entry *entry;
|
||||
struct xkb_key_type_entry new;
|
||||
|
||||
darray_foreach(entry, type->entries) {
|
||||
if (entry->mods.mods != mods)
|
||||
continue;
|
||||
|
||||
/* Map exists without previous preserve (or "None"); override. */
|
||||
if (entry->preserve.mods == 0) {
|
||||
entry->preserve.mods = preserve_mods;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Map exists with same preserve; do nothing. */
|
||||
if (entry->preserve.mods == preserve_mods) {
|
||||
log_vrb(info->ctx, 10,
|
||||
"Identical definitions for preserve[%s] in %s; "
|
||||
"Ignored\n",
|
||||
ModMaskText(info->ctx, &info->mods, mods),
|
||||
TypeTxt(info, type));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Map exists with different preserve; latter wins. */
|
||||
log_vrb(info->ctx, 1,
|
||||
"Multiple definitions for preserve[%s] in %s; "
|
||||
"Using %s, ignoring %s\n",
|
||||
ModMaskText(info->ctx, &info->mods, mods),
|
||||
TypeTxt(info, type),
|
||||
ModMaskText(info->ctx, &info->mods, preserve_mods),
|
||||
ModMaskText(info->ctx, &info->mods, entry->preserve.mods));
|
||||
|
||||
entry->preserve.mods = preserve_mods;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map does not exist, i.e. preserve[] came before map[].
|
||||
* Create a map with the specified mask mapping to Level1. The level
|
||||
* may be overridden later with an explicit map[] statement.
|
||||
*/
|
||||
new.level = 0;
|
||||
new.mods.mods = mods;
|
||||
new.preserve.mods = preserve_mods;
|
||||
darray_append(type->entries, new);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
|
||||
ExprDef *value)
|
||||
{
|
||||
xkb_mod_mask_t mods, preserve_mods;
|
||||
|
||||
if (arrayNdx == NULL)
|
||||
return ReportTypeShouldBeArray(info, type, "preserve entry");
|
||||
|
||||
if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods, &mods))
|
||||
return ReportTypeBadType(info, type, "preserve entry",
|
||||
"modifier mask");
|
||||
|
||||
if (mods & ~type->mods) {
|
||||
const char *before, *after;
|
||||
|
||||
before = ModMaskText(info->ctx, &info->mods, mods);
|
||||
mods &= type->mods;
|
||||
after = ModMaskText(info->ctx, &info->mods, mods);
|
||||
|
||||
log_vrb(info->ctx, 1,
|
||||
"Preserve for modifiers not used by the %s type; "
|
||||
"Index %s converted to %s\n",
|
||||
TypeTxt(info, type), before, after);
|
||||
}
|
||||
|
||||
if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods,
|
||||
&preserve_mods)) {
|
||||
log_err(info->ctx,
|
||||
"Preserve value in a key type is not a modifier mask; "
|
||||
"Ignoring preserve[%s] in type %s\n",
|
||||
ModMaskText(info->ctx, &info->mods, mods),
|
||||
TypeTxt(info, type));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preserve_mods & ~mods) {
|
||||
const char *before, *after;
|
||||
|
||||
before = ModMaskText(info->ctx, &info->mods, preserve_mods);
|
||||
preserve_mods &= mods;
|
||||
after = ModMaskText(info->ctx, &info->mods, preserve_mods);
|
||||
|
||||
log_vrb(info->ctx, 1,
|
||||
"Illegal value for preserve[%s] in type %s; "
|
||||
"Converted %s to %s\n",
|
||||
ModMaskText(info->ctx, &info->mods, mods),
|
||||
TypeTxt(info, type), before, after);
|
||||
}
|
||||
|
||||
return AddPreserve(info, type, mods, preserve_mods);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type,
|
||||
xkb_level_index_t level, xkb_atom_t name, bool clobber)
|
||||
{
|
||||
/* New name. */
|
||||
if (level >= darray_size(type->level_names)) {
|
||||
darray_resize0(type->level_names, level + 1);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Same level, same name. */
|
||||
if (darray_item(type->level_names, level) == name) {
|
||||
log_vrb(info->ctx, 10,
|
||||
"Duplicate names for level %d of key type %s; Ignored\n",
|
||||
level + 1, TypeTxt(info, type));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Same level, different name. */
|
||||
if (darray_item(type->level_names, level) != XKB_ATOM_NONE) {
|
||||
const char *old, *new;
|
||||
old = xkb_atom_text(info->ctx,
|
||||
darray_item(type->level_names, level));
|
||||
new = xkb_atom_text(info->ctx, name);
|
||||
log_vrb(info->ctx, 1,
|
||||
"Multiple names for level %d of key type %s; "
|
||||
"Using %s, ignoring %s\n",
|
||||
level + 1, TypeTxt(info, type),
|
||||
(clobber ? new : old), (clobber ? old : new));
|
||||
|
||||
if (!clobber)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* XXX: What about different level, same name? */
|
||||
|
||||
finish:
|
||||
darray_item(type->level_names, level) = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
SetLevelName(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
|
||||
ExprDef *value)
|
||||
{
|
||||
xkb_level_index_t level;
|
||||
xkb_atom_t level_name;
|
||||
|
||||
if (arrayNdx == NULL)
|
||||
return ReportTypeShouldBeArray(info, type, "level name");
|
||||
|
||||
if (!ExprResolveLevel(info->ctx, arrayNdx, &level))
|
||||
return ReportTypeBadType(info, type, "level name", "integer");
|
||||
|
||||
if (!ExprResolveString(info->ctx, value, &level_name)) {
|
||||
log_err(info->ctx,
|
||||
"Non-string name for level %d in key type %s; "
|
||||
"Ignoring illegal level name definition\n",
|
||||
level + 1, xkb_atom_text(info->ctx, type->name));
|
||||
return false;
|
||||
}
|
||||
|
||||
return AddLevelName(info, type, level, level_name, true);
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
SetKeyTypeField(KeyTypesInfo *info, KeyTypeInfo *type,
|
||||
const char *field, ExprDef *arrayNdx, ExprDef *value)
|
||||
{
|
||||
bool ok = false;
|
||||
enum type_field type_field = 0;
|
||||
|
||||
if (istreq(field, "modifiers")) {
|
||||
type_field = TYPE_FIELD_MASK;
|
||||
ok = SetModifiers(info, type, arrayNdx, value);
|
||||
}
|
||||
else if (istreq(field, "map")) {
|
||||
type_field = TYPE_FIELD_MAP;
|
||||
ok = SetMapEntry(info, type, arrayNdx, value);
|
||||
}
|
||||
else if (istreq(field, "preserve")) {
|
||||
type_field = TYPE_FIELD_PRESERVE;
|
||||
ok = SetPreserve(info, type, arrayNdx, value);
|
||||
}
|
||||
else if (istreq(field, "levelname") || istreq(field, "level_name")) {
|
||||
type_field = TYPE_FIELD_LEVEL_NAME;
|
||||
ok = SetLevelName(info, type, arrayNdx, value);
|
||||
} else {
|
||||
log_err(info->ctx,
|
||||
"Unknown field %s in key type %s; Definition ignored\n",
|
||||
field, TypeTxt(info, type));
|
||||
}
|
||||
|
||||
type->defined |= type_field;
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleKeyTypeBody(KeyTypesInfo *info, VarDef *def, KeyTypeInfo *type)
|
||||
{
|
||||
bool ok = true;
|
||||
const char *elem, *field;
|
||||
ExprDef *arrayNdx;
|
||||
|
||||
for (; def; def = (VarDef *) def->common.next) {
|
||||
ok = ExprResolveLhs(info->ctx, def->name, &elem, &field,
|
||||
&arrayNdx);
|
||||
if (!ok)
|
||||
continue;
|
||||
|
||||
if (elem && istreq(elem, "type")) {
|
||||
log_err(info->ctx,
|
||||
"Support for changing the default type has been removed; "
|
||||
"Statement ignored\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
ok = SetKeyTypeField(info, type, field, arrayNdx, def->value);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool
|
||||
HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge)
|
||||
{
|
||||
KeyTypeInfo type = {
|
||||
.defined = 0,
|
||||
.merge = (def->merge == MERGE_DEFAULT ? merge : def->merge),
|
||||
.name = def->name,
|
||||
.mods = 0,
|
||||
.num_levels = 1,
|
||||
.entries = darray_new(),
|
||||
.level_names = darray_new(),
|
||||
};
|
||||
|
||||
if (!HandleKeyTypeBody(info, def->body, &type)) {
|
||||
info->errorCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AddKeyType(info, &type, true)) {
|
||||
info->errorCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
free(info->name);
|
||||
info->name = strdup_safe(file->name);
|
||||
|
||||
for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
|
||||
switch (stmt->type) {
|
||||
case STMT_INCLUDE:
|
||||
ok = HandleIncludeKeyTypes(info, (IncludeStmt *) stmt);
|
||||
break;
|
||||
case STMT_TYPE:
|
||||
ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge);
|
||||
break;
|
||||
case STMT_VAR:
|
||||
log_err(info->ctx,
|
||||
"Support for changing the default type has been removed; "
|
||||
"Statement ignored\n");
|
||||
ok = true;
|
||||
break;
|
||||
case STMT_VMOD:
|
||||
ok = HandleVModDef(info->ctx, &info->mods, (VModDef *) stmt, merge);
|
||||
break;
|
||||
default:
|
||||
log_err(info->ctx,
|
||||
"Key type files may not include other declarations; "
|
||||
"Ignoring %s\n", stmt_type_to_string(stmt->type));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
info->errorCount++;
|
||||
|
||||
if (info->errorCount > 10) {
|
||||
log_err(info->ctx,
|
||||
"Abandoning keytypes file \"%s\"\n", file->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static bool
|
||||
CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
|
||||
{
|
||||
unsigned num_types;
|
||||
struct xkb_key_type *types;
|
||||
|
||||
num_types = darray_empty(info->types) ? 1 : darray_size(info->types);
|
||||
types = calloc(num_types, sizeof(*types));
|
||||
if (!types)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If no types were specified, a default unnamed one-level type is
|
||||
* used for all keys.
|
||||
*/
|
||||
if (darray_empty(info->types)) {
|
||||
struct xkb_key_type *type = &types[0];
|
||||
|
||||
type->mods.mods = 0;
|
||||
type->num_levels = 1;
|
||||
type->entries = NULL;
|
||||
type->num_entries = 0;
|
||||
type->name = xkb_atom_intern_literal(keymap->ctx, "default");
|
||||
type->level_names = NULL;
|
||||
type->num_level_names = 0;
|
||||
}
|
||||
else {
|
||||
for (unsigned i = 0; i < num_types; i++) {
|
||||
KeyTypeInfo *def = &darray_item(info->types, i);
|
||||
struct xkb_key_type *type = &types[i];
|
||||
|
||||
type->name = def->name;
|
||||
type->mods.mods = def->mods;
|
||||
type->num_levels = def->num_levels;
|
||||
darray_steal(def->level_names, &type->level_names, &type->num_level_names);
|
||||
darray_steal(def->entries, &type->entries, &type->num_entries);
|
||||
}
|
||||
}
|
||||
|
||||
keymap->types_section_name = strdup_safe(info->name);
|
||||
XkbEscapeMapName(keymap->types_section_name);
|
||||
keymap->num_types = num_types;
|
||||
keymap->types = types;
|
||||
keymap->mods = info->mods;
|
||||
return true;
|
||||
}
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
bool
|
||||
CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
|
||||
enum merge_mode merge)
|
||||
{
|
||||
KeyTypesInfo info;
|
||||
|
||||
InitKeyTypesInfo(&info, keymap->ctx, &keymap->mods);
|
||||
|
||||
HandleKeyTypesFile(&info, file, merge);
|
||||
if (info.errorCount != 0)
|
||||
goto err_info;
|
||||
|
||||
if (!CopyKeyTypesToKeymap(keymap, &info))
|
||||
goto err_info;
|
||||
|
||||
ClearKeyTypesInfo(&info);
|
||||
return true;
|
||||
|
||||
err_info:
|
||||
ClearKeyTypesInfo(&info);
|
||||
return false;
|
||||
}
|
105
src/3rdparty/xkbcommon/src/xkbcomp/vmod.c
vendored
105
src/3rdparty/xkbcommon/src/xkbcomp/vmod.c
vendored
@ -1,105 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "text.h"
|
||||
#include "expr.h"
|
||||
#include "vmod.h"
|
||||
|
||||
bool
|
||||
HandleVModDef(struct xkb_context *ctx, struct xkb_mod_set *mods,
|
||||
VModDef *stmt, enum merge_mode merge)
|
||||
{
|
||||
xkb_mod_index_t i;
|
||||
struct xkb_mod *mod;
|
||||
xkb_mod_mask_t mapping;
|
||||
|
||||
merge = (merge == MERGE_DEFAULT ? stmt->merge : merge);
|
||||
|
||||
if (stmt->value) {
|
||||
/*
|
||||
* This is a statement such as 'virtualModifiers NumLock = Mod1';
|
||||
* it sets the vmod-to-real-mod[s] mapping directly instead of going
|
||||
* through modifier_map or some such.
|
||||
*/
|
||||
if (!ExprResolveModMask(ctx, stmt->value, MOD_REAL, mods, &mapping)) {
|
||||
log_err(ctx,
|
||||
"Declaration of %s ignored\n",
|
||||
xkb_atom_text(ctx, stmt->name));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mapping = 0;
|
||||
}
|
||||
|
||||
xkb_mods_enumerate(i, mod, mods) {
|
||||
if (mod->name == stmt->name) {
|
||||
if (mod->type != MOD_VIRT) {
|
||||
log_err(ctx,
|
||||
"Can't add a virtual modifier named \"%s\"; "
|
||||
"there is already a non-virtual modifier with this name! Ignored\n",
|
||||
xkb_atom_text(ctx, mod->name));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mod->mapping == mapping)
|
||||
return true;
|
||||
|
||||
if (mod->mapping != 0) {
|
||||
xkb_mod_mask_t use, ignore;
|
||||
|
||||
use = (merge == MERGE_OVERRIDE ? mapping : mod->mapping);
|
||||
ignore = (merge == MERGE_OVERRIDE ? mod->mapping : mapping);
|
||||
|
||||
log_warn(ctx,
|
||||
"Virtual modifier %s defined multiple times; "
|
||||
"Using %s, ignoring %s\n",
|
||||
xkb_atom_text(ctx, stmt->name),
|
||||
ModMaskText(ctx, mods, use),
|
||||
ModMaskText(ctx, mods, ignore));
|
||||
|
||||
mapping = use;
|
||||
}
|
||||
|
||||
mod->mapping = mapping;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mods->num_mods >= XKB_MAX_MODS) {
|
||||
log_err(ctx,
|
||||
"Too many modifiers defined (maximum %d)\n",
|
||||
XKB_MAX_MODS);
|
||||
return false;
|
||||
}
|
||||
|
||||
mods->mods[mods->num_mods].name = stmt->name;
|
||||
mods->mods[mods->num_mods].type = MOD_VIRT;
|
||||
mods->mods[mods->num_mods].mapping = mapping;
|
||||
mods->num_mods++;
|
||||
return true;
|
||||
}
|
34
src/3rdparty/xkbcommon/src/xkbcomp/vmod.h
vendored
34
src/3rdparty/xkbcommon/src/xkbcomp/vmod.h
vendored
@ -1,34 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#ifndef XKBCOMP_VMOD_H
|
||||
#define XKBCOMP_VMOD_H
|
||||
|
||||
bool
|
||||
HandleVModDef(struct xkb_context *ctx, struct xkb_mod_set *mods,
|
||||
VModDef *stmt, enum merge_mode merge);
|
||||
|
||||
#endif
|
298
src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-keymap.c
vendored
298
src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-keymap.c
vendored
@ -1,298 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 Dan Nicholson
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Dan Nicholson <dbn.lists@gmail.com>
|
||||
* Daniel Stone <daniel@fooishbar.org>
|
||||
* Ran Benita <ran234@gmail.com>
|
||||
*/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
|
||||
static void
|
||||
ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods)
|
||||
{
|
||||
mods->mask = mod_mask_get_effective(keymap, mods->mods);
|
||||
}
|
||||
|
||||
static void
|
||||
UpdateActionMods(struct xkb_keymap *keymap, union xkb_action *act,
|
||||
xkb_mod_mask_t modmap)
|
||||
{
|
||||
switch (act->type) {
|
||||
case ACTION_TYPE_MOD_SET:
|
||||
case ACTION_TYPE_MOD_LATCH:
|
||||
case ACTION_TYPE_MOD_LOCK:
|
||||
if (act->mods.flags & ACTION_MODS_LOOKUP_MODMAP)
|
||||
act->mods.mods.mods = modmap;
|
||||
ComputeEffectiveMask(keymap, &act->mods.mods);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct xkb_sym_interpret default_interpret = {
|
||||
.sym = XKB_KEY_NoSymbol,
|
||||
.repeat = true,
|
||||
.match = MATCH_ANY_OR_NONE,
|
||||
.mods = 0,
|
||||
.virtual_mod = XKB_MOD_INVALID,
|
||||
.action = { .type = ACTION_TYPE_NONE },
|
||||
};
|
||||
|
||||
/**
|
||||
* Find an interpretation which applies to this particular level, either by
|
||||
* finding an exact match for the symbol and modifier combination, or a
|
||||
* generic XKB_KEY_NoSymbol match.
|
||||
*/
|
||||
static const struct xkb_sym_interpret *
|
||||
FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
|
||||
xkb_layout_index_t group, xkb_level_index_t level)
|
||||
{
|
||||
const xkb_keysym_t *syms;
|
||||
int num_syms;
|
||||
|
||||
num_syms = xkb_keymap_key_get_syms_by_level(keymap, key->keycode, group,
|
||||
level, &syms);
|
||||
if (num_syms == 0)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* There may be multiple matchings interprets; we should always return
|
||||
* the most specific. Here we rely on compat.c to set up the
|
||||
* sym_interprets array from the most specific to the least specific,
|
||||
* such that when we find a match we return immediately.
|
||||
*/
|
||||
for (unsigned i = 0; i < keymap->num_sym_interprets; i++) {
|
||||
const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i];
|
||||
|
||||
xkb_mod_mask_t mods;
|
||||
bool found = false;
|
||||
|
||||
if ((num_syms > 1 || interp->sym != syms[0]) &&
|
||||
interp->sym != XKB_KEY_NoSymbol)
|
||||
continue;
|
||||
|
||||
if (interp->level_one_only && level != 0)
|
||||
mods = 0;
|
||||
else
|
||||
mods = key->modmap;
|
||||
|
||||
switch (interp->match) {
|
||||
case MATCH_NONE:
|
||||
found = !(interp->mods & mods);
|
||||
break;
|
||||
case MATCH_ANY_OR_NONE:
|
||||
found = (!mods || (interp->mods & mods));
|
||||
break;
|
||||
case MATCH_ANY:
|
||||
found = (interp->mods & mods);
|
||||
break;
|
||||
case MATCH_ALL:
|
||||
found = ((interp->mods & mods) == interp->mods);
|
||||
break;
|
||||
case MATCH_EXACTLY:
|
||||
found = (interp->mods == mods);
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
return interp;
|
||||
}
|
||||
|
||||
return &default_interpret;
|
||||
}
|
||||
|
||||
static bool
|
||||
ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
|
||||
{
|
||||
xkb_mod_mask_t vmodmap = 0;
|
||||
xkb_layout_index_t group;
|
||||
xkb_level_index_t level;
|
||||
|
||||
/* If we've been told not to bind interps to this key, then don't. */
|
||||
if (key->explicit & EXPLICIT_INTERP)
|
||||
return true;
|
||||
|
||||
for (group = 0; group < key->num_groups; group++) {
|
||||
for (level = 0; level < XkbKeyNumLevels(key, group); level++) {
|
||||
const struct xkb_sym_interpret *interp;
|
||||
|
||||
interp = FindInterpForKey(keymap, key, group, level);
|
||||
if (!interp)
|
||||
continue;
|
||||
|
||||
/* Infer default key behaviours from the base level. */
|
||||
if (group == 0 && level == 0)
|
||||
if (!(key->explicit & EXPLICIT_REPEAT) && interp->repeat)
|
||||
key->repeats = true;
|
||||
|
||||
if ((group == 0 && level == 0) || !interp->level_one_only)
|
||||
if (interp->virtual_mod != XKB_MOD_INVALID)
|
||||
vmodmap |= (1u << interp->virtual_mod);
|
||||
|
||||
if (interp->action.type != ACTION_TYPE_NONE)
|
||||
key->groups[group].levels[level].action = interp->action;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(key->explicit & EXPLICIT_VMODMAP))
|
||||
key->vmodmap = vmodmap;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This collects a bunch of disparate functions which was done in the server
|
||||
* at various points that really should've been done within xkbcomp. Turns out
|
||||
* your actions and types are a lot more useful when any of your modifiers
|
||||
* other than Shift actually do something ...
|
||||
*/
|
||||
static bool
|
||||
UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
|
||||
{
|
||||
struct xkb_key *key;
|
||||
struct xkb_mod *mod;
|
||||
struct xkb_led *led;
|
||||
unsigned int i, j;
|
||||
|
||||
/* Find all the interprets for the key and bind them to actions,
|
||||
* which will also update the vmodmap. */
|
||||
xkb_keys_foreach(key, keymap)
|
||||
if (!ApplyInterpsToKey(keymap, key))
|
||||
return false;
|
||||
|
||||
/* Update keymap->mods, the virtual -> real mod mapping. */
|
||||
xkb_keys_foreach(key, keymap)
|
||||
xkb_mods_enumerate(i, mod, &keymap->mods)
|
||||
if (key->vmodmap & (1u << i))
|
||||
mod->mapping |= key->modmap;
|
||||
|
||||
/* Now update the level masks for all the types to reflect the vmods. */
|
||||
for (i = 0; i < keymap->num_types; i++) {
|
||||
ComputeEffectiveMask(keymap, &keymap->types[i].mods);
|
||||
|
||||
for (j = 0; j < keymap->types[i].num_entries; j++) {
|
||||
ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].mods);
|
||||
ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].preserve);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update action modifiers. */
|
||||
xkb_keys_foreach(key, keymap)
|
||||
for (i = 0; i < key->num_groups; i++)
|
||||
for (j = 0; j < XkbKeyNumLevels(key, i); j++)
|
||||
UpdateActionMods(keymap, &key->groups[i].levels[j].action,
|
||||
key->modmap);
|
||||
|
||||
/* Update vmod -> led maps. */
|
||||
xkb_leds_foreach(led, keymap)
|
||||
ComputeEffectiveMask(keymap, &led->mods);
|
||||
|
||||
/* Find maximum number of groups out of all keys in the keymap. */
|
||||
xkb_keys_foreach(key, keymap)
|
||||
keymap->num_groups = MAX(keymap->num_groups, key->num_groups);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*compile_file_fn)(XkbFile *file,
|
||||
struct xkb_keymap *keymap,
|
||||
enum merge_mode merge);
|
||||
|
||||
static const compile_file_fn compile_file_fns[LAST_KEYMAP_FILE_TYPE + 1] = {
|
||||
[FILE_TYPE_KEYCODES] = CompileKeycodes,
|
||||
[FILE_TYPE_TYPES] = CompileKeyTypes,
|
||||
[FILE_TYPE_COMPAT] = CompileCompatMap,
|
||||
[FILE_TYPE_SYMBOLS] = CompileSymbols,
|
||||
};
|
||||
|
||||
bool
|
||||
CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
|
||||
{
|
||||
bool ok;
|
||||
XkbFile *files[LAST_KEYMAP_FILE_TYPE + 1] = { NULL };
|
||||
enum xkb_file_type type;
|
||||
struct xkb_context *ctx = keymap->ctx;
|
||||
|
||||
/* Collect section files and check for duplicates. */
|
||||
for (file = (XkbFile *) file->defs; file;
|
||||
file = (XkbFile *) file->common.next) {
|
||||
if (file->file_type < FIRST_KEYMAP_FILE_TYPE ||
|
||||
file->file_type > LAST_KEYMAP_FILE_TYPE) {
|
||||
if (file->file_type == FILE_TYPE_GEOMETRY) {
|
||||
log_vrb(ctx, 1,
|
||||
"Geometry sections are not supported; ignoring\n");
|
||||
} else {
|
||||
log_err(ctx, "Cannot define %s in a keymap file\n",
|
||||
xkb_file_type_to_string(file->file_type));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (files[file->file_type]) {
|
||||
log_err(ctx,
|
||||
"More than one %s section in keymap file; "
|
||||
"All sections after the first ignored\n",
|
||||
xkb_file_type_to_string(file->file_type));
|
||||
continue;
|
||||
}
|
||||
|
||||
files[file->file_type] = file;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that all required section were provided.
|
||||
* Report everything before failing.
|
||||
*/
|
||||
ok = true;
|
||||
for (type = FIRST_KEYMAP_FILE_TYPE;
|
||||
type <= LAST_KEYMAP_FILE_TYPE;
|
||||
type++) {
|
||||
if (files[type] == NULL) {
|
||||
log_err(ctx, "Required section %s missing from keymap\n",
|
||||
xkb_file_type_to_string(type));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
/* Compile sections. */
|
||||
for (type = FIRST_KEYMAP_FILE_TYPE;
|
||||
type <= LAST_KEYMAP_FILE_TYPE;
|
||||
type++) {
|
||||
log_dbg(ctx, "Compiling %s \"%s\"\n",
|
||||
xkb_file_type_to_string(type), files[type]->name);
|
||||
|
||||
ok = compile_file_fns[type](files[type], keymap, merge);
|
||||
if (!ok) {
|
||||
log_err(ctx, "Failed to compile %s\n",
|
||||
xkb_file_type_to_string(type));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return UpdateDerivedKeymapFields(keymap);
|
||||
}
|
3392
src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-parser.c
vendored
3392
src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-parser.c
vendored
File diff suppressed because it is too large
Load Diff
124
src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h
vendored
124
src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h
vendored
@ -1,124 +0,0 @@
|
||||
/************************************************************
|
||||
* Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Silicon Graphics not be
|
||||
* used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific prior written permission.
|
||||
* Silicon Graphics makes no representation about the suitability
|
||||
* of this software for any purpose. It is provided "as is"
|
||||
* without any express or implied warranty.
|
||||
*
|
||||
* SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
* GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
********************************************************/
|
||||
|
||||
#ifndef XKBCOMP_PRIV_H
|
||||
#define XKBCOMP_PRIV_H
|
||||
|
||||
#include "keymap.h"
|
||||
#include "ast.h"
|
||||
|
||||
struct xkb_component_names {
|
||||
char *keycodes;
|
||||
char *types;
|
||||
char *compat;
|
||||
char *symbols;
|
||||
};
|
||||
|
||||
char *
|
||||
text_v1_keymap_get_as_string(struct xkb_keymap *keymap);
|
||||
|
||||
XkbFile *
|
||||
XkbParseFile(struct xkb_context *ctx, FILE *file,
|
||||
const char *file_name, const char *map);
|
||||
|
||||
XkbFile *
|
||||
XkbParseString(struct xkb_context *ctx,
|
||||
const char *string, size_t len,
|
||||
const char *file_name, const char *map);
|
||||
|
||||
void
|
||||
FreeXkbFile(XkbFile *file);
|
||||
|
||||
XkbFile *
|
||||
XkbFileFromComponents(struct xkb_context *ctx,
|
||||
const struct xkb_component_names *kkctgs);
|
||||
|
||||
bool
|
||||
CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap,
|
||||
enum merge_mode merge);
|
||||
|
||||
bool
|
||||
CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap,
|
||||
enum merge_mode merge);
|
||||
|
||||
bool
|
||||
CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap,
|
||||
enum merge_mode merge);
|
||||
|
||||
bool
|
||||
CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
|
||||
enum merge_mode merge);
|
||||
|
||||
bool
|
||||
CompileKeymap(XkbFile *file, struct xkb_keymap *keymap,
|
||||
enum merge_mode merge);
|
||||
|
||||
/***====================================================================***/
|
||||
|
||||
static inline bool
|
||||
ReportNotArray(struct xkb_context *ctx, const char *type, const char *field,
|
||||
const char *name)
|
||||
{
|
||||
log_err(ctx,
|
||||
"The %s %s field is not an array; "
|
||||
"Ignoring illegal assignment in %s\n",
|
||||
type, field, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportShouldBeArray(struct xkb_context *ctx, const char *type,
|
||||
const char *field, const char *name)
|
||||
{
|
||||
log_err(ctx,
|
||||
"Missing subscript for %s %s; "
|
||||
"Ignoring illegal assignment in %s\n",
|
||||
type, field, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportBadType(struct xkb_context *ctx, const char *type, const char *field,
|
||||
const char *name, const char *wanted)
|
||||
{
|
||||
log_err(ctx, "The %s %s field must be a %s; "
|
||||
"Ignoring illegal assignment in %s\n",
|
||||
type, field, wanted, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ReportBadField(struct xkb_context *ctx, const char *type, const char *field,
|
||||
const char *name)
|
||||
{
|
||||
log_err(ctx,
|
||||
"Unknown %s field %s in %s; "
|
||||
"Ignoring assignment to unknown field in %s\n",
|
||||
type, field, name, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
139
src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
vendored
139
src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
vendored
@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 Dan Nicholson
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Dan Nicholson <dbn.lists@gmail.com>
|
||||
* Ran Benita <ran234@gmail.com>
|
||||
* Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#include "xkbcomp-priv.h"
|
||||
#include "rules.h"
|
||||
|
||||
static bool
|
||||
compile_keymap_file(struct xkb_keymap *keymap, XkbFile *file)
|
||||
{
|
||||
if (file->file_type != FILE_TYPE_KEYMAP) {
|
||||
log_err(keymap->ctx,
|
||||
"Cannot compile a %s file alone into a keymap\n",
|
||||
xkb_file_type_to_string(file->file_type));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CompileKeymap(file, keymap, MERGE_OVERRIDE)) {
|
||||
log_err(keymap->ctx,
|
||||
"Failed to compile keymap\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
text_v1_keymap_new_from_names(struct xkb_keymap *keymap,
|
||||
const struct xkb_rule_names *rmlvo)
|
||||
{
|
||||
bool ok;
|
||||
struct xkb_component_names kccgst;
|
||||
XkbFile *file;
|
||||
|
||||
log_dbg(keymap->ctx,
|
||||
"Compiling from RMLVO: rules '%s', model '%s', layout '%s', "
|
||||
"variant '%s', options '%s'\n",
|
||||
rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant,
|
||||
rmlvo->options);
|
||||
|
||||
ok = xkb_components_from_rules(keymap->ctx, rmlvo, &kccgst);
|
||||
if (!ok) {
|
||||
log_err(keymap->ctx,
|
||||
"Couldn't look up rules '%s', model '%s', layout '%s', "
|
||||
"variant '%s', options '%s'\n",
|
||||
rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant,
|
||||
rmlvo->options);
|
||||
return false;
|
||||
}
|
||||
|
||||
log_dbg(keymap->ctx,
|
||||
"Compiling from KcCGST: keycodes '%s', types '%s', "
|
||||
"compat '%s', symbols '%s'\n",
|
||||
kccgst.keycodes, kccgst.types, kccgst.compat, kccgst.symbols);
|
||||
|
||||
file = XkbFileFromComponents(keymap->ctx, &kccgst);
|
||||
|
||||
free(kccgst.keycodes);
|
||||
free(kccgst.types);
|
||||
free(kccgst.compat);
|
||||
free(kccgst.symbols);
|
||||
|
||||
if (!file) {
|
||||
log_err(keymap->ctx,
|
||||
"Failed to generate parsed XKB file from components\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = compile_keymap_file(keymap, file);
|
||||
FreeXkbFile(file);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool
|
||||
text_v1_keymap_new_from_string(struct xkb_keymap *keymap,
|
||||
const char *string, size_t len)
|
||||
{
|
||||
bool ok;
|
||||
XkbFile *xkb_file;
|
||||
|
||||
xkb_file = XkbParseString(keymap->ctx, string, len, "(input string)", NULL);
|
||||
if (!xkb_file) {
|
||||
log_err(keymap->ctx, "Failed to parse input xkb string\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ok = compile_keymap_file(keymap, xkb_file);
|
||||
FreeXkbFile(xkb_file);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool
|
||||
text_v1_keymap_new_from_file(struct xkb_keymap *keymap, FILE *file)
|
||||
{
|
||||
bool ok;
|
||||
XkbFile *xkb_file;
|
||||
|
||||
xkb_file = XkbParseFile(keymap->ctx, file, "(unknown file)", NULL);
|
||||
if (!xkb_file) {
|
||||
log_err(keymap->ctx, "Failed to parse input xkb file\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = compile_keymap_file(keymap, xkb_file);
|
||||
FreeXkbFile(xkb_file);
|
||||
return ok;
|
||||
}
|
||||
|
||||
const struct xkb_keymap_format_ops text_v1_keymap_format_ops = {
|
||||
.keymap_new_from_names = text_v1_keymap_new_from_names,
|
||||
.keymap_new_from_string = text_v1_keymap_new_from_string,
|
||||
.keymap_new_from_file = text_v1_keymap_new_from_file,
|
||||
.keymap_get_as_string = text_v1_keymap_get_as_string,
|
||||
};
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Daniel Stone
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#ifndef _XKBCOMMON_COMPAT_H
|
||||
#define _XKBCOMMON_COMPAT_H
|
||||
|
||||
/**
|
||||
* Renamed keymap API.
|
||||
*/
|
||||
#define xkb_group_index_t xkb_layout_index_t
|
||||
#define xkb_group_mask_t xkb_layout_mask_t
|
||||
#define xkb_map_compile_flags xkb_keymap_compile_flags
|
||||
#define XKB_GROUP_INVALID XKB_LAYOUT_INVALID
|
||||
|
||||
#define XKB_STATE_DEPRESSED \
|
||||
(XKB_STATE_MODS_DEPRESSED | XKB_STATE_LAYOUT_DEPRESSED)
|
||||
#define XKB_STATE_LATCHED \
|
||||
(XKB_STATE_MODS_LATCHED | XKB_STATE_LAYOUT_LATCHED)
|
||||
#define XKB_STATE_LOCKED \
|
||||
(XKB_STATE_MODS_LOCKED | XKB_STATE_LAYOUT_LOCKED)
|
||||
#define XKB_STATE_EFFECTIVE \
|
||||
(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED | XKB_STATE_LOCKED | \
|
||||
XKB_STATE_MODS_EFFECTIVE | XKB_STATE_LAYOUT_EFFECTIVE)
|
||||
|
||||
#define xkb_map_new_from_names(context, names, flags) \
|
||||
xkb_keymap_new_from_names(context, names, flags)
|
||||
#define xkb_map_new_from_file(context, file, format, flags) \
|
||||
xkb_keymap_new_from_file(context, file, format, flags)
|
||||
#define xkb_map_new_from_string(context, string, format, flags) \
|
||||
xkb_keymap_new_from_string(context, string, format, flags)
|
||||
#define xkb_map_get_as_string(keymap) \
|
||||
xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1)
|
||||
#define xkb_map_ref(keymap) xkb_keymap_ref(keymap)
|
||||
#define xkb_map_unref(keymap) xkb_keymap_unref(keymap)
|
||||
|
||||
#define xkb_map_num_mods(keymap) xkb_keymap_num_mods(keymap)
|
||||
#define xkb_map_mod_get_name(keymap, idx) xkb_keymap_mod_get_name(keymap, idx)
|
||||
#define xkb_map_mod_get_index(keymap, str) xkb_keymap_mod_get_index(keymap, str)
|
||||
#define xkb_key_mod_index_is_consumed(state, key, mod) \
|
||||
xkb_state_mod_index_is_consumed(state, key, mod)
|
||||
#define xkb_key_mod_mask_remove_consumed(state, key, modmask) \
|
||||
xkb_state_mod_mask_remove_consumed(state, key, modmask)
|
||||
|
||||
#define xkb_map_num_groups(keymap) xkb_keymap_num_layouts(keymap)
|
||||
#define xkb_key_num_groups(keymap, key) \
|
||||
xkb_keymap_num_layouts_for_key(keymap, key)
|
||||
#define xkb_map_group_get_name(keymap, idx) \
|
||||
xkb_keymap_layout_get_name(keymap, idx)
|
||||
#define xkb_map_group_get_index(keymap, str) \
|
||||
xkb_keymap_layout_get_index(keymap, str)
|
||||
|
||||
#define xkb_map_num_leds(keymap) xkb_keymap_num_leds(keymap)
|
||||
#define xkb_map_led_get_name(keymap, idx) xkb_keymap_led_get_name(keymap, idx)
|
||||
#define xkb_map_led_get_index(keymap, str) \
|
||||
xkb_keymap_led_get_index(keymap, str)
|
||||
|
||||
#define xkb_key_repeats(keymap, key) xkb_keymap_key_repeats(keymap, key)
|
||||
|
||||
#define xkb_key_get_syms(state, key, syms_out) \
|
||||
xkb_state_key_get_syms(state, key, syms_out)
|
||||
|
||||
#define xkb_state_group_name_is_active(state, name, type) \
|
||||
xkb_state_layout_name_is_active(state, name, type)
|
||||
#define xkb_state_group_index_is_active(state, idx, type) \
|
||||
xkb_state_layout_index_is_active(state, idx, type)
|
||||
|
||||
#define xkb_state_serialize_group(state, component) \
|
||||
xkb_state_serialize_layout(state, component)
|
||||
|
||||
#define xkb_state_get_map(state) xkb_state_get_keymap(state)
|
||||
|
||||
/* Not needed anymore, since there's NO_FLAGS. */
|
||||
#define XKB_MAP_COMPILE_PLACEHOLDER XKB_KEYMAP_COMPILE_NO_FLAGS
|
||||
#define XKB_MAP_COMPILE_NO_FLAGS XKB_KEYMAP_COMPILE_NO_FLAGS
|
||||
|
||||
#endif
|
493
src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compose.h
vendored
493
src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compose.h
vendored
@ -1,493 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _XKBCOMMON_COMPOSE_H
|
||||
#define _XKBCOMMON_COMPOSE_H
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libxkbcommon Compose API - support for Compose and dead-keys.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup compose Compose and dead-keys support
|
||||
* Support for Compose and dead-keys.
|
||||
* @since 0.5.0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page compose-overview Overview
|
||||
* @parblock
|
||||
*
|
||||
* Compose and dead-keys are a common feature of many keyboard input
|
||||
* systems. They extend the range of the keysysm that can be produced
|
||||
* directly from a keyboard by using a sequence of key strokes, instead
|
||||
* of just one.
|
||||
*
|
||||
* Here are some example sequences, in the libX11 Compose file format:
|
||||
*
|
||||
* <dead_acute> <a> : "á" aacute # LATIN SMALL LETTER A WITH ACUTE
|
||||
* <Multi_key> <A> <T> : "@" at # COMMERCIAL AT
|
||||
*
|
||||
* When the user presses a key which produces the `<dead_acute>` keysym,
|
||||
* nothing initially happens (thus the key is dubbed a "dead-key"). But
|
||||
* when the user enters `<a>`, "á" is "composed", in place of "a". If
|
||||
* instead the user had entered a keysym which does not follow
|
||||
* `<dead_acute>` in any compose sequence, the sequence is said to be
|
||||
* "cancelled".
|
||||
*
|
||||
* Compose files define many such sequences. For a description of the
|
||||
* common file format for Compose files, see the Compose(5) man page.
|
||||
*
|
||||
* A successfuly-composed sequence has two results: a keysym and a UTF-8
|
||||
* string. At least one of the two is defined for each sequence. If only
|
||||
* a keysym is given, the keysym's string representation is used for the
|
||||
* result string (using xkb_keysym_to_utf8()).
|
||||
*
|
||||
* This library provides low-level support for Compose file parsing and
|
||||
* processing. Higher-level APIs (such as libX11's `Xutf8LookupString`(3))
|
||||
* may be built upon it, or it can be used directly.
|
||||
*
|
||||
* @endparblock
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page compose-conflicting Conflicting Sequences
|
||||
* @parblock
|
||||
*
|
||||
* To avoid ambiguity, a sequence is not allowed to be a prefix of another.
|
||||
* In such a case, the conflict is resolved thus:
|
||||
*
|
||||
* 1. A longer sequence overrides a shorter one.
|
||||
* 2. An equal sequence overrides an existing one.
|
||||
* 3. A shorter sequence does not override a longer one.
|
||||
*
|
||||
* Sequences of length 1 are allowed.
|
||||
*
|
||||
* @endparblock
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page compose-cancellation Cancellation Behavior
|
||||
* @parblock
|
||||
*
|
||||
* What should happen when a sequence is cancelled? For example, consider
|
||||
* there are only the above sequences, and the input keysyms are
|
||||
* `<dead_acute> <b>`. There are a few approaches:
|
||||
*
|
||||
* 1. Swallow the cancelling keysym; that is, no keysym is produced.
|
||||
* This is the approach taken by libX11.
|
||||
* 2. Let the cancelling keysym through; that is, `<b>` is produced.
|
||||
* 3. Replay the entire sequence; that is, `<dead_acute> <b>` is produced.
|
||||
* This is the approach taken by Microsoft Windows (approximately;
|
||||
* instead of `<dead_acute>`, the underlying key is used. This is
|
||||
* difficult to simulate with XKB keymaps).
|
||||
*
|
||||
* You can program whichever approach best fits users' expectations.
|
||||
*
|
||||
* @endparblock
|
||||
*/
|
||||
|
||||
/**
|
||||
* @struct xkb_compose_table
|
||||
* Opaque Compose table object.
|
||||
*
|
||||
* The compose table holds the definitions of the Compose sequences, as
|
||||
* gathered from Compose files. It is immutable.
|
||||
*/
|
||||
struct xkb_compose_table;
|
||||
|
||||
/**
|
||||
* @struct xkb_compose_state
|
||||
* Opaque Compose state object.
|
||||
*
|
||||
* The compose state maintains state for compose sequence matching, such
|
||||
* as which possible sequences are being matched, and the position within
|
||||
* these sequences. It acts as a simple state machine wherein keysyms are
|
||||
* the input, and composed keysyms and strings are the output.
|
||||
*
|
||||
* The compose state is usually associated with a keyboard device.
|
||||
*/
|
||||
struct xkb_compose_state;
|
||||
|
||||
/** Flags affecting Compose file compilation. */
|
||||
enum xkb_compose_compile_flags {
|
||||
/** Do not apply any flags. */
|
||||
XKB_COMPOSE_COMPILE_NO_FLAGS = 0
|
||||
};
|
||||
|
||||
/** The recognized Compose file formats. */
|
||||
enum xkb_compose_format {
|
||||
/** The classic libX11 Compose text format, described in Compose(5). */
|
||||
XKB_COMPOSE_FORMAT_TEXT_V1 = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* @page compose-locale Compose Locale
|
||||
* @parblock
|
||||
*
|
||||
* Compose files are locale dependent:
|
||||
* - Compose files are written for a locale, and the locale is used when
|
||||
* searching for the appropriate file to use.
|
||||
* - Compose files may reference the locale internally, with directives
|
||||
* such as \%L.
|
||||
*
|
||||
* As such, functions like xkb_compose_table_new_from_locale() require
|
||||
* a `locale` parameter. This will usually be the current locale (see
|
||||
* locale(7) for more details). You may also want to allow the user to
|
||||
* explicitly configure it, so he can use the Compose file of a given
|
||||
* locale, but not use that locale for other things.
|
||||
*
|
||||
* You may query the current locale as follows:
|
||||
* @code
|
||||
* const char *locale;
|
||||
* locale = setlocale(LC_CTYPE, NULL);
|
||||
* @endcode
|
||||
*
|
||||
* This will only give useful results if the program had previously set
|
||||
* the current locale using setlocale(3), with `LC_CTYPE` or `LC_ALL`
|
||||
* and a non-NULL argument.
|
||||
*
|
||||
* If you prefer not to use the locale system of the C runtime library,
|
||||
* you may nevertheless obtain the user's locale directly using
|
||||
* environment variables, as described in locale(7). For example,
|
||||
* @code
|
||||
* const char *locale;
|
||||
* locale = getenv("LC_ALL");
|
||||
* if (!locale || !*locale)
|
||||
* locale = getenv("LC_CTYPE");
|
||||
* if (!locale || !*locale)
|
||||
* locale = getenv("LANG");
|
||||
* if (!locale || !*locale)
|
||||
* locale = "C";
|
||||
* @endcode
|
||||
*
|
||||
* Note that some locales supported by the C standard library may not
|
||||
* have a Compose file assigned.
|
||||
*
|
||||
* @endparblock
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a compose table for a given locale.
|
||||
*
|
||||
* The locale is used for searching the file-system for an appropriate
|
||||
* Compose file. The search order is described in Compose(5). It is
|
||||
* affected by the following environment variables:
|
||||
*
|
||||
* 1. `XCOMPOSEFILE` - see Compose(5).
|
||||
* 2. `HOME` - see Compose(5).
|
||||
* 3. `XLOCALEDIR` - if set, used as the base directory for the system's
|
||||
* X locale files, e.g. `/usr/share/X11/locale`, instead of the
|
||||
* preconfigured directory.
|
||||
*
|
||||
* @param context
|
||||
* The library context in which to create the compose table.
|
||||
* @param locale
|
||||
* The current locale. See @ref compose-locale.\n
|
||||
*
|
||||
* The value is copied, so it is safe to pass the result of getenv(3)
|
||||
* (or similar) without fear of it being invalidated by a subsequent
|
||||
* setenv(3) (or similar).
|
||||
* @param flags
|
||||
* Optional flags for the compose table, or 0.
|
||||
*
|
||||
* @returns A compose table for the given locale, or NULL if the
|
||||
* compilation failed or a Compose file was not found.
|
||||
*
|
||||
* @memberof xkb_compose_table
|
||||
*/
|
||||
struct xkb_compose_table *
|
||||
xkb_compose_table_new_from_locale(struct xkb_context *context,
|
||||
const char *locale,
|
||||
enum xkb_compose_compile_flags flags);
|
||||
|
||||
/**
|
||||
* Create a new compose table from a Compose file.
|
||||
*
|
||||
* @param context
|
||||
* The library context in which to create the compose table.
|
||||
* @param file
|
||||
* The Compose file to compile.
|
||||
* @param locale
|
||||
* The current locale. See @ref compose-locale.
|
||||
* @param format
|
||||
* The text format of the Compose file to compile.
|
||||
* @param flags
|
||||
* Optional flags for the compose table, or 0.
|
||||
*
|
||||
* @returns A compose table compiled from the given file, or NULL if
|
||||
* the compilation failed.
|
||||
*
|
||||
* @memberof xkb_compose_table
|
||||
*/
|
||||
struct xkb_compose_table *
|
||||
xkb_compose_table_new_from_file(struct xkb_context *context,
|
||||
FILE *file,
|
||||
const char *locale,
|
||||
enum xkb_compose_format format,
|
||||
enum xkb_compose_compile_flags flags);
|
||||
|
||||
/**
|
||||
* Create a new compose table from a memory buffer.
|
||||
*
|
||||
* This is just like xkb_compose_table_new_from_file(), but instead of
|
||||
* a file, gets the table as one enormous string.
|
||||
*
|
||||
* @see xkb_compose_table_new_from_file()
|
||||
* @memberof xkb_compose_table
|
||||
*/
|
||||
struct xkb_compose_table *
|
||||
xkb_compose_table_new_from_buffer(struct xkb_context *context,
|
||||
const char *buffer, size_t length,
|
||||
const char *locale,
|
||||
enum xkb_compose_format format,
|
||||
enum xkb_compose_compile_flags flags);
|
||||
|
||||
/**
|
||||
* Take a new reference on a compose table.
|
||||
*
|
||||
* @returns The passed in object.
|
||||
*
|
||||
* @memberof xkb_compose_table
|
||||
*/
|
||||
struct xkb_compose_table *
|
||||
xkb_compose_table_ref(struct xkb_compose_table *table);
|
||||
|
||||
/**
|
||||
* Release a reference on a compose table, and possibly free it.
|
||||
*
|
||||
* @param table The object. If it is NULL, this function does nothing.
|
||||
*
|
||||
* @memberof xkb_compose_table
|
||||
*/
|
||||
void
|
||||
xkb_compose_table_unref(struct xkb_compose_table *table);
|
||||
|
||||
/** Flags for compose state creation. */
|
||||
enum xkb_compose_state_flags {
|
||||
/** Do not apply any flags. */
|
||||
XKB_COMPOSE_STATE_NO_FLAGS = 0
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new compose state object.
|
||||
*
|
||||
* @param table
|
||||
* The compose table the state will use.
|
||||
* @param flags
|
||||
* Optional flags for the compose state, or 0.
|
||||
*
|
||||
* @returns A new compose state, or NULL on failure.
|
||||
*
|
||||
* @memberof xkb_compose_state
|
||||
*/
|
||||
struct xkb_compose_state *
|
||||
xkb_compose_state_new(struct xkb_compose_table *table,
|
||||
enum xkb_compose_state_flags flags);
|
||||
|
||||
/**
|
||||
* Take a new reference on a compose state object.
|
||||
*
|
||||
* @returns The passed in object.
|
||||
*
|
||||
* @memberof xkb_compose_state
|
||||
*/
|
||||
struct xkb_compose_state *
|
||||
xkb_compose_state_ref(struct xkb_compose_state *state);
|
||||
|
||||
/**
|
||||
* Release a reference on a compose state object, and possibly free it.
|
||||
*
|
||||
* @param state The object. If NULL, do nothing.
|
||||
*
|
||||
* @memberof xkb_compose_state
|
||||
*/
|
||||
void
|
||||
xkb_compose_state_unref(struct xkb_compose_state *state);
|
||||
|
||||
/**
|
||||
* Get the compose table which a compose state object is using.
|
||||
*
|
||||
* @returns The compose table which was passed to xkb_compose_state_new()
|
||||
* when creating this state object.
|
||||
*
|
||||
* This function does not take a new reference on the compose table; you
|
||||
* must explicitly reference it yourself if you plan to use it beyond the
|
||||
* lifetime of the state.
|
||||
*
|
||||
* @memberof xkb_compose_state
|
||||
*/
|
||||
struct xkb_compose_table *
|
||||
xkb_compose_state_get_compose_table(struct xkb_compose_state *state);
|
||||
|
||||
/** Status of the Compose sequence state machine. */
|
||||
enum xkb_compose_status {
|
||||
/** The initial state; no sequence has started yet. */
|
||||
XKB_COMPOSE_NOTHING,
|
||||
/** In the middle of a sequence. */
|
||||
XKB_COMPOSE_COMPOSING,
|
||||
/** A complete sequence has been matched. */
|
||||
XKB_COMPOSE_COMPOSED,
|
||||
/** The last sequence was cancelled due to an unmatched keysym. */
|
||||
XKB_COMPOSE_CANCELLED
|
||||
};
|
||||
|
||||
/** The effect of a keysym fed to xkb_compose_state_feed(). */
|
||||
enum xkb_compose_feed_result {
|
||||
/** The keysym had no effect - it did not affect the status. */
|
||||
XKB_COMPOSE_FEED_IGNORED,
|
||||
/** The keysym started, advanced or cancelled a sequence. */
|
||||
XKB_COMPOSE_FEED_ACCEPTED
|
||||
};
|
||||
|
||||
/**
|
||||
* Feed one keysym to the Compose sequence state machine.
|
||||
*
|
||||
* This function can advance into a compose sequence, cancel a sequence,
|
||||
* start a new sequence, or do nothing in particular. The resulting
|
||||
* status may be observed with xkb_compose_state_get_status().
|
||||
*
|
||||
* Some keysyms, such as keysyms for modifier keys, are ignored - they
|
||||
* have no effect on the status or otherwise.
|
||||
*
|
||||
* The following is a description of the possible status transitions, in
|
||||
* the format CURRENT STATUS => NEXT STATUS, given a non-ignored input
|
||||
* keysym `keysym`:
|
||||
*
|
||||
@verbatim
|
||||
NOTHING or CANCELLED or COMPOSED =>
|
||||
NOTHING if keysym does not start a sequence.
|
||||
COMPOSING if keysym starts a sequence.
|
||||
COMPOSED if keysym starts and terminates a single-keysym sequence.
|
||||
|
||||
COMPOSING =>
|
||||
COMPOSING if keysym advances any of the currently possible
|
||||
sequences but does not terminate any of them.
|
||||
COMPOSED if keysym terminates one of the currently possible
|
||||
sequences.
|
||||
CANCELLED if keysym does not advance any of the currently
|
||||
possible sequences.
|
||||
@endverbatim
|
||||
*
|
||||
* The current Compose formats do not support multiple-keysyms.
|
||||
* Therefore, if you are using a function such as xkb_state_key_get_syms()
|
||||
* and it returns more than one keysym, consider feeding XKB_KEY_NoSymbol
|
||||
* instead.
|
||||
*
|
||||
* @param state
|
||||
* The compose state object.
|
||||
* @param keysym
|
||||
* A keysym, usually obtained after a key-press event, with a
|
||||
* function such as xkb_state_key_get_one_sym().
|
||||
*
|
||||
* @returns Whether the keysym was ignored. This is useful, for example,
|
||||
* if you want to keep a record of the sequence matched thus far.
|
||||
*
|
||||
* @memberof xkb_compose_state
|
||||
*/
|
||||
enum xkb_compose_feed_result
|
||||
xkb_compose_state_feed(struct xkb_compose_state *state,
|
||||
xkb_keysym_t keysym);
|
||||
|
||||
/**
|
||||
* Reset the Compose sequence state machine.
|
||||
*
|
||||
* The status is set to XKB_COMPOSE_NOTHING, and the current sequence
|
||||
* is discarded.
|
||||
*
|
||||
* @memberof xkb_compose_state
|
||||
*/
|
||||
void
|
||||
xkb_compose_state_reset(struct xkb_compose_state *state);
|
||||
|
||||
/**
|
||||
* Get the current status of the compose state machine.
|
||||
*
|
||||
* @see xkb_compose_status
|
||||
* @memberof xkb_compose_state
|
||||
**/
|
||||
enum xkb_compose_status
|
||||
xkb_compose_state_get_status(struct xkb_compose_state *state);
|
||||
|
||||
/**
|
||||
* Get the result Unicode/UTF-8 string for a composed sequence.
|
||||
*
|
||||
* See @ref compose-overview for more details. This function is only
|
||||
* useful when the status is XKB_COMPOSE_COMPOSED.
|
||||
*
|
||||
* @param[in] state
|
||||
* The compose state.
|
||||
* @param[out] buffer
|
||||
* A buffer to write the string into.
|
||||
* @param[in] size
|
||||
* Size of the buffer.
|
||||
*
|
||||
* @warning If the buffer passed is too small, the string is truncated
|
||||
* (though still NUL-terminated).
|
||||
*
|
||||
* @returns
|
||||
* The number of bytes required for the string, excluding the NUL byte.
|
||||
* If the sequence is not complete, or does not have a viable result
|
||||
* string, returns 0, and sets `buffer` to the empty string (if possible).
|
||||
* @returns
|
||||
* You may check if truncation has occurred by comparing the return value
|
||||
* with the size of `buffer`, similarly to the `snprintf`(3) function.
|
||||
* You may safely pass NULL and 0 to `buffer` and `size` to find the
|
||||
* required size (without the NUL-byte).
|
||||
*
|
||||
* @memberof xkb_compose_state
|
||||
**/
|
||||
int
|
||||
xkb_compose_state_get_utf8(struct xkb_compose_state *state,
|
||||
char *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Get the result keysym for a composed sequence.
|
||||
*
|
||||
* See @ref compose-overview for more details. This function is only
|
||||
* useful when the status is XKB_COMPOSE_COMPOSED.
|
||||
*
|
||||
* @returns The result keysym. If the sequence is not complete, or does
|
||||
* not specify a result keysym, returns XKB_KEY_NoSymbol.
|
||||
*
|
||||
* @memberof xkb_compose_state
|
||||
**/
|
||||
xkb_keysym_t
|
||||
xkb_compose_state_get_one_sym(struct xkb_compose_state *state);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* _XKBCOMMON_COMPOSE_H */
|
3004
src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h
vendored
3004
src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h
vendored
File diff suppressed because it is too large
Load Diff
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#ifndef _XKBCOMMON_NAMES_H
|
||||
#define _XKBCOMMON_NAMES_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Predefined names for common modifiers and LEDs.
|
||||
*/
|
||||
|
||||
#define XKB_MOD_NAME_SHIFT "Shift"
|
||||
#define XKB_MOD_NAME_CAPS "Lock"
|
||||
#define XKB_MOD_NAME_CTRL "Control"
|
||||
#define XKB_MOD_NAME_ALT "Mod1"
|
||||
#define XKB_MOD_NAME_NUM "Mod2"
|
||||
#define XKB_MOD_NAME_LOGO "Mod4"
|
||||
|
||||
#define XKB_LED_NAME_CAPS "Caps Lock"
|
||||
#define XKB_LED_NAME_NUM "Num Lock"
|
||||
#define XKB_LED_NAME_SCROLL "Scroll Lock"
|
||||
|
||||
#endif
|
244
src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h
vendored
244
src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h
vendored
@ -1,244 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Ran Benita
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _XKBCOMMON_X11_H
|
||||
#define _XKBCOMMON_X11_H
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libxkbcommon-x11 API - Additional X11 support for xkbcommon.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup x11 X11 support
|
||||
* Additional X11 support for xkbcommon.
|
||||
* @since 0.4.0
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page x11-overview Overview
|
||||
* @parblock
|
||||
*
|
||||
* The xkbcommon-x11 module provides a means for creating an xkb_keymap
|
||||
* corresponding to the currently active keymap on the X server. To do
|
||||
* so, it queries the XKB X11 extension using the xcb-xkb library. It
|
||||
* can be used as a replacement for Xlib's keyboard handling.
|
||||
*
|
||||
* Following is an example workflow using xkbcommon-x11. A complete
|
||||
* example may be found in the test/interactive-x11.c file in the
|
||||
* xkbcommon source repository. On startup:
|
||||
*
|
||||
* 1. Connect to the X server using xcb_connect().
|
||||
* 2. Setup the XKB X11 extension. You can do this either by using the
|
||||
* xcb_xkb_use_extension() request directly, or by using the
|
||||
* xkb_x11_setup_xkb_extension() helper function.
|
||||
*
|
||||
* The XKB extension supports using separate keymaps and states for
|
||||
* different keyboard devices. The devices are identified by an integer
|
||||
* device ID and are managed by another X11 extension, XInput. The
|
||||
* original X11 protocol only had one keyboard device, called the "core
|
||||
* keyboard", which is still supported as a "virtual device".
|
||||
*
|
||||
* 3. We will use the core keyboard as an example. To get its device ID,
|
||||
* use either the xcb_xkb_get_device_info() request directly, or the
|
||||
* xkb_x11_get_core_keyboard_device_id() helper function.
|
||||
* 4. Create an initial xkb_keymap for this device, using the
|
||||
* xkb_x11_keymap_new_from_device() function.
|
||||
* 5. Create an initial xkb_state for this device, using the
|
||||
* xkb_x11_state_new_from_device() function.
|
||||
*
|
||||
* @note At this point, you may consider setting various XKB controls and
|
||||
* XKB per-client flags. For example, enabling detectable autorepeat: \n
|
||||
* https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Detectable_Autorepeat
|
||||
*
|
||||
* Next, you need to react to state changes (e.g. a modifier was pressed,
|
||||
* the layout was changed) and to keymap changes (e.g. a tool like xkbcomp,
|
||||
* setxkbmap or xmodmap was used):
|
||||
*
|
||||
* 6. Select to listen to at least the following XKB events:
|
||||
* NewKeyboardNotify, MapNotify, StateNotify; using the
|
||||
* xcb_xkb_select_events_aux() request.
|
||||
* 7. When NewKeyboardNotify or MapNotify are received, recreate the
|
||||
* xkb_keymap and xkb_state as described above.
|
||||
* 8. When StateNotify is received, update the xkb_state accordingly
|
||||
* using the xkb_state_update_mask() function.
|
||||
*
|
||||
* @note It is also possible to use the KeyPress/KeyRelease @p state
|
||||
* field to find the effective modifier and layout state, instead of
|
||||
* using XkbStateNotify: \n
|
||||
* https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Computing_A_State_Field_from_an_XKB_State
|
||||
* \n However, XkbStateNotify is more accurate.
|
||||
*
|
||||
* @note There is no need to call xkb_state_update_key(); the state is
|
||||
* already synchronized.
|
||||
*
|
||||
* Finally, when a key event is received, you can use ordinary xkbcommon
|
||||
* functions, like xkb_state_key_get_one_sym() and xkb_state_key_get_utf8(),
|
||||
* as you normally would.
|
||||
*
|
||||
* @endparblock
|
||||
*/
|
||||
|
||||
/**
|
||||
* The minimal compatible major version of the XKB X11 extension which
|
||||
* this library can use.
|
||||
*/
|
||||
#define XKB_X11_MIN_MAJOR_XKB_VERSION 1
|
||||
/**
|
||||
* The minimal compatible minor version of the XKB X11 extension which
|
||||
* this library can use (for the minimal major version).
|
||||
*/
|
||||
#define XKB_X11_MIN_MINOR_XKB_VERSION 0
|
||||
|
||||
/** Flags for the xkb_x11_setup_xkb_extension() function. */
|
||||
enum xkb_x11_setup_xkb_extension_flags {
|
||||
/** Do not apply any flags. */
|
||||
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS = 0
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the XKB X11 extension for this X client.
|
||||
*
|
||||
* The xkbcommon-x11 library uses various XKB requests. Before doing so,
|
||||
* an X client must notify the server that it will be using the extension.
|
||||
* This function (or an XCB equivalent) must be called before any other
|
||||
* function in this library is used.
|
||||
*
|
||||
* Some X servers may not support or disable the XKB extension. If you
|
||||
* want to support such servers, you need to use a different fallback.
|
||||
*
|
||||
* You may call this function several times; it is idempotent.
|
||||
*
|
||||
* @param connection
|
||||
* An XCB connection to the X server.
|
||||
* @param major_xkb_version
|
||||
* See @p minor_xkb_version.
|
||||
* @param minor_xkb_version
|
||||
* The XKB extension version to request. To operate correctly, you
|
||||
* must have (major_xkb_version, minor_xkb_version) >=
|
||||
* (XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION),
|
||||
* though this is not enforced.
|
||||
* @param flags
|
||||
* Optional flags, or 0.
|
||||
* @param[out] major_xkb_version_out
|
||||
* See @p minor_xkb_version_out.
|
||||
* @param[out] minor_xkb_version_out
|
||||
* Backfilled with the compatible XKB extension version numbers picked
|
||||
* by the server. Can be NULL.
|
||||
* @param[out] base_event_out
|
||||
* Backfilled with the XKB base (also known as first) event code, needed
|
||||
* to distinguish XKB events. Can be NULL.
|
||||
* @param[out] base_error_out
|
||||
* Backfilled with the XKB base (also known as first) error code, needed
|
||||
* to distinguish XKB errors. Can be NULL.
|
||||
*
|
||||
* @returns 1 on success, or 0 on failure.
|
||||
*/
|
||||
int
|
||||
xkb_x11_setup_xkb_extension(xcb_connection_t *connection,
|
||||
uint16_t major_xkb_version,
|
||||
uint16_t minor_xkb_version,
|
||||
enum xkb_x11_setup_xkb_extension_flags flags,
|
||||
uint16_t *major_xkb_version_out,
|
||||
uint16_t *minor_xkb_version_out,
|
||||
uint8_t *base_event_out,
|
||||
uint8_t *base_error_out);
|
||||
|
||||
/**
|
||||
* Get the keyboard device ID of the core X11 keyboard.
|
||||
*
|
||||
* @param connection An XCB connection to the X server.
|
||||
*
|
||||
* @returns A device ID which may be used with other xkb_x11_* functions,
|
||||
* or -1 on failure.
|
||||
*/
|
||||
int32_t
|
||||
xkb_x11_get_core_keyboard_device_id(xcb_connection_t *connection);
|
||||
|
||||
/**
|
||||
* Create a keymap from an X11 keyboard device.
|
||||
*
|
||||
* This function queries the X server with various requests, fetches the
|
||||
* details of the active keymap on a keyboard device, and creates an
|
||||
* xkb_keymap from these details.
|
||||
*
|
||||
* @param context
|
||||
* The context in which to create the keymap.
|
||||
* @param connection
|
||||
* An XCB connection to the X server.
|
||||
* @param device_id
|
||||
* An XInput device ID (in the range 0-127) with input class KEY.
|
||||
* Passing values outside of this range is an error (the XKB protocol
|
||||
* predates the XInput2 protocol, which first allowed IDs > 127).
|
||||
* @param flags
|
||||
* Optional flags for the keymap, or 0.
|
||||
*
|
||||
* @returns A keymap retrieved from the X server, or NULL on failure.
|
||||
*
|
||||
* @memberof xkb_keymap
|
||||
*/
|
||||
struct xkb_keymap *
|
||||
xkb_x11_keymap_new_from_device(struct xkb_context *context,
|
||||
xcb_connection_t *connection,
|
||||
int32_t device_id,
|
||||
enum xkb_keymap_compile_flags flags);
|
||||
|
||||
/**
|
||||
* Create a new keyboard state object from an X11 keyboard device.
|
||||
*
|
||||
* This function is the same as xkb_state_new(), only pre-initialized
|
||||
* with the state of the device at the time this function is called.
|
||||
*
|
||||
* @param keymap
|
||||
* The keymap for which to create the state.
|
||||
* @param connection
|
||||
* An XCB connection to the X server.
|
||||
* @param device_id
|
||||
* An XInput 1 device ID (in the range 0-255) with input class KEY.
|
||||
* Passing values outside of this range is an error.
|
||||
*
|
||||
* @returns A new keyboard state object, or NULL on failure.
|
||||
*
|
||||
* @memberof xkb_state
|
||||
*/
|
||||
struct xkb_state *
|
||||
xkb_x11_state_new_from_device(struct xkb_keymap *keymap,
|
||||
xcb_connection_t *connection,
|
||||
int32_t device_id);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* _XKBCOMMON_X11_H */
|
1868
src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h
vendored
1868
src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h
vendored
File diff suppressed because it is too large
Load Diff
@ -647,24 +647,24 @@ template<> class QTypeInfo<A> : public QTypeInfoMerger<A, B, C, D> {};
|
||||
//! [52]
|
||||
struct Foo {
|
||||
void overloadedFunction();
|
||||
void overloadedFunction(int, QString);
|
||||
void overloadedFunction(int, const QString &);
|
||||
};
|
||||
... qOverload<>(&Foo::overloadedFunction)
|
||||
... qOverload<int, QString>(&Foo::overloadedFunction)
|
||||
... qOverload<int, const QString &>(&Foo::overloadedFunction)
|
||||
//! [52]
|
||||
|
||||
//! [53]
|
||||
... QOverload<>::of(&Foo::overloadedFunction)
|
||||
... QOverload<int, QString>::of(&Foo::overloadedFunction)
|
||||
... QOverload<int, const QString &>::of(&Foo::overloadedFunction)
|
||||
//! [53]
|
||||
|
||||
//! [54]
|
||||
struct Foo {
|
||||
void overloadedFunction(int, QString);
|
||||
void overloadedFunction(int, QString) const;
|
||||
void overloadedFunction(int, const QString &);
|
||||
void overloadedFunction(int, const QString &) const;
|
||||
};
|
||||
... qConstOverload<int, QString>(&Foo::overloadedFunction)
|
||||
... qNonConstOverload<int, QString>(&Foo::overloadedFunction)
|
||||
... qConstOverload<int, const QString &>(&Foo::overloadedFunction)
|
||||
... qNonConstOverload<int, const QString &>(&Foo::overloadedFunction)
|
||||
//! [54]
|
||||
|
||||
//! [qlikely]
|
||||
|
@ -162,17 +162,17 @@ Float qbswapFloatHelper(Float source)
|
||||
return qFromUnaligned<Float>(&temp);
|
||||
}
|
||||
|
||||
template <> inline qfloat16 qbswap<qfloat16>(qfloat16 source)
|
||||
inline qfloat16 qbswap(qfloat16 source)
|
||||
{
|
||||
return qbswapFloatHelper(source);
|
||||
}
|
||||
|
||||
template <> inline float qbswap<float>(float source)
|
||||
inline float qbswap(float source)
|
||||
{
|
||||
return qbswapFloatHelper(source);
|
||||
}
|
||||
|
||||
template <> inline double qbswap<double>(double source)
|
||||
inline double qbswap(double source)
|
||||
{
|
||||
return qbswapFloatHelper(source);
|
||||
}
|
||||
@ -185,7 +185,7 @@ template <> inline double qbswap<double>(double source)
|
||||
*/
|
||||
template <typename T> inline void qbswap(const T src, void *dest)
|
||||
{
|
||||
qToUnaligned<T>(qbswap<T>(src), dest);
|
||||
qToUnaligned<T>(qbswap(src), dest);
|
||||
}
|
||||
|
||||
template <int Size> void *qbswap(const void *source, qsizetype count, void *dest) noexcept;
|
||||
@ -223,9 +223,9 @@ template <typename T> inline void qFromLittleEndian(const void *source, qsizetyp
|
||||
#else // Q_LITTLE_ENDIAN
|
||||
|
||||
template <typename T> inline Q_DECL_CONSTEXPR T qToBigEndian(T source)
|
||||
{ return qbswap<T>(source); }
|
||||
{ return qbswap(source); }
|
||||
template <typename T> inline Q_DECL_CONSTEXPR T qFromBigEndian(T source)
|
||||
{ return qbswap<T>(source); }
|
||||
{ return qbswap(source); }
|
||||
template <typename T> inline Q_DECL_CONSTEXPR T qToLittleEndian(T source)
|
||||
{ return source; }
|
||||
template <typename T> inline Q_DECL_CONSTEXPR T qFromLittleEndian(T source)
|
||||
|
@ -58,14 +58,21 @@
|
||||
|
||||
#if defined(Q_CC_MSVC)
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_CC_MSVC)
|
||||
#include <float.h>
|
||||
# include <float.h>
|
||||
# if defined(Q_PROCESSOR_X86_64) || defined(Q_PROCESSOR_ARM_64)
|
||||
# define Q_INTRINSIC_MUL_OVERFLOW64
|
||||
# define Q_UMULH(v1, v2) __umulh(v1, v2);
|
||||
# define Q_SMULH(v1, v2) __mulh(v1, v2);
|
||||
# pragma intrinsic(__umulh)
|
||||
# pragma intrinsic(__mulh)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64)
|
||||
#include <arm64_ghs.h>
|
||||
# define Q_INTRINSIC_MUL_OVERFLOW64
|
||||
# define Q_UMULH(v1, v2) __MULUH64(v1, v2);
|
||||
# define Q_SMULH(v1, v2) __MULSH64(v1, v2);
|
||||
#endif
|
||||
|
||||
#if !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || defined(Q_CC_INTEL))
|
||||
@ -327,26 +334,26 @@ mul_overflow(T v1, T v2, T *r)
|
||||
return lr > std::numeric_limits<T>::max() || lr < std::numeric_limits<T>::min();
|
||||
}
|
||||
|
||||
# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64)
|
||||
# if defined(Q_INTRINSIC_MUL_OVERFLOW64)
|
||||
template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r)
|
||||
{
|
||||
*r = v1 * v2;
|
||||
return __MULUH64(v1, v2);
|
||||
return Q_UMULH(v1, v2);
|
||||
}
|
||||
template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r)
|
||||
{
|
||||
qint64 high = __MULSH64(v1, v2);
|
||||
if (high == 0) {
|
||||
*r = v1 * v2;
|
||||
return *r < 0;
|
||||
}
|
||||
if (high == -1) {
|
||||
*r = v1 * v2;
|
||||
return *r >= 0;
|
||||
}
|
||||
return true;
|
||||
// This is slightly more complex than the unsigned case above: the sign bit
|
||||
// of 'low' must be replicated as the entire 'high', so the only valid
|
||||
// values for 'high' are 0 and -1. Use unsigned multiply since it's the same
|
||||
// as signed for the low bits and use a signed right shift to verify that
|
||||
// 'high' is nothing but sign bits that match the sign of 'low'.
|
||||
|
||||
qint64 high = __mulh(v1, v2);
|
||||
*r = qint64(quint64(v1) * quint64(v2));
|
||||
return (*r >> 63) != high;
|
||||
}
|
||||
|
||||
# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64)
|
||||
template <> inline bool mul_overflow(uint64_t v1, uint64_t v2, uint64_t *r)
|
||||
{
|
||||
return mul_overflow<quint64>(v1,v2,reinterpret_cast<quint64*>(r));
|
||||
@ -356,8 +363,8 @@ template <> inline bool mul_overflow(int64_t v1, int64_t v2, int64_t *r)
|
||||
{
|
||||
return mul_overflow<qint64>(v1,v2,reinterpret_cast<qint64*>(r));
|
||||
}
|
||||
|
||||
#endif
|
||||
# endif // OS_INTEGRITY ARM64
|
||||
# endif // Q_INTRINSIC_MUL_OVERFLOW64
|
||||
|
||||
# if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86)
|
||||
// We can use intrinsics for the unsigned operations with MSVC
|
||||
@ -369,37 +376,8 @@ template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r)
|
||||
# if defined(Q_PROCESSOR_X86_64)
|
||||
template <> inline bool add_overflow(quint64 v1, quint64 v2, quint64 *r)
|
||||
{ return _addcarry_u64(0, v1, v2, reinterpret_cast<unsigned __int64 *>(r)); }
|
||||
|
||||
# pragma intrinsic(_umul128)
|
||||
template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r)
|
||||
{
|
||||
// use 128-bit multiplication with the _umul128 intrinsic
|
||||
// https://msdn.microsoft.com/en-us/library/3dayytw9.aspx
|
||||
quint64 high;
|
||||
*r = _umul128(v1, v2, &high);
|
||||
return high;
|
||||
}
|
||||
|
||||
# pragma intrinsic(_mul128)
|
||||
template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r)
|
||||
{
|
||||
// Use 128-bit multiplication with the _mul128 intrinsic
|
||||
// https://msdn.microsoft.com/en-us/library/82cxdw50.aspx
|
||||
|
||||
// This is slightly more complex than the unsigned case above: the sign bit
|
||||
// of 'low' must be replicated as the entire 'high', so the only valid
|
||||
// values for 'high' are 0 and -1.
|
||||
|
||||
qint64 high;
|
||||
*r = _mul128(v1, v2, &high);
|
||||
if (high == 0)
|
||||
return *r < 0;
|
||||
if (high == -1)
|
||||
return *r >= 0;
|
||||
return true;
|
||||
}
|
||||
# endif // x86-64
|
||||
# endif // MSVC x86
|
||||
# endif // MSVC X86
|
||||
#endif // !GCC
|
||||
}
|
||||
#endif // Q_CLANG_QDOC
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
QAppleRefCounted(QAppleRefCounted &&other) : value(other.value) { other.value = T(); }
|
||||
QAppleRefCounted(const QAppleRefCounted &other) : value(other.value) { if (value) RetainFunction(value); }
|
||||
~QAppleRefCounted() { if (value) ReleaseFunction(value); }
|
||||
operator T() { return value; }
|
||||
operator T() const { return value; }
|
||||
void swap(QAppleRefCounted &other) Q_DECL_NOEXCEPT_EXPR(noexcept(qSwap(value, other.value)))
|
||||
{ qSwap(value, other.value); }
|
||||
QAppleRefCounted &operator=(const QAppleRefCounted &other)
|
||||
|
@ -341,7 +341,7 @@ inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate:
|
||||
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
|
||||
"Return type of the slot is not compatible with the return type of the signal.");
|
||||
|
||||
const int *types = 0;
|
||||
const int *types = nullptr;
|
||||
if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
|
||||
types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
|
||||
|
||||
|
@ -168,11 +168,11 @@ int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library
|
||||
parseSectionHeader(dataStart + soff, &strtab);
|
||||
m_stringTableFileOffset = strtab.offset;
|
||||
|
||||
if ((quint32)(m_stringTableFileOffset + e_shentsize) >= fdlen || m_stringTableFileOffset == 0) {
|
||||
if ((quint32)(strtab.offset + strtab.size) > fdlen || strtab.offset == 0) {
|
||||
if (lib)
|
||||
lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)")
|
||||
.arg(library, QLibrary::tr("string table seems to be at %1")
|
||||
.arg(QString::number(soff, 16)));
|
||||
.arg(QString::number(strtab.offset, 16)));
|
||||
return Corrupt;
|
||||
}
|
||||
|
||||
|
@ -4112,7 +4112,8 @@ ushort QByteArray::toUShort(bool *ok, int base) const
|
||||
/*!
|
||||
Returns the byte array converted to a \c double value.
|
||||
|
||||
Returns 0.0 if the conversion fails.
|
||||
Returns an infinity if the conversion overflows or 0.0 if the
|
||||
conversion fails for other reasons (e.g. underflow).
|
||||
|
||||
If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
|
||||
to \c false, and success by setting *\a{ok} to \c true.
|
||||
@ -4147,7 +4148,8 @@ double QByteArray::toDouble(bool *ok) const
|
||||
/*!
|
||||
Returns the byte array converted to a \c float value.
|
||||
|
||||
Returns 0.0 if the conversion fails.
|
||||
Returns an infinity if the conversion overflows or 0.0 if the
|
||||
conversion fails for other reasons (e.g. underflow).
|
||||
|
||||
If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
|
||||
to \c false, and success by setting *\a{ok} to \c true.
|
||||
|
@ -1371,8 +1371,10 @@ qulonglong QLocale::toULongLong(const QString &s, bool *ok) const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the float represented by the localized string \a s, or 0.0
|
||||
if the conversion failed.
|
||||
Returns the float represented by the localized string \a s.
|
||||
|
||||
Returns an infinity if the conversion overflows or 0.0 if the
|
||||
conversion fails for any other reason (e.g. underflow).
|
||||
|
||||
If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
|
||||
to \c false, and success by setting *\a{ok} to \c true.
|
||||
@ -1391,8 +1393,10 @@ float QLocale::toFloat(const QString &s, bool *ok) const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the double represented by the localized string \a s, or
|
||||
0.0 if the conversion failed.
|
||||
Returns the double represented by the localized string \a s.
|
||||
|
||||
Returns an infinity if the conversion overflows or 0.0 if the
|
||||
conversion fails for any other reason (e.g. underflow).
|
||||
|
||||
If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
|
||||
to \c false, and success by setting *\a{ok} to \c true.
|
||||
@ -1538,8 +1542,10 @@ qulonglong QLocale::toULongLong(const QStringRef &s, bool *ok) const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the float represented by the localized string \a s, or 0.0
|
||||
if the conversion failed.
|
||||
Returns the float represented by the localized string \a s.
|
||||
|
||||
Returns an infinity if the conversion overflows or 0.0 if the
|
||||
conversion fails for any other reason (e.g. underflow).
|
||||
|
||||
If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
|
||||
to \c false, and success by setting *\a{ok} to \c true.
|
||||
@ -1560,8 +1566,10 @@ float QLocale::toFloat(const QStringRef &s, bool *ok) const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the double represented by the localized string \a s, or
|
||||
0.0 if the conversion failed.
|
||||
Returns the double represented by the localized string \a s.
|
||||
|
||||
Returns an infinity if the conversion overflows or 0.0 if the
|
||||
conversion fails for any other reason (e.g. underflow).
|
||||
|
||||
If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
|
||||
to \c false, and success by setting *\a{ok} to \c true.
|
||||
@ -1710,8 +1718,10 @@ qulonglong QLocale::toULongLong(QStringView s, bool *ok) const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the float represented by the localized string \a s, or 0.0
|
||||
if the conversion failed.
|
||||
Returns the float represented by the localized string \a s.
|
||||
|
||||
Returns an infinity if the conversion overflows or 0.0 if the
|
||||
conversion fails for any other reason (e.g. underflow).
|
||||
|
||||
If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
|
||||
to \c false, and success by setting *\a{ok} to \c true.
|
||||
@ -1729,8 +1739,10 @@ float QLocale::toFloat(QStringView s, bool *ok) const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the double represented by the localized string \a s, or
|
||||
0.0 if the conversion failed.
|
||||
Returns the double represented by the localized string \a s.
|
||||
|
||||
Returns an infinity if the conversion overflows or 0.0 if the
|
||||
conversion fails for any other reason (e.g. underflow).
|
||||
|
||||
If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
|
||||
to \c false, and success by setting *\a{ok} to \c true.
|
||||
|
@ -251,7 +251,16 @@ public:
|
||||
if (std::fabs(d) > std::numeric_limits<float>::max()) {
|
||||
if (ok != 0)
|
||||
*ok = false;
|
||||
return 0.0f;
|
||||
const float huge = std::numeric_limits<float>::infinity();
|
||||
return d < 0 ? -huge : huge;
|
||||
}
|
||||
if (std::fabs(d) >= std::numeric_limits<double>::min() // i.e. d != 0
|
||||
&& std::fabs(d) < std::numeric_limits<float>::min()) {
|
||||
// Values smaller than std::numeric_limits<double>::min() have
|
||||
// failed already; match them.
|
||||
if (ok != 0)
|
||||
*ok = false;
|
||||
return 0;
|
||||
}
|
||||
return float(d);
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ double qt_asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
|
||||
ok = false;
|
||||
for (int i = 0; i < processed; ++i) {
|
||||
char c = num[i];
|
||||
if ((c < '0' || c > '9') && c != '.' && c != '-' && c != '+' && c != 'e') {
|
||||
if ((c < '0' || c > '9') && c != '.' && c != '-' && c != '+' && c != 'e' && c != 'E') {
|
||||
// Garbage found
|
||||
processed = 0;
|
||||
return 0.0;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user