Merge remote-tracking branch 'origin/stable' into dev

Conflicts:
	mkspecs/qnx-armv7le-qcc/qplatformdefs.h
	src/printsupport/kernel/qcups.cpp
	src/widgets/styles/qstyle.h
	tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp

Change-Id: Ia41e13051169a6d4a8a1267548e7d47b859bb267
This commit is contained in:
Frederik Gladhorn 2014-04-11 14:36:55 +02:00
commit 98d3e40fb7
319 changed files with 5662 additions and 3868 deletions

View File

@ -1,10 +0,0 @@
SOURCES = egl4gles1.cpp
for(p, QMAKE_LIBDIR_EGL) {
exists($$p):LIBS += -L$$p
}
!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL
!isEmpty(QMAKE_LIBS_EGL): LIBS += $$QMAKE_LIBS_EGL
CONFIG -= qt

View File

@ -40,9 +40,15 @@
****************************************************************************/ ****************************************************************************/
#include <systemd/sd-journal.h> #include <systemd/sd-journal.h>
#include <syslog.h>
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
sd_journal_print_with_location(LOG_INFO, "CODE_FILE=foo.c", "CODE_LINE=0", "unknown_function", "test message"); sd_journal_send("MESSAGE=%s", "test message",
"PRIORITY=%i", LOG_INFO,
"CODE_FUNC=%s", "unknown",
"CODE_LINE=%d", 0,
"CODE_FILE=%s", "foo.c",
NULL);
return 0; return 0;
} }

View File

@ -1,12 +0,0 @@
SOURCES = opengles1.cpp
INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1
for(p, QMAKE_LIBDIR_OPENGL_ES1) {
exists($$p):LIBS += -L$$p
}
CONFIG -= qt
LIBS += $$QMAKE_LIBS_OPENGL_ES1
mac {
DEFINES += BUILD_ON_MAC
}

20
configure vendored
View File

@ -2270,9 +2270,6 @@ Configure options:
-system-sqlite ..... Use sqlite from the operating system. -system-sqlite ..... Use sqlite from the operating system.
-no-javascript-jit . Do not build the JavaScriptCore JIT compiler.
+ -javascript-jit .... Build the JavaScriptCore JIT compiler.
-no-qml-debug ...... Do not build the in-process QML debugging support. -no-qml-debug ...... Do not build the in-process QML debugging support.
+ -qml-debug ......... Build the QML debugging support. + -qml-debug ......... Build the QML debugging support.
@ -2419,6 +2416,9 @@ Additional options:
-no-iconv .......... Do not compile support for iconv(3). -no-iconv .......... Do not compile support for iconv(3).
* -iconv ............. Compile support for iconv(3). * -iconv ............. Compile support for iconv(3).
-no-evdev .......... Do not compile support for evdev.
* -evdev ............. Compile support for evdev.
-no-icu ............ Do not compile support for ICU libraries. -no-icu ............ Do not compile support for ICU libraries.
+ -icu ............... Compile support for ICU libraries. + -icu ............... Compile support for ICU libraries.
@ -2773,7 +2773,8 @@ if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ];
EditionString="Technology Preview" EditionString="Technology Preview"
elif [ $COMMERCIAL_USER = "yes" ]; then elif [ $COMMERCIAL_USER = "yes" ]; then
if test -x "$relpath/bin/licheck"; then if test -x "$relpath/bin/licheck"; then
LicheckOutput=`$relpath/bin/licheck $relpath $outpath $PLATFORM $XPLATFORM` LicheckOutput=`$relpath/bin/licheck $OPT_CONFIRM_LICENSE $relpath $outpath\
$PLATFORM $XPLATFORM`
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
exit 1 exit 1
else else
@ -3102,7 +3103,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then
CFG_PKGCONFIG="no" CFG_PKGCONFIG="no"
CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples" CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples"
CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store
CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtlocation qtmacextras qtserialport qttools qtwebkit qtwebkit-examples" CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtmacextras qtserialport qttools qtwebkit qtwebkit-examples"
# If the user passes -sdk on the command line we build a SDK-specific Qt build. # If the user passes -sdk on the command line we build a SDK-specific Qt build.
# Otherwise we build a joined simulator and device build, which is the default. # Otherwise we build a joined simulator and device build, which is the default.
@ -3707,7 +3708,7 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ];
EXTRA_SRCS="\"\$(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp\" \ EXTRA_SRCS="\"\$(SOURCE_PATH)/src/corelib/io/qfilesystemengine_unix.cpp\" \
\"\$(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp\" \ \"\$(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_unix.cpp\" \
\"\$(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp\" \ \"\$(SOURCE_PATH)/src/corelib/io/qfsfileengine_unix.cpp\" \
\"\$(SOURCE_PATH)/src/corelib/tools/qlocal_unix.cpp\"" \"\$(SOURCE_PATH)/src/corelib/tools/qlocale_unix.cpp\""
EXEEXT= EXEEXT=
fi fi
if [ "$BUILD_ON_MAC" = "yes" ]; then if [ "$BUILD_ON_MAC" = "yes" ]; then
@ -5052,11 +5053,12 @@ if [ "$CFG_KMS" != "no" ]; then
fi fi
# Detect libxkbcommon # Detect libxkbcommon
MIN_REQ_XKBCOMMON="0.4.1"
ORIG_CFG_XKBCOMMON="$CFG_XKBCOMMON" ORIG_CFG_XKBCOMMON="$CFG_XKBCOMMON"
# currently only xcb platform plugin supports building xkbcommon # currently only xcb platform plugin supports building xkbcommon
if [ "$CFG_XCB" != "no" ]; then if [ "$CFG_XCB" != "no" ]; then
if [ "$CFG_XKBCOMMON" = "auto" ] || [ "$CFG_XKBCOMMON" = "system" ]; then if [ "$CFG_XKBCOMMON" = "auto" ] || [ "$CFG_XKBCOMMON" = "system" ]; then
if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xkbcommon xkbcommon-x11 >= 0.4.0" 2>/dev/null; then if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xkbcommon xkbcommon-x11 >= $MIN_REQ_XKBCOMMON" 2>/dev/null; then
QMAKE_CFLAGS_XKBCOMMON="`$PKG_CONFIG --cflags xkbcommon xkbcommon-x11 2>/dev/null`" QMAKE_CFLAGS_XKBCOMMON="`$PKG_CONFIG --cflags xkbcommon xkbcommon-x11 2>/dev/null`"
QMAKE_LIBS_XKBCOMMON="`$PKG_CONFIG --libs xkbcommon xkbcommon-x11 2>/dev/null`" QMAKE_LIBS_XKBCOMMON="`$PKG_CONFIG --libs xkbcommon xkbcommon-x11 2>/dev/null`"
@ -6047,6 +6049,7 @@ QMakeVar set sql-plugins "$SQL_PLUGINS"
# X11/Unix/Mac only configs # X11/Unix/Mac only configs
[ "$CFG_CUPS" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CUPS" [ "$CFG_CUPS" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CUPS"
[ "$CFG_ICONV" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_ICONV" [ "$CFG_ICONV" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_ICONV"
[ "$CFG_EVDEV" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EVDEV"
[ "$CFG_GLIB" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_GLIB" [ "$CFG_GLIB" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_GLIB"
[ "$CFG_QGTKSTYLE" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_STYLE_GTK" [ "$CFG_QGTKSTYLE" != "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_STYLE_GTK"
[ "$CFG_CLOCK_MONOTONIC" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CLOCK_MONOTONIC" [ "$CFG_CLOCK_MONOTONIC" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CLOCK_MONOTONIC"
@ -6466,6 +6469,7 @@ report_support " ALSA ..................." "$CFG_ALSA"
report_support " CUPS ..................." "$CFG_CUPS" report_support " CUPS ..................." "$CFG_CUPS"
[ "$XPLATFORM_MINGW" = "yes" ] && \ [ "$XPLATFORM_MINGW" = "yes" ] && \
report_support " DirectWrite ............" "$CFG_DIRECTWRITE" report_support " DirectWrite ............" "$CFG_DIRECTWRITE"
report_support " Evdev .................." "$CFG_EVDEV"
report_support " FontConfig ............." "$CFG_FONTCONFIG" report_support " FontConfig ............." "$CFG_FONTCONFIG"
report_support " FreeType ..............." "$CFG_FREETYPE" system "system library" yes "bundled copy" report_support " FreeType ..............." "$CFG_FREETYPE" system "system library" yes "bundled copy"
report_support " Glib ..................." "$CFG_GLIB" report_support " Glib ..................." "$CFG_GLIB"
@ -6561,7 +6565,7 @@ if [ "$CFG_OPENSSL" = "linked" ] && [ "$OPENSSL_LIBS" = "" ]; then
echo echo
fi fi
if [ "$ORIG_CFG_XKBCOMMON" != qt ] && [ "$CFG_XKBCOMMON" = qt ]; then if [ "$ORIG_CFG_XKBCOMMON" != qt ] && [ "$CFG_XKBCOMMON" = qt ]; then
echo "NOTE: libxkbcommon and libxkbcommon-x11 0.4.0 or higher not found on the system, will use " echo "NOTE: libxkbcommon and libxkbcommon-x11 $MIN_REQ_XKBCOMMON or higher not found on the system, will use "
echo "the bundled version from 3rd party directory." echo "the bundled version from 3rd party directory."
fi fi
if [ "$CFG_XKBCOMMON" = "qt" ] && [ "$CFG_XKB_CONFIG_ROOT" = "not found" ]; then if [ "$CFG_XKBCOMMON" = "qt" ] && [ "$CFG_XKB_CONFIG_ROOT" = "not found" ]; then

View File

@ -10,3 +10,5 @@ dita.metadata.default.audience = programmer
#Set the main Qt index.html #Set the main Qt index.html
navigation.homepage = "Qt $QT_VER" navigation.homepage = "Qt $QT_VER"
buildversion = "Qt $QT_VERSION Reference Documentation" buildversion = "Qt $QT_VERSION Reference Documentation"
sourcedirs += includes

View File

@ -468,8 +468,8 @@
\title Qt Creator: Adding Debuggers \title Qt Creator: Adding Debuggers
*/ */
/*! /*!
\externalpage http://qt-project.org/doc/qtcreator/creator-android-app-tutorial.html \externalpage http://qt-project.org/doc/qtcreator/creator-mobile-app-tutorial.html
\title Qt Creator: Creating an Android Application \title Qt Creator: Creating a Mobile Application
*/ */
/*! /*!
\externalpage http://qt-project.org/doc/qtcreator/creator-diff-editor.html \externalpage http://qt-project.org/doc/qtcreator/creator-diff-editor.html

View File

@ -0,0 +1,5 @@
\section1 Running the Example
To run the example from \l{Qt Creator Manual}{Qt Creator}, open the \gui Welcome
mode and select the example from \gui Examples. For more information, visit
\l{Qt Creator: Building and Running an Example}{Building and Running an Example}.

View File

@ -464,7 +464,7 @@ List
*/ */
ul { ul {
padding-bottom: 2px margin-top: 10px;
} }
li { li {

View File

@ -348,7 +348,7 @@ List
*/ */
ul { ul {
padding-bottom: 2px margin-top: 10px;
} }
li { li {

View File

@ -5,6 +5,6 @@ CONFIG += no_docs_target
SUBDIRS += analogclock SUBDIRS += analogclock
SUBDIRS += rasterwindow SUBDIRS += rasterwindow
contains(QT_CONFIG, opengl(es1|es2)?) { contains(QT_CONFIG, opengl(es2)?) {
SUBDIRS += openglwindow SUBDIRS += openglwindow
} }

View File

@ -1,320 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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 Digia Plc and its Subsidiary(-ies) 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 "glwindow.h"
#include <QGuiApplication>
#include <QScreen>
#include <QTimer>
#include <math.h>
#include <stdio.h>
inline void CrossProduct(qreal &xOut, qreal &yOut, qreal &zOut, qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2)
{
xOut = y1 * z2 - z1 * y2;
yOut = z1 * x2 - x1 * z2;
zOut = x1 * y2 - y1 * x2;
}
inline void Normalize(qreal &x, qreal &y, qreal &z)
{
qreal l = sqrt(x*x + y*y + z*z);
x = x / l;
y = y / l;
z = z / l;
}
GLWindow::GLWindow()
{
setSurfaceType(OpenGLSurface);
qtLogo = true;
createdVertices = 0;
createdNormals = 0;
m_vertexNumber = 0;
frames = 0;
m_fScale = 1;
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setMajorVersion(1);
format.setMinorVersion(1);
setGeometry(QGuiApplication::primaryScreen()->availableGeometry());
setFormat(format);
create();
m_context = new QOpenGLContext;
m_context->setFormat(format);
m_context->create();
m_context->makeCurrent(this);
initializeGL();
QTimer *timer = new QTimer(this);
timer->setInterval(16);
connect(timer, SIGNAL(timeout()), this, SLOT(paintGL()));
timer->start();
}
GLWindow::~GLWindow()
{
if (createdVertices)
delete[] createdVertices;
if (createdNormals)
delete[] createdNormals;
delete m_context;
}
void GLWindow::paintQtLogo()
{
glDisable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0, createdVertices);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT,0,createdNormals);
glDrawArrays(GL_TRIANGLES, 0, m_vertexNumber / 3);
}
void GLWindow::initializeGL ()
{
glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat aLightPosition[] = {0.0f,0.3f,1.0f,0.0f};
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, aLightPosition);
m_fAngle = 0;
m_fScale = 1;
createGeometry();
}
void GLWindow::paintGL()
{
m_context->makeCurrent(this);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMatrixMode(GL_TEXTURE);
glPushMatrix();
//Since OpenGL ES does not support glPush/PopAttrib(GL_ALL_ATTRIB_BITS)
//we have to take care of the states ourselves
glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_FLAT);
glFrontFace(GL_CW);
glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(m_fAngle, 0.0f, 1.0f, 0.0f);
glRotatef(m_fAngle, 1.0f, 0.0f, 0.0f);
glRotatef(m_fAngle, 0.0f, 0.0f, 1.0f);
glScalef(m_fScale, m_fScale,m_fScale);
glTranslatef(0.0f,-0.2f,0.0f);
GLfloat matDiff[] = {0.40f, 1.0f, 0.0f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff);
paintQtLogo();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
m_context->swapBuffers(this);
m_fAngle += 1.0f;
}
void GLWindow::createGeometry()
{
vertices.clear();
normals.clear();
qreal x1 = +0.06f;
qreal y1 = -0.14f;
qreal x2 = +0.14f;
qreal y2 = -0.06f;
qreal x3 = +0.08f;
qreal y3 = +0.00f;
qreal x4 = +0.30f;
qreal y4 = +0.22f;
quad(x1, y1, x2, y2, y2, x2, y1, x1);
quad(x3, y3, x4, y4, y4, x4, y3, x3);
extrude(x1, y1, x2, y2);
extrude(x2, y2, y2, x2);
extrude(y2, x2, y1, x1);
extrude(y1, x1, x1, y1);
extrude(x3, y3, x4, y4);
extrude(x4, y4, y4, x4);
extrude(y4, x4, y3, x3);
const qreal Pi = 3.14159f;
const int NumSectors = 100;
for (int i = 0; i < NumSectors; ++i) {
qreal angle1 = (i * 2 * Pi) / NumSectors;
qreal x5 = 0.30 * sin(angle1);
qreal y5 = 0.30 * cos(angle1);
qreal x6 = 0.20 * sin(angle1);
qreal y6 = 0.20 * cos(angle1);
qreal angle2 = ((i + 1) * 2 * Pi) / NumSectors;
qreal x7 = 0.20 * sin(angle2);
qreal y7 = 0.20 * cos(angle2);
qreal x8 = 0.30 * sin(angle2);
qreal y8 = 0.30 * cos(angle2);
quad(x5, y5, x6, y6, x7, y7, x8, y8);
extrude(x6, y6, x7, y7);
extrude(x8, y8, x5, y5);
}
m_vertexNumber = vertices.size();
createdVertices = new GLfloat[m_vertexNumber];
createdNormals = new GLfloat[m_vertexNumber];
for (int i = 0;i < m_vertexNumber;i++) {
createdVertices[i] = vertices.at(i) * 2;
createdNormals[i] = normals.at(i);
}
vertices.clear();
normals.clear();
}
void GLWindow::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
{
qreal nx, ny, nz;
vertices << x1 << y1 << -0.05f;
vertices << x2 << y2 << -0.05f;
vertices << x4 << y4 << -0.05f;
vertices << x3 << y3 << -0.05f;
vertices << x4 << y4 << -0.05f;
vertices << x2 << y2 << -0.05f;
CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0, x4 - x1, y4 - y1, 0);
Normalize(nx, ny, nz);
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
vertices << x4 << y4 << 0.05f;
vertices << x2 << y2 << 0.05f;
vertices << x1 << y1 << 0.05f;
vertices << x2 << y2 << 0.05f;
vertices << x4 << y4 << 0.05f;
vertices << x3 << y3 << 0.05f;
CrossProduct(nx, ny, nz, x2 - x4, y2 - y4, 0, x1 - x4, y1 - y4, 0);
Normalize(nx, ny, nz);
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
}
void GLWindow::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
{
qreal nx, ny, nz;
vertices << x1 << y1 << +0.05f;
vertices << x2 << y2 << +0.05f;
vertices << x1 << y1 << -0.05f;
vertices << x2 << y2 << -0.05f;
vertices << x1 << y1 << -0.05f;
vertices << x2 << y2 << +0.05f;
CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0.0f, 0.0f, 0.0f, -0.1f);
Normalize(nx, ny, nz);
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
}

View File

@ -1,78 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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 Digia Plc and its Subsidiary(-ies) 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 GLWINDOW_H
#define GLWINDOW_H
#include <GLES/gl.h>
#include <QOpenGLContext>
#include <QWindow>
#include <QTime>
class GLWindow : public QWindow {
Q_OBJECT
public:
GLWindow();
~GLWindow();
protected slots:
void paintGL();
void initializeGL();
private:
qreal m_fAngle;
qreal m_fScale;
QOpenGLContext *m_context;
void paintQtLogo();
void createGeometry();
void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4);
void extrude(qreal x1, qreal y1, qreal x2, qreal y2);
QList<qreal> vertices;
QList<qreal> normals;
GLfloat *createdVertices;
GLfloat *createdNormals;
int m_vertexNumber;
bool qtLogo;
int frames;
QTime time;
};
#endif

View File

@ -1,11 +0,0 @@
QT += gui
SOURCES += main.cpp
SOURCES += glwindow.cpp
HEADERS += glwindow.h
RESOURCES += texture.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/opengl/hellogl_es
INSTALLS += target

View File

@ -1,52 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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 Digia Plc and its Subsidiary(-ies) 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 <QGuiApplication>
#include "glwindow.h"
int main( int argc, char ** argv )
{
Q_INIT_RESOURCE(texture);
QGuiApplication a( argc, argv );
GLWindow window;
window.show();
return a.exec();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>qt.png</file>
</qresource>
</RCC>

View File

@ -2,16 +2,8 @@ requires(qtHaveModule(opengl))
TEMPLATE = subdirs TEMPLATE = subdirs
contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2){ contains(QT_CONFIG, opengles2) {
contains(QT_CONFIG, opengles2) { SUBDIRS = hellogl_es2
SUBDIRS = hellogl_es2
} else {
SUBDIRS = hellogl_es
}
SUBDIRS += textures
contains(QT_CONFIG, opengles1) {
SUBDIRS += hellogl
}
} else { } else {
SUBDIRS = 2dpainting \ SUBDIRS = 2dpainting \
grabber \ grabber \
@ -19,13 +11,13 @@ contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2){
overpainting \ overpainting \
pbuffers \ pbuffers \
framebufferobject2 \ framebufferobject2 \
samplebuffers \ samplebuffers
textures
} }
SUBDIRS += hellowindow \ SUBDIRS += hellowindow \
paintedwindow \ paintedwindow \
contextinfo \ contextinfo \
cube cube \
textures
EXAMPLE_FILES = shared EXAMPLE_FILES = shared

View File

@ -1,6 +1,6 @@
INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD
qtHaveModule(opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) { qtHaveModule(opengl)|contains(QT_CONFIG, opengles2) {
DEFINES += QT_OPENGL_SUPPORT DEFINES += QT_OPENGL_SUPPORT
QT += opengl widgets QT += opengl widgets
} }

View File

@ -22,11 +22,11 @@ SUBDIRS = \
tutorials \ tutorials \
widgets widgets
contains(QT_CONFIG, opengl(es1|es2)?) { contains(QT_CONFIG, opengl(es2)?) {
SUBDIRS += windowcontainer SUBDIRS += windowcontainer
} }
!contains(QT_CONFIG, opengl(es1|es2)?): SUBDIRS -= windowcontainer !contains(QT_CONFIG, opengl(es2)?): SUBDIRS -= windowcontainer
contains(DEFINES, QT_NO_CURSOR): SUBDIRS -= mainwindows contains(DEFINES, QT_NO_CURSOR): SUBDIRS -= mainwindows
contains(DEFINES, QT_NO_DRAGANDDROP): SUBDIRS -= draganddrop contains(DEFINES, QT_NO_DRAGANDDROP): SUBDIRS -= draganddrop
mac:SUBDIRS += mac mac:SUBDIRS += mac

View File

@ -186,7 +186,6 @@ QMAKE_LIBS_X11 =
QMAKE_LIBS_THREAD = QMAKE_LIBS_THREAD =
QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL = QMAKE_LIBS_OPENGL =
QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 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.") !exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.")

View File

@ -5,7 +5,7 @@
load(qt_config) load(qt_config)
DEFINES += Q_OS_BLACKBERRY DEFINES += Q_OS_BLACKBERRY
CONFIG += blackberry QMAKE_PLATFORM += blackberry
LIBS += -lbps LIBS += -lbps
# Blackberry also has support for stack smashing protection in its libc # Blackberry also has support for stack smashing protection in its libc

View File

@ -39,4 +39,4 @@
** **
****************************************************************************/ ****************************************************************************/
#include "../qnx-armv7le-qcc/qplatformdefs.h" #include "../qnx-armle-v7-qcc/qplatformdefs.h"

View File

@ -5,7 +5,7 @@
load(qt_config) load(qt_config)
DEFINES += Q_OS_BLACKBERRY DEFINES += Q_OS_BLACKBERRY
CONFIG += blackberry QMAKE_PLATFORM += blackberry
LIBS += -lbps LIBS += -lbps
# Blackberry also has support for stack smashing protection in its libc # Blackberry also has support for stack smashing protection in its libc

View File

@ -15,11 +15,6 @@ QMAKE_RANLIB = ranlib -s
QMAKE_LINK = $$QMAKE_CXX QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_CXX QMAKE_LINK_SHLIB = $$QMAKE_CXX
# No OpenGL ES1
QMAKE_INCDIR_OPENGL_ES1 =
QMAKE_LIBDIR_OPENGL_ES1 =
QMAKE_LIBS_OPENGL_ES1 =
# OpenGL ES2 # OpenGL ES2
QMAKE_INCDIR_OPENGL_ES2 = QMAKE_INCDIR_OPENGL_ES2 =
QMAKE_LIBDIR_OPENGL_ES2 = QMAKE_LIBDIR_OPENGL_ES2 =

View File

@ -74,8 +74,6 @@ QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$ANDROID_PLATFORM_PA
QMAKE_INCDIR_X11 = QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 = QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL = QMAKE_INCDIR_OPENGL =
QMAKE_INCDIR_OPENGL_ES1 =
QMAKE_LIBDIR_OPENGL_ES1 =
QMAKE_INCDIR_OPENGL_ES2 = QMAKE_INCDIR_OPENGL_ES2 =
QMAKE_LIBDIR_OPENGL_ES2 = QMAKE_LIBDIR_OPENGL_ES2 =
@ -110,7 +108,6 @@ QMAKE_LIBS_QT_OPENGL =
QMAKE_LIBS_QTOPIA = QMAKE_LIBS_QTOPIA =
QMAKE_LIBS_THREAD = QMAKE_LIBS_THREAD =
QMAKE_LIBS_OPENGL = QMAKE_LIBS_OPENGL =
QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $$QMAKE_LIBS QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $$QMAKE_LIBS
load(qt_config) load(qt_config)

View File

@ -13,8 +13,6 @@ QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 = QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL = QMAKE_INCDIR_OPENGL =
QMAKE_LIBDIR_OPENGL = QMAKE_LIBDIR_OPENGL =
QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL
QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL
QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL
QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL
QMAKE_INCDIR_EGL = QMAKE_INCDIR_EGL =
@ -28,7 +26,6 @@ QMAKE_LIBS_X11 = -lXext -lX11 -lm
QMAKE_LIBS_NIS = -lnsl QMAKE_LIBS_NIS = -lnsl
QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL = -lGL QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
QMAKE_LIBS_OPENVG = -lOpenVG QMAKE_LIBS_OPENVG = -lOpenVG
QMAKE_LIBS_THREAD = -lpthread QMAKE_LIBS_THREAD = -lpthread

View File

@ -4,7 +4,7 @@
include(qcc-base.conf) include(qcc-base.conf)
CONFIG += qnx QMAKE_PLATFORM += qnx
#Choose qnx QPA Plugin as default #Choose qnx QPA Plugin as default
QT_QPA_DEFAULT_PLATFORM = qnx QT_QPA_DEFAULT_PLATFORM = qnx
@ -29,7 +29,6 @@ QMAKE_LIBS = -lm
QMAKE_LIBS_NETWORK = -lsocket QMAKE_LIBS_NETWORK = -lsocket
# OpenGL libraries have a dependency on libEGL # OpenGL libraries have a dependency on libEGL
QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM -lEGL
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 -lEGL QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 -lEGL
QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_EGL = -lEGL

View File

@ -65,7 +65,6 @@ QMAKE_LIBS_COMPAT =
QMAKE_EXTENSION_STATICLIB = lib QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_EGL = libEGL.lib QMAKE_LIBS_EGL = libEGL.lib
QMAKE_LIBS_OPENGL_ES1 = libGLES_CM.lib
QMAKE_LIBS_OPENGL_ES2 = libGLESv2.lib QMAKE_LIBS_OPENGL_ES2 = libGLESv2.lib
QMAKE_LIBS_QT_ENTRY = -lqtmain QMAKE_LIBS_QT_ENTRY = -lqtmain

View File

@ -111,15 +111,22 @@ if(build_all|CONFIG(debug, debug|release)): CMAKE_DEBUG_TYPE = debug
if(build_all|CONFIG(release, debug|release)): CMAKE_RELEASE_TYPE = release if(build_all|CONFIG(release, debug|release)): CMAKE_RELEASE_TYPE = release
contains(CONFIG, plugin) { contains(CONFIG, plugin) {
PLUGIN_MODULE_NAME = !isEmpty(PLUGIN_EXTENDS):!equals(PLUGIN_EXTENDS, -) {
for (mod, QT_MODULES) { count(PLUGIN_EXTENDS, 1, greaterThan): \
types = $$replace(QT.$${mod}.plugin_types, /.*$, ) error("Plugin declares to extend multiple modules. We don't handle that ...")
contains(types, $$PLUGIN_TYPE) { PLUGIN_MODULE_NAME = $$PLUGIN_EXTENDS
PLUGIN_MODULE_NAME = $$mod } else {
break() PLUGIN_MODULE_NAME =
for (mod, QT_MODULES) {
contains(QT.$${mod}.plugin_types, $$PLUGIN_TYPE) {
!isEmpty(PLUGIN_MODULE_NAME): \
error("Multiple modules claim plugin type '$$PLUGIN_TYPE' ($$mod, in addition to $$PLUGIN_MODULE_NAME)")
PLUGIN_MODULE_NAME = $$mod
break()
}
} }
isEmpty(PLUGIN_MODULE_NAME): error("No module claims plugin type '$$PLUGIN_TYPE'")
} }
isEmpty(PLUGIN_MODULE_NAME): return()
CMAKE_MODULE_NAME = $$cmakeModuleName($$PLUGIN_MODULE_NAME) CMAKE_MODULE_NAME = $$cmakeModuleName($$PLUGIN_MODULE_NAME)

View File

@ -1,23 +1,8 @@
# On UNIX, we can use config tests to figure out if egl.h is in INCLUDEPATH += $$QMAKE_INCDIR_EGL
# EGL/egl.h or GLES/egl.h. Sadly, there are no config tests on WinCE LIBS_PRIVATE += $$QMAKE_LIBS_EGL
# so we have to assume that for GLES 1.1 (CL), the EGL header is in QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL
# GLES/egl.h. We also assume there is no separate libEGL.lib library, QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL
# so we use the GL library instead. LIBS += $$QMAKE_LFLAGS_EGL
for(p, QMAKE_LIBDIR_EGL) {
wince*:contains(QT_CONFIG, opengles1) { exists($$p): LIBS_PRIVATE += -L$$p
INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1
LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES1
for(p, QMAKE_LIBDIR_OPENGL_ES1) {
exists($$p):LIBS_PRIVATE += -L$$p
}
DEFINES += QT_GLES_EGL
} else {
INCLUDEPATH += $$QMAKE_INCDIR_EGL
LIBS_PRIVATE += $$QMAKE_LIBS_EGL
QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL
LIBS += $$QMAKE_LFLAGS_EGL
for(p, QMAKE_LIBDIR_EGL) {
exists($$p):LIBS_PRIVATE += -L$$p
}
} }

View File

@ -37,6 +37,13 @@ qt:!isEmpty(QT_CONFIG) {
} }
} }
macx-xcode:!isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) {
debug_information_format.name = DEBUG_INFORMATION_FORMAT
debug_information_format.value = $$QMAKE_XCODE_DEBUG_INFORMATION_FORMAT
debug_information_format.build = debug
QMAKE_MAC_XCODE_SETTINGS += debug_information_format
}
cache(QMAKE_XCODE_DEVELOPER_PATH, stash) cache(QMAKE_XCODE_DEVELOPER_PATH, stash)
cache(QMAKE_XCODE_VERSION, stash) cache(QMAKE_XCODE_VERSION, stash)

