diff options
Diffstat (limited to 'src-qt5/core/libLumina/LInputDevice.cpp')
-rw-r--r-- | src-qt5/core/libLumina/LInputDevice.cpp | 181 |
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 //====================== |