aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core/libLumina/LInputDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/core/libLumina/LInputDevice.cpp')
-rw-r--r--src-qt5/core/libLumina/LInputDevice.cpp181
1 files changed, 172 insertions, 9 deletions
diff --git a/src-qt5/core/libLumina/LInputDevice.cpp b/src-qt5/core/libLumina/LInputDevice.cpp
index d141e39a..a04dd607 100644
--- a/src-qt5/core/libLumina/LInputDevice.cpp
+++ b/src-qt5/core/libLumina/LInputDevice.cpp
@@ -17,6 +17,8 @@
#include <xcb/xinput.h>
#include <xcb/xproto.h>
+#include <LUtils.h>
+
//===================
// LInputDevice Class
//===================
@@ -24,8 +26,10 @@
LInputDevice::LInputDevice(unsigned int id, unsigned int type){
devID = id;
devType = type;
+ //ATOM_FLOAT = 0; //init this when needed later
//devName = name;
getProperties(); //need to populate the name/atom correlations for properties
+ readProperties(); //populate the hash with the current values of the properties
}
LInputDevice::~LInputDevice(){
@@ -53,17 +57,46 @@ bool LInputDevice::isExtension(){
}
// Property Management
-QStringList LInputDevice::listProperties(){
+QList<int> LInputDevice::listProperties(){
return devProps.keys();
}
-QVariant LInputDevice::propertyValue(QString prop){
- if(!devProps.contains(prop)){ return QVariant(); }
- //Now generate the property request
- // xcb_input_get_device_property_cookie_t cookie = xcb_input_get_device_property_unchecked( QX11Info::connection(), devProps.value(prop), \
-// XCB_ATOM_ATOM, 0, 1000, devID, NULL);
- QVariant result;
- return result;
+QString LInputDevice::propertyName(int prop){
+ if(devProps.contains(prop)){ return devProps[prop].name; }
+ else{ return ""; }
+}
+
+QVariant LInputDevice::getPropertyValue(int prop){
+ if(devProps.contains(prop)){ return devProps[prop].value; }
+ else{ return QVariant(); }
+}
+
+bool LInputDevice::setPropertyValue(int prop, QVariant value){
+ if(!devProps.contains(prop)){ return false; }
+ //Need the float atom for some properties - make sure we have that first
+ /*if(ATOM_FLOAT==0){
+ xcb_intern_atom_reply_t *ar = xcb_intern_atom_reply(QX11Info::connection(), \
+ xcb_intern_atom(QX11Info::connection(), 0, 1, "FLOAT"), NULL);
+ if(ar!=0){
+ ATOM_FLOAT = ar->atom;
+ free(ar);
+ }
+ }*/
+ //Now setup the argument
+ bool ok = false;
+ QStringList args;
+ args << "--set-prop";
+ args << QString::number(devID);
+ args << QString::number(prop); //prop ID
+ args << variantToString(value);
+ ok = (0 == LUtils::runCmd("xinput", args) );
+ if(ok){
+ //Need to update the value in the hash as well
+ propData dat = devProps[prop];
+ dat.value = value;
+ devProps.insert(prop, dat);
+ }
+ return ok;
}
// === PRIVATE ===
@@ -78,12 +111,142 @@ void LInputDevice::getProperties(){
for(int i=0; i<reply->num_atoms; i++){ cookies << xcb_get_atom_name(QX11Info::connection(), atoms[i]); }
for(int i=0; i<reply->num_atoms; i++){
xcb_get_atom_name_reply_t *nr = xcb_get_atom_name_reply(QX11Info::connection(), cookies[i], NULL);
- devProps.insert(QString::fromUtf8( xcb_get_atom_name_name(nr), xcb_get_atom_name_name_length(nr) ),atoms[i] );
+ propData DATA;
+ DATA.name = QString::fromUtf8( xcb_get_atom_name_name(nr), xcb_get_atom_name_name_length(nr) );
+ DATA.atom = atoms[i];
+ DATA.id = (int)(atoms[i]);
+ devProps.insert(DATA.id,DATA);
::free(nr);
}
//Done with data structure
::free(reply);
}
+
+void LInputDevice::readProperties(){
+ QList<int> props = devProps.keys();
+ //XINPUT UTILITY USAGE (alternative to XCB which actually works right now)
+ QStringList info = LUtils::getCmdOutput("xinput list-props "+QString::number(devID));
+ for(int i=0; i<props.length(); i++){
+ propData PROP = devProps[props[i]];
+ QStringList filter = info.filter(" ("+QString::number(PROP.id)+"):");
+ if(filter.length()==1){
+ QString val = filter.first().section("):",1,-1).simplified();
+ //Now figure out what type of value this is and save it into the QVariant
+ QVariant variant;
+ if(val.split(", ").length()>1){
+ //some kind of array
+ QList<QVariant> list;
+ QStringList valList = val.split(", ");
+ for(int j=0; j<valList.length(); j++){ list << valueToVariant(valList[j]); }
+ variant = QVariant(list);
+ }else{
+ variant = valueToVariant(val);
+ }
+ PROP.value = variant;
+ }
+ devProps.insert(props[i], PROP);
+ }
+
+//XCB Code (non-functional - issue with library itself? 12/6/16 - Ken Moore)
+ /*QVariant result;
+ if(!devProps.contains(prop)){qDebug() << "Invalid Property"; return result; }
+ //Now generate the property request
+ xcb_input_get_device_property_cookie_t cookie = xcb_input_get_device_property_unchecked( QX11Info::connection(), devProps.value(prop).atom, \
+ XCB_ATOM_ATOM, 0, 1000, devID, 0);
+ xcb_input_get_device_property_reply_t *reply = xcb_input_get_device_property_reply(QX11Info::connection(), cookie, NULL);
+ if(reply==0){ qDebug() << "Could not get reply!"; return result; }
+ //Now read off the value of the property
+ if(ATOM_FLOAT==0){
+ xcb_intern_atom_reply_t *ar = xcb_intern_atom_reply(QX11Info::connection(), \
+ xcb_intern_atom(QX11Info::connection(), 0, 1, "FLOAT"), NULL);
+ if(ar!=0){
+ ATOM_FLOAT = ar->atom;
+ free(ar);
+ }
+ }
+ //Turn the reply into the proper items array (depends on format of the return data)
+ xcb_input_get_device_property_items_t items;
+ qDebug() <<QByteArray::fromRawData( (char*)(xcb_input_get_device_property_items(reply) ) , reply->num_items);
+ void *buffer = xcb_input_get_device_property_items(reply);
+ xcb_input_get_device_property_items_serialize( &buffer, reply->num_items, reply->format, &items);
+
+ //if(reply->num_items > 0){
+ //qDebug() << "Format:" << reply->format << "Length:" << length;
+ //qDebug() << "Response Type:" << reply->response_type << "Pads:" << reply->pad0 << reply->pad1;
+ switch(reply->type){
+ case XCB_ATOM_INTEGER:
+ //qDebug() << "Got Integer";
+
+ break;
+ case XCB_ATOM_CARDINAL:
+ //qDebug() << "Got Cardinal";
+
+ break;
+ case XCB_ATOM_STRING:
+ qDebug() << "Got String:";
+ if(reply->format==8){
+ result.setValue( QByteArray::fromRawData( (char*) xcb_input_get_device_property_items_data_8(&items), sizeof(xcb_input_get_device_property_items_data_8(&items))/sizeof(char)) );
+ }
+ break;
+ case XCB_ATOM_ATOM:
+ //qDebug() << "Got Atom";
+
+ break;
+ default:
+ qDebug() << "Other Type:" << reply->type;
+ }
+ //}
+ free(reply); //done with this structure
+ return result;*/
+}
+
+QVariant LInputDevice::valueToVariant(QString value){
+ //Read through the string and see what type of value it is
+ if(value.count("\"")==2){
+ //String value or atom
+ if(value.endsWith(")")){
+ //ATOM (name string +(atomID))
+ return QVariant(value); //don't strip off the atom number -- keep that within the parenthesis
+ }else{
+ //String
+ value = value.section("\"",1,-2); //everything between the quotes
+ return QVariant(value);
+ }
+ }else if(value.contains(".")){
+ //float/double number
+ return QVariant( value.toDouble() );
+ }else{
+ //integer or boolian (no way to tell right now - assume all int)
+ bool ok = false;
+ int intval = value.toInt(&ok);
+ if(ok){ return QVariant(intval); }
+ }
+ return QVariant();
+}
+
+QString LInputDevice::variantToString(QVariant value){
+ if( value.canConvert< QList<QVariant> >() ){
+ //List of variants
+ QStringList out;
+ QList<QVariant> list = value.toList();
+ for(int i=0; i<list.length(); i++){ out << variantToString(list[i]); }
+ return out.join(", ");
+ }else{
+ //Single value
+ if(value.canConvert<double>() ){
+ return QString::number(value.toDouble());
+ }else if(value.canConvert<int>() ){
+ return QString::number(value.toInt());
+ }else if( value.canConvert<QString>() ){
+ //See if this is an atom first
+ QString val = value.toString();
+ if(val.contains("(")){ val = val.section("(",1,-1).section(")",0,0); }
+ return val;
+ }
+ }
+ return ""; //nothing to return
+}
+
//======================
// LInput Static Functions
//======================
bgstack15