View File

@ -33,6 +33,16 @@ isEmpty(QMAKE_TARGET_BUNDLE_PREFIX) {
cache(QMAKE_TARGET_BUNDLE_PREFIX) cache(QMAKE_TARGET_BUNDLE_PREFIX)
} }
# Make the default debug info format for static debug builds
# DWARF instead of DWARF with dSYM. This cuts down build times
# for application debug builds significantly, as Xcode doesn't
# have to pull out all the DWARF info from the Qt static libs
# and put it into a dSYM file. We don't need that dSYM file in
# the first place, since the information is available in the
# object files inside the archives (static libraries).
contains(QT_CONFIG, static): \
QMAKE_XCODE_DEBUG_INFORMATION_FORMAT = dwarf
# This variable is used by the xcode_dynamic_library_suffix # This variable is used by the xcode_dynamic_library_suffix
# feature, which allows Xcode to choose the Qt libraries to link to # feature, which allows Xcode to choose the Qt libraries to link to
# at build time, depending on the current Xcode SDK and configuration. # at build time, depending on the current Xcode SDK and configuration.

View File

@ -45,12 +45,7 @@ for(tool, $$list(QMAKE_CC QMAKE_CXX QMAKE_FIX_RPATH QMAKE_AR QMAKE_RANLIB QMAKE_
} }
isEmpty(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.platform_name) { isEmpty(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.platform_name) {
# We use xml as the output format instead of json since plutil on 10.6 does not have that option QMAKE_MAC_PLATFORM_NAME = $$system("/usr/libexec/PlistBuddy -c 'print DefaultProperties:PLATFORM_NAME' $$QMAKE_MAC_SDK_PATH/SDKSettings.plist 2>/dev/null")
QMAKE_MAC_PLATFORM_NAME = $$system("/usr/bin/plutil -convert xml1 \"$$QMAKE_MAC_SDK_PATH/SDKSettings.plist\" -o - 2>/dev/null | " \
"sed '/^<!DOCTYPE/d' | " \ # Don't look up http://www.apple.com/DTDs/PropertyList-1.0.dtd
"PERL5LIB= xpath 'string(//key[.=\"PLATFORM_NAME\"]/following-sibling::*[1])' 2>/dev/null | " \
"sed 's/.*Value: \\(.*\\)/\\1/'")
isEmpty(QMAKE_MAC_PLATFORM_NAME): error("Could not resolve platform name for SDK '$$QMAKE_MAC_SDK'") isEmpty(QMAKE_MAC_PLATFORM_NAME): error("Could not resolve platform name for SDK '$$QMAKE_MAC_SDK'")
cache(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.platform_name, set stash, QMAKE_MAC_PLATFORM_NAME) cache(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.platform_name, set stash, QMAKE_MAC_PLATFORM_NAME)
} else { } else {

View File

@ -1,2 +0,0 @@
QMAKE_LIBS_OPENGL_ES2 =
LIBS += $$QMAKE_LIBS_OPENGL_ES1

View File

@ -73,10 +73,11 @@ wince*:static:gui {
QTLIB += qmenu_wce.res QTLIB += qmenu_wce.res
} }
# static builds: link qml import plugins into the app.
qt_module_deps = $$QT $$QT_PRIVATE qt_module_deps = $$QT $$QT_PRIVATE
qt_module_deps = $$replace(qt_module_deps, -private$, _private) qt_module_deps = $$replace(qt_module_deps, -private$, _private)
qt_module_deps = $$resolve_depends(qt_module_deps, "QT.") qt_module_deps = $$resolve_depends(qt_module_deps, "QT.")
# static builds: link qml import plugins into the app.
contains(qt_module_deps, qml): \ contains(qt_module_deps, qml): \
contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan { contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan {
# run qmlimportscanner # run qmlimportscanner
@ -162,6 +163,37 @@ contains(qt_module_deps, qml): \
} }
} }
contains(TEMPLATE, .*app) {
autoplugs =
for (qtmod, qt_module_deps) {
for (ptype, QT.$${qtmod}.plugin_types) {
isEmpty(QTPLUGIN.$$ptype) {
for (plug, QT_PLUGINS) {
equals(QT_PLUGIN.$${plug}.TYPE, $$ptype) {
for (dep, QT_PLUGIN.$${plug}.EXTENDS) {
!contains(qt_module_deps, $$dep) {
plug =
break()
}
}
autoplugs += $$plug
}
}
} else {
plug = $$eval(QTPLUGIN.$$ptype)
!equals(plug, -): \
autoplugs += $$plug
}
}
}
manualplugs = $$QTPLUGIN
manualplugs -= $$autoplugs
QTPLUGIN -= $$manualplugs
!isEmpty(QTPLUGIN): \
warning("Redundant entries in QTPLUGIN: $$QTPLUGIN")
QTPLUGIN = $$manualplugs $$autoplugs
}
QT_PLUGIN_VERIFY = DEPLOYMENT_PLUGIN QT_PLUGIN_VERIFY = DEPLOYMENT_PLUGIN
contains(QT_CONFIG, static) { contains(QT_CONFIG, static) {
QT_PLUGIN_VERIFY += QTPLUGIN QT_PLUGIN_VERIFY += QTPLUGIN
@ -209,7 +241,12 @@ for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) {
# Only link against plugin in static builds # Only link against plugin in static builds
isEqual(QT_CURRENT_VERIFY, QTPLUGIN): { isEqual(QT_CURRENT_VERIFY, QTPLUGIN): {
!isEmpty(QT_PLUGINPATH): LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/$$QT_PLUGINPATH !isEmpty(QT_PLUGINPATH) {
plugpath = $$eval(QT_PLUGIN.$${QTPLUG}.PATH)
isEmpty(plugpath): \
plugpath = $$[QT_INSTALL_PLUGINS/get]
LIBS *= -L$$plugpath/$$QT_PLUGINPATH
}
LIBS += $$QT_LINKAGE LIBS += $$QT_LINKAGE
# if the plugin is linked statically there is no need to deploy it # if the plugin is linked statically there is no need to deploy it
DEPLOYMENT_PLUGIN -= $$QT_CURRENT_VERIFY DEPLOYMENT_PLUGIN -= $$QT_CURRENT_VERIFY

View File

@ -70,6 +70,10 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
module_config = "QT.$${MODULE_ID}.CONFIG = $$MODULE_CONFIG" module_config = "QT.$${MODULE_ID}.CONFIG = $$MODULE_CONFIG"
else: \ else: \
module_config = module_config =
!isEmpty(MODULE_PLUGIN_TYPES): \
module_plugtypes = "QT.$${MODULE_ID}.plugin_types = $$replace(MODULE_PLUGIN_TYPES, /.*$, )"
else: \
module_plugtypes =
!no_module_headers:!minimal_syncqt { !no_module_headers:!minimal_syncqt {
MODULE_INCLUDES = \$\$QT_MODULE_INCLUDE_BASE \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME MODULE_INCLUDES = \$\$QT_MODULE_INCLUDE_BASE \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME
MODULE_PRIVATE_INCLUDES = \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME/$$VERSION \ MODULE_PRIVATE_INCLUDES = \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME/$$VERSION \
@ -100,7 +104,7 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
"QT.$${MODULE_ID}.plugins = \$\$QT_MODULE_PLUGIN_BASE" \ "QT.$${MODULE_ID}.plugins = \$\$QT_MODULE_PLUGIN_BASE" \
"QT.$${MODULE_ID}.imports = \$\$QT_MODULE_IMPORT_BASE" \ "QT.$${MODULE_ID}.imports = \$\$QT_MODULE_IMPORT_BASE" \
"QT.$${MODULE_ID}.qml = \$\$QT_MODULE_QML_BASE" \ "QT.$${MODULE_ID}.qml = \$\$QT_MODULE_QML_BASE" \
$$join(MODULE_PLUGIN_TYPES, " ", "QT.$${MODULE_ID}.plugin_types = ") $$module_plugtypes
MODULE_PRI_CONT += \ MODULE_PRI_CONT += \
"QT.$${MODULE_ID}.depends =$$join(MODULE_DEPENDS, " ", " ")" \ "QT.$${MODULE_ID}.depends =$$join(MODULE_DEPENDS, " ", " ")" \
$$module_rundep \ $$module_rundep \

View File

@ -27,14 +27,43 @@ tool_plugin {
CONFIG(static, static|shared) { CONFIG(static, static|shared) {
isEmpty(MODULE): MODULE = $$basename(TARGET) isEmpty(MODULE): MODULE = $$basename(TARGET)
MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_plugin_$${MODULE}.pri mod_work_pfx = $$MODULE_QMAKE_OUTDIR/mkspecs/modules
force_independent: \
mod_inst_pfx = $$MODULE_QMAKE_OUTDIR/mkspecs/modules-inst
else: \
mod_inst_pfx = $$mod_work_pfx
MODULE_PRI = $$mod_inst_pfx/qt_plugin_$${MODULE}.pri
MODULE_FWD_PRI = $$mod_work_pfx/qt_plugin_$${MODULE}.pri
!build_pass { !build_pass {
MODULE_PRI_CONT = \ MODULE_PRI_CONT = \
"QT_PLUGIN.$${MODULE}.TYPE = $$PLUGIN_TYPE" \ "QT_PLUGIN.$${MODULE}.TYPE = $$PLUGIN_TYPE" \
"QT_PLUGIN.$${MODULE}.CLASS_NAME = $$PLUGIN_CLASS_NAME" "QT_PLUGIN.$${MODULE}.EXTENDS = $$PLUGIN_EXTENDS" \
"QT_PLUGIN.$${MODULE}.CLASS_NAME = $$PLUGIN_CLASS_NAME" \
"QT_PLUGINS += $$MODULE"
write_file($$MODULE_PRI, MODULE_PRI_CONT)|error("Aborting.") write_file($$MODULE_PRI, MODULE_PRI_CONT)|error("Aborting.")
MODULE_PRI_FILES = $$MODULE_PRI
force_independent {
# Create a forwarding module .pri file
MODULE_FWD_PRI_CONT = \
"QT_PLUGIN.$${MODULE}.PATH = $$MODULE_BASE_OUTDIR/plugins" \
"include($$MODULE_PRI)"
write_file($$MODULE_FWD_PRI, MODULE_FWD_PRI_CONT)|error("Aborting.")
touch($$MODULE_FWD_PRI, $$MODULE_PRI)
MODULE_PRI_FILES += $$MODULE_FWD_PRI
}
# Then, inject the new module into the current cache state
!contains(QMAKE_INTERNAL_INCLUDED_FILES, $$MODULE_FWD_PRI): \ # before the actual include()!
cache(QMAKE_INTERNAL_INCLUDED_FILES, add transient, MODULE_PRI_FILES)
include($$MODULE_FWD_PRI)
for(var, $$list(TYPE EXTENDS CLASS_NAME PATH)): \
defined(QT_PLUGIN.$${MODULE}.$$var, var): \
cache(QT_PLUGIN.$${MODULE}.$$var, transient)
cache(QT_PLUGINS, transient)
} }
pritarget.path = $$[QT_HOST_DATA]/mkspecs/modules pritarget.path = $$[QT_HOST_DATA]/mkspecs/modules

View File

@ -1,9 +1,4 @@
contains(QT_CONFIG, opengles1) { contains(QT_CONFIG, opengles2) {
INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES1
!isEmpty(QMAKE_LIBDIR_OPENGL_ES1):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES1
target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES1
else:LIBS += $$QMAKE_LIBS_OPENGL_ES1
} else:contains(QT_CONFIG, opengles2) {
INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2 INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2
!isEmpty(QMAKE_LIBDIR_OPENGL_ES2):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES2 !isEmpty(QMAKE_LIBDIR_OPENGL_ES2):QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES2
target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES2 target_qt:LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL_ES2

View File

@ -1,4 +1,6 @@
CONFIG -= windows CONFIG -= windows
contains(TEMPLATE, ".*app") { contains(TEMPLATE, ".*app") {
QMAKE_LFLAGS += $$QMAKE_LFLAGS_CONSOLE $$QMAKE_LFLAGS_EXE QMAKE_LFLAGS += \
$$replace(QMAKE_LFLAGS_CONSOLE, @QMAKE_SUBSYSTEM_SUFFIX@, $$QMAKE_SUBSYSTEM_SUFFIX) \
$$QMAKE_LFLAGS_EXE
} }

View File

@ -0,0 +1,10 @@
load(qt_config)
equals(QMAKE_TARGET_OS, xp) {
# http://blogs.msdn.com/b/vcblog/archive/2012/10/08/10357555.aspx?PageIndex=3
equals(QT_ARCH, x86_64) {
QMAKE_SUBSYSTEM_SUFFIX = ,5.02
} else {
QMAKE_SUBSYSTEM_SUFFIX = ,5.01
}
}

View File

@ -1,6 +1,8 @@
CONFIG -= console CONFIG -= console
contains(TEMPLATE, ".*app"){ contains(TEMPLATE, ".*app"){
QMAKE_LFLAGS += $$QMAKE_LFLAGS_WINDOWS $$QMAKE_LFLAGS_EXE QMAKE_LFLAGS += \
$$replace(QMAKE_LFLAGS_WINDOWS, @QMAKE_SUBSYSTEM_SUFFIX@, $$QMAKE_SUBSYSTEM_SUFFIX) \
$$QMAKE_LFLAGS_EXE
mingw:DEFINES += QT_NEEDS_QMAIN mingw:DEFINES += QT_NEEDS_QMAIN
qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) { qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) {

View File

@ -16,8 +16,6 @@ QMAKE_INCDIR_X11 = /usr/X11R6/include
QMAKE_LIBDIR_X11 = /usr/X11R6/lib QMAKE_LIBDIR_X11 = /usr/X11R6/lib
QMAKE_INCDIR_OPENGL = /usr/X11R6/include QMAKE_INCDIR_OPENGL = /usr/X11R6/include
QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL
QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL
QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL
QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL
QMAKE_INCDIR_EGL = QMAKE_INCDIR_EGL =
@ -31,7 +29,6 @@ QMAKE_LIBS_X11 = -lXext -lX11 -lm
QMAKE_LIBS_NIS = -lnsl QMAKE_LIBS_NIS = -lnsl
QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL = -lGL QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
QMAKE_LIBS_OPENVG = -lOpenVG QMAKE_LIBS_OPENVG = -lOpenVG
QMAKE_LIBS_THREAD = -lpthread QMAKE_LIBS_THREAD = -lpthread

View File

@ -178,22 +178,6 @@ macx-xcode {
QMAKE_SUBSTITUTES += copy_image QMAKE_SUBSTITUTES += copy_image
launch_images.files = $$copy_image.output launch_images.files = $$copy_image.output
QMAKE_BUNDLE_DATA += launch_images QMAKE_BUNDLE_DATA += launch_images
# Make the default debug information format for debug builds
# DWARF instead of DWARF with dSYM. This cuts down build times
# for application debug builds significantly, as Xcode doesn't
# have to pull out all the DWARF info from our static libraries
# and put it into a dSYM file. We don't need that dSYM file in
# the first place, since the information is available in the
# object files inside the archives (static libraries). The only
# unfortunate side effect of this is that the user won't be
# able to break on specific lines of main(). This is due to
# using ld to rename the main-function, and will go away once
# we implement a separate tool to do the symbol renaming.
debug_information_format.name = DEBUG_INFORMATION_FORMAT
debug_information_format.value = dwarf
debug_information_format.build = debug
QMAKE_MAC_XCODE_SETTINGS += debug_information_format
} }
macx-xcode { macx-xcode {

View File

@ -0,0 +1,7 @@
#
# qmake configuration for qnx-qcc armv7 targets
#
include(../common/qcc-base-qnx-armv7le.conf)
DEFINES += QT_NO_CLIPBOARD

View File

@ -1,9 +1,9 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2012 - 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the config.tests of the Qt Toolkit. ** This file is part of the QtCore module of the Qt Toolkit.
** **
** $QT_BEGIN_LICENSE:LGPL$ ** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage ** Commercial License Usage
@ -39,13 +39,71 @@
** **
****************************************************************************/ ****************************************************************************/
#include <GLES/egl.h> #ifndef QPLATFORMDEFS_H
#define QPLATFORMDEFS_H
int main(int, char **) // Get Qt defines/settings
#include "qglobal.h"
// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
#include <unistd.h>
#define __STDC_CONSTANT_MACROS
// We are hot - unistd.h should have turned on the specific APIs we requested
#include <pthread.h>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/ipc.h>
#include <sys/time.h>
// QNX doesn't have the System V <sys/shm.h> header. This is not a standard
// POSIX header, it's only documented in the Single UNIX Specification.
// The preferred POSIX compliant way to share memory is to use the functions
// in <sys/mman.h> that comply with the POSIX Real Time Interface (1003.1b).
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <netinet/in.h>
#ifndef QT_NO_IPV6IFNAME
#include <net/if.h>
#endif
// for htonl
#include <arpa/inet.h>
#define QT_USE_XOPEN_LFS_EXTENSIONS
#if !defined(__EXT_QNX__READDIR64_R)
#define QT_NO_READDIR64
#endif
#include "../common/posix/qplatformdefs.h"
#if defined(__EXT_QNX__READDIR64_R)
#define QT_EXT_QNX_READDIR_R ::_readdir64_r
#elif defined(__EXT_QNX__READDIR_R)
#define QT_EXT_QNX_READDIR_R ::_readdir_r
#endif
#define QT_SNPRINTF ::snprintf
#define QT_VSNPRINTF ::vsnprintf
// QNX6 doesn't have getpagesize()
inline int getpagesize()
{ {
EGLint x = 0; return ::sysconf(_SC_PAGESIZE);
EGLDisplay dpy = 0;
EGLContext ctx = 0;
eglDestroyContext(dpy, ctx);
return 0;
} }
#include <stdlib.h>
#define QT_QWS_TEMP_DIR QString::fromLatin1(qgetenv("TMP"))
#endif // QPLATFORMDEFS_H

View File

@ -1,7 +1,5 @@
# #
# qmake configuration for qnx-qcc armv7 targets # deprecated, please use qnx-armle-v7-qcc instead
# #
warning("You are using deprecated mkspecs. Please use qnx-armle-v7-qcc instead.")
include(../common/qcc-base-qnx-armv7le.conf) include(../qnx-armle-v7-qcc/qmake.conf)
DEFINES += QT_NO_CLIPBOARD

View File

@ -39,9 +39,4 @@
** **
****************************************************************************/ ****************************************************************************/
#ifndef QPLATFORMDEFS_H #include "../qnx-armle-v7-qcc/qplatformdefs.h"
#define QPLATFORMDEFS_H
#include "../common/qnx/qplatformdefs.h"
#endif // QPLATFORMDEFS_H

View File

@ -130,8 +130,6 @@ QMAKE_LIBDIR = ${ANDROID_PRODUCT_OUT}/obj/lib
QMAKE_INCDIR_X11 = QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 = QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL = QMAKE_INCDIR_OPENGL =
QMAKE_INCDIR_OPENGL_ES1 =
QMAKE_LIBDIR_OPENGL_ES1 =
QMAKE_INCDIR_OPENGL_ES2 = QMAKE_INCDIR_OPENGL_ES2 =
QMAKE_LIBDIR_OPENGL_ES2 = QMAKE_LIBDIR_OPENGL_ES2 =
@ -172,7 +170,6 @@ QMAKE_LIBS_QT_OPENGL =
QMAKE_LIBS_QTOPIA = QMAKE_LIBS_QTOPIA =
QMAKE_LIBS_THREAD = QMAKE_LIBS_THREAD =
QMAKE_LIBS_OPENGL = QMAKE_LIBS_OPENGL =
QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM
QMAKE_LIBS_OPENGL_ES2 = -lEGL -lGLESv2 $$QMAKE_LIBS QMAKE_LIBS_OPENGL_ES2 = -lEGL -lGLESv2 $$QMAKE_LIBS
CONFIG += linux-android-9 android-9 linux-android android android-no-sdk android_app CONFIG += linux-android-9 android-9 linux-android android android-no-sdk android_app

View File

@ -85,8 +85,6 @@ QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 = QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL = QMAKE_INCDIR_OPENGL =
QMAKE_LIBDIR_OPENGL = QMAKE_LIBDIR_OPENGL =
QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL
QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL
QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL
QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL
QMAKE_INCDIR_EGL = QMAKE_INCDIR_EGL =
@ -100,7 +98,6 @@ QMAKE_LIBS_X11 = -lXext -lX11 -lm
QMAKE_LIBS_NIS = -lnsl QMAKE_LIBS_NIS = -lnsl
QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL = -lGL QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
QMAKE_LIBS_OPENVG = -lOpenVG QMAKE_LIBS_OPENVG = -lOpenVG
QMAKE_LIBS_THREAD = -lpthread QMAKE_LIBS_THREAD = -lpthread

View File

@ -70,8 +70,8 @@ QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO
QMAKE_LFLAGS_DEBUG = /DEBUG QMAKE_LFLAGS_DEBUG = /DEBUG
QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@
QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\"
QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_DLL = /DLL
QMAKE_LFLAGS_LTCG = /LTCG QMAKE_LFLAGS_LTCG = /LTCG

View File

@ -70,8 +70,8 @@ QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO
QMAKE_LFLAGS_DEBUG = /DEBUG QMAKE_LFLAGS_DEBUG = /DEBUG
QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@
QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\"
QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_DLL = /DLL
QMAKE_LFLAGS_LTCG = /LTCG QMAKE_LFLAGS_LTCG = /LTCG

View File

@ -1696,11 +1696,10 @@
If the OpenGL implementation uses EGL (most OpenGL/ES systems), If the OpenGL implementation uses EGL (most OpenGL/ES systems),
then QMAKE_INCDIR_EGL may also need to be set. then QMAKE_INCDIR_EGL may also need to be set.
\section1 QMAKE_INCDIR_OPENGL_ES1, QMAKE_INCDIR_OPENGL_ES2 \section1 QMAKE_INCDIR_OPENGL_ES2
These variables specify the location of OpenGL headers files to be added This variable specifies the location of OpenGL header files to be added
to \l{INCLUDEPATH} when building a target with OpenGL ES 1 to \l{INCLUDEPATH} when building a target with OpenGL ES 2 support.
or OpenGL ES 2 support respectively.
The value of this variable is typically handled by qmake or The value of this variable is typically handled by qmake or
\l{#QMAKESPEC}{qmake.conf} and rarely \l{#QMAKESPEC}{qmake.conf} and rarely

View File

@ -210,7 +210,7 @@ UnixMakefileGenerator::init()
// replace place holders // replace place holders
pchFlags = pchFlags.replace("${QMAKE_PCH_INPUT}", pchFlags = pchFlags.replace("${QMAKE_PCH_INPUT}",
fileFixify(project->first("PRECOMPILED_HEADER").toQString())); project->first("PRECOMPILED_HEADER").toQString());
pchFlags = pchFlags.replace("${QMAKE_PCH_OUTPUT_BASE}", pchBaseName); pchFlags = pchFlags.replace("${QMAKE_PCH_OUTPUT_BASE}", pchBaseName);
if (project->isActiveConfig("icc_pch_style")) { if (project->isActiveConfig("icc_pch_style")) {
// icc style // icc style
@ -921,7 +921,8 @@ UnixMakefileGenerator::escapeFilePath(const QString &path) const
{ {
QString ret = path; QString ret = path;
if(!ret.isEmpty()) { if(!ret.isEmpty()) {
ret = unescapeFilePath(ret).replace(QLatin1Char(' '), QLatin1String("\\ ")); ret = unescapeFilePath(ret).replace(QLatin1Char(' '), QLatin1String("\\ "))
.replace(QLatin1Char('\t'), QLatin1String("\\\t"));
debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData());
} }
return ret; return ret;

View File

@ -1779,8 +1779,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool)
xml << tag("PropertyGroup") xml << tag("PropertyGroup")
<< attrTag("Condition", generateCondition(tool)) << attrTag("Condition", generateCondition(tool))
<< attrTag("Label", "Configuration") << attrTag("Label", "Configuration")
<< attrTagS(_PlatformToolSet, platformToolSetVersion(tool.CompilerVersion, << attrTagS(_PlatformToolSet, tool.PlatformToolSet)
tool.WinPhone))
<< attrTagS(_OutputDirectory, tool.OutputDirectory) << attrTagS(_OutputDirectory, tool.OutputDirectory)
<< attrTagT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage) << attrTagT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage)
<< attrTagT(_BuildBrowserInformation, tool.BuildBrowserInformation) << attrTagT(_BuildBrowserInformation, tool.BuildBrowserInformation)
@ -2193,27 +2192,4 @@ QString VCXProjectWriter::generateCondition(const VCConfiguration &config)
return QStringLiteral("'$(Configuration)|$(Platform)'=='") + config.Name + QLatin1Char('\''); return QStringLiteral("'$(Configuration)|$(Platform)'=='") + config.Name + QLatin1Char('\'');
} }
QString VCXProjectWriter::platformToolSetVersion(const DotNET version, bool winphoneBuild)
{
// The PlatformToolset string corresponds to the name of a directory in
// $(VCTargetsPath)\Platforms\{Win32,x64,...}\PlatformToolsets
// e.g. v90, v100, v110, v110_xp, v120_CTP_Nov, v120, or WindowsSDK7.1
// This environment variable may be set by a commandline build
// environment such as the Windows SDK command prompt
QByteArray envVar = qgetenv("PlatformToolset");
if (!envVar.isEmpty())
return envVar;
switch (version)
{
case NET2012:
return winphoneBuild ? "v110_wp80" : "v110";
case NET2013:
return "v120";
default:
return QString();
}
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -184,7 +184,6 @@ private:
static void outputFileConfigs(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter, const VCFilterFile &info, const QString &filtername); static void outputFileConfigs(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter, const VCFilterFile &info, const QString &filtername);
static bool outputFileConfig(VCFilter &filter, XmlOutput &xml, XmlOutput &xmlFilter, const QString &filename, const QString &filtername, bool fileAllreadyAdded); static bool outputFileConfig(VCFilter &filter, XmlOutput &xml, XmlOutput &xmlFilter, const QString &filename, const QString &filtername, bool fileAllreadyAdded);
static QString generateCondition(const VCConfiguration &config); static QString generateCondition(const VCConfiguration &config);
static QString platformToolSetVersion(const DotNET version, bool winphoneBuild);
friend class XTreeNode; friend class XTreeNode;
friend class XFlatNode; friend class XFlatNode;

View File

@ -901,6 +901,7 @@ public:
QString OutputDirectory; QString OutputDirectory;
QString PrimaryOutput; QString PrimaryOutput;
QString ProgramDatabase; QString ProgramDatabase;
QString PlatformToolSet;
triState RegisterOutput; triState RegisterOutput;
useOfATL UseOfATL; useOfATL UseOfATL;
useOfMfc UseOfMfc; useOfMfc UseOfMfc;

View File

@ -384,6 +384,35 @@ QUuid VcprojGenerator::increaseUUID(const QUuid &id)
return result; return result;
} }
QString VcprojGenerator::retrievePlatformToolSet() const
{
// The PlatformToolset string corresponds to the name of a directory in
// $(VCTargetsPath)\Platforms\{Win32,x64,...}\PlatformToolsets
// e.g. v90, v100, v110, v110_xp, v120_CTP_Nov, v120, or WindowsSDK7.1
// This environment variable may be set by a commandline build
// environment such as the Windows SDK command prompt
QByteArray envVar = qgetenv("PlatformToolset");
if (!envVar.isEmpty())
return envVar;
QString suffix;
if (vcProject.Configuration.WinPhone)
suffix = "_wp80";
else if (project->first("QMAKE_TARGET_OS") == "xp")
suffix = "_xp";
switch (vcProject.Configuration.CompilerVersion)
{
case NET2012:
return QStringLiteral("v110") + suffix;
case NET2013:
return QStringLiteral("v120") + suffix;
default:
return QString();
}
}
ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QString, QString> &projLookup, ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QString, QString> &projLookup,
QHash<QString, QString> &projGuids, QHash<QString, QString> &projGuids,
QHash<VcsolutionDepend *, QStringList> &extraSubdirs, QHash<VcsolutionDepend *, QStringList> &extraSubdirs,
@ -969,10 +998,14 @@ void VcprojGenerator::initConfiguration()
if (!conf.OutputDirectory.endsWith("\\")) if (!conf.OutputDirectory.endsWith("\\"))
conf.OutputDirectory += '\\'; conf.OutputDirectory += '\\';
if (conf.CompilerVersion >= NET2010) { if (conf.CompilerVersion >= NET2010) {
conf.PlatformToolSet = retrievePlatformToolSet();
// The target name could have been changed. // The target name could have been changed.
conf.PrimaryOutput = project->first("TARGET").toQString(); conf.PrimaryOutput = project->first("TARGET").toQString();
if ( !conf.PrimaryOutput.isEmpty() && !project->first("TARGET_VERSION_EXT").isEmpty() && project->isActiveConfig("shared")) if (!conf.PrimaryOutput.isEmpty() && project->first("TEMPLATE") == "vclib"
&& project->isActiveConfig("shared")) {
conf.PrimaryOutput.append(project->first("TARGET_VERSION_EXT").toQString()); conf.PrimaryOutput.append(project->first("TARGET_VERSION_EXT").toQString());
}
} }
if (conf.CompilerVersion >= NET2012) { if (conf.CompilerVersion >= NET2012) {

View File

@ -144,6 +144,7 @@ private:
QHash<QString, ProStringList> &subdirProjectLookup, QHash<QString, ProStringList> &subdirProjectLookup,
const ProStringList &allDependencies = ProStringList()); const ProStringList &allDependencies = ProStringList());
QUuid increaseUUID(const QUuid &id); QUuid increaseUUID(const QUuid &id);
QString retrievePlatformToolSet() const;
friend class VCFilter; friend class VCFilter;
}; };

View File

@ -883,7 +883,7 @@ QString Win32MakefileGenerator::escapeFilePath(const QString &path) const
QString ret = path; QString ret = path;
if(!ret.isEmpty()) { if(!ret.isEmpty()) {
ret = unescapeFilePath(ret); ret = unescapeFilePath(ret);
if(ret.contains(" ")) if (ret.contains(' ') || ret.contains('\t'))
ret = "\"" + ret + "\""; ret = "\"" + ret + "\"";
debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData());
} }

View File

@ -1277,9 +1277,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnFalse; return ReturnFalse;
} }
int cnt = values(map(args.at(0))).count(); int cnt = values(map(args.at(0))).count();
int val = args.at(1).toQString(m_tmp1).toInt();
if (args.count() == 3) { if (args.count() == 3) {
const ProString &comp = args.at(2); const ProString &comp = args.at(2);
const int val = args.at(1).toQString(m_tmp1).toInt();
if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) { if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) {
return returnBool(cnt > val); return returnBool(cnt > val);
} else if (comp == QLatin1String(">=")) { } else if (comp == QLatin1String(">=")) {
@ -1290,13 +1290,13 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return returnBool(cnt <= val); return returnBool(cnt <= val);
} else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual") } else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual")
|| comp == QLatin1String("=") || comp == QLatin1String("==")) { || comp == QLatin1String("=") || comp == QLatin1String("==")) {
return returnBool(cnt == val); // fallthrough
} else { } else {
evalError(fL1S("Unexpected modifier to count(%2).").arg(comp.toQString(m_tmp1))); evalError(fL1S("Unexpected modifier to count(%2).").arg(comp.toQString(m_tmp1)));
return ReturnFalse; return ReturnFalse;
} }
} }
return returnBool(cnt == args.at(1).toQString(m_tmp1).toInt()); return returnBool(cnt == val);
} }
case T_GREATERTHAN: case T_GREATERTHAN:
case T_LESSTHAN: { case T_LESSTHAN: {

View File

@ -691,11 +691,12 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
CFDictionaryRef attributes = CTRunGetAttributes (run); CFDictionaryRef attributes = CTRunGetAttributes (run);
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName)); CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0); CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
CFRange range = CTRunGetStringRange (run);
if (!CFEqual (run_cg_font, face_data->cg_font)) if (!CFEqual (run_cg_font, face_data->cg_font))
{ {
CFRelease (run_cg_font); CFRelease (run_cg_font);
CFRange range = CTRunGetStringRange (run);
buffer->ensure (buffer->len + range.length); buffer->ensure (buffer->len + range.length);
if (buffer->in_error) if (buffer->in_error)
FAIL ("Buffer resize failed"); FAIL ("Buffer resize failed");
@ -732,11 +733,16 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
} }
CFRelease (run_cg_font); CFRelease (run_cg_font);
/* CoreText throws away the PDF token, while the OpenType backend will add a zero-advance
* glyph for this. We need to make sure the two produce the same output. */
UniChar endGlyph = CFStringGetCharacterAtIndex(string_ref, range.location + range.length - 1);
bool endWithPDF = endGlyph == 0x202c;
unsigned int num_glyphs = CTRunGetGlyphCount (run); unsigned int num_glyphs = CTRunGetGlyphCount (run);
if (num_glyphs == 0) if (num_glyphs == 0)
continue; continue;
buffer->ensure (buffer->len + num_glyphs); buffer->ensure (buffer->len + num_glyphs + (endWithPDF ? 1 : 0));
scratch = buffer->get_scratch_buffer (&scratch_size); scratch = buffer->get_scratch_buffer (&scratch_size);
@ -783,10 +789,27 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
buffer->len++; buffer->len++;
} }
if (endWithPDF) {
hb_glyph_info_t *info = &buffer->info[buffer->len];
info->codepoint = 0xffff;
info->cluster = range.location + range.length - 1;
/* Currently, we do all x-positioning by setting the advance, we never use x-offset. */
info->mask = 0;
info->var1.u32 = 0;
info->var2.u32 = 0;
buffer->len++;
}
} }
buffer->clear_positions (); buffer->clear_positions ();
bool bufferRtl = !HB_DIRECTION_IS_FORWARD (buffer->props.direction);
bool runRtl = (CTRunGetStatus(static_cast<CTRunRef>(CFArrayGetValueAtIndex(glyph_runs, 0))) & kCTRunStatusRightToLeft);
unsigned int count = buffer->len; unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; ++i) { for (unsigned int i = 0; i < count; ++i) {
hb_glyph_info_t *info = &buffer->info[i]; hb_glyph_info_t *info = &buffer->info[i];
@ -796,6 +819,12 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
pos->x_advance = info->mask; pos->x_advance = info->mask;
pos->x_offset = info->var1.u32; pos->x_offset = info->var1.u32;
pos->y_offset = info->var2.u32; pos->y_offset = info->var2.u32;
if (bufferRtl != runRtl && i < count / 2) {
unsigned int temp = buffer->info[count - i - 1].cluster;
buffer->info[count - i - 1].cluster = info->cluster;
info->cluster = temp;
}
} }
/* Fix up clusters so that we never return out-of-order indices; /* Fix up clusters so that we never return out-of-order indices;

View File

@ -161,7 +161,7 @@ MD5Final(struct MD5Context *ctx, md5byte digest[16])
static void static void
MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
{ {
register UWORD32 a, b, c, d; UWORD32 a, b, c, d;
a = buf[0]; a = buf[0];
b = buf[1]; b = buf[1];

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite ** This file is an amalgamation of many separate C source files from SQLite
** version 3.8.4.2. By combining all the individual C code files into this ** version 3.8.4.3. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation ** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be ** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements ** possible if the files were compiled separately. Performance improvements
@ -222,9 +222,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.8.4.2" #define SQLITE_VERSION "3.8.4.3"
#define SQLITE_VERSION_NUMBER 3008004 #define SQLITE_VERSION_NUMBER 3008004
#define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e" #define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@ -115273,7 +115273,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
for(; k<last; k++, pOp++){ for(; k<last; k++, pOp++){
if( pOp->p1!=pLevel->iTabCur ) continue; if( pOp->p1!=pLevel->iTabCur ) continue;
if( pOp->opcode==OP_Column ){ if( pOp->opcode==OP_Column ){
pOp->opcode = OP_SCopy; pOp->opcode = OP_Copy;
pOp->p1 = pOp->p2 + pTabItem->regResult; pOp->p1 = pOp->p2 + pTabItem->regResult;
pOp->p2 = pOp->p3; pOp->p2 = pOp->p3;
pOp->p3 = 0; pOp->p3 = 0;

View File

@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.8.4.2" #define SQLITE_VERSION "3.8.4.3"
#define SQLITE_VERSION_NUMBER 3008004 #define SQLITE_VERSION_NUMBER 3008004
#define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e" #define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers

View File

@ -26,7 +26,8 @@ SOURCES += \
$$PWD/xkbcommon/src/text.c \ $$PWD/xkbcommon/src/text.c \
$$PWD/xkbcommon/src/context-priv.c \ $$PWD/xkbcommon/src/context-priv.c \
$$PWD/xkbcommon/src/keymap-priv.c \ $$PWD/xkbcommon/src/keymap-priv.c \
$$PWD/xkbcommon/src/utils.c $$PWD/xkbcommon/src/utils.c \
$$PWD/xkbcommon/src/utf8.c
SOURCES += \ SOURCES += \
$$PWD/xkbcommon/src/xkbcomp/action.c \ $$PWD/xkbcommon/src/xkbcomp/action.c \
@ -54,7 +55,7 @@ SOURCES += \
SOURCES += \ SOURCES += \
$$PWD/xkbcommon/src/x11/util.c \ $$PWD/xkbcommon/src/x11/util.c \
$$PWD/xkbcommon/src/x11/x11-keymap.c \ # renamed: keymap.c -> x11-keymap.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-keymap.c $$PWD/xkbcommon/src/x11/x11-state.c # renamed: state.c -> x11-state.c
} }
TR_EXCLUDE += $$PWD/* TR_EXCLUDE += $$PWD/*

View File

@ -1,3 +1,46 @@
libxkbcommon 0.4.1
==================
- 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:
http://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 libxkbcommon 0.4.0
================== ==================

View File

@ -1,114 +0,0 @@
Overview {#mainpage}
========
xkbcommon is a keymap compiler and support library which processes a
reduced subset of keymaps as defined by the XKB specification. Primarily,
a keymap is created from a set of Rules/Model/Layout/Variant/Options names,
processed through an XKB ruleset, and compiled into a struct xkb_keymap,
which is the base type for all xkbcommon operations.
From an xkb_keymap, an xkb_state object is created which holds the current
state of all modifiers, groups, LEDs, etc, relating to that keymap. All
key events must be fed into the xkb_state object using xkb_state_update_key().
Once this is done, the xkb_state object will be properly updated, and the
keysyms to use can be obtained with xkb_state_key_get_syms().
libxkbcommon does not distribute a dataset itself, other than for testing
purposes. The most common dataset is xkeyboard-config, as used by all
current distributions for their X11 XKB data. More information on
xkeyboard-config is available here:
http://www.freedesktop.org/wiki/Software/XKeyboardConfig
API
===
While xkbcommon'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. The supported API is available
in the <xkbcommon/xkbcommon-*.h> files. Additional support is provided for
X11 (XCB) clients, in the xkbcommon-x11 library, <xkbcommon/xkbcommon-x11.h>.
The xkbcommon API and ABI are stable. We will attempt to not break ABI during
a minor release series, so applications written against 0.1.0 should be
completely compatible with 0.5.3, but not necessarily with 1.0.0. However, new
symbols may be introduced in any release. Thus, anyone packaging xkbcommon
should make sure any package depending on it depends on a release greater than
or equal to the version it was built against (or earlier, if it doesn't use
any newly-introduced symbols), but less than the next major release.
Relation to X11
===============
Relative to the XKB 1.1 specification implemented in current X servers,
xkbcommon has removed support for some parts of the specification which
introduced unnecessary complications. Many of these removals were in fact
not implemented, or half-implemented at best, as well as being totally
unused in the standard dataset.
Notable removals:
- geometry support
+ there were very few geometry definitions available, and while
xkbcommon was responsible for parsing this insanely complex format,
it never actually did anything with it
+ hopefully someone will develop a companion library which supports
keyboard geometries in a more useful format
- KcCGST (keycodes/compat/geometry/symbols/types) API
+ use RMLVO instead; KcCGST is now an implementation detail
+ including pre-defined keymap files
- XKM support
+ may come in an optional X11 support/compatibility library
- around half of the interpret actions
+ pointer device, message and redirect actions in particular
- non-virtual modifiers
+ core and virtual modifiers have been collapsed into the same
namespace, with a 'significant' flag that largely parallels the
core/virtual split
- radio groups
+ completely unused in current keymaps, never fully implemented
- overlays
+ almost completely unused in current keymaps
- key behaviors
+ used to implement radio groups and overlays, and to deal with things
like keys that physically lock; unused in current keymaps
- indicator behaviours such as LED-controls-key
+ the only supported LED behaviour is key-controls-LED; again this
was never really used in current keymaps
Notable additions:
- 32-bit keycodes
- extended number of modifiers
- extended number of groups
- multiple keysyms per level
+ this requires incompatible dataset changes, such that X11 would
not be able to parse these
Development
===========
An extremely rudimentary homepage can be found at:
http://xkbcommon.org
xkbcommon is maintained in git at github.com:
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.
Bugs are tracked in Bugzilla at:
https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon
Or in github at:
https://github.com/xkbcommon/libxkbcommon/issues
The maintainers are Daniel Stone and Ran Benita, who can be reached at:
<daniel@fooishbar.org>
<ran234@gmail.com>
Credits
=======
Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon
off the ground initially.

109
src/3rdparty/xkbcommon/README.md vendored Normal file
View File

@ -0,0 +1,109 @@
# libxkbcommon
xkbcommon is a keymap compiler and support library which processes a
reduced subset of keymaps as defined by the XKB specification. Primarily,
a keymap is created from a set of Rules/Model/Layout/Variant/Options names,
processed through an XKB ruleset, and compiled into a struct xkb_keymap,
which is the base type for all xkbcommon operations.
From an xkb_keymap, an xkb_state object is created which holds the current
state of all modifiers, groups, LEDs, etc, relating to that keymap. All
key events must be fed into the xkb_state object using xkb_state_update_key().
Once this is done, the xkb_state object will be properly updated, and the
keysyms to use can be obtained with xkb_state_key_get_syms().
libxkbcommon does not distribute a dataset itself, other than for testing
purposes. The most common dataset is xkeyboard-config, as used by all
current distributions for their X11 XKB data. More information on
xkeyboard-config is available here:
http://www.freedesktop.org/wiki/Software/XKeyboardConfig
## Quick Guide
See [Quick Guide](doc/quick-guide.md).
## API
While xkbcommon'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. The supported API is available
in the xkbcommon/xkbcommon-*.h files. Additional support is provided for
X11 (XCB) clients, in the xkbcommon-x11 library, xkbcommon/xkbcommon-x11.h.
The xkbcommon API and ABI are stable. We will attempt to not break ABI during
a minor release series, so applications written against 0.1.0 should be
completely compatible with 0.5.3, but not necessarily with 1.0.0. However, new
symbols may be introduced in any release. Thus, anyone packaging xkbcommon
should make sure any package depending on it depends on a release greater than
or equal to the version it was built against (or earlier, if it doesn't use
any newly-introduced symbols), but less than the next major release.
## Relation to X11
Relative to the XKB 1.1 specification implemented in current X servers,
xkbcommon has removed support for some parts of the specification which
introduced unnecessary complications. Many of these removals were in fact
not implemented, or half-implemented at best, as well as being totally
unused in the standard dataset.
Notable removals:
- geometry support
+ there were very few geometry definitions available, and while
xkbcommon was responsible for parsing this insanely complex format,
it never actually did anything with it
+ hopefully someone will develop a companion library which supports
keyboard geometries in a more useful format
- KcCGST (keycodes/compat/geometry/symbols/types) API
+ use RMLVO instead; KcCGST is now an implementation detail
+ including pre-defined keymap files
- XKM support
+ may come in an optional X11 support/compatibility library
- around half of the interpret actions
+ pointer device, message and redirect actions in particular
- non-virtual modifiers
+ core and virtual modifiers have been collapsed into the same
namespace, with a 'significant' flag that largely parallels the
core/virtual split
- radio groups
+ completely unused in current keymaps, never fully implemented
- overlays
+ almost completely unused in current keymaps
- key behaviors
+ used to implement radio groups and overlays, and to deal with things
like keys that physically lock; unused in current keymaps
- indicator behaviours such as LED-controls-key
+ the only supported LED behaviour is key-controls-LED; again this
was never really used in current keymaps
Notable additions:
- 32-bit keycodes
- extended number of modifiers
- extended number of groups
- multiple keysyms per level
+ this requires incompatible dataset changes, such that X11 would
not be able to parse these
## Development
An extremely rudimentary homepage can be found at
http://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>
Bugs are also welcome, and may be reported 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.

View File

@ -112,60 +112,79 @@ xkb_context_get_buffer(struct xkb_context *ctx, size_t size)
#define DEFAULT_XKB_OPTIONS NULL #define DEFAULT_XKB_OPTIONS NULL
#endif #endif
const char * static const char *
xkb_context_get_default_rules(struct xkb_context *ctx) xkb_context_get_default_rules(struct xkb_context *ctx)
{ {
const char *env = NULL; const char *env = NULL;
if (ctx->use_environment_names) if (ctx->use_environment_names)
env = getenv("XKB_DEFAULT_RULES"); env = secure_getenv("XKB_DEFAULT_RULES");
return env ? env : DEFAULT_XKB_RULES; return env ? env : DEFAULT_XKB_RULES;
} }
const char * static const char *
xkb_context_get_default_model(struct xkb_context *ctx) xkb_context_get_default_model(struct xkb_context *ctx)
{ {
const char *env = NULL; const char *env = NULL;
if (ctx->use_environment_names) if (ctx->use_environment_names)
env = getenv("XKB_DEFAULT_MODEL"); env = secure_getenv("XKB_DEFAULT_MODEL");
return env ? env : DEFAULT_XKB_MODEL; return env ? env : DEFAULT_XKB_MODEL;
} }
const char * static const char *
xkb_context_get_default_layout(struct xkb_context *ctx) xkb_context_get_default_layout(struct xkb_context *ctx)
{ {
const char *env = NULL; const char *env = NULL;
if (ctx->use_environment_names) if (ctx->use_environment_names)
env = getenv("XKB_DEFAULT_LAYOUT"); env = secure_getenv("XKB_DEFAULT_LAYOUT");
return env ? env : DEFAULT_XKB_LAYOUT; return env ? env : DEFAULT_XKB_LAYOUT;
} }
const char * static const char *
xkb_context_get_default_variant(struct xkb_context *ctx) xkb_context_get_default_variant(struct xkb_context *ctx)
{ {
const char *env = NULL; const char *env = NULL;
const char *layout = getenv("XKB_DEFAULT_VARIANT"); const char *layout = secure_getenv("XKB_DEFAULT_LAYOUT");
/* We don't want to inherit the variant if they haven't also set a /* We don't want to inherit the variant if they haven't also set a
* layout, since they're so closely paired. */ * layout, since they're so closely paired. */
if (layout && ctx->use_environment_names) if (layout && ctx->use_environment_names)
env = getenv("XKB_DEFAULT_VARIANT"); env = secure_getenv("XKB_DEFAULT_VARIANT");
return env ? env : DEFAULT_XKB_VARIANT; return env ? env : DEFAULT_XKB_VARIANT;
} }
const char * static const char *
xkb_context_get_default_options(struct xkb_context *ctx) xkb_context_get_default_options(struct xkb_context *ctx)
{ {
const char *env = NULL; const char *env = NULL;
if (ctx->use_environment_names) if (ctx->use_environment_names)
env = getenv("XKB_DEFAULT_OPTIONS"); env = secure_getenv("XKB_DEFAULT_OPTIONS");
return env ? env : DEFAULT_XKB_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);
}

