File indexing completed on 2024-11-24 05:00:47

0001 /*
0002     SPDX-FileCopyrightText: 2013 Alexander Mezin <mezin.alexander@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "propertyinfo.h"
0008 
0009 #include <QVariant>
0010 
0011 #include <X11/Xatom.h>
0012 #include <X11/Xlib.h>
0013 #include <X11/extensions/XInput2.h>
0014 
0015 void XDeleter(void *p)
0016 {
0017     if (p) {
0018         XFree(p);
0019     }
0020 }
0021 
0022 PropertyInfo::PropertyInfo()
0023     : type(0)
0024     , format(0)
0025     , nitems(0)
0026     , f(nullptr)
0027     , i(nullptr)
0028     , b(nullptr)
0029     , display(nullptr)
0030     , device(0)
0031     , prop(0)
0032 {
0033 }
0034 
0035 PropertyInfo::PropertyInfo(Display *display, int device, Atom prop, Atom floatType)
0036     : type(0)
0037     , format(0)
0038     , nitems(0)
0039     , f(nullptr)
0040     , i(nullptr)
0041     , b(nullptr)
0042     , display(display)
0043     , device(device)
0044     , prop(prop)
0045 {
0046     unsigned char *dataPtr = nullptr;
0047     unsigned long bytes_after;
0048     XIGetProperty(display, device, prop, 0, 1000, False, AnyPropertyType, &type, &format, &nitems, &bytes_after, &dataPtr);
0049     data = std::shared_ptr<unsigned char>(dataPtr, XDeleter);
0050 
0051     if (format == CHAR_BIT && type == XA_INTEGER) {
0052         b = reinterpret_cast<char *>(dataPtr);
0053     }
0054     if (format == sizeof(int) * CHAR_BIT && (type == XA_INTEGER || type == XA_CARDINAL)) {
0055         i = reinterpret_cast<int *>(dataPtr);
0056     }
0057     if (format == sizeof(float) * CHAR_BIT && floatType && type == floatType) {
0058         f = reinterpret_cast<float *>(dataPtr);
0059     }
0060 }
0061 
0062 QVariant PropertyInfo::value(unsigned offset) const
0063 {
0064     QVariant v;
0065     if (offset >= nitems) {
0066         return v;
0067     }
0068 
0069     if (b) {
0070         v = QVariant(static_cast<int>(b[offset]));
0071     }
0072     if (i) {
0073         v = QVariant(i[offset]);
0074     }
0075     if (f) {
0076         v = QVariant(f[offset]);
0077     }
0078 
0079     return v;
0080 }
0081 
0082 void PropertyInfo::set()
0083 {
0084     XIChangeProperty(display, device, prop, type, format, XIPropModeReplace, data.get(), nitems);
0085 }