View File

@ -82,7 +82,7 @@ xkb_context_include_path_append_default(struct xkb_context *ctx)
ret |= xkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_ROOT); ret |= xkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_ROOT);
home = getenv("HOME"); home = secure_getenv("HOME");
if (!home) if (!home)
return ret; return ret;
err = asprintf(&user_path, "%s/.xkb", home); err = asprintf(&user_path, "%s/.xkb", home);
@ -252,11 +252,11 @@ xkb_context_new(enum xkb_context_flags flags)
ctx->log_verbosity = 0; ctx->log_verbosity = 0;
/* Environment overwrites defaults. */ /* Environment overwrites defaults. */
env = getenv("XKB_LOG_LEVEL"); env = secure_getenv("XKB_LOG_LEVEL");
if (env) if (env)
xkb_context_set_log_level(ctx, log_level(env)); xkb_context_set_log_level(ctx, log_level(env));
env = getenv("XKB_LOG_VERBOSITY"); env = secure_getenv("XKB_LOG_VERBOSITY");
if (env) if (env)
xkb_context_set_log_verbosity(ctx, log_verbosity(env)); xkb_context_set_log_verbosity(ctx, log_verbosity(env));

View File

@ -91,20 +91,9 @@ ATTR_PRINTF(4, 5) void
xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity, xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity,
const char *fmt, ...); const char *fmt, ...);
const char * void
xkb_context_get_default_rules(struct xkb_context *ctx); xkb_context_sanitize_rule_names(struct xkb_context *ctx,
struct xkb_rule_names *rmlvo);
const char *
xkb_context_get_default_model(struct xkb_context *ctx);
const char *
xkb_context_get_default_layout(struct xkb_context *ctx);
const char *
xkb_context_get_default_variant(struct xkb_context *ctx);
const char *
xkb_context_get_default_options(struct xkb_context *ctx);
/* /*
* The format is not part of the argument list in order to avoid the * The format is not part of the argument list in order to avoid the

View File

@ -23,93 +23,15 @@
#ifndef CCAN_DARRAY_H #ifndef CCAN_DARRAY_H
#define CCAN_DARRAY_H #define CCAN_DARRAY_H
/* Originally taken from: http://ccodearchive.net/info/darray.html
* But modified for libxkbcommon. */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include <limits.h>
/* #define darray(type) struct { type *item; unsigned size; unsigned alloc; }
* SYNOPSIS
*
* Life cycle of a darray (dynamically-allocated array):
*
* darray(int) a = darray_new();
* darray_free(a);
*
* struct {darray(int) a;} foo;
* darray_init(foo.a);
* darray_free(foo.a);
*
* Typedefs for darrays of common types:
*
* darray_char, darray_schar, darray_uchar
* darray_short, darray_int, darray_long
* darray_ushort, darray_uint, darray_ulong
*
* Access:
*
* T darray_item(darray(T) arr, size_t index);
* size_t darray_size(darray(T) arr);
* size_t darray_alloc(darray(T) arr);
* bool darray_empty(darray(T) arr);
*
* // Access raw memory, starting from the item in offset.
* // Not safe, be careful, etc.
* T* darray_mem(darray(T) arr, size_t offset);
*
* Insertion (single item):
*
* void darray_append(darray(T) arr, T item);
* void darray_prepend(darray(T) arr, T item);
* void darray_push(darray(T) arr, T item); // same as darray_append
*
* Insertion (multiple items):
*
* void darray_append_items(darray(T) arr, T *items, size_t count);
* void darray_prepend_items(darray(T) arr, T *items, size_t count);
*
* void darray_appends(darray(T) arr, [T item, [...]]);
* void darray_prepends(darray(T) arr, [T item, [...]]);
*
* Removal:
*
* T darray_pop(darray(T) arr | darray_size(arr) != 0);
* T* darray_pop_check(darray(T*) arr);
*
* Replacement:
*
* void darray_from_items(darray(T) arr, T *items, size_t count);
* void darray_from_c(darray(T) arr, T c_array[N]);
*
* String buffer:
*
* void darray_append_string(darray(char) arr, const char *str);
* void darray_append_lit(darray(char) arr, char stringLiteral[N+1]);
*
* void darray_prepend_string(darray(char) arr, const char *str);
* void darray_prepend_lit(darray(char) arr, char stringLiteral[N+1]);
*
* void darray_from_string(darray(T) arr, const char *str);
* void darray_from_lit(darray(char) arr, char stringLiteral[N+1]);
*
* Size management:
*
* void darray_resize(darray(T) arr, size_t newSize);
* void darray_resize0(darray(T) arr, size_t newSize);
*
* void darray_realloc(darray(T) arr, size_t newAlloc);
* void darray_growalloc(darray(T) arr, size_t newAlloc);
*
* Traversal:
*
* darray_foreach(T *&i, darray(T) arr) {...}
* darray_foreach_reverse(T *&i, darray(T) arr) {...}
*
* Except for darray_foreach and darray_foreach_reverse,
* all macros evaluate their non-darray arguments only once.
*/
/*** Life cycle ***/
#define darray(type) struct { type *item; size_t size; size_t alloc; }
#define darray_new() { 0, 0, 0 } #define darray_new() { 0, 0, 0 }
@ -118,7 +40,8 @@
} while (0) } while (0)
#define darray_free(arr) do { \ #define darray_free(arr) do { \
free((arr).item); darray_init(arr); \ free((arr).item); \
darray_init(arr); \
} while (0) } while (0)
/* /*
@ -154,11 +77,8 @@ typedef darray (unsigned long) darray_ulong;
#define darray_item(arr, i) ((arr).item[i]) #define darray_item(arr, i) ((arr).item[i])
#define darray_size(arr) ((arr).size) #define darray_size(arr) ((arr).size)
#define darray_alloc(arr) ((arr).alloc)
#define darray_empty(arr) ((arr).size == 0) #define darray_empty(arr) ((arr).size == 0)
#define darray_mem(arr, offset) ((arr).item + (offset)) #define darray_mem(arr, offset) ((arr).item + (offset))
#define darray_same(arr1, arr2) ((arr1).item == (arr2).item)
/*** Insertion (single item) ***/ /*** Insertion (single item) ***/
@ -167,74 +87,20 @@ typedef darray (unsigned long) darray_ulong;
(arr).item[(arr).size - 1] = (__VA_ARGS__); \ (arr).item[(arr).size - 1] = (__VA_ARGS__); \
} while (0) } while (0)
#define darray_prepend(arr, ...) do { \
darray_resize(arr, (arr).size + 1); \
memmove((arr).item + 1, (arr).item, \
((arr).size - 1) * sizeof(*(arr).item)); \
(arr).item[0] = (__VA_ARGS__); \
} while (0)
#define darray_push(arr, ...) darray_append(arr, __VA_ARGS__)
/*** Insertion (multiple items) ***/ /*** Insertion (multiple items) ***/
#define darray_append_items(arr, items, count) do { \ #define darray_append_items(arr, items, count) do { \
size_t __count = (count), __oldSize = (arr).size; \ unsigned __count = (count), __oldSize = (arr).size; \
darray_resize(arr, __oldSize + __count); \ darray_resize(arr, __oldSize + __count); \
memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \ memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
} while (0) } while (0)
#define darray_prepend_items(arr, items, count) do { \
size_t __count = (count), __oldSize = (arr).size; \
darray_resize(arr, __count + __oldSize); \
memmove((arr).item + __count, (arr).item, \
__oldSize * sizeof(*(arr).item)); \
memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
} while (0)
#define darray_append_items_nullterminate(arr, items, count) do { \
size_t __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_prepend_items_nullterminate(arr, items, count) do { \
size_t __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)
#define darray_appends_t(arr, type, ...) do { \
type __src[] = { __VA_ARGS__ }; \
darray_append_items(arr, __src, sizeof(__src) / sizeof(*__src)); \
} while (0)
#define darray_prepends_t(arr, type, ...) do { \
type __src[] = { __VA_ARGS__ }; \
darray_prepend_items(arr, __src, sizeof(__src) / sizeof(*__src)); \
} while (0)
/*** Removal ***/
/* Warning: Do not call darray_pop on an empty darray. */
#define darray_pop(arr) ((arr).item[--(arr).size])
#define darray_pop_check(arr) ((arr).size ? darray_pop(arr) : NULL)
/*** Replacement ***/
#define darray_from_items(arr, items, count) do { \ #define darray_from_items(arr, items, count) do { \
size_t __count = (count); \ unsigned __count = (count); \
darray_resize(arr, __count); \ darray_resize(arr, __count); \
memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
} while (0) } while (0)
#define darray_from_c(arr, c_array) \
darray_from_items(arr, c_array, sizeof(c_array) / sizeof(*(c_array)))
#define darray_copy(arr_to, arr_from) \ #define darray_copy(arr_to, arr_from) \
darray_from_items((arr_to), (arr_from).item, (arr_from).size) darray_from_items((arr_to), (arr_from).item, (arr_from).size)
@ -251,24 +117,20 @@ typedef darray (unsigned long) darray_ulong;
(arr).size--; \ (arr).size--; \
} while (0) } while (0)
#define darray_prepend_string(arr, str) do { \ #define darray_appends_nullterminate(arr, items, count) do { \
const char *__str = (str); \ unsigned __count = (count), __oldSize = (arr).size; \
darray_prepend_items_nullterminate(arr, __str, strlen(__str)); \ darray_resize(arr, __oldSize + __count + 1); \
memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
(arr).item[--(arr).size] = 0; \
} while (0) } while (0)
#define darray_prepend_lit(arr, stringLiteral) \ #define darray_prepends_nullterminate(arr, items, count) do { \
darray_prepend_items_nullterminate(arr, stringLiteral, \ unsigned __count = (count), __oldSize = (arr).size; \
sizeof(stringLiteral) - 1) darray_resize(arr, __count + __oldSize + 1); \
memmove((arr).item + __count, (arr).item, \
#define darray_from_string(arr, str) do { \ __oldSize * sizeof(*(arr).item)); \
const char *__str = (str); \ memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
darray_from_items(arr, __str, strlen(__str) + 1); \ (arr).item[--(arr).size] = 0; \
(arr).size--; \
} while (0)
#define darray_from_lit(arr, stringLiteral) do { \
darray_from_items(arr, stringLiteral, sizeof(stringLiteral)); \
(arr).size--; \
} while (0) } while (0)
/*** Size management ***/ /*** Size management ***/
@ -277,7 +139,7 @@ typedef darray (unsigned long) darray_ulong;
darray_growalloc(arr, (arr).size = (newSize)) darray_growalloc(arr, (arr).size = (newSize))
#define darray_resize0(arr, newSize) do { \ #define darray_resize0(arr, newSize) do { \
size_t __oldSize = (arr).size, __newSize = (newSize); \ unsigned __oldSize = (arr).size, __newSize = (newSize); \
(arr).size = __newSize; \ (arr).size = __newSize; \
if (__newSize > __oldSize) { \ if (__newSize > __oldSize) { \
darray_growalloc(arr, __newSize); \ darray_growalloc(arr, __newSize); \
@ -292,14 +154,16 @@ typedef darray (unsigned long) darray_ulong;
} while (0) } while (0)
#define darray_growalloc(arr, need) do { \ #define darray_growalloc(arr, need) do { \
size_t __need = (need); \ unsigned __need = (need); \
if (__need > (arr).alloc) \ if (__need > (arr).alloc) \
darray_realloc(arr, darray_next_alloc((arr).alloc, __need)); \ darray_realloc(arr, darray_next_alloc((arr).alloc, __need, \
sizeof(*(arr).item))); \
} while (0) } while (0)
static inline size_t static inline unsigned
darray_next_alloc(size_t alloc, size_t need) darray_next_alloc(unsigned alloc, unsigned need, unsigned itemSize)
{ {
assert(need < UINT_MAX / itemSize / 2); /* Overflow. */
if (alloc == 0) if (alloc == 0)
alloc = 4; alloc = 4;
while (alloc < need) while (alloc < need)
@ -309,11 +173,6 @@ darray_next_alloc(size_t alloc, size_t need)
/*** Traversal ***/ /*** Traversal ***/
/*
* darray_foreach(T *&i, darray(T) arr) {...}
*
* Traverse a darray. `i` must be declared in advance as a pointer to an item.
*/
#define darray_foreach(i, arr) \ #define darray_foreach(i, arr) \
for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++) for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++)
@ -331,58 +190,7 @@ darray_next_alloc(size_t alloc, size_t need)
(idx) < (arr).size; \ (idx) < (arr).size; \
(idx)++, (val)++) (idx)++, (val)++)
/*
* darray_foreach_reverse(T *&i, darray(T) arr) {...}
*
* Like darray_foreach, but traverse in reverse order.
*/
#define darray_foreach_reverse(i, arr) \ #define darray_foreach_reverse(i, arr) \
for ((i) = &(arr).item[(arr).size]; (i)-- > &(arr).item[0]; ) for ((i) = &(arr).item[(arr).size]; (i)-- > &(arr).item[0]; )
#endif /* CCAN_DARRAY_H */ #endif /* CCAN_DARRAY_H */
/*
*
* darray_growalloc(arr, newAlloc) sees if the darray can currently hold newAlloc items;
* if not, it increases the alloc to satisfy this requirement, allocating slack
* space to avoid having to reallocate for every size increment.
*
* darray_from_string(arr, str) copies a string to an darray_char.
*
* darray_push(arr, item) pushes an item to the end of the darray.
* darray_pop(arr) pops it back out. Be sure there is at least one item in the darray before calling.
* darray_pop_check(arr) does the same as darray_pop, but returns NULL if there are no more items left in the darray.
*
* darray_make_room(arr, room) ensures there's 'room' elements of space after the end of the darray, and it returns a pointer to this space.
* Currently requires HAVE_STATEMENT_EXPR, but I plan to remove this dependency by creating an inline function.
*
* The following require HAVE_TYPEOF==1 :
*
* darray_appends(arr, item0, item1...) appends a collection of comma-delimited items to the darray.
* darray_prepends(arr, item0, item1...) prepends a collection of comma-delimited items to the darray.\
*
*
* Examples:
*
* darray(int) arr;
* int *i;
*
* darray_appends(arr, 0,1,2,3,4);
* darray_appends(arr, -5,-4,-3,-2,-1);
* darray_foreach(i, arr)
* printf("%d ", *i);
* printf("\n");
*
* darray_free(arr);
*
*
* typedef struct {int n,d;} Fraction;
* darray(Fraction) fractions;
* Fraction *i;
*
* darray_appends(fractions, {3,4}, {3,5}, {2,1});
* darray_foreach(i, fractions)
* printf("%d/%d\n", i->n, i->d);
*
* darray_free(fractions);
*/

View File

@ -30,12 +30,7 @@ static void
update_builtin_keymap_fields(struct xkb_keymap *keymap) update_builtin_keymap_fields(struct xkb_keymap *keymap)
{ {
struct xkb_context *ctx = keymap->ctx; struct xkb_context *ctx = keymap->ctx;
const struct xkb_mod builtin_mods[] = {
/*
* Add predefined (AKA real, core, X11) modifiers.
* The order is important!
*/
darray_appends_t(keymap->mods, struct xkb_mod,
{ .name = xkb_atom_intern_literal(ctx, "Shift"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Shift"), .type = MOD_REAL },
{ .name = xkb_atom_intern_literal(ctx, "Lock"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Lock"), .type = MOD_REAL },
{ .name = xkb_atom_intern_literal(ctx, "Control"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Control"), .type = MOD_REAL },
@ -43,7 +38,14 @@ update_builtin_keymap_fields(struct xkb_keymap *keymap)
{ .name = xkb_atom_intern_literal(ctx, "Mod2"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Mod2"), .type = MOD_REAL },
{ .name = xkb_atom_intern_literal(ctx, "Mod3"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Mod3"), .type = MOD_REAL },
{ .name = xkb_atom_intern_literal(ctx, "Mod4"), .type = MOD_REAL }, { .name = xkb_atom_intern_literal(ctx, "Mod4"), .type = MOD_REAL },
{ .name = xkb_atom_intern_literal(ctx, "Mod5"), .type = MOD_REAL }); { .name = xkb_atom_intern_literal(ctx, "Mod5"), .type = MOD_REAL },
};
/*
* Add predefined (AKA real, core, X11) modifiers.
* The order is important!
*/
darray_append_items(keymap->mods, builtin_mods, ARRAY_SIZE(builtin_mods));
} }
struct xkb_keymap * struct xkb_keymap *

View File

@ -146,7 +146,7 @@ enum xkb_action_flags {
ACTION_ABSOLUTE_SWITCH = (1 << 5), ACTION_ABSOLUTE_SWITCH = (1 << 5),
ACTION_ABSOLUTE_X = (1 << 6), ACTION_ABSOLUTE_X = (1 << 6),
ACTION_ABSOLUTE_Y = (1 << 7), ACTION_ABSOLUTE_Y = (1 << 7),
ACTION_NO_ACCEL = (1 << 8), ACTION_ACCEL = (1 << 8),
ACTION_SAME_SCREEN = (1 << 9), ACTION_SAME_SCREEN = (1 << 9),
}; };
@ -223,7 +223,7 @@ struct xkb_pointer_button_action {
enum xkb_action_type type; enum xkb_action_type type;
enum xkb_action_flags flags; enum xkb_action_flags flags;
uint8_t count; uint8_t count;
int8_t button; uint8_t button;
}; };
struct xkb_private_action { struct xkb_private_action {
@ -262,10 +262,10 @@ struct xkb_key_type {
struct xkb_sym_interpret { struct xkb_sym_interpret {
xkb_keysym_t sym; xkb_keysym_t sym;
enum xkb_match_operation match; enum xkb_match_operation match;
bool level_one_only;
xkb_mod_mask_t mods; xkb_mod_mask_t mods;
xkb_mod_index_t virtual_mod; xkb_mod_index_t virtual_mod;
union xkb_action action; union xkb_action action;
bool level_one_only;
bool repeat; bool repeat;
}; };

View File

@ -37,6 +37,7 @@
#include "xkbcommon/xkbcommon.h" #include "xkbcommon/xkbcommon.h"
#include "utils.h" #include "utils.h"
#include "utf8.h"
/* We don't use the uint32_t types here, to save some space. */ /* We don't use the uint32_t types here, to save some space. */
struct codepair { struct codepair {
@ -838,15 +839,15 @@ static const struct codepair keysymtab[] = {
static uint32_t static uint32_t
bin_search(const struct codepair *table, size_t length, xkb_keysym_t keysym) bin_search(const struct codepair *table, size_t length, xkb_keysym_t keysym)
{ {
int first = 0; size_t first = 0;
int last = length; size_t last = length;
if (keysym < table[0].keysym || keysym > table[length].keysym) if (keysym < table[0].keysym || keysym > table[length].keysym)
return 0; return 0;
/* binary search in table */ /* binary search in table */
while (last >= first) { while (last >= first) {
int mid = (first + last) / 2; size_t mid = (first + last) / 2;
if (table[mid].keysym < keysym) if (table[mid].keysym < keysym)
first = mid + 1; first = mid + 1;
else if (table[mid].keysym > keysym) else if (table[mid].keysym > keysym)
@ -912,47 +913,6 @@ xkb_keysym_to_utf32(xkb_keysym_t keysym)
* Author: Rob Bradford <rob@linux.intel.com> * Author: Rob Bradford <rob@linux.intel.com>
*/ */
static 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 <= 0x1fffff) {
length = 4;
head = 0xf0;
}
else if (unichar <= 0x3ffffff) {
length = 5;
head = 0xf8;
}
else {
length = 6;
head = 0xfc;
}
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;
}
XKB_EXPORT int XKB_EXPORT int
xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size) xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size)
{ {

View File

@ -64,7 +64,11 @@ compare_by_keysym(const void *a, const void *b)
{ {
const xkb_keysym_t *key = a; const xkb_keysym_t *key = a;
const struct name_keysym *entry = b; const struct name_keysym *entry = b;
return *key - (int32_t) entry->keysym; if (*key < entry->keysym)
return -1;
if (*key > entry->keysym)
return 1;
return 0;
} }
static int static int

View File

@ -49,13 +49,25 @@ struct scanner {
size_t len; size_t len;
char buf[1024]; char buf[1024];
size_t buf_pos; size_t buf_pos;
int line, column; unsigned line, column;
/* The line/column of the start of the current token. */ /* The line/column of the start of the current token. */
int token_line, token_column; unsigned token_line, token_column;
const char *file_name; const char *file_name;
struct xkb_context *ctx; struct xkb_context *ctx;
}; };
#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 static inline void
scanner_init(struct scanner *s, struct xkb_context *ctx, scanner_init(struct scanner *s, struct xkb_context *ctx,
const char *string, size_t len, const char *file_name) const char *string, size_t len, const char *file_name)
@ -72,7 +84,9 @@ scanner_init(struct scanner *s, struct xkb_context *ctx,
static inline char static inline char
peek(struct scanner *s) peek(struct scanner *s)
{ {
return s->pos < s->len ? s->s[s->pos] : '\0'; if (unlikely(s->pos >= s->len))
return '\0';
return s->s[s->pos];
} }
static inline bool static inline bool
@ -90,9 +104,9 @@ eol(struct scanner *s)
static inline char static inline char
next(struct scanner *s) next(struct scanner *s)
{ {
if (eof(s)) if (unlikely(eof(s)))
return '\0'; return '\0';
if (eol(s)) { if (unlikely(eol(s))) {
s->line++; s->line++;
s->column = 1; s->column = 1;
} }
@ -105,7 +119,7 @@ next(struct scanner *s)
static inline bool static inline bool
chr(struct scanner *s, char ch) chr(struct scanner *s, char ch)
{ {
if (peek(s) != ch) if (likely(peek(s) != ch))
return false; return false;
s->pos++; s->column++; s->pos++; s->column++;
return true; return true;

View File

@ -61,6 +61,7 @@
#include "keymap.h" #include "keymap.h"
#include "keysym.h" #include "keysym.h"
#include "utf8.h"
struct xkb_filter { struct xkb_filter {
union xkb_action action; union xkb_action action;
@ -108,7 +109,7 @@ struct xkb_state {
* < Left Shift down, Right Shift down, Left Shift Up > * < Left Shift down, Right Shift down, Left Shift Up >
* the modifier should still be set. This keeps the count. * the modifier should still be set. This keeps the count.
*/ */
int16_t mod_key_count[sizeof(xkb_mod_mask_t) * 8]; int16_t mod_key_count[XKB_MAX_MODS];
int refcnt; int refcnt;
darray(struct xkb_filter) filters; darray(struct xkb_filter) filters;
@ -121,9 +122,8 @@ get_entry_for_key_state(struct xkb_state *state, const struct xkb_key *key,
{ {
const struct xkb_key_type *type = key->groups[group].type; const struct xkb_key_type *type = key->groups[group].type;
xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask; xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask;
unsigned int i;
for (i = 0; i < type->num_entries; i++) { for (unsigned i = 0; i < type->num_entries; i++) {
/* /*
* If the virtual modifiers are not bound to anything, we're * If the virtual modifiers are not bound to anything, we're
* supposed to skip the entry (xserver does this with cached * supposed to skip the entry (xserver does this with cached
@ -170,7 +170,7 @@ wrap_group_into_range(int32_t group,
if (num_groups == 0) if (num_groups == 0)
return XKB_LAYOUT_INVALID; return XKB_LAYOUT_INVALID;
if (group < num_groups) if (group >= 0 && (xkb_layout_index_t) group < num_groups)
return group; return group;
switch (out_of_range_group_action) { switch (out_of_range_group_action) {
@ -623,30 +623,42 @@ xkb_state_led_update_all(struct xkb_state *state)
xkb_mod_mask_t mod_mask = 0; xkb_mod_mask_t mod_mask = 0;
xkb_layout_mask_t group_mask = 0; xkb_layout_mask_t group_mask = 0;
if (led->which_mods & XKB_STATE_MODS_EFFECTIVE) if (led->which_mods != 0 && led->mods.mask != 0) {
mod_mask |= state->components.mods; if (led->which_mods & XKB_STATE_MODS_EFFECTIVE)
if (led->which_mods & XKB_STATE_MODS_DEPRESSED) mod_mask |= state->components.mods;
mod_mask |= state->components.base_mods; if (led->which_mods & XKB_STATE_MODS_DEPRESSED)
if (led->which_mods & XKB_STATE_MODS_LATCHED) mod_mask |= state->components.base_mods;
mod_mask |= state->components.latched_mods; if (led->which_mods & XKB_STATE_MODS_LATCHED)
if (led->which_mods & XKB_STATE_MODS_LOCKED) mod_mask |= state->components.latched_mods;
mod_mask |= state->components.locked_mods; if (led->which_mods & XKB_STATE_MODS_LOCKED)
if (led->mods.mask & mod_mask) mod_mask |= state->components.locked_mods;
state->components.leds |= (1 << idx);
if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE) if (led->mods.mask & mod_mask) {
group_mask |= (1 << state->components.group); state->components.leds |= (1u << idx);
if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED) continue;
group_mask |= (1 << state->components.base_group); }
if (led->which_groups & XKB_STATE_LAYOUT_LATCHED) }
group_mask |= (1 << state->components.latched_group);
if (led->which_groups & XKB_STATE_LAYOUT_LOCKED)
group_mask |= (1 << state->components.locked_group);
if (led->groups & group_mask)
state->components.leds |= (1 << idx);
if (led->ctrls & state->keymap->enabled_ctrls) if (led->which_groups != 0 && led->groups != 0) {
state->components.leds |= (1 << idx); if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE)
group_mask |= (1u << state->components.group);
if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED)
group_mask |= (1u << state->components.base_group);
if (led->which_groups & XKB_STATE_LAYOUT_LATCHED)
group_mask |= (1u << state->components.latched_group);
if (led->which_groups & XKB_STATE_LAYOUT_LOCKED)
group_mask |= (1u << state->components.locked_group);
if (led->groups & group_mask) {
state->components.leds |= (1u << idx);
continue;
}
}
if (led->ctrls & state->keymap->enabled_ctrls) {
state->components.leds |= (1u << idx);
continue;
}
} }
} }
@ -657,23 +669,27 @@ xkb_state_led_update_all(struct xkb_state *state)
static void static void
xkb_state_update_derived(struct xkb_state *state) xkb_state_update_derived(struct xkb_state *state)
{ {
xkb_layout_index_t wrapped;
state->components.mods = (state->components.base_mods | state->components.mods = (state->components.base_mods |
state->components.latched_mods | state->components.latched_mods |
state->components.locked_mods); state->components.locked_mods);
/* TODO: Use groups_wrap control instead of always RANGE_WRAP. */ /* TODO: Use groups_wrap control instead of always RANGE_WRAP. */
wrapped = wrap_group_into_range(state->components.locked_group,
state->keymap->num_groups,
RANGE_WRAP, 0);
state->components.locked_group = state->components.locked_group =
wrap_group_into_range(state->components.locked_group, (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped);
state->keymap->num_groups,
RANGE_WRAP, 0);
wrapped = wrap_group_into_range(state->components.base_group +
state->components.latched_group +
state->components.locked_group,
state->keymap->num_groups,
RANGE_WRAP, 0);
state->components.group = state->components.group =
wrap_group_into_range(state->components.base_group + (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped);
state->components.latched_group +
state->components.locked_group,
state->keymap->num_groups,
RANGE_WRAP, 0);
xkb_state_led_update_all(state); xkb_state_led_update_all(state);
} }
@ -781,7 +797,7 @@ xkb_state_update_mask(struct xkb_state *state,
num_mods = xkb_keymap_num_mods(state->keymap); num_mods = xkb_keymap_num_mods(state->keymap);
for (idx = 0; idx < num_mods; idx++) { for (idx = 0; idx < num_mods; idx++) {
xkb_mod_mask_t mod = (1 << idx); xkb_mod_mask_t mod = (1u << idx);
if (base_mods & mod) if (base_mods & mod)
state->components.base_mods |= mod; state->components.base_mods |= mod;
if (latched_mods & mod) if (latched_mods & mod)
@ -826,6 +842,53 @@ err:
return 0; return 0;
} }
/*
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
*/
static bool
should_do_caps_transformation(struct xkb_state *state, xkb_keycode_t kc)
{
xkb_mod_index_t caps =
xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS);
return
xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 &&
xkb_state_mod_index_is_consumed(state, kc, caps) == 0;
}
/*
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
*/
static bool
should_do_ctrl_transformation(struct xkb_state *state, xkb_keycode_t kc)
{
xkb_mod_index_t ctrl =
xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CTRL);
return
xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_EFFECTIVE) > 0 &&
xkb_state_mod_index_is_consumed(state, kc, ctrl) == 0;
}
/* Verbatim from libX11:src/xkb/XKBBind.c */
static char
XkbToControl(char ch)
{
char c = ch;
if ((c >= '@' && c < '\177') || c == ' ')
c &= 0x1F;
else if (c == '2')
c = '\000';
else if (c >= '3' && c <= '7')
c -= ('3' - '\033');
else if (c == '8')
c = '\177';
else if (c == '/')
c = '_' & 0x1F;
return c;
}
/** /**
* Provides either exactly one symbol, or XKB_KEY_NoSymbol. * Provides either exactly one symbol, or XKB_KEY_NoSymbol.
*/ */
@ -835,7 +898,6 @@ xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc)
const xkb_keysym_t *syms; const xkb_keysym_t *syms;
xkb_keysym_t sym; xkb_keysym_t sym;
int num_syms; int num_syms;
xkb_mod_index_t caps;
num_syms = xkb_state_key_get_syms(state, kc, &syms); num_syms = xkb_state_key_get_syms(state, kc, &syms);
if (num_syms != 1) if (num_syms != 1)
@ -843,18 +905,135 @@ xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc)
sym = syms[0]; sym = syms[0];
/* if (should_do_caps_transformation(state, kc))
* Perform capitalization transformation, see:
* http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
*/
caps = xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS);
if (xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 &&
xkb_state_mod_index_is_consumed(state, kc, caps) == 0)
sym = xkb_keysym_to_upper(sym); sym = xkb_keysym_to_upper(sym);
return sym; return sym;
} }
/*
* The caps and ctrl transformations require some special handling,
* so we cannot simply use xkb_state_get_one_sym() for them.
* In particular, if Control is set, we must try very hard to find
* some layout in which the keysym is ASCII and thus can be (maybe)
* converted to a control character. libX11 allows to disable this
* behavior with the XkbLC_ControlFallback (see XkbSetXlibControls(3)),
* but it is enabled by default, yippee.
*/
static xkb_keysym_t
get_one_sym_for_string(struct xkb_state *state, xkb_keycode_t kc)
{
xkb_level_index_t level;
xkb_layout_index_t layout, num_layouts;
const xkb_keysym_t *syms;
int nsyms;
xkb_keysym_t sym;
layout = xkb_state_key_get_layout(state, kc);
num_layouts = xkb_keymap_num_layouts_for_key(state->keymap, kc);
level = xkb_state_key_get_level(state, kc, layout);
if (layout == XKB_LAYOUT_INVALID || num_layouts == 0 ||
level == XKB_LEVEL_INVALID)
return XKB_KEY_NoSymbol;
nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc,
layout, level, &syms);
if (nsyms != 1)
return XKB_KEY_NoSymbol;
sym = syms[0];
if (should_do_ctrl_transformation(state, kc) && sym > 127u) {
for (xkb_layout_index_t i = 0; i < num_layouts; i++) {
level = xkb_state_key_get_level(state, kc, i);
if (level == XKB_LEVEL_INVALID)
continue;
nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc,
i, level, &syms);
if (nsyms == 1 && syms[0] <= 127u) {
sym = syms[0];
break;
}
}
}
if (should_do_caps_transformation(state, kc)) {
sym = xkb_keysym_to_upper(sym);
}
return sym;
}
XKB_EXPORT int
xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t kc,
char *buffer, size_t size)
{
xkb_keysym_t sym;
const xkb_keysym_t *syms;
int nsyms;
int offset;
char tmp[7];
sym = get_one_sym_for_string(state, kc);
if (sym != XKB_KEY_NoSymbol) {
nsyms = 1; syms = &sym;
}
else {
nsyms = xkb_state_key_get_syms(state, kc, &syms);
}
/* Make sure not to truncate in the middle of a UTF-8 sequence. */
offset = 0;
for (int i = 0; i < nsyms; i++) {
int ret = xkb_keysym_to_utf8(syms[i], tmp, sizeof(tmp));
if (ret <= 0)
goto err_bad;
ret--;
if ((size_t) (offset + ret) <= size)
memcpy(buffer + offset, tmp, ret);
offset += ret;
}
if ((size_t) offset >= size)
goto err_trunc;
buffer[offset] = '\0';
if (!is_valid_utf8(buffer, offset))
goto err_bad;
if (offset == 1 && (unsigned int) buffer[0] <= 127u &&
should_do_ctrl_transformation(state, kc))
buffer[0] = XkbToControl(buffer[0]);
return offset;
err_trunc:
if (size > 0)
buffer[size - 1] = '\0';
return offset;
err_bad:
if (size > 0)
buffer[0] = '\0';
return 0;
}
XKB_EXPORT uint32_t
xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t kc)
{
xkb_keysym_t sym;
uint32_t cp;
sym = get_one_sym_for_string(state, kc);
cp = xkb_keysym_to_utf32(sym);
if (cp <= 127u && should_do_ctrl_transformation(state, kc))
cp = (uint32_t) XkbToControl((char) cp);
return cp;
}
/** /**
* Serialises the requested modifier state into an xkb_mod_mask_t, with all * Serialises the requested modifier state into an xkb_mod_mask_t, with all
* the same disclaimers as in xkb_state_update_mask. * the same disclaimers as in xkb_state_update_mask.
@ -913,7 +1092,7 @@ xkb_state_mod_index_is_active(struct xkb_state *state,
if (idx >= xkb_keymap_num_mods(state->keymap)) if (idx >= xkb_keymap_num_mods(state->keymap))
return -1; return -1;
return !!(xkb_state_serialize_mods(state, type) & (1 << idx)); return !!(xkb_state_serialize_mods(state, type) & (1u << idx));
} }
/** /**
@ -964,7 +1143,7 @@ xkb_state_mod_indices_are_active(struct xkb_state *state,
ret = -1; ret = -1;
break; break;
} }
wanted |= (1 << idx); wanted |= (1u << idx);
} }
va_end(ap); va_end(ap);
@ -1015,7 +1194,7 @@ xkb_state_mod_names_are_active(struct xkb_state *state,
ret = -1; ret = -1;
break; break;
} }
wanted |= (1 << idx); wanted |= (1u << idx);
} }
va_end(ap); va_end(ap);
@ -1042,11 +1221,11 @@ xkb_state_layout_index_is_active(struct xkb_state *state,
if (type & XKB_STATE_LAYOUT_EFFECTIVE) if (type & XKB_STATE_LAYOUT_EFFECTIVE)
ret |= (state->components.group == idx); ret |= (state->components.group == idx);
if (type & XKB_STATE_LAYOUT_DEPRESSED) if (type & XKB_STATE_LAYOUT_DEPRESSED)
ret |= (state->components.base_group == idx); ret |= (state->components.base_group == (int32_t) idx);
if (type & XKB_STATE_LAYOUT_LATCHED) if (type & XKB_STATE_LAYOUT_LATCHED)
ret |= (state->components.latched_group == idx); ret |= (state->components.latched_group == (int32_t) idx);
if (type & XKB_STATE_LAYOUT_LOCKED) if (type & XKB_STATE_LAYOUT_LOCKED)
ret |= (state->components.locked_group == idx); ret |= (state->components.locked_group == (int32_t) idx);
return ret; return ret;
} }
@ -1077,7 +1256,7 @@ xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
darray_item(state->keymap->leds, idx).name == XKB_ATOM_NONE) darray_item(state->keymap->leds, idx).name == XKB_ATOM_NONE)
return -1; return -1;
return !!(state->components.leds & (1 << idx)); return !!(state->components.leds & (1u << idx));
} }
/** /**
@ -1097,18 +1276,24 @@ xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
static xkb_mod_mask_t static xkb_mod_mask_t
key_get_consumed(struct xkb_state *state, const struct xkb_key *key) key_get_consumed(struct xkb_state *state, const struct xkb_key *key)
{ {
const struct xkb_key_type *type;
const struct xkb_key_type_entry *entry; const struct xkb_key_type_entry *entry;
xkb_mod_mask_t preserve;
xkb_layout_index_t group; xkb_layout_index_t group;
group = xkb_state_key_get_layout(state, key->keycode); group = xkb_state_key_get_layout(state, key->keycode);
if (group == XKB_LAYOUT_INVALID) if (group == XKB_LAYOUT_INVALID)
return 0; return 0;
entry = get_entry_for_key_state(state, key, group); type = key->groups[group].type;
if (!entry)
return 0;
return entry->mods.mask & ~entry->preserve.mask; entry = get_entry_for_key_state(state, key, group);
if (entry)
preserve = entry->preserve.mask;
else
preserve = 0;
return type->mods.mask & ~preserve;
} }
/** /**
@ -1132,7 +1317,7 @@ xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
if (!key || idx >= xkb_keymap_num_mods(state->keymap)) if (!key || idx >= xkb_keymap_num_mods(state->keymap))
return -1; return -1;
return !!((1 << idx) & key_get_consumed(state, key)); return !!((1u << idx) & key_get_consumed(state, key));
} }
/** /**
@ -1154,3 +1339,14 @@ xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc,
return mask & ~key_get_consumed(state, key); return mask & ~key_get_consumed(state, key);
} }
XKB_EXPORT xkb_mod_mask_t
xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t kc)
{
const struct xkb_key *key = XkbKey(state->keymap, kc);
if (!key)
return 0;
return key_get_consumed(state, key);
}

View File

@ -280,7 +280,7 @@ ModMaskText(const struct xkb_keymap *keymap, xkb_mod_mask_t mask)
darray_enumerate(i, mod, keymap->mods) { darray_enumerate(i, mod, keymap->mods) {
int ret; int ret;
if (!(mask & (1 << i))) if (!(mask & (1u << i)))
continue; continue;
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
@ -307,14 +307,14 @@ LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask)
for (unsigned i = 0; mask; i++) { for (unsigned i = 0; mask; i++) {
int ret; int ret;
if (!(mask & (1 << i))) if (!(mask & (1u << i)))
continue; continue;
mask &= ~(1 << i); mask &= ~(1u << i);
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
pos == 0 ? "" : "+", pos == 0 ? "" : "+",
LookupValue(modComponentMaskNames, 1 << i)); LookupValue(modComponentMaskNames, 1u << i));
if (ret <= 0 || pos + ret >= sizeof(buf)) if (ret <= 0 || pos + ret >= sizeof(buf))
break; break;
else else
@ -339,14 +339,14 @@ ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask)
for (unsigned i = 0; mask; i++) { for (unsigned i = 0; mask; i++) {
int ret; int ret;
if (!(mask & (1 << i))) if (!(mask & (1u << i)))
continue; continue;
mask &= ~(1 << i); mask &= ~(1u << i);
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
pos == 0 ? "" : "+", pos == 0 ? "" : "+",
LookupValue(ctrlMaskNames, 1 << i)); LookupValue(ctrlMaskNames, 1u << i));
if (ret <= 0 || pos + ret >= sizeof(buf)) if (ret <= 0 || pos + ret >= sizeof(buf))
break; break;
else else

142
src/3rdparty/xkbcommon/src/utf8.c vendored Normal file
View File

@ -0,0 +1,142 @@
/*
* 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 <= 0x1fffff) {
length = 4;
head = 0xf0;
}
else if (unichar <= 0x3ffffff) {
length = 5;
head = 0xf8;
}
else {
length = 6;
head = 0xfc;
}
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
* http://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 Normal file
View File

@ -0,0 +1,36 @@
/*
* 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

View File

@ -163,13 +163,13 @@ is_graph(char ch)
* Note: this is 1-based! It's more useful this way, and returns 0 when * Note: this is 1-based! It's more useful this way, and returns 0 when
* mask is all 0s. * mask is all 0s.
*/ */
static inline int static inline unsigned
msb_pos(uint32_t mask) msb_pos(uint32_t mask)
{ {
int pos = 0; unsigned pos = 0;
while (mask) { while (mask) {
pos++; pos++;
mask >>= 1; mask >>= 1u;
} }
return pos; return pos;
} }
@ -187,6 +187,22 @@ unmap_file(const char *str, size_t size);
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MAX3(a, b, c) MAX(MAX((a), (b)), (c)) #define MAX3(a, b, c) MAX(MAX((a), (b)), (c))
#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 */ /* Compiler Attributes */
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__) #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__)

View File

@ -43,13 +43,13 @@
/* Constants from /usr/include/X11/extensions/XKB.h */ /* Constants from /usr/include/X11/extensions/XKB.h */
/* XkbNumModifiers. */ /* XkbNumModifiers. */
#define NUM_REAL_MODS 8 #define NUM_REAL_MODS 8u
/* XkbNumVirtualMods. */ /* XkbNumVirtualMods. */
#define NUM_VMODS 16 #define NUM_VMODS 16u
/* XkbNoModifier. */ /* XkbNoModifier. */
#define NO_MODIFIER 0xff #define NO_MODIFIER 0xff
/* XkbNumIndicators. */ /* XkbNumIndicators. */
#define NUM_INDICATORS 32 #define NUM_INDICATORS 32u
/* XkbAllIndicatorsMask. */ /* XkbAllIndicatorsMask. */
#define ALL_INDICATORS_MASK 0xffffffff #define ALL_INDICATORS_MASK 0xffffffff
@ -92,11 +92,14 @@ translate_mods(uint8_t rmods, uint16_t vmods_low, uint16_t vmods_high)
{ {
/* We represent mod masks in a single uint32_t value, with real mods /* We represent mod masks in a single uint32_t value, with real mods
* first and vmods after (though we don't make these distinctions). */ * first and vmods after (though we don't make these distinctions). */
return rmods | (vmods_low << 8) | (vmods_high << 16); return
((xkb_mod_mask_t) rmods) |
((xkb_mod_mask_t) vmods_low << 8) |
((xkb_mod_mask_t) vmods_high << 16);
} }
static enum xkb_action_controls static enum xkb_action_controls
translate_controls_mask(uint16_t wire) translate_controls_mask(uint32_t wire)
{ {
enum xkb_action_controls ret = 0; enum xkb_action_controls ret = 0;
if (wire & XCB_XKB_BOOL_CTRL_REPEAT_KEYS) if (wire & XCB_XKB_BOOL_CTRL_REPEAT_KEYS)
@ -218,8 +221,8 @@ translate_action(union xkb_action *action, const xcb_xkb_action_t *wire)
action->ptr.x = (wire->moveptr.xLow | (wire->moveptr.xHigh << 8)); action->ptr.x = (wire->moveptr.xLow | (wire->moveptr.xHigh << 8));
action->ptr.y = (wire->moveptr.yLow | (wire->moveptr.yHigh << 8)); action->ptr.y = (wire->moveptr.yLow | (wire->moveptr.yHigh << 8));
if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION) if (!(wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION))
action->ptr.flags |= ACTION_NO_ACCEL; action->ptr.flags |= ACTION_ACCEL;
if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_X) if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_X)
action->ptr.flags |= ACTION_ABSOLUTE_X; action->ptr.flags |= ACTION_ABSOLUTE_X;
if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_Y) if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_Y)
@ -263,7 +266,7 @@ translate_action(union xkb_action *action, const xcb_xkb_action_t *wire)
action->screen.screen = wire->switchscreen.newScreen; action->screen.screen = wire->switchscreen.newScreen;
if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION) if (!(wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION))
action->screen.flags |= ACTION_SAME_SCREEN; action->screen.flags |= ACTION_SAME_SCREEN;
if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_ABSOLUTE) if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_ABSOLUTE)
action->screen.flags |= ACTION_ABSOLUTE_SWITCH; action->screen.flags |= ACTION_ABSOLUTE_SWITCH;
@ -351,7 +354,7 @@ get_types(struct xkb_keymap *keymap, xcb_connection_t *conn,
xcb_xkb_mod_def_iterator_t preserves_iter = xcb_xkb_mod_def_iterator_t preserves_iter =
xcb_xkb_key_type_preserve_iterator(wire_type); xcb_xkb_key_type_preserve_iterator(wire_type);
FAIL_UNLESS(preserves_length <= type->num_entries); FAIL_UNLESS((unsigned) preserves_length <= type->num_entries);
for (int j = 0; j < preserves_length; j++) { for (int j = 0; j < preserves_length; j++) {
xcb_xkb_mod_def_t *wire_preserve = preserves_iter.data; xcb_xkb_mod_def_t *wire_preserve = preserves_iter.data;
@ -402,7 +405,7 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn,
FAIL_UNLESS(key->num_groups <= ARRAY_SIZE(wire_sym_map->kt_index)); FAIL_UNLESS(key->num_groups <= ARRAY_SIZE(wire_sym_map->kt_index));
ALLOC_OR_FAIL(key->groups, key->num_groups); ALLOC_OR_FAIL(key->groups, key->num_groups);
for (int j = 0; j < key->num_groups; j++) { for (unsigned j = 0; j < key->num_groups; j++) {
FAIL_UNLESS(wire_sym_map->kt_index[j] < keymap->num_types); FAIL_UNLESS(wire_sym_map->kt_index[j] < keymap->num_types);
key->groups[j].type = &keymap->types[wire_sym_map->kt_index[j]]; key->groups[j].type = &keymap->types[wire_sym_map->kt_index[j]];
@ -424,7 +427,7 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn,
int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map); int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map);
xcb_keysym_t *syms_iter = xcb_xkb_key_sym_map_syms(wire_sym_map); xcb_keysym_t *syms_iter = xcb_xkb_key_sym_map_syms(wire_sym_map);
FAIL_UNLESS(syms_length == wire_sym_map->width * key->num_groups); FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups);
for (int j = 0; j < syms_length; j++) { for (int j = 0; j < syms_length; j++) {
xcb_keysym_t wire_keysym = *syms_iter; xcb_keysym_t wire_keysym = *syms_iter;
@ -468,9 +471,12 @@ get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn,
for (int i = 0; i < acts_count_length; i++) { for (int i = 0; i < acts_count_length; i++) {
xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data; xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data;
int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map);
uint8_t wire_count = *acts_count_iter; uint8_t wire_count = *acts_count_iter;
struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i]; struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i];
FAIL_UNLESS(wire_count == 0 || wire_count == syms_length);
for (int j = 0; j < wire_count; j++) { for (int j = 0; j < wire_count; j++) {
xcb_xkb_action_t *wire_action = acts_iter.data; xcb_xkb_action_t *wire_action = acts_iter.data;
const xkb_layout_index_t group = j / wire_sym_map->width; const xkb_layout_index_t group = j / wire_sym_map->width;
@ -505,8 +511,8 @@ get_vmods(struct xkb_keymap *keymap, xcb_connection_t *conn,
darray_resize0(keymap->mods, darray_resize0(keymap->mods,
NUM_REAL_MODS + msb_pos(reply->virtualMods)); NUM_REAL_MODS + msb_pos(reply->virtualMods));
for (int i = 0; i < NUM_VMODS; i++) { for (unsigned i = 0; i < NUM_VMODS; i++) {
if (reply->virtualMods & (1 << i)) { if (reply->virtualMods & (1u << i)) {
uint8_t wire = *iter; uint8_t wire = *iter;
struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i); struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i);
@ -530,11 +536,13 @@ get_explicits(struct xkb_keymap *keymap, xcb_connection_t *conn,
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
xcb_xkb_set_explicit_t *wire = iter.data; xcb_xkb_set_explicit_t *wire = iter.data;
struct xkb_key *key = &keymap->keys[wire->keycode]; struct xkb_key *key;
FAIL_UNLESS(wire->keycode >= keymap->min_key_code && FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
wire->keycode <= keymap->max_key_code); wire->keycode <= keymap->max_key_code);
key = &keymap->keys[wire->keycode];
if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_1) && if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_1) &&
key->num_groups > 0) key->num_groups > 0)
key->groups[0].explicit_type = true; key->groups[0].explicit_type = true;
@ -573,11 +581,12 @@ get_modmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
xcb_xkb_key_mod_map_t *wire = iter.data; xcb_xkb_key_mod_map_t *wire = iter.data;
struct xkb_key *key = &keymap->keys[wire->keycode]; struct xkb_key *key;
FAIL_UNLESS(wire->keycode >= keymap->min_key_code && FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
wire->keycode <= keymap->max_key_code); wire->keycode <= keymap->max_key_code);
key = &keymap->keys[wire->keycode];
key->modmap = wire->mods; key->modmap = wire->mods;
xcb_xkb_key_mod_map_next(&iter); xcb_xkb_key_mod_map_next(&iter);
@ -599,11 +608,12 @@ get_vmodmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
xcb_xkb_key_v_mod_map_t *wire = iter.data; xcb_xkb_key_v_mod_map_t *wire = iter.data;
struct xkb_key *key = &keymap->keys[wire->keycode]; struct xkb_key *key;
FAIL_UNLESS(wire->keycode >= keymap->min_key_code && FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
wire->keycode <= keymap->max_key_code); wire->keycode <= keymap->max_key_code);
key = &keymap->keys[wire->keycode];
key->vmodmap = translate_mods(0, wire->vmods, 0); key->vmodmap = translate_mods(0, wire->vmods, 0);
xcb_xkb_key_v_mod_map_next(&iter); xcb_xkb_key_v_mod_map_next(&iter);
@ -677,8 +687,8 @@ get_indicators(struct xkb_keymap *keymap, xcb_connection_t *conn,
darray_resize0(keymap->leds, msb_pos(reply->which)); darray_resize0(keymap->leds, msb_pos(reply->which));
for (int i = 0; i < NUM_INDICATORS; i++) { for (unsigned i = 0; i < NUM_INDICATORS; i++) {
if (reply->which & (1 << i)) { if (reply->which & (1u << i)) {
xcb_xkb_indicator_map_t *wire = iter.data; xcb_xkb_indicator_map_t *wire = iter.data;
struct xkb_led *led = &darray_item(keymap->leds, i); struct xkb_led *led = &darray_item(keymap->leds, i);
@ -879,8 +889,8 @@ get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
FAIL_UNLESS(msb_pos(reply->indicators) <= darray_size(keymap->leds)); FAIL_UNLESS(msb_pos(reply->indicators) <= darray_size(keymap->leds));
for (int i = 0; i < NUM_INDICATORS; i++) { for (unsigned i = 0; i < NUM_INDICATORS; i++) {
if (reply->indicators & (1 << i)) { if (reply->indicators & (1u << i)) {
xcb_atom_t wire = *iter; xcb_atom_t wire = *iter;
struct xkb_led *led = &darray_item(keymap->leds, i); struct xkb_led *led = &darray_item(keymap->leds, i);
@ -911,8 +921,8 @@ get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
*/ */
darray_resize0(keymap->mods, NUM_REAL_MODS + msb_pos(reply->virtualMods)); darray_resize0(keymap->mods, NUM_REAL_MODS + msb_pos(reply->virtualMods));
for (int i = 0; i < NUM_VMODS; i++) { for (unsigned i = 0; i < NUM_VMODS; i++) {
if (reply->virtualMods & (1 << i)) { if (reply->virtualMods & (1u << i)) {
xcb_atom_t wire = *iter; xcb_atom_t wire = *iter;
struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i); struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i);
@ -959,7 +969,7 @@ get_key_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
FAIL_UNLESS(reply->minKeyCode == keymap->min_key_code); FAIL_UNLESS(reply->minKeyCode == keymap->min_key_code);
FAIL_UNLESS(reply->maxKeyCode == keymap->max_key_code); FAIL_UNLESS(reply->maxKeyCode == keymap->max_key_code);
FAIL_UNLESS(reply->firstKey == keymap->min_key_code); FAIL_UNLESS(reply->firstKey == keymap->min_key_code);
FAIL_UNLESS(reply->firstKey + reply->nKeys - 1 == keymap->max_key_code); FAIL_UNLESS(reply->firstKey + reply->nKeys - 1U == keymap->max_key_code);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
xcb_xkb_key_name_t *wire = iter.data; xcb_xkb_key_name_t *wire = iter.data;
@ -1023,7 +1033,7 @@ static bool
get_names(struct xkb_keymap *keymap, xcb_connection_t *conn, get_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
uint16_t device_id) uint16_t device_id)
{ {
static const xcb_xkb_name_detail_t required_names = static const xcb_xkb_name_detail_t wanted =
(XCB_XKB_NAME_DETAIL_KEYCODES | (XCB_XKB_NAME_DETAIL_KEYCODES |
XCB_XKB_NAME_DETAIL_SYMBOLS | XCB_XKB_NAME_DETAIL_SYMBOLS |
XCB_XKB_NAME_DETAIL_TYPES | XCB_XKB_NAME_DETAIL_TYPES |
@ -1035,17 +1045,21 @@ get_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
XCB_XKB_NAME_DETAIL_KEY_ALIASES | XCB_XKB_NAME_DETAIL_KEY_ALIASES |
XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES | XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES |
XCB_XKB_NAME_DETAIL_GROUP_NAMES); XCB_XKB_NAME_DETAIL_GROUP_NAMES);
static const xcb_xkb_name_detail_t required =
(XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
XCB_XKB_NAME_DETAIL_KEY_NAMES |
XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES);
xcb_xkb_get_names_cookie_t cookie = xcb_xkb_get_names_cookie_t cookie =
xcb_xkb_get_names(conn, device_id, required_names); xcb_xkb_get_names(conn, device_id, wanted);
xcb_xkb_get_names_reply_t *reply = xcb_xkb_get_names_reply_t *reply =
xcb_xkb_get_names_reply(conn, cookie, NULL); xcb_xkb_get_names_reply(conn, cookie, NULL);
xcb_xkb_get_names_value_list_t list; xcb_xkb_get_names_value_list_t list;
FAIL_IF_BAD_REPLY(reply, "XkbGetNames"); FAIL_IF_BAD_REPLY(reply, "XkbGetNames");
if ((reply->which & required_names) != required_names) FAIL_UNLESS((reply->which & required) == required);
goto fail;
xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply), xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply),
reply->nTypes, reply->nTypes,
@ -1093,13 +1107,14 @@ get_controls(struct xkb_keymap *keymap, xcb_connection_t *conn,
xcb_xkb_get_controls_reply(conn, cookie, NULL); xcb_xkb_get_controls_reply(conn, cookie, NULL);
FAIL_IF_BAD_REPLY(reply, "XkbGetControls"); FAIL_IF_BAD_REPLY(reply, "XkbGetControls");
FAIL_UNLESS(reply->numGroups > 0 && reply->numGroups <= 4);
keymap->enabled_ctrls = translate_controls_mask(reply->enabledControls); keymap->enabled_ctrls = translate_controls_mask(reply->enabledControls);
keymap->num_groups = reply->numGroups; keymap->num_groups = reply->numGroups;
FAIL_UNLESS(keymap->max_key_code < XCB_XKB_CONST_PER_KEY_BIT_ARRAY_SIZE * 8); FAIL_UNLESS(keymap->max_key_code < XCB_XKB_CONST_PER_KEY_BIT_ARRAY_SIZE * 8);
for (int i = keymap->min_key_code; i <= keymap->max_key_code; i++) for (xkb_keycode_t i = keymap->min_key_code; i <= keymap->max_key_code; i++)
keymap->keys[i].repeats = !!(reply->perKeyRepeat[i / 8] & (1 << (i % 8))); keymap->keys[i].repeats = !!(reply->perKeyRepeat[i / 8] & (1 << (i % 8)));
free(reply); free(reply);
@ -1119,7 +1134,7 @@ xkb_x11_keymap_new_from_device(struct xkb_context *ctx,
struct xkb_keymap *keymap; struct xkb_keymap *keymap;
const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1; const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1;
if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
log_err_func(ctx, "unrecognized flags: %#x\n", flags); log_err_func(ctx, "unrecognized flags: %#x\n", flags);
return NULL; return NULL;
} }

View File

@ -26,8 +26,8 @@
#include <xcb/xkb.h> #include <xcb/xkb.h>
#include "xkbcommon/xkbcommon-x11.h"
#include "keymap.h" #include "keymap.h"
#include "xkbcommon/xkbcommon-x11.h"
/* Get a strdup'd name of an X atom. */ /* Get a strdup'd name of an X atom. */
bool bool

View File

@ -110,10 +110,10 @@ get_keymap_format_ops(enum xkb_keymap_format format)
[XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops, [XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops,
}; };
if ((int) format < 0 || (int) format >= ARRAY_SIZE(keymap_format_ops)) if ((int) format < 0 || (int) format >= (int) ARRAY_SIZE(keymap_format_ops))
return NULL; return NULL;
return keymap_format_ops[format]; return keymap_format_ops[(int) format];
} }
XKB_EXPORT struct xkb_keymap * XKB_EXPORT struct xkb_keymap *
@ -132,33 +132,20 @@ xkb_keymap_new_from_names(struct xkb_context *ctx,
return NULL; return NULL;
} }
if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
log_err_func(ctx, "unrecognized flags: %#x\n", flags); log_err_func(ctx, "unrecognized flags: %#x\n", flags);
return NULL; return NULL;
} }
keymap = xkb_keymap_new(ctx, format, flags);
if (!keymap)
return NULL;
if (rmlvo_in) if (rmlvo_in)
rmlvo = *rmlvo_in; rmlvo = *rmlvo_in;
else else
memset(&rmlvo, 0, sizeof(rmlvo)); memset(&rmlvo, 0, sizeof(rmlvo));
xkb_context_sanitize_rule_names(ctx, &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);
keymap = xkb_keymap_new(ctx, format, flags);
if (!keymap)
return NULL;
if (!ops->keymap_new_from_names(keymap, &rmlvo)) { if (!ops->keymap_new_from_names(keymap, &rmlvo)) {
xkb_keymap_unref(keymap); xkb_keymap_unref(keymap);
@ -193,7 +180,7 @@ xkb_keymap_new_from_buffer(struct xkb_context *ctx,
return NULL; return NULL;
} }
if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
log_err_func(ctx, "unrecognized flags: %#x\n", flags); log_err_func(ctx, "unrecognized flags: %#x\n", flags);
return NULL; return NULL;
} }
@ -230,7 +217,7 @@ xkb_keymap_new_from_file(struct xkb_context *ctx,
return NULL; return NULL;
} }
if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) { if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
log_err_func(ctx, "unrecognized flags: %#x\n", flags); log_err_func(ctx, "unrecognized flags: %#x\n", flags);
return NULL; return NULL;
} }

View File

@ -118,6 +118,8 @@ NewActionsInfo(void)
/* Increment default button. */ /* Increment default button. */
info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.flags = 0; info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.flags = 0;
info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.value = 1; 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; return info;
} }
@ -186,10 +188,10 @@ fieldText(enum action_field field)
/***====================================================================***/ /***====================================================================***/
static inline bool static inline bool
ReportMismatch(struct xkb_keymap *keymap, enum xkb_action_type action, ReportMismatch(struct xkb_context *ctx, enum xkb_action_type action,
enum action_field field, const char *type) enum action_field field, const char *type)
{ {
log_err(keymap->ctx, log_err(ctx,
"Value of %s field must be of type %s; " "Value of %s field must be of type %s; "
"Action %s definition ignored\n", "Action %s definition ignored\n",
fieldText(field), type, ActionTypeText(action)); fieldText(field), type, ActionTypeText(action));
@ -197,10 +199,10 @@ ReportMismatch(struct xkb_keymap *keymap, enum xkb_action_type action,
} }
static inline bool static inline bool
ReportIllegal(struct xkb_keymap *keymap, enum xkb_action_type action, ReportIllegal(struct xkb_context *ctx, enum xkb_action_type action,
enum action_field field) enum action_field field)
{ {
log_err(keymap->ctx, log_err(ctx,
"Field %s is not defined for an action of type %s; " "Field %s is not defined for an action of type %s; "
"Action definition ignored\n", "Action definition ignored\n",
fieldText(field), ActionTypeText(action)); fieldText(field), ActionTypeText(action));
@ -208,10 +210,10 @@ ReportIllegal(struct xkb_keymap *keymap, enum xkb_action_type action,
} }
static inline bool static inline bool
ReportActionNotArray(struct xkb_keymap *keymap, enum xkb_action_type action, ReportActionNotArray(struct xkb_context *ctx, enum xkb_action_type action,
enum action_field field) enum action_field field)
{ {
log_err(keymap->ctx, log_err(ctx,
"The %s field in the %s action is not an array; " "The %s field in the %s action is not an array; "
"Action definition ignored\n", "Action definition ignored\n",
fieldText(field), ActionTypeText(action)); fieldText(field), ActionTypeText(action));
@ -228,42 +230,40 @@ HandleNoAction(struct xkb_keymap *keymap, union xkb_action *action,
} }
static bool static bool
CheckLatchLockFlags(struct xkb_keymap *keymap, enum xkb_action_type action, CheckBooleanFlag(struct xkb_context *ctx, enum xkb_action_type action,
enum action_field field, const ExprDef *value, enum action_field field, enum xkb_action_flags flag,
enum xkb_action_flags *flags_inout) const ExprDef *array_ndx, const ExprDef *value,
enum xkb_action_flags *flags_inout)
{ {
enum xkb_action_flags tmp; bool set;
bool result;
if (field == ACTION_FIELD_CLEAR_LOCKS) if (array_ndx)
tmp = ACTION_LOCK_CLEAR; return ReportActionNotArray(ctx, action, field);
else if (field == ACTION_FIELD_LATCH_TO_LOCK)
tmp = ACTION_LATCH_TO_LOCK; if (!ExprResolveBoolean(ctx, value, &set))
return ReportMismatch(ctx, action, field, "boolean");
if (set)
*flags_inout |= flag;
else else
return false; /* WSGO! */ *flags_inout &= ~flag;
if (!ExprResolveBoolean(keymap->ctx, value, &result))
return ReportMismatch(keymap, action, field, "boolean");
if (result)
*flags_inout |= tmp;
else
*flags_inout &= ~tmp;
return true; return true;
} }
static bool static bool
CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action, CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action,
const ExprDef *value, enum xkb_action_flags *flags_inout, const ExprDef *array_ndx, const ExprDef *value,
xkb_mod_mask_t *mods_rtrn) enum xkb_action_flags *flags_inout, xkb_mod_mask_t *mods_rtrn)
{ {
if (array_ndx)
return ReportActionNotArray(keymap->ctx, action, ACTION_FIELD_MODIFIERS);
if (value->expr.op == EXPR_IDENT) { if (value->expr.op == EXPR_IDENT) {
const char *valStr; const char *valStr;
valStr = xkb_atom_text(keymap->ctx, value->ident.ident); valStr = xkb_atom_text(keymap->ctx, value->ident.ident);
if (valStr && (istreq(valStr, "usemodmapmods") || if (valStr && (istreq(valStr, "usemodmapmods") ||
istreq(valStr, "modmapmods"))) { istreq(valStr, "modmapmods"))) {
*mods_rtrn = 0; *mods_rtrn = 0;
*flags_inout |= ACTION_MODS_LOOKUP_MODMAP; *flags_inout |= ACTION_MODS_LOOKUP_MODMAP;
return true; return true;
@ -271,232 +271,13 @@ CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action,
} }
if (!ExprResolveModMask(keymap, value, MOD_BOTH, mods_rtrn)) if (!ExprResolveModMask(keymap, value, MOD_BOTH, mods_rtrn))
return ReportMismatch(keymap, action, return ReportMismatch(keymap->ctx, action,
ACTION_FIELD_MODIFIERS, "modifier mask"); ACTION_FIELD_MODIFIERS, "modifier mask");
*flags_inout &= ~ACTION_MODS_LOOKUP_MODMAP; *flags_inout &= ~ACTION_MODS_LOOKUP_MODMAP;
return true; return true;
} }
static bool
HandleSetLatchMods(struct xkb_keymap *keymap, union xkb_action *action,
enum action_field field, const ExprDef *array_ndx,
const ExprDef *value)
{
struct xkb_mod_action *act = &action->mods;
enum xkb_action_flags rtrn, t1;
xkb_mod_mask_t t2;
if (array_ndx != NULL) {
switch (field) {
case ACTION_FIELD_CLEAR_LOCKS:
case ACTION_FIELD_LATCH_TO_LOCK:
case ACTION_FIELD_MODIFIERS:
return ReportActionNotArray(keymap, action->type, field);
default:
break;
}
}
switch (field) {
case ACTION_FIELD_CLEAR_LOCKS:
case ACTION_FIELD_LATCH_TO_LOCK:
rtrn = act->flags;
if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) {
act->flags = rtrn;
return true;
}
return false;
case ACTION_FIELD_MODIFIERS:
t1 = act->flags;
if (CheckModifierField(keymap, action->type, value, &t1, &t2)) {
act->flags = t1;
act->mods.mods = t2;
return true;
}
return false;
default:
break;
}
return ReportIllegal(keymap, action->type, field);
}
static bool
HandleLockMods(struct xkb_keymap *keymap, union xkb_action *action,
enum action_field field, const ExprDef *array_ndx,
const ExprDef *value)
{
struct xkb_mod_action *act = &action->mods;
enum xkb_action_flags t1;
xkb_mod_mask_t t2;
if (array_ndx && field == ACTION_FIELD_MODIFIERS)
return ReportActionNotArray(keymap, action->type, field);
switch (field) {
case ACTION_FIELD_MODIFIERS:
t1 = act->flags;
if (CheckModifierField(keymap, action->type, value, &t1, &t2)) {
act->flags = t1;
act->mods.mods = t2;
return true;
}
return false;
default:
break;
}
return ReportIllegal(keymap, action->type, field);
}
static bool
CheckGroupField(struct xkb_keymap *keymap, unsigned action,
const ExprDef *value, enum xkb_action_flags *flags_inout,
xkb_layout_index_t *grp_rtrn)
{
const ExprDef *spec;
if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) {
*flags_inout &= ~ACTION_ABSOLUTE_SWITCH;
spec = value->unary.child;
}
else {
*flags_inout |= ACTION_ABSOLUTE_SWITCH;
spec = value;
}
if (!ExprResolveGroup(keymap->ctx, spec, grp_rtrn))
return ReportMismatch(keymap, action, ACTION_FIELD_GROUP,
"integer (range 1..8)");
if (value->expr.op == EXPR_NEGATE)
*grp_rtrn = -*grp_rtrn;
else if (value->expr.op != EXPR_UNARY_PLUS)
(*grp_rtrn)--;
return true;
}
static bool
HandleSetLatchGroup(struct xkb_keymap *keymap, union xkb_action *action,
enum action_field field, const ExprDef *array_ndx,
const ExprDef *value)
{
struct xkb_group_action *act = &action->group;
enum xkb_action_flags rtrn, t1;
xkb_layout_index_t t2;
if (array_ndx != NULL) {
switch (field) {
case ACTION_FIELD_CLEAR_LOCKS:
case ACTION_FIELD_LATCH_TO_LOCK:
case ACTION_FIELD_GROUP:
return ReportActionNotArray(keymap, action->type, field);
default:
break;
}
}
switch (field) {
case ACTION_FIELD_CLEAR_LOCKS:
case ACTION_FIELD_LATCH_TO_LOCK:
rtrn = act->flags;
if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) {
act->flags = rtrn;
return true;
}
return false;
case ACTION_FIELD_GROUP:
t1 = act->flags;
if (CheckGroupField(keymap, action->type, value, &t1, &t2)) {
act->flags = t1;
act->group = t2;
return true;
}
return false;
default:
break;
}
return ReportIllegal(keymap, action->type, field);
}
static bool
HandleLockGroup(struct xkb_keymap *keymap, union xkb_action *action,
enum action_field field, const ExprDef *array_ndx,
const ExprDef *value)
{
struct xkb_group_action *act = &action->group;
enum xkb_action_flags t1;
xkb_layout_index_t t2;
if ((array_ndx != NULL) && (field == ACTION_FIELD_GROUP))
return ReportActionNotArray(keymap, action->type, field);
if (field == ACTION_FIELD_GROUP) {
t1 = act->flags;
if (CheckGroupField(keymap, action->type, value, &t1, &t2)) {
act->flags = t1;
act->group = t2;
return true;
}
return false;
}
return ReportIllegal(keymap, action->type, field);
}
static bool
HandleMovePtr(struct xkb_keymap *keymap, union xkb_action *action,
enum action_field field, const ExprDef *array_ndx,
const ExprDef *value)
{
struct xkb_pointer_action *act = &action->ptr;
if (array_ndx && (field == ACTION_FIELD_X || field == ACTION_FIELD_Y))
return ReportActionNotArray(keymap, action->type, field);
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 (!ExprResolveInteger(keymap->ctx, value, &val))
return ReportMismatch(keymap, action->type, field, "integer");
if (field == ACTION_FIELD_X) {
if (absolute)
act->flags |= ACTION_ABSOLUTE_X;
act->x = val;
}
else {
if (absolute)
act->flags |= ACTION_ABSOLUTE_Y;
act->y = val;
}
return true;
}
else if (field == ACTION_FIELD_ACCEL) {
bool set;
if (!ExprResolveBoolean(keymap->ctx, value, &set))
return ReportMismatch(keymap, action->type, field, "boolean");
if (set)
act->flags &= ~ACTION_NO_ACCEL;
else
act->flags |= ACTION_NO_ACCEL;
}
return ReportIllegal(keymap, action->type, field);
}
static const LookupEntry lockWhich[] = { static const LookupEntry lockWhich[] = {
{ "both", 0 }, { "both", 0 },
{ "lock", ACTION_LOCK_NO_UNLOCK }, { "lock", ACTION_LOCK_NO_UNLOCK },
@ -505,6 +286,165 @@ static const LookupEntry lockWhich[] = {
{ NULL, 0 } { 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_keymap *keymap, 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(keymap, 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(keymap->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(keymap->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(keymap->ctx, action->type, array_ndx, value,
&act->flags);
return ReportIllegal(keymap->ctx, action->type, field);
}
static bool
CheckGroupField(struct xkb_context *ctx, unsigned 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_keymap *keymap, 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(keymap->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(keymap->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(keymap->ctx, action->type, field,
ACTION_LATCH_TO_LOCK, array_ndx, value,
&act->flags);
return ReportIllegal(keymap->ctx, action->type, field);
}
static bool
HandleMovePtr(struct xkb_keymap *keymap, 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(keymap->ctx, action->type, field);
if (!ExprResolveInteger(keymap->ctx, value, &val))
return ReportMismatch(keymap->ctx, action->type, field, "integer");
if (val < INT16_MIN || val > INT16_MAX) {
log_err(keymap->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(keymap->ctx, action->type, field,
ACTION_ACCEL, array_ndx, value, &act->flags);
}
return ReportIllegal(keymap->ctx, action->type, field);
}
static bool static bool
HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action, HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action,
enum action_field field, const ExprDef *array_ndx, enum action_field field, const ExprDef *array_ndx,
@ -516,10 +456,10 @@ HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action,
int btn; int btn;
if (array_ndx) if (array_ndx)
return ReportActionNotArray(keymap, action->type, field); return ReportActionNotArray(keymap->ctx, action->type, field);
if (!ExprResolveButton(keymap->ctx, value, &btn)) if (!ExprResolveButton(keymap->ctx, value, &btn))
return ReportMismatch(keymap, action->type, field, return ReportMismatch(keymap->ctx, action->type, field,
"integer (range 1..5)"); "integer (range 1..5)");
if (btn < 0 || btn > 5) { if (btn < 0 || btn > 5) {
@ -534,40 +474,30 @@ HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action,
} }
else if (action->type == ACTION_TYPE_PTR_LOCK && else if (action->type == ACTION_TYPE_PTR_LOCK &&
field == ACTION_FIELD_AFFECT) { field == ACTION_FIELD_AFFECT) {
enum xkb_action_flags val; return CheckAffectField(keymap->ctx, action->type, array_ndx, value,
&act->flags);
if (array_ndx)
return ReportActionNotArray(keymap, action->type, field);
if (!ExprResolveEnum(keymap->ctx, value, &val, lockWhich))
return ReportMismatch(keymap, action->type, field,
"lock or unlock");
act->flags &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK);
act->flags |= val;
return true;
} }
else if (field == ACTION_FIELD_COUNT) { else if (field == ACTION_FIELD_COUNT) {
int btn; int val;
if (array_ndx) if (array_ndx)
return ReportActionNotArray(keymap, action->type, field); return ReportActionNotArray(keymap->ctx, action->type, field);
/* XXX: Should this actually be ResolveButton? */ if (!ExprResolveInteger(keymap->ctx, value, &val))
if (!ExprResolveButton(keymap->ctx, value, &btn)) return ReportMismatch(keymap->ctx, action->type, field, "integer");
return ReportMismatch(keymap, action->type, field, "integer");
if (btn < 0 || btn > 255) { if (val < 0 || val > 255) {
log_err(keymap->ctx, log_err(keymap->ctx,
"The count field must have a value in the range 0..255; " "The count field must have a value in the range 0..255; "
"Illegal count %d ignored\n", btn); "Illegal count %d ignored\n", val);
return false; return false;
} }
act->count = btn; act->count = (uint8_t) val;
return true; return true;
} }
return ReportIllegal(keymap, action->type, field);
return ReportIllegal(keymap->ctx, action->type, field);
} }
static const LookupEntry ptrDflts[] = { static const LookupEntry ptrDflts[] = {
@ -588,10 +518,10 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
unsigned int val; unsigned int val;
if (array_ndx) if (array_ndx)
return ReportActionNotArray(keymap, action->type, field); return ReportActionNotArray(keymap->ctx, action->type, field);
if (!ExprResolveEnum(keymap->ctx, value, &val, ptrDflts)) if (!ExprResolveEnum(keymap->ctx, value, &val, ptrDflts))
return ReportMismatch(keymap, action->type, field, return ReportMismatch(keymap->ctx, action->type, field,
"pointer component"); "pointer component");
return true; return true;
} }
@ -600,7 +530,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
int btn; int btn;
if (array_ndx) if (array_ndx)
return ReportActionNotArray(keymap, action->type, field); return ReportActionNotArray(keymap->ctx, action->type, field);
if (value->expr.op == EXPR_NEGATE || if (value->expr.op == EXPR_NEGATE ||
value->expr.op == EXPR_UNARY_PLUS) { value->expr.op == EXPR_UNARY_PLUS) {
@ -613,7 +543,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
} }
if (!ExprResolveButton(keymap->ctx, button, &btn)) if (!ExprResolveButton(keymap->ctx, button, &btn))
return ReportMismatch(keymap, action->type, field, return ReportMismatch(keymap->ctx, action->type, field,
"integer (range 1..5)"); "integer (range 1..5)");
if (btn < 0 || btn > 5) { if (btn < 0 || btn > 5) {
@ -633,7 +563,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
return true; return true;
} }
return ReportIllegal(keymap, action->type, field); return ReportIllegal(keymap->ctx, action->type, field);
} }
static bool static bool
@ -648,7 +578,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
int val; int val;
if (array_ndx) if (array_ndx)
return ReportActionNotArray(keymap, action->type, field); return ReportActionNotArray(keymap->ctx, action->type, field);
if (value->expr.op == EXPR_NEGATE || if (value->expr.op == EXPR_NEGATE ||
value->expr.op == EXPR_UNARY_PLUS) { value->expr.op == EXPR_UNARY_PLUS) {
@ -661,7 +591,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
} }
if (!ExprResolveInteger(keymap->ctx, scrn, &val)) if (!ExprResolveInteger(keymap->ctx, scrn, &val))
return ReportMismatch(keymap, action->type, field, return ReportMismatch(keymap->ctx, action->type, field,
"integer (0..255)"); "integer (0..255)");
if (val < 0 || val > 255) { if (val < 0 || val > 255) {
@ -675,23 +605,12 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
return true; return true;
} }
else if (field == ACTION_FIELD_SAME) { else if (field == ACTION_FIELD_SAME) {
bool set; return CheckBooleanFlag(keymap->ctx, action->type, field,
ACTION_SAME_SCREEN, array_ndx, value,
if (array_ndx) &act->flags);
return ReportActionNotArray(keymap, action->type, field);
if (!ExprResolveBoolean(keymap->ctx, value, &set))
return ReportMismatch(keymap, action->type, field, "boolean");
if (set)
act->flags &= ~ACTION_SAME_SCREEN;
else
act->flags |= ACTION_SAME_SCREEN;
return true;
} }
return ReportIllegal(keymap, action->type, field); return ReportIllegal(keymap->ctx, action->type, field);
} }
static bool static bool
@ -705,17 +624,21 @@ HandleSetLockControls(struct xkb_keymap *keymap, union xkb_action *action,
unsigned int mask; unsigned int mask;
if (array_ndx) if (array_ndx)
return ReportActionNotArray(keymap, action->type, field); return ReportActionNotArray(keymap->ctx, action->type, field);
if (!ExprResolveMask(keymap->ctx, value, &mask, ctrlMaskNames)) if (!ExprResolveMask(keymap->ctx, value, &mask, ctrlMaskNames))
return ReportMismatch(keymap, action->type, field, return ReportMismatch(keymap->ctx, action->type, field,
"controls mask"); "controls mask");
act->ctrls = mask; act->ctrls = mask;
return true; return true;
} }
else if (field == ACTION_FIELD_AFFECT) {
return CheckAffectField(keymap->ctx, action->type, array_ndx, value,
&act->flags);
}
return ReportIllegal(keymap, action->type, field); return ReportIllegal(keymap->ctx, action->type, field);
} }
static bool static bool
@ -728,8 +651,11 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
if (field == ACTION_FIELD_TYPE) { if (field == ACTION_FIELD_TYPE) {
int type; int type;
if (array_ndx)
return ReportActionNotArray(keymap->ctx, action->type, field);
if (!ExprResolveInteger(keymap->ctx, value, &type)) if (!ExprResolveInteger(keymap->ctx, value, &type))
return ReportMismatch(keymap, ACTION_TYPE_PRIVATE, field, "integer"); return ReportMismatch(keymap->ctx, ACTION_TYPE_PRIVATE, field, "integer");
if (type < 0 || type > 255) { if (type < 0 || type > 255) {
log_err(keymap->ctx, log_err(keymap->ctx,
@ -764,17 +690,17 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
if (array_ndx == NULL) { if (array_ndx == NULL) {
xkb_atom_t val; xkb_atom_t val;
const char *str; const char *str;
int len; size_t len;
if (!ExprResolveString(keymap->ctx, value, &val)) if (!ExprResolveString(keymap->ctx, value, &val))
return ReportMismatch(keymap, action->type, field, "string"); return ReportMismatch(keymap->ctx, action->type, field, "string");
str = xkb_atom_text(keymap->ctx, val); str = xkb_atom_text(keymap->ctx, val);
len = strlen(str); len = strlen(str);
if (len < 1 || len > 7) { if (len < 1 || len > 7) {
log_warn(keymap->ctx, log_warn(keymap->ctx,
"A private action has 7 data bytes; " "A private action has 7 data bytes; "
"Extra %d bytes ignored\n", len - 6); "Illegal data ignored\n");
return false; return false;
} }
@ -791,7 +717,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
return false; return false;
} }
if (ndx < 0 || ndx >= sizeof(act->data)) { if (ndx < 0 || (size_t) ndx >= sizeof(act->data)) {
log_err(keymap->ctx, log_err(keymap->ctx,
"The data for a private action is %lu bytes long; " "The data for a private action is %lu bytes long; "
"Attempt to use data[%d] ignored\n", "Attempt to use data[%d] ignored\n",
@ -800,7 +726,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
} }
if (!ExprResolveInteger(keymap->ctx, value, &datum)) if (!ExprResolveInteger(keymap->ctx, value, &datum))
return ReportMismatch(keymap, act->type, field, "integer"); return ReportMismatch(keymap->ctx, act->type, field, "integer");
if (datum < 0 || datum > 255) { if (datum < 0 || datum > 255) {
log_err(keymap->ctx, log_err(keymap->ctx,
@ -814,7 +740,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
} }
} }
return ReportIllegal(keymap, ACTION_TYPE_NONE, field); return ReportIllegal(keymap->ctx, ACTION_TYPE_NONE, field);
} }
typedef bool (*actionHandler)(struct xkb_keymap *keymap, typedef bool (*actionHandler)(struct xkb_keymap *keymap,
@ -825,12 +751,12 @@ typedef bool (*actionHandler)(struct xkb_keymap *keymap,
static const actionHandler handleAction[_ACTION_TYPE_NUM_ENTRIES] = { static const actionHandler handleAction[_ACTION_TYPE_NUM_ENTRIES] = {
[ACTION_TYPE_NONE] = HandleNoAction, [ACTION_TYPE_NONE] = HandleNoAction,
[ACTION_TYPE_MOD_SET] = HandleSetLatchMods, [ACTION_TYPE_MOD_SET] = HandleSetLatchLockMods,
[ACTION_TYPE_MOD_LATCH] = HandleSetLatchMods, [ACTION_TYPE_MOD_LATCH] = HandleSetLatchLockMods,
[ACTION_TYPE_MOD_LOCK] = HandleLockMods, [ACTION_TYPE_MOD_LOCK] = HandleSetLatchLockMods,
[ACTION_TYPE_GROUP_SET] = HandleSetLatchGroup, [ACTION_TYPE_GROUP_SET] = HandleSetLatchLockGroup,
[ACTION_TYPE_GROUP_LATCH] = HandleSetLatchGroup, [ACTION_TYPE_GROUP_LATCH] = HandleSetLatchLockGroup,
[ACTION_TYPE_GROUP_LOCK] = HandleLockGroup, [ACTION_TYPE_GROUP_LOCK] = HandleSetLatchLockGroup,
[ACTION_TYPE_PTR_MOVE] = HandleMovePtr, [ACTION_TYPE_PTR_MOVE] = HandleMovePtr,
[ACTION_TYPE_PTR_BUTTON] = HandlePtrBtn, [ACTION_TYPE_PTR_BUTTON] = HandlePtrBtn,
[ACTION_TYPE_PTR_LOCK] = HandlePtrBtn, [ACTION_TYPE_PTR_LOCK] = HandlePtrBtn,
@ -921,7 +847,6 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
return true; return true;
} }
bool bool
SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field, SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field,
ExprDef *array_ndx, ExprDef *value, ActionsInfo *info) ExprDef *array_ndx, ExprDef *value, ActionsInfo *info)

View File

@ -53,7 +53,6 @@
#include "xkbcomp-priv.h" #include "xkbcomp-priv.h"
#include "ast-build.h" #include "ast-build.h"
#include "parser-priv.h"
#include "include.h" #include "include.h"
ParseCommon * ParseCommon *
@ -202,7 +201,7 @@ ExprCreateKeysymList(xkb_keysym_t sym)
ExprDef * ExprDef *
ExprCreateMultiKeysymList(ExprDef *expr) ExprCreateMultiKeysymList(ExprDef *expr)
{ {
size_t nLevels = darray_size(expr->keysym_list.symsMapIndex); unsigned nLevels = darray_size(expr->keysym_list.symsMapIndex);
darray_resize(expr->keysym_list.symsMapIndex, 1); darray_resize(expr->keysym_list.symsMapIndex, 1);
darray_resize(expr->keysym_list.symsNumEntries, 1); darray_resize(expr->keysym_list.symsNumEntries, 1);
@ -215,7 +214,7 @@ ExprCreateMultiKeysymList(ExprDef *expr)
ExprDef * ExprDef *
ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym) ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
{ {
size_t nSyms = darray_size(expr->keysym_list.syms); unsigned nSyms = darray_size(expr->keysym_list.syms);
darray_append(expr->keysym_list.symsMapIndex, nSyms); darray_append(expr->keysym_list.symsMapIndex, nSyms);
darray_append(expr->keysym_list.symsNumEntries, 1); darray_append(expr->keysym_list.symsNumEntries, 1);
@ -227,8 +226,8 @@ ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
ExprDef * ExprDef *
ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append) ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append)
{ {
size_t nSyms = darray_size(expr->keysym_list.syms); unsigned nSyms = darray_size(expr->keysym_list.syms);
size_t numEntries = darray_size(append->keysym_list.syms); unsigned numEntries = darray_size(append->keysym_list.syms);
darray_append(expr->keysym_list.symsMapIndex, nSyms); darray_append(expr->keysym_list.symsMapIndex, nSyms);
darray_append(expr->keysym_list.symsNumEntries, numEntries); darray_append(expr->keysym_list.symsNumEntries, numEntries);
@ -356,7 +355,7 @@ SymbolsCreate(xkb_atom_t keyName, VarDef *symbols)
} }
GroupCompatDef * GroupCompatDef *
GroupCompatCreate(int group, ExprDef *val) GroupCompatCreate(unsigned group, ExprDef *val)
{ {
GroupCompatDef *def = malloc(sizeof(*def)); GroupCompatDef *def = malloc(sizeof(*def));
if (!def) if (!def)
@ -372,7 +371,7 @@ GroupCompatCreate(int group, ExprDef *val)
} }
ModMapDef * ModMapDef *
ModMapCreate(uint32_t modifier, ExprDef *keys) ModMapCreate(xkb_atom_t modifier, ExprDef *keys)
{ {
ModMapDef *def = malloc(sizeof(*def)); ModMapDef *def = malloc(sizeof(*def));
if (!def) if (!def)
@ -404,7 +403,7 @@ LedMapCreate(xkb_atom_t name, VarDef *body)
} }
LedNameDef * LedNameDef *
LedNameCreate(int ndx, ExprDef *name, bool virtual) LedNameCreate(unsigned ndx, ExprDef *name, bool virtual)
{ {
LedNameDef *def = malloc(sizeof(*def)); LedNameDef *def = malloc(sizeof(*def));
if (!def) if (!def)
@ -496,8 +495,8 @@ err:
} }
XkbFile * XkbFile *
XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name, XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs,
ParseCommon *defs, enum xkb_map_flags flags) enum xkb_map_flags flags)
{ {
XkbFile *file; XkbFile *file;
@ -533,7 +532,7 @@ XkbFileFromComponents(struct xkb_context *ctx,
if (!include) if (!include)
goto err; goto err;
file = XkbFileCreate(ctx, type, NULL, &include->common, 0); file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0);
if (!file) { if (!file) {
FreeInclude(include); FreeInclude(include);
goto err; goto err;
@ -542,7 +541,7 @@ XkbFileFromComponents(struct xkb_context *ctx,
defs = AppendStmt(defs, &file->common); defs = AppendStmt(defs, &file->common);
} }
file = XkbFileCreate(ctx, FILE_TYPE_KEYMAP, NULL, defs, 0); file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0);
if (!file) if (!file)
goto err; goto err;
@ -565,7 +564,7 @@ FreeExpr(ExprDef *expr)
case EXPR_UNARY_PLUS: case EXPR_UNARY_PLUS:
case EXPR_NOT: case EXPR_NOT:
case EXPR_INVERT: case EXPR_INVERT:
FreeStmt(&expr->unary.child->common); FreeStmt((ParseCommon *) expr->unary.child);
break; break;
case EXPR_DIVIDE: case EXPR_DIVIDE:
@ -573,16 +572,16 @@ FreeExpr(ExprDef *expr)
case EXPR_SUBTRACT: case EXPR_SUBTRACT:
case EXPR_MULTIPLY: case EXPR_MULTIPLY:
case EXPR_ASSIGN: case EXPR_ASSIGN:
FreeStmt(&expr->binary.left->common); FreeStmt((ParseCommon *) expr->binary.left);
FreeStmt(&expr->binary.right->common); FreeStmt((ParseCommon *) expr->binary.right);
break; break;
case EXPR_ACTION_DECL: case EXPR_ACTION_DECL:
FreeStmt(&expr->action.args->common); FreeStmt((ParseCommon *) expr->action.args);
break; break;
case EXPR_ARRAY_REF: case EXPR_ARRAY_REF:
FreeStmt(&expr->array_ref.entry->common); FreeStmt((ParseCommon *) expr->array_ref.entry);
break; break;
case EXPR_KEYSYM_LIST: case EXPR_KEYSYM_LIST:
@ -619,12 +618,10 @@ void
FreeStmt(ParseCommon *stmt) FreeStmt(ParseCommon *stmt)
{ {
ParseCommon *next; ParseCommon *next;
YYSTYPE u;
while (stmt) while (stmt)
{ {
next = stmt->next; next = stmt->next;
u.any = stmt;
switch (stmt->type) { switch (stmt->type) {
case STMT_INCLUDE: case STMT_INCLUDE:
@ -633,36 +630,36 @@ FreeStmt(ParseCommon *stmt)
stmt = NULL; stmt = NULL;
break; break;
case STMT_EXPR: case STMT_EXPR:
FreeExpr(u.expr); FreeExpr((ExprDef *) stmt);
break; break;
case STMT_VAR: case STMT_VAR:
FreeStmt(&u.var->name->common); FreeStmt((ParseCommon *) ((VarDef *) stmt)->name);
FreeStmt(&u.var->value->common); FreeStmt((ParseCommon *) ((VarDef *) stmt)->value);
break; break;
case STMT_TYPE: case STMT_TYPE:
FreeStmt(&u.keyType->body->common); FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body);
break; break;
case STMT_INTERP: case STMT_INTERP:
FreeStmt(&u.interp->match->common); FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match);
FreeStmt(&u.interp->def->common); FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def);
break; break;
case STMT_VMOD: case STMT_VMOD:
FreeStmt(&u.vmod->value->common); FreeStmt((ParseCommon *) ((VModDef *) stmt)->value);
break; break;
case STMT_SYMBOLS: case STMT_SYMBOLS:
FreeStmt(&u.syms->symbols->common); FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols);
break; break;
case STMT_MODMAP: case STMT_MODMAP:
FreeStmt(&u.modMask->keys->common); FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys);
break; break;
case STMT_GROUP_COMPAT: case STMT_GROUP_COMPAT:
FreeStmt(&u.groupCompat->def->common); FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def);
break; break;
case STMT_LED_MAP: case STMT_LED_MAP:
FreeStmt(&u.ledMap->body->common); FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body);
break; break;
case STMT_LED_NAME: case STMT_LED_NAME:
FreeStmt(&u.ledName->name->common); FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name);
break; break;
default: default:
break; break;

View File

@ -98,23 +98,23 @@ SymbolsDef *
SymbolsCreate(xkb_atom_t keyName, VarDef *symbols); SymbolsCreate(xkb_atom_t keyName, VarDef *symbols);
GroupCompatDef * GroupCompatDef *
GroupCompatCreate(int group, ExprDef *def); GroupCompatCreate(unsigned group, ExprDef *def);
ModMapDef * ModMapDef *
ModMapCreate(uint32_t modifier, ExprDef *keys); ModMapCreate(xkb_atom_t modifier, ExprDef *keys);
LedMapDef * LedMapDef *
LedMapCreate(xkb_atom_t name, VarDef *body); LedMapCreate(xkb_atom_t name, VarDef *body);
LedNameDef * LedNameDef *
LedNameCreate(int ndx, ExprDef *name, bool virtual); LedNameCreate(unsigned ndx, ExprDef *name, bool virtual);
IncludeStmt * IncludeStmt *
IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge); IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge);
XkbFile * XkbFile *
XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name, XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs,
ParseCommon *defs, enum xkb_map_flags flags); enum xkb_map_flags flags);
void void
FreeStmt(ParseCommon *stmt); FreeStmt(ParseCommon *stmt);

View File

@ -143,9 +143,7 @@ expr_op_type_to_string(enum expr_op_type type);
const char * const char *
expr_value_type_to_string(enum expr_value_type type); expr_value_type_to_string(enum expr_value_type type);
/* This struct contains fields common to all other AST nodes. It is only typedef struct _ParseCommon {
* ever embedded in other structs, so save some memory by packing it. */
typedef struct ATTR_PACKED _ParseCommon {
struct _ParseCommon *next; struct _ParseCommon *next;
enum stmt_type type; enum stmt_type type;
} ParseCommon; } ParseCommon;
@ -226,7 +224,7 @@ typedef struct {
typedef struct { typedef struct {
ExprCommon expr; ExprCommon expr;
darray(xkb_keysym_t) syms; darray(xkb_keysym_t) syms;
darray(int) symsMapIndex; darray(unsigned int) symsMapIndex;
darray(unsigned int) symsNumEntries; darray(unsigned int) symsNumEntries;
} ExprKeysymList; } ExprKeysymList;
@ -299,7 +297,7 @@ typedef struct {
typedef struct { typedef struct {
ParseCommon common; ParseCommon common;
enum merge_mode merge; enum merge_mode merge;
int group; unsigned group;
ExprDef *def; ExprDef *def;
} GroupCompatDef; } GroupCompatDef;
@ -314,7 +312,7 @@ typedef struct {
typedef struct { typedef struct {
ParseCommon common; ParseCommon common;
enum merge_mode merge; enum merge_mode merge;
int ndx; unsigned ndx;
ExprDef *name; ExprDef *name;
bool virtual; bool virtual;
} LedNameDef; } LedNameDef;

View File

@ -54,179 +54,6 @@
#include "vmod.h" #include "vmod.h"
#include "include.h" #include "include.h"
/*
* The xkb_compat section
* =====================
* This section is the third to be processed, after xkb_keycodes and
* xkb_types.
*
* Interpret statements
* --------------------
* Statements of the form:
* interpret Num_Lock+Any { ... }
* interpret Shift_Lock+AnyOf(Shift+Lock) { ... }
*
* The xkb_symbols section (see symbols.c) allows the keymap author to do,
* among other things, the following for each key:
* - Bind an action, like SetMods or LockGroup, to the key. Actions, like
* symbols, are specified for each level of each group in the key
* separately.
* - Add a virtual modifier to the key's virtual modifier mapping (vmodmap).
* - Specify whether the key should repeat or not.
*
* However, doing this for each key (or level) is tedious and inflexible.
* Interpret's are a mechanism to apply these settings to a bunch of
* keys/levels at once.
*
* Each interpret specifies a condition by which it attaches to certain
* levels. The condition consists of two parts:
* - A keysym. If the level has a different (or more than one) keysym, the
* match failes. Leaving out the keysym is equivalent to using the
* NoSymbol keysym, which always matches successfully.
* - A modifier predicate. The predicate consists of a matching operation
* and a mask of (real) modifiers. The modifers are matched against the
* key's modifier map (modmap). The matching operation can be one of the
* following:
* + AnyOfOrNone - The modmap must either be empty or include at least
* one of the specified modifiers.
* + AnyOf - The modmap must include at least one of the specified
* modifiers.
* + NoneOf - The modmap must not include any of the specified modifiers.
* + AllOf - The modmap must include all of the specified modifiers (but
* may include others as well).
* + Exactly - The modmap must be exactly the same as the specified
* modifiers.
* Leaving out the predicate is equivalent to usign AnyOfOrNone while
* specifying all modifiers. Leaving out just the matching condtition
* is equivalent to using Exactly.
* An interpret may also include "useModMapMods = level1;" - see below.
*
* If a level fulfils the conditions of several interpret's, only the
* most specific one is used:
* - A specific keysym will always match before a generic NoSymbol
* condition.
* - If the keysyms are the same, the interpret with the more specific
* matching operation is used. The above list is sorted from least to
* most specific.
* - If both the keysyms and the matching operations are the same (but the
* modifiers are different), the first interpret is used.
*
* As described above, once an interpret "attaches" to a level, it can bind
* an action to that level, add one virtual modifier to the key's vmodmap,
* or set the key's repeat setting. You should note the following:
* - The key repeat is a property of the entire key; it is not level-specific.
* In order to avoid confusion, it is only inspected for the first level of
* the first group; the interpret's repeat setting is ignored when applied
* to other levels.
* - If one of the above fields was set directly for a key in xkb_symbols,
* the explicit setting takes precedence over the interpret.
*
* The body of the statment may include statements of the following
* forms (all of which are optional):
*
* - useModMapMods statement:
* useModMapMods = level1;
*
* When set to 'level1', the interpret will only match levels which are
* the first level of the first group of the keys. This can be useful in
* conjunction with e.g. a virtualModifier statement.
*
* - action statement:
* action = LockMods(modifiers=NumLock);
*
* Bind this action to the matching levels.
*
* - virtual modifier statement:
* virtualModifier = NumLock;
*
* Add this virtual modifier to the key's vmodmap. The given virtual
* modifier must be declared at the top level of the file with a
* virtual_modifiers statement, e.g.:
* virtual_modifiers NumLock;
*
* - repeat statement:
* repeat = True;
*
* Set whether the key should repeat or not. Must be a boolean value.
*
* Led map statements
* ------------------------
* Statements of the form:
* indicator "Shift Lock" { ... }
*
* This statement specifies the behavior and binding of the LED (a.k.a
* indicator) with the given name ("Shift Lock" above). The name should
* have been declared previously in the xkb_keycodes section (see Led
* name statement), and given an index there. If it wasn't, it is created
* with the next free index.
* The body of the statement describes the conditions of the keyboard
* state which will cause the LED to be lit. It may include the following
* statements:
*
* - modifiers statment:
* modifiers = ScrollLock;
*
* If the given modifiers are in the required state (see below), the
* led is lit.
*
* - whichModifierState statment:
* whichModState = Latched + Locked;
*
* Can be any combination of:
* base, latched, locked, effective
* any (i.e. all of the above)
* none (i.e. none of the above)
* compat (legacy value, treated as effective)
* This will cause the respective portion of the modifer state (see
* struct xkb_state) to be matched against the modifiers given in the
* "modifiers" statement.
*
* Here's a simple example:
* indicator "Num Lock" {
* modifiers = NumLock;
* whichModState = Locked;
* };
* Whenever the NumLock modifier is locked, the Num Lock LED will light
* up.
*
* - groups statment:
* groups = All - group1;
*
* If the given groups are in the required state (see below), the led
* is lit.
*
* - whichGroupState statment:
* whichGroupState = Effective;
*
* Can be any combination of:
* base, latched, locked, effective
* any (i.e. all of the above)
* none (i.e. none of the above)
* This will cause the respective portion of the group state (see
* struct xkb_state) to be matched against the groups given in the
* "groups" statement.
*
* Note: the above conditions are disjunctive, i.e. if any of them are
* satisfied the led is lit.
*
* Virtual modifier statements
* ---------------------------
* Statements of the form:
* virtual_modifiers LControl;
*
* Can appear in the xkb_types, xkb_compat, xkb_symbols sections.
* TODO
*
* Effect on keymap
* ----------------
* After all of the xkb_compat sections have been compiled, the following
* members of struct xkb_keymap are finalized:
* darray(struct xkb_sym_interpret) sym_interprets;
* darray(struct xkb_led) leds;
* char *compat_section_name;
* TODO: virtual modifiers.
*/
enum si_field { enum si_field {
SI_FIELD_VIRTUAL_MOD = (1 << 0), SI_FIELD_VIRTUAL_MOD = (1 << 0),
SI_FIELD_ACTION = (1 << 1), SI_FIELD_ACTION = (1 << 1),
@ -555,16 +382,28 @@ MergeIncludedCompatMaps(CompatInfo *into, CompatInfo *from,
from->name = NULL; from->name = NULL;
} }
darray_foreach(si, from->interps) { if (darray_empty(into->interps)) {
si->merge = (merge == MERGE_DEFAULT ? si->merge : merge); into->interps = from->interps;
if (!AddInterp(into, si, false)) darray_init(from->interps);
into->errorCount++; }
else {
darray_foreach(si, from->interps) {
si->merge = (merge == MERGE_DEFAULT ? si->merge : merge);
if (!AddInterp(into, si, false))
into->errorCount++;
}
} }
darray_foreach(ledi, from->leds) { if (darray_empty(into->leds)) {
ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge); into->leds = from->leds;
if (!AddLedMap(into, ledi, false)) darray_init(from->leds);
into->errorCount++; }
else {
darray_foreach(ledi, from->leds) {
ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge);
if (!AddLedMap(into, ledi, false))
into->errorCount++;
}
} }
} }
@ -929,7 +768,7 @@ HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge)
ok = HandleGlobalVar(info, (VarDef *) stmt); ok = HandleGlobalVar(info, (VarDef *) stmt);
break; break;
case STMT_VMOD: case STMT_VMOD:
ok = HandleVModDef(info->keymap, (VModDef *) stmt); ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge);
break; break;
default: default:
log_err(info->keymap->ctx, log_err(info->keymap->ctx,

View File

@ -116,7 +116,7 @@ LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field,
if (ndx == XKB_MOD_INVALID) if (ndx == XKB_MOD_INVALID)
return false; return false;
*val_rtrn = (1 << ndx); *val_rtrn = (1u << ndx);
return true; return true;
} }
@ -427,14 +427,8 @@ ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr,
bool bool
ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn) ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn)
{ {
int result; return ExprResolveIntegerLookup(ctx, expr, btn_rtrn, SimpleLookup,
buttonNames);
if (!ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
buttonNames))
return false;
*btn_rtrn = result;
return true;
} }
bool bool

View File

@ -29,79 +29,6 @@
#include "expr.h" #include "expr.h"
#include "include.h" #include "include.h"
/*
* The xkb_keycodes section
* ========================
*
* This is the simplest section type, and is the first one to be
* compiled. The purpose of this is mostly to map between the
* hardware/evdev scancodes and xkb keycodes. Each key is given a name
* by which it can be referred to later, e.g. in the symbols section.
*
* Keycode statements
* ------------------
* Statements of the form:
* <TLDE> = 49;
* <AE01> = 10;
*
* The above would let 49 and 10 be valid keycodes in the keymap, and
* assign them the names TLDE and AE01 respectively. The format <WXYZ> is
* always used to refer to a key by name.
*
* [ The naming convention <AE01> just denoted the position of the key
* in the main alphanumric section of the keyboard, with the two letters
* specifying the row and the two digits specifying the column, from
* the bottom left.]
*
* In the common case this just maps to the evdev scancodes from
* /usr/include/linux/input.h, e.g. the following definitions:
* #define KEY_GRAVE 41
* #define KEY_1 2
* Similar definitions appear in the xf86-input-keyboard driver. Note
* that in all current keymaps there's a constant offset of 8 (for
* historical reasons).
*
* If there's a conflict, like the same name given to different keycodes,
* or same keycode given different names, it is resolved according to the
* merge mode which applies to the definitions.
*
* Alias statements
* ----------------
* Statements of the form:
* alias <MENU> = <COMP>;
*
* Allows to refer to a previously defined key (here <COMP>) by another
* name (here <MENU>). Conflicts are handled similarly.
*
* LED name statements
* -------------------------
* Statements of the form:
* indicator 1 = "Caps Lock";
* indicator 2 = "Num Lock";
* indicator 3 = "Scroll Lock";
*
* Assigns a name to the keyboard LED (a.k.a indicator) with the given index.
* The led may be referred by this name later in the compat section
* and by the user.
*
* Effect on the keymap
* --------------------
* After all of the xkb_keycodes sections have been compiled, the
* following members of struct xkb_keymap are finalized:
* xkb_keycode_t min_key_code;
* xkb_keycode_t max_key_code;
* unsigned int num_aliases;
* struct xkb_key_alias *key_aliases;
* char *keycodes_section_name;
* The 'name' field of leds declared in xkb_keycodes:
* darray(struct xkb_led) leds;
* Further, the array of keys:
* struct xkb_key *keys;
* had been resized to its final size (i.e. all of the xkb_key objects are
* referable by their keycode). However the objects themselves do not
* contain any useful information besides the key name at this point.
*/
typedef struct { typedef struct {
enum merge_mode merge; enum merge_mode merge;
@ -322,7 +249,7 @@ AddKeyName(KeyNamesInfo *info, xkb_keycode_t kc, xkb_atom_t name,
/***====================================================================***/ /***====================================================================***/
static int static bool
HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge); HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge);
static void static void
@ -459,7 +386,7 @@ HandleKeycodeDef(KeyNamesInfo *info, KeycodeDef *stmt, enum merge_mode merge)
return AddKeyName(info, stmt->value, stmt->name, merge, false, true); return AddKeyName(info, stmt->value, stmt->name, merge, false, true);
} }
static int static bool
HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge) HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge)
{ {
AliasInfo *old, new; AliasInfo *old, new;
@ -499,7 +426,7 @@ HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge)
return true; return true;
} }
static int static bool
HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt) HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt)
{ {
const char *elem, *field; const char *elem, *field;
@ -524,7 +451,7 @@ HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt)
return true; return true;
} }
static int static bool
HandleLedNameDef(KeyNamesInfo *info, LedNameDef *def, HandleLedNameDef(KeyNamesInfo *info, LedNameDef *def,
enum merge_mode merge) enum merge_mode merge)
{ {

View File

@ -92,7 +92,7 @@ check_write_buf(struct buf *buf, const char *fmt, ...)
if (printed < 0) if (printed < 0)
goto err; goto err;
if (printed >= available) if ((size_t) printed >= available)
if (!do_realloc(buf, printed)) if (!do_realloc(buf, printed))
goto err; goto err;
@ -103,7 +103,7 @@ check_write_buf(struct buf *buf, const char *fmt, ...)
printed = vsnprintf(buf->buf + buf->size, available, fmt, args); printed = vsnprintf(buf->buf + buf->size, available, fmt, args);
va_end(args); va_end(args);
if (printed >= available || printed < 0) if (printed < 0 || (size_t) printed >= available)
goto err; goto err;
buf->size += printed; buf->size += printed;
@ -273,6 +273,20 @@ write_led_map(struct xkb_keymap *keymap, struct buf *buf,
return true; 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 static bool
write_action(struct xkb_keymap *keymap, struct buf *buf, write_action(struct xkb_keymap *keymap, struct buf *buf,
const union xkb_action *action, const union xkb_action *action,
@ -289,20 +303,17 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
type = ActionTypeText(action->type); type = ActionTypeText(action->type);
switch (action->type) { switch (action->type) {
case ACTION_TYPE_MOD_LOCK:
case ACTION_TYPE_MOD_SET: case ACTION_TYPE_MOD_SET:
case ACTION_TYPE_MOD_LATCH: case ACTION_TYPE_MOD_LATCH:
case ACTION_TYPE_MOD_LOCK:
if (action->mods.flags & ACTION_MODS_LOOKUP_MODMAP) if (action->mods.flags & ACTION_MODS_LOOKUP_MODMAP)
args = "modMapMods"; args = "modMapMods";
else else
args = ModMaskText(keymap, action->mods.mods.mods); args = ModMaskText(keymap, action->mods.mods.mods);
write_buf(buf, "%s%s(modifiers=%s%s%s)%s", prefix, type, args, write_buf(buf, "%s%s(modifiers=%s%s%s%s)%s", prefix, type, args,
(action->type != ACTION_TYPE_MOD_LOCK && (action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "",
(action->mods.flags & ACTION_LOCK_CLEAR)) ? (action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "",
",clearLocks" : "", (action->type == ACTION_TYPE_MOD_LOCK) ? affect_lock_text(action->mods.flags) : "",
(action->type != ACTION_TYPE_MOD_LOCK &&
(action->mods.flags & ACTION_LATCH_TO_LOCK)) ?
",latchToLock" : "",
suffix); suffix);
break; break;
@ -310,16 +321,10 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
case ACTION_TYPE_GROUP_LATCH: case ACTION_TYPE_GROUP_LATCH:
case ACTION_TYPE_GROUP_LOCK: case ACTION_TYPE_GROUP_LOCK:
write_buf(buf, "%s%s(group=%s%d%s%s)%s", prefix, type, write_buf(buf, "%s%s(group=%s%d%s%s)%s", prefix, type,
(!(action->group.flags & ACTION_ABSOLUTE_SWITCH) && (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) && action->group.group > 0) ? "+" : "",
action->group.group > 0) ? "+" : "", (action->group.flags & ACTION_ABSOLUTE_SWITCH) ? action->group.group + 1 : action->group.group,
(action->group.flags & ACTION_ABSOLUTE_SWITCH) ? (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "",
action->group.group + 1 : action->group.group, (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "",
(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); suffix);
break; break;
@ -329,35 +334,17 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
case ACTION_TYPE_PTR_MOVE: case ACTION_TYPE_PTR_MOVE:
write_buf(buf, "%s%s(x=%s%d,y=%s%d%s)%s", prefix, type, write_buf(buf, "%s%s(x=%s%d,y=%s%d%s)%s", prefix, type,
(!(action->ptr.flags & ACTION_ABSOLUTE_X) && (!(action->ptr.flags & ACTION_ABSOLUTE_X) && action->ptr.x >= 0) ? "+" : "",
action->ptr.x >= 0) ? "+" : "",
action->ptr.x, action->ptr.x,
(!(action->ptr.flags & ACTION_ABSOLUTE_Y) && (!(action->ptr.flags & ACTION_ABSOLUTE_Y) && action->ptr.y >= 0) ? "+" : "",
action->ptr.y >= 0) ? "+" : "",
action->ptr.y, action->ptr.y,
(action->ptr.flags & ACTION_NO_ACCEL) ? ",!accel" : "", (action->ptr.flags & ACTION_ACCEL) ? "" : ",!accel",
suffix); suffix);
break; break;
case ACTION_TYPE_PTR_LOCK: case ACTION_TYPE_PTR_LOCK:
switch (action->btn.flags & args = affect_lock_text(action->btn.flags);
(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) { /* fallthrough */
case ACTION_LOCK_NO_UNLOCK:
args = ",affect=lock";
break;
case ACTION_LOCK_NO_LOCK:
args = ",affect=unlock";
break;
case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK:
args = ",affect=neither";
break;
default:
args = ",affect=both";
break;
}
case ACTION_TYPE_PTR_BUTTON: case ACTION_TYPE_PTR_BUTTON:
write_buf(buf, "%s%s(button=", prefix, type); write_buf(buf, "%s%s(button=", prefix, type);
if (action->btn.button > 0 && action->btn.button <= 5) if (action->btn.button > 0 && action->btn.button <= 5)
@ -374,25 +361,25 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
case ACTION_TYPE_PTR_DEFAULT: case ACTION_TYPE_PTR_DEFAULT:
write_buf(buf, "%s%s(", prefix, type); write_buf(buf, "%s%s(", prefix, type);
write_buf(buf, "affect=button,button=%s%d", write_buf(buf, "affect=button,button=%s%d",
(!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) && (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) && action->dflt.value >= 0) ? "+" : "",
action->dflt.value >= 0) ? "+" : "",
action->dflt.value); action->dflt.value);
write_buf(buf, ")%s", suffix); write_buf(buf, ")%s", suffix);
break; break;
case ACTION_TYPE_SWITCH_VT: case ACTION_TYPE_SWITCH_VT:
write_buf(buf, "%s%s(screen=%s%d,%ssame)%s", prefix, type, write_buf(buf, "%s%s(screen=%s%d,%ssame)%s", prefix, type,
(!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) && (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) && action->screen.screen >= 0) ? "+" : "",
action->screen.screen >= 0) ? "+" : "",
action->screen.screen, action->screen.screen,
(action->screen.flags & ACTION_SAME_SCREEN) ? "!" : "", (action->screen.flags & ACTION_SAME_SCREEN) ? "" : "!",
suffix); suffix);
break; break;
case ACTION_TYPE_CTRL_SET: case ACTION_TYPE_CTRL_SET:
case ACTION_TYPE_CTRL_LOCK: case ACTION_TYPE_CTRL_LOCK:
write_buf(buf, "%s%s(controls=%s)%s", prefix, type, write_buf(buf, "%s%s(controls=%s%s)%s", prefix, type,
ControlMaskText(keymap->ctx, action->ctrls.ctrls), suffix); ControlMaskText(keymap->ctx, action->ctrls.ctrls),
(action->type == ACTION_TYPE_CTRL_LOCK) ? affect_lock_text(action->ctrls.flags) : "",
suffix);
break; break;
case ACTION_TYPE_NONE: case ACTION_TYPE_NONE:
@ -429,7 +416,7 @@ write_compat(struct xkb_keymap *keymap, struct buf *buf)
write_buf(buf, "\tinterpret.useModMapMods= AnyLevel;\n"); write_buf(buf, "\tinterpret.useModMapMods= AnyLevel;\n");
write_buf(buf, "\tinterpret.repeat= False;\n"); write_buf(buf, "\tinterpret.repeat= False;\n");
for (int i = 0; i < keymap->num_sym_interprets; i++) { for (unsigned i = 0; i < keymap->num_sym_interprets; i++) {
const struct xkb_sym_interpret *si = &keymap->sym_interprets[i]; const struct xkb_sym_interpret *si = &keymap->sym_interprets[i];
write_buf(buf, "\tinterpret %s+%s(%s) {\n", write_buf(buf, "\tinterpret %s+%s(%s) {\n",
@ -635,7 +622,7 @@ write_symbols(struct xkb_keymap *keymap, struct buf *buf)
continue; continue;
darray_enumerate(i, mod, keymap->mods) darray_enumerate(i, mod, keymap->mods)
if (key->modmap & (1 << i)) if (key->modmap & (1u << i))
write_buf(buf, "\tmodifier_map %s { %s };\n", write_buf(buf, "\tmodifier_map %s { %s };\n",
xkb_atom_text(keymap->ctx, mod->name), xkb_atom_text(keymap->ctx, mod->name),
KeyNameText(keymap->ctx, key->name)); KeyNameText(keymap->ctx, key->name));

View File

@ -39,7 +39,7 @@ ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods)
mods->mask = mods->mods & MOD_REAL_MASK_ALL; mods->mask = mods->mods & MOD_REAL_MASK_ALL;
darray_enumerate(i, mod, keymap->mods) darray_enumerate(i, mod, keymap->mods)
if (mods->mods & (1 << i)) if (mods->mods & (1u << i))
mods->mask |= mod->mapping; mods->mask |= mod->mapping;
} }
@ -92,7 +92,7 @@ FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
* sym_interprets array from the most specific to the least specific, * sym_interprets array from the most specific to the least specific,
* such that when we find a match we return immediately. * such that when we find a match we return immediately.
*/ */
for (int i = 0; i < keymap->num_sym_interprets; i++) { for (unsigned i = 0; i < keymap->num_sym_interprets; i++) {
const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i]; const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i];
xkb_mod_mask_t mods; xkb_mod_mask_t mods;
@ -158,7 +158,7 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
if ((group == 0 && level == 0) || !interp->level_one_only) if ((group == 0 && level == 0) || !interp->level_one_only)
if (interp->virtual_mod != XKB_MOD_INVALID) if (interp->virtual_mod != XKB_MOD_INVALID)
vmodmap |= (1 << interp->virtual_mod); vmodmap |= (1u << interp->virtual_mod);
if (interp->action.type != ACTION_TYPE_NONE) if (interp->action.type != ACTION_TYPE_NONE)
key->groups[group].levels[level].action = interp->action; key->groups[group].levels[level].action = interp->action;
@ -194,7 +194,7 @@ UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
/* Update keymap->mods, the virtual -> real mod mapping. */ /* Update keymap->mods, the virtual -> real mod mapping. */
xkb_foreach_key(key, keymap) xkb_foreach_key(key, keymap)
darray_enumerate(i, mod, keymap->mods) darray_enumerate(i, mod, keymap->mods)
if (key->vmodmap & (1 << i)) if (key->vmodmap & (1u << i))
mod->mapping |= key->modmap; mod->mapping |= key->modmap;
/* Now update the level masks for all the types to reflect the vmods. */ /* Now update the level masks for all the types to reflect the vmods. */

View File

@ -339,10 +339,9 @@ keyword_gperf_lookup (register const char *str, register unsigned int len)
int int
keyword_to_token(const char *string) keyword_to_token(const char *string, unsigned int len)
{ {
const struct keyword_tok *kt; const struct keyword_tok *kt = keyword_gperf_lookup(string, len);
kt = keyword_gperf_lookup(string, strlen(string));
if (!kt) if (!kt)
return -1; return -1;
return kt->tok; return kt->tok;

View File

@ -27,24 +27,18 @@
#ifndef XKBCOMP_PARSER_PRIV_H #ifndef XKBCOMP_PARSER_PRIV_H
#define XKBCOMP_PARSER_PRIV_H #define XKBCOMP_PARSER_PRIV_H
struct scanner;
struct parser_param; struct parser_param;
#include "scanner-utils.h"
#include "parser.h" #include "parser.h"
int
scanner_error(struct scanner *scanner, const char *msg);
void
scanner_warn(struct scanner *s, const char *msg);
int int
_xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner); _xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner);
XkbFile * XkbFile *
parse(struct xkb_context *ctx, void *scanner, const char *map); parse(struct xkb_context *ctx, struct scanner *scanner, const char *map);
int int
keyword_to_token(const char *string); keyword_to_token(const char *string, unsigned int len);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -175,7 +175,7 @@ typedef union YYSTYPE
{ {
/* Line 2068 of yacc.c */ /* Line 2068 of yacc.c */
#line 167 "parser.y" #line 161 "parser.y"
int ival; int ival;
int64_t num; int64_t num;

View File

@ -52,84 +52,6 @@
#include "include.h" #include "include.h"
#include "scanner-utils.h" #include "scanner-utils.h"
/*
* The rules file
* ==============
* The purpose of this file is to map between configuration values that
* are easy for a user to specify and understand, and the configuration
* values xkbcomp uses and understands.
* xkbcomp uses the xkb_component_names struct, which maps directly to
* include statements of the appropriate sections, called for short
* KcCGST (see keycodes.c, types.c, compat.c, symbols.c; geometry.c was
* removed). These are not really intuitive or straight-forward for
* the uninitiated.
* Instead, the user passes in a xkb_rule_names struct, which consists
* of the name of a rules file (in Linux this is usually "evdev"), a
* keyboard model (e.g. "pc105"), a set of layouts (which will end up
* in different groups, e.g. "us,fr"), variants (used to alter/augment
* the respective layout, e.g. "intl,dvorak"), and a set of options
* (used to tweak some general behavior of the keyboard, e.g.
* "ctrl:nocaps,compose:menu" to make the Caps Lock key act like Ctrl
* and the Menu key like Compose). We call these RMLVO.
*
* Format of the file
* ------------------
* The file consists of rule sets, each consisting of rules (one per
* line), which match the MLVO values on the left hand side, and, if
* the values match to the values the user passed in, results in the
* values on the right hand side being added to the resulting KcCGST.
* Since some values are related and repeated often, it is possible
* to group them together and refer to them by a group name in the
* rules.
* Along with matching values by simple string equality, and for
* membership in a group defined previously, rules may also contain
* "wildcard" values - "*" - which always match. These usually appear
* near the end.
*
* Grammer
* -------
* (It might be helpful to look at a file like rules/evdev along with
* this grammer. Comments, whitespace, etc. are not shown.)
*
* File ::= { "!" (Group | RuleSet) }
*
* Group ::= GroupName "=" { GroupElement } "\n"
* GroupName ::= "$"<ident>
* GroupElement ::= <ident>
*
* RuleSet ::= Mapping { Rule }
*
* Mapping ::= { Mlvo } "=" { Kccgst } "\n"
* Mlvo ::= "model" | "option" | ("layout" | "variant") [ Index ]
* Index ::= "[" 1..XKB_NUM_GROUPS "]"
* Kccgst ::= "keycodes" | "symbols" | "types" | "compat" | "geometry"
*
* Rule ::= { MlvoValue } "=" { KccgstValue } "\n"
* MlvoValue ::= "*" | GroupName | <ident>
* KccgstValue ::= <ident>
*
* Notes:
* - The order of values in a Rule must be the same as the Mapping it
* follows. The mapping line determines the meaning of the values in
* the rules which follow in the RuleSet.
* - If a Rule is matched, %-expansion is performed on the KccgstValue,
* as follows:
* %m, %l, %v:
* The model, layout or variant, if only one was given (e.g.
* %l for "us,il" is invalid).
* %l[1], %v[1]:
* Layout or variant for the specified group Index, if more than
* one was given (e.g. %l[1] for "us" is invalid).
* %+m, %+l, %+v, %+l[1], %+v[1]
* As above, but prefixed with '+'. Similarly, '|', '-', '_' may be
* used instead of '+'.
* %(m), %(l), %(l[1]), %(v), %(v[1]):
* As above, but prefixed by '(' and suffixed by ')'.
* In case the expansion is invalid, as described above, it is
* skipped (the rest of the string is still processed); this includes
* the prefix and suffix (that's why you shouldn't use e.g. "(%v[1])").
*/
/* Scanner / Lexer */ /* Scanner / Lexer */
/* Values returned with some tokens, like yylval. */ /* Values returned with some tokens, like yylval. */
@ -137,14 +59,6 @@ union lvalue {
struct sval string; struct sval string;
}; };
/*
* Holds the location in the file of the last processed token,
* like yylloc.
*/
struct location {
int line, column;
};
enum rules_token { enum rules_token {
TOK_END_OF_FILE = 0, TOK_END_OF_FILE = 0,
TOK_END_OF_LINE, TOK_END_OF_LINE,
@ -156,14 +70,6 @@ enum rules_token {
TOK_ERROR TOK_ERROR
}; };
/* C99 is stupid. Just use the 1 variant when there are no args. */
#define scanner_error1(scanner, loc, msg) \
log_warn((scanner)->ctx, "rules/%s:%d:%d: %s\n", \
(scanner)->file_name, (loc)->line, (loc)->column, msg)
#define scanner_error(scanner, loc, fmt, ...) \
log_warn((scanner)->ctx, "rules/%s:%d:%d: " fmt "\n", \
(scanner)->file_name, (loc)->line, (loc)->column, __VA_ARGS__)
static inline bool static inline bool
is_ident(char ch) is_ident(char ch)
{ {
@ -171,7 +77,7 @@ is_ident(char ch)
} }
static enum rules_token static enum rules_token
lex(struct scanner *s, union lvalue *val, struct location *loc) lex(struct scanner *s, union lvalue *val)
{ {
skip_more_whitespace_and_comments: skip_more_whitespace_and_comments:
/* Skip spaces. */ /* Skip spaces. */
@ -191,8 +97,7 @@ skip_more_whitespace_and_comments:
/* Escaped line continuation. */ /* Escaped line continuation. */
if (chr(s, '\\')) { if (chr(s, '\\')) {
if (!eol(s)) { if (!eol(s)) {
scanner_error1(s, loc, scanner_err(s, "illegal new line escape; must appear at end of line");
"illegal new line escape; must appear at end of line");
return TOK_ERROR; return TOK_ERROR;
} }
next(s); next(s);
@ -203,8 +108,8 @@ skip_more_whitespace_and_comments:
if (eof(s)) return TOK_END_OF_FILE; if (eof(s)) return TOK_END_OF_FILE;
/* New token. */ /* New token. */
loc->line = s->line; s->token_line = s->line;
loc->column = s->column; s->token_column = s->column;
/* Operators and punctuation. */ /* Operators and punctuation. */
if (chr(s, '!')) return TOK_BANG; if (chr(s, '!')) return TOK_BANG;
@ -220,8 +125,7 @@ skip_more_whitespace_and_comments:
val->string.len++; val->string.len++;
} }
if (val->string.len == 0) { if (val->string.len == 0) {
scanner_error1(s, loc, scanner_err(s, "unexpected character after \'$\'; expected name");
"unexpected character after \'$\'; expected name");
return TOK_ERROR; return TOK_ERROR;
} }
return TOK_GROUP_NAME; return TOK_GROUP_NAME;
@ -238,7 +142,7 @@ skip_more_whitespace_and_comments:
return TOK_IDENTIFIER; return TOK_IDENTIFIER;
} }
scanner_error1(s, loc, "unrecognized token"); scanner_err(s, "unrecognized token");
return TOK_ERROR; return TOK_ERROR;
} }
@ -330,7 +234,6 @@ struct matcher {
struct xkb_context *ctx; struct xkb_context *ctx;
/* Input.*/ /* Input.*/
struct rule_names rmlvo; struct rule_names rmlvo;
struct location loc;
union lvalue val; union lvalue val;
struct scanner scanner; struct scanner scanner;
darray(struct group) groups; darray(struct group) groups;
@ -410,10 +313,8 @@ matcher_free(struct matcher *m)
free(m); free(m);
} }
#define matcher_error1(matcher, msg) \ #define matcher_err(matcher, fmt, ...) \
scanner_error1(&(matcher)->scanner, &(matcher)->loc, msg) scanner_err(&(matcher)->scanner, fmt, ## __VA_ARGS__)
#define matcher_error(matcher, fmt, ...) \
scanner_error(&(matcher)->scanner, &(matcher)->loc, fmt, __VA_ARGS__)
static void static void
matcher_group_start_new(struct matcher *m, struct sval name) matcher_group_start_new(struct matcher *m, struct sval name)
@ -474,19 +375,15 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident)
/* Not found. */ /* Not found. */
if (mlvo >= _MLVO_NUM_ENTRIES) { if (mlvo >= _MLVO_NUM_ENTRIES) {
matcher_error(m, matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set",
"invalid mapping: %.*s is not a valid value here; " ident.len, ident.start);
"ignoring rule set",
ident.len, ident.start);
m->mapping.skip = true; m->mapping.skip = true;
return; return;
} }
if (m->mapping.defined_mlvo_mask & (1 << mlvo)) { if (m->mapping.defined_mlvo_mask & (1u << mlvo)) {
matcher_error(m, matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set",
"invalid mapping: %.*s appears twice on the same line; " mlvo_sval.len, mlvo_sval.start);
"ignoring rule set",
mlvo_sval.len, mlvo_sval.start);
m->mapping.skip = true; m->mapping.skip = true;
return; return;
} }
@ -497,10 +394,8 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident)
int consumed = extract_layout_index(ident.start + mlvo_sval.len, int consumed = extract_layout_index(ident.start + mlvo_sval.len,
ident.len - mlvo_sval.len, &idx); ident.len - mlvo_sval.len, &idx);
if ((int) (ident.len - mlvo_sval.len) != consumed) { if ((int) (ident.len - mlvo_sval.len) != consumed) {
matcher_error(m, matcher_err(m, "invalid mapping: \"%.*s\" may only be followed by a valid group index; ignoring rule set",
"invalid mapping:\" %.*s\" may only be followed by a valid group index; " mlvo_sval.len, mlvo_sval.start);
"ignoring rule set",
mlvo_sval.len, mlvo_sval.start);
m->mapping.skip = true; m->mapping.skip = true;
return; return;
} }
@ -512,17 +407,15 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident)
m->mapping.variant_idx = idx; m->mapping.variant_idx = idx;
} }
else { else {
matcher_error(m, matcher_err(m, "invalid mapping: \"%.*s\" cannot be followed by a group index; ignoring rule set",
"invalid mapping: \"%.*s\" cannot be followed by a group index; " mlvo_sval.len, mlvo_sval.start);
"ignoring rule set",
mlvo_sval.len, mlvo_sval.start);
m->mapping.skip = true; m->mapping.skip = true;
return; return;
} }
} }
m->mapping.mlvo_at_pos[m->mapping.num_mlvo] = mlvo; m->mapping.mlvo_at_pos[m->mapping.num_mlvo] = mlvo;
m->mapping.defined_mlvo_mask |= 1 << mlvo; m->mapping.defined_mlvo_mask |= 1u << mlvo;
m->mapping.num_mlvo++; m->mapping.num_mlvo++;
} }
@ -541,25 +434,21 @@ matcher_mapping_set_kccgst(struct matcher *m, struct sval ident)
/* Not found. */ /* Not found. */
if (kccgst >= _KCCGST_NUM_ENTRIES) { if (kccgst >= _KCCGST_NUM_ENTRIES) {
matcher_error(m, matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set",
"invalid mapping: %.*s is not a valid value here; " ident.len, ident.start);
"ignoring rule set",
ident.len, ident.start);
m->mapping.skip = true; m->mapping.skip = true;
return; return;
} }
if (m->mapping.defined_kccgst_mask & (1 << kccgst)) { if (m->mapping.defined_kccgst_mask & (1u << kccgst)) {
matcher_error(m, matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set",
"invalid mapping: %.*s appears twice on the same line; " kccgst_sval.len, kccgst_sval.start);
"ignoring rule set",
kccgst_sval.len, kccgst_sval.start);
m->mapping.skip = true; m->mapping.skip = true;
return; return;
} }
m->mapping.kccgst_at_pos[m->mapping.num_kccgst] = kccgst; m->mapping.kccgst_at_pos[m->mapping.num_kccgst] = kccgst;
m->mapping.defined_kccgst_mask |= 1 << kccgst; m->mapping.defined_kccgst_mask |= 1u << kccgst;
m->mapping.num_kccgst++; m->mapping.num_kccgst++;
} }
@ -567,16 +456,12 @@ static void
matcher_mapping_verify(struct matcher *m) matcher_mapping_verify(struct matcher *m)
{ {
if (m->mapping.num_mlvo == 0) { if (m->mapping.num_mlvo == 0) {
matcher_error1(m, matcher_err(m, "invalid mapping: must have at least one value on the left hand side; ignoring rule set");
"invalid mapping: must have at least one value on the left hand side; "
"ignoring rule set");
goto skip; goto skip;
} }
if (m->mapping.num_kccgst == 0) { if (m->mapping.num_kccgst == 0) {
matcher_error1(m, matcher_err(m, "invalid mapping: must have at least one value on the right hand side; ignoring rule set");
"invalid mapping: must have at least one value on the right hand side; "
"ignoring rule set");
goto skip; goto skip;
} }
@ -585,7 +470,7 @@ matcher_mapping_verify(struct matcher *m)
* See the "Notes" section in the overview above. * See the "Notes" section in the overview above.
*/ */
if (m->mapping.defined_mlvo_mask & (1 << MLVO_LAYOUT)) { if (m->mapping.defined_mlvo_mask & (1u << MLVO_LAYOUT)) {
if (m->mapping.layout_idx == XKB_LAYOUT_INVALID) { if (m->mapping.layout_idx == XKB_LAYOUT_INVALID) {
if (darray_size(m->rmlvo.layouts) > 1) if (darray_size(m->rmlvo.layouts) > 1)
goto skip; goto skip;
@ -597,7 +482,7 @@ matcher_mapping_verify(struct matcher *m)
} }
} }
if (m->mapping.defined_mlvo_mask & (1 << MLVO_VARIANT)) { if (m->mapping.defined_mlvo_mask & (1u << MLVO_VARIANT)) {
if (m->mapping.variant_idx == XKB_LAYOUT_INVALID) { if (m->mapping.variant_idx == XKB_LAYOUT_INVALID) {
if (darray_size(m->rmlvo.variants) > 1) if (darray_size(m->rmlvo.variants) > 1)
goto skip; goto skip;
@ -627,9 +512,7 @@ matcher_rule_set_mlvo_common(struct matcher *m, struct sval ident,
enum mlvo_match_type match_type) enum mlvo_match_type match_type)
{ {
if (m->rule.num_mlvo_values + 1 > m->mapping.num_mlvo) { if (m->rule.num_mlvo_values + 1 > m->mapping.num_mlvo) {
matcher_error1(m, matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule");
"invalid rule: has more values than the mapping line; "
"ignoring rule");
m->rule.skip = true; m->rule.skip = true;
return; return;
} }
@ -661,9 +544,7 @@ static void
matcher_rule_set_kccgst(struct matcher *m, struct sval ident) matcher_rule_set_kccgst(struct matcher *m, struct sval ident)
{ {
if (m->rule.num_kccgst_values + 1 > m->mapping.num_kccgst) { if (m->rule.num_kccgst_values + 1 > m->mapping.num_kccgst) {
matcher_error1(m, matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule");
"invalid rule: has more values than the mapping line; "
"ignoring rule");
m->rule.skip = true; m->rule.skip = true;
return; return;
} }
@ -720,20 +601,10 @@ static bool
append_expanded_kccgst_value(struct matcher *m, darray_char *to, append_expanded_kccgst_value(struct matcher *m, darray_char *to,
struct sval value) struct sval value)
{ {
const size_t original_size = darray_size(*to);
const char *s = value.start; const char *s = value.start;
darray_char expanded = darray_new();
/* char ch;
* Appending bar to foo -> foo (not an error if this happens) bool expanded_plus, to_plus;
* Appending +bar to foo -> foo+bar
* Appending bar to +foo -> bar+foo
* Appending +bar to +foo -> +foo+bar
*/
if (!darray_empty(*to) && s[0] != '+' && s[0] != '|') {
if (darray_item(*to, 0) == '+' || darray_item(*to, 0) == '|')
darray_prepend_items_nullterminate(*to, value.start, value.len);
return true;
}
/* /*
* Some ugly hand-lexing here, but going through the scanner is more * Some ugly hand-lexing here, but going through the scanner is more
@ -743,12 +614,12 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to,
enum rules_mlvo mlv; enum rules_mlvo mlv;
xkb_layout_index_t idx; xkb_layout_index_t idx;
char pfx, sfx; char pfx, sfx;
struct sval expanded; struct sval expanded_value;
/* Check if that's a start of an expansion. */ /* Check if that's a start of an expansion. */
if (s[i] != '%') { if (s[i] != '%') {
/* Just a normal character. */ /* Just a normal character. */
darray_append_items_nullterminate(*to, &s[i++], 1); darray_appends_nullterminate(expanded, &s[i++], 1);
continue; continue;
} }
if (++i >= value.len) goto error; if (++i >= value.len) goto error;
@ -777,9 +648,7 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to,
int consumed; int consumed;
if (mlv != MLVO_LAYOUT && mlv != MLVO_VARIANT) { if (mlv != MLVO_LAYOUT && mlv != MLVO_VARIANT) {
matcher_error1(m, matcher_err(m, "invalid index in %%-expansion; may only index layout or variant");
"invalid index in %%-expansion; "
"may only index layout or variant");
goto error; goto error;
} }
@ -795,46 +664,65 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to,
} }
/* Get the expanded value. */ /* Get the expanded value. */
expanded.len = 0; expanded_value.len = 0;
if (mlv == MLVO_LAYOUT) { if (mlv == MLVO_LAYOUT) {
if (idx != XKB_LAYOUT_INVALID && if (idx != XKB_LAYOUT_INVALID &&
idx < darray_size(m->rmlvo.layouts) && idx < darray_size(m->rmlvo.layouts) &&
darray_size(m->rmlvo.layouts) > 1) darray_size(m->rmlvo.layouts) > 1)
expanded = darray_item(m->rmlvo.layouts, idx); expanded_value = darray_item(m->rmlvo.layouts, idx);
else if (idx == XKB_LAYOUT_INVALID && else if (idx == XKB_LAYOUT_INVALID &&
darray_size(m->rmlvo.layouts) == 1) darray_size(m->rmlvo.layouts) == 1)
expanded = darray_item(m->rmlvo.layouts, 0); expanded_value = darray_item(m->rmlvo.layouts, 0);
} }
else if (mlv == MLVO_VARIANT) { else if (mlv == MLVO_VARIANT) {
if (idx != XKB_LAYOUT_INVALID && if (idx != XKB_LAYOUT_INVALID &&
idx < darray_size(m->rmlvo.variants) && idx < darray_size(m->rmlvo.variants) &&
darray_size(m->rmlvo.variants) > 1) darray_size(m->rmlvo.variants) > 1)
expanded = darray_item(m->rmlvo.variants, idx); expanded_value = darray_item(m->rmlvo.variants, idx);
else if (idx == XKB_LAYOUT_INVALID && else if (idx == XKB_LAYOUT_INVALID &&
darray_size(m->rmlvo.variants) == 1) darray_size(m->rmlvo.variants) == 1)
expanded = darray_item(m->rmlvo.variants, 0); expanded_value = darray_item(m->rmlvo.variants, 0);
} }
else if (mlv == MLVO_MODEL) { else if (mlv == MLVO_MODEL) {
expanded = m->rmlvo.model; expanded_value = m->rmlvo.model;
} }
/* If we didn't get one, skip silently. */ /* If we didn't get one, skip silently. */
if (expanded.len <= 0) if (expanded_value.len <= 0)
continue; continue;
if (pfx != 0) if (pfx != 0)
darray_append_items_nullterminate(*to, &pfx, 1); darray_appends_nullterminate(expanded, &pfx, 1);
darray_append_items_nullterminate(*to, expanded.start, expanded.len); darray_appends_nullterminate(expanded,
expanded_value.start, expanded_value.len);
if (sfx != 0) if (sfx != 0)
darray_append_items_nullterminate(*to, &sfx, 1); darray_appends_nullterminate(expanded, &sfx, 1);
} }
/*
* Appending bar to foo -> foo (not an error if this happens)
* Appending +bar to foo -> foo+bar
* Appending bar to +foo -> bar+foo
* Appending +bar to +foo -> +foo+bar
*/
ch = (darray_empty(expanded) ? '\0' : darray_item(expanded, 0));
expanded_plus = (ch == '+' || ch == '|');
ch = (darray_empty(*to) ? '\0' : darray_item(*to, 0));
to_plus = (ch == '+' || ch == '|');
if (expanded_plus || darray_empty(*to))
darray_appends_nullterminate(*to, expanded.item, expanded.size);
else if (to_plus)
darray_prepends_nullterminate(*to, expanded.item, expanded.size);
darray_free(expanded);
return true; return true;
error: error:
matcher_error1(m, "invalid %%-expansion in value; not used"); darray_free(expanded);
darray_resize(*to, original_size); matcher_err(m, "invalid %%-expansion in value; not used");
return false; return false;
} }
@ -843,9 +731,7 @@ matcher_rule_verify(struct matcher *m)
{ {
if (m->rule.num_mlvo_values != m->mapping.num_mlvo || if (m->rule.num_mlvo_values != m->mapping.num_mlvo ||
m->rule.num_kccgst_values != m->mapping.num_kccgst) { m->rule.num_kccgst_values != m->mapping.num_kccgst) {
matcher_error1(m, matcher_err(m, "invalid rule: must have same number of values as mapping line; ignoring rule");
"invalid rule: must have same number of values as mapping line;"
"ignoring rule");
m->rule.skip = true; m->rule.skip = true;
} }
} }
@ -907,7 +793,7 @@ matcher_rule_apply_if_matches(struct matcher *m)
static enum rules_token static enum rules_token
gettok(struct matcher *m) gettok(struct matcher *m)
{ {
return lex(&m->scanner, &m->val, &m->loc); return lex(&m->scanner, &m->val);
} }
static bool static bool
@ -1068,7 +954,7 @@ finish:
return true; return true;
state_error: state_error:
matcher_error1(m, "unexpected token"); matcher_err(m, "unexpected token");
error: error:
return false; return false;
} }
@ -1091,12 +977,13 @@ xkb_components_from_rules(struct xkb_context *ctx,
ret = map_file(file, &string, &size); ret = map_file(file, &string, &size);
if (!ret) { if (!ret) {
log_err(ctx, "Couldn't read rules file: %s\n", strerror(errno)); log_err(ctx, "Couldn't read rules file \"%s\": %s\n",
path, strerror(errno));
goto err_file; goto err_file;
} }
matcher = matcher_new(ctx, rmlvo); matcher = matcher_new(ctx, rmlvo);
ret = matcher_match(matcher, string, size, rmlvo->rules, out); ret = matcher_match(matcher, string, size, path, out);
if (!ret) if (!ret)
log_err(ctx, "No components returned from XKB rules \"%s\"\n", path); log_err(ctx, "No components returned from XKB rules \"%s\"\n", path);
matcher_free(matcher); matcher_free(matcher);

View File

@ -23,27 +23,6 @@
#include "xkbcomp-priv.h" #include "xkbcomp-priv.h"
#include "parser-priv.h" #include "parser-priv.h"
#include "scanner-utils.h"
static void
scanner_log(enum xkb_log_level level, struct scanner *s, const char *msg)
{
xkb_log(s->ctx, level, 0, "%s:%d:%d: %s\n", s->file_name,
s->token_line, s->token_column, msg);
}
int
scanner_error(struct scanner *s, const char *msg)
{
scanner_log(XKB_LOG_LEVEL_ERROR, s, msg);
return ERROR_TOK;
}
void
scanner_warn(struct scanner *s, const char *msg)
{
scanner_log(XKB_LOG_LEVEL_WARNING, s, msg);
}
static bool static bool
number(struct scanner *s, int64_t *out, int *out_tok) number(struct scanner *s, int64_t *out, int *out_tok)
@ -123,11 +102,13 @@ skip_more_whitespace_and_comments:
buf_append(s, next(s)); buf_append(s, next(s));
} }
} }
if (!buf_append(s, '\0') || !chr(s, '\"')) if (!buf_append(s, '\0') || !chr(s, '\"')) {
return scanner_error(s, "unterminated string literal"); scanner_err(s, "unterminated string literal");
return ERROR_TOK;
}
yylval->str = strdup(s->buf); yylval->str = strdup(s->buf);
if (!yylval->str) if (!yylval->str)
return scanner_error(s, "scanner out of memory"); return ERROR_TOK;
return STRING; return STRING;
} }
@ -135,8 +116,10 @@ skip_more_whitespace_and_comments:
if (chr(s, '<')) { if (chr(s, '<')) {
while (is_graph(peek(s)) && peek(s) != '>') while (is_graph(peek(s)) && peek(s) != '>')
buf_append(s, next(s)); buf_append(s, next(s));
if (!buf_append(s, '\0') || !chr(s, '>')) if (!buf_append(s, '\0') || !chr(s, '>')) {
return scanner_error(s, "unterminated key name literal"); scanner_err(s, "unterminated key name literal");
return ERROR_TOK;
}
/* Empty key name literals are allowed. */ /* Empty key name literals are allowed. */
yylval->sval = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1); yylval->sval = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1);
return KEYNAME; return KEYNAME;
@ -165,27 +148,32 @@ skip_more_whitespace_and_comments:
s->buf_pos = 0; s->buf_pos = 0;
while (is_alnum(peek(s)) || peek(s) == '_') while (is_alnum(peek(s)) || peek(s) == '_')
buf_append(s, next(s)); buf_append(s, next(s));
if (!buf_append(s, '\0')) if (!buf_append(s, '\0')) {
return scanner_error(s, "identifier too long"); scanner_err(s, "identifier too long");
return ERROR_TOK;
}
/* Keyword. */ /* Keyword. */
tok = keyword_to_token(s->buf); tok = keyword_to_token(s->buf, s->buf_pos - 1);
if (tok != -1) return tok; if (tok != -1) return tok;
yylval->str = strdup(s->buf); yylval->str = strdup(s->buf);
if (!yylval->str) if (!yylval->str)
return scanner_error(s, "scanner out of memory"); return ERROR_TOK;
return IDENT; return IDENT;
} }
/* Number literal (hexadecimal / decimal / float). */ /* Number literal (hexadecimal / decimal / float). */
if (number(s, &yylval->num, &tok)) { if (number(s, &yylval->num, &tok)) {
if (tok == ERROR_TOK) if (tok == ERROR_TOK) {
return scanner_error(s, "malformed number literal"); scanner_err(s, "malformed number literal");
return ERROR_TOK;
}
return tok; return tok;
} }
return scanner_error(s, "unrecognized token"); scanner_err(s, "unrecognized token");
return ERROR_TOK;
} }
XkbFile * XkbFile *

Some files were not shown because too many files have changed in this diff Show More