GithubHelp home page GithubHelp logo

Comments (11)

KarlK90 avatar KarlK90 commented on June 12, 2024

Hi @george-norton 👋,

I have been doing some work to support trackpads within the digitizer feature.
I currently have some hacked together report handling code which works, but I would like to make it nicer.

Cool! I see that you have pushed your implementation to https://github.com/george-norton/qmk_firmware/tree/multitouch_experiment. So I'll base my suggestions on that branch.

The certification report is a pain as its 257 bytes, but Windows 8.1 wont work without a valid response. Later versions of Windows require us to return something, but they don't validate it.

We can just go with the example certification report - like you already implemented.

I was wondering how I can best take advantage of it.

Sure, happy to give some feedback. The usb_report_storage_t structure is the right place to implement the needed functionality:

For the capabilities and certification feature the default get_report handlers implementations e.g. usb(_shared)_get_report won't cut it. You'll have to implement a specialization usb(_shared)_get_report_multitouch_foobar (naming is made up, you'll find a better one 🙂) that additionally handles the two extra cases. For code re-use just call the already existing handlers if the request you're getting isn't one of the two extra cases.

When constructing your IN endpoint in usb_endpoints.c you can just the QMK_USB_REPORT_STORAGE constructor and pass in your new handlers.

Make sure to increase the DIGITIZER_EPSIZE and SHARED_EPSIZE to match biggest report you're going to send over IN endpoints (if there is a size increase). The capabilities and certification reports are only send over EP0 - e.g. no need to increase the IN endpoint sizes to e.g. 257 bytes.

The Get Report values are known at compile time, so I was wondering about populating them in the report storage structure as complete reports at compile time, but the buffer (64 bytes) isn't big enough for the certification report.

The usb_report_storage_t.reports buffer is solely meant for handling the regular HID get report request which shall return the last sent input report over the IN endpoint. Just store the well know reports in a const array in a source file that is platform independent - which can be then be referenced in the handlers. We maybe won't support AVR for this feature but there is a port of QMK to riot-os coming up, that probably wants to implement this as well.

The set report handling doesn't appear to be in place, but perhaps the code could be extended a little?

Sure, you can just add a function pointer (maybe rename the existing set_report to store_report and re-use set_report?) to the usb_report_storage_t and add a new dispatch function usb_set_report_cb (like usb_get_report_cb) which is then called in usb_requests_hook_cb. For the keyboard and shared interface endpoints this would mean the same implementation, but most of the endpoints get a NULL pointer as the default implementation that isn't called at all.

At this point I would say that usb_report_storage_t has outgrown it's name. Why not rename it to usb_report_handler_t or something like that.

It may also be nice if the actual content of these descriptors is platform independent, although the certification report will never fit on an AVR, we could at least support multitouch on Linux and fall back to mouse reporting on Mac (Apple do not support 3rd party trackpads) and Windows.

That would be great - I personally neither use Windows nor MacOS on a daily basis.

This functionality would also be useful for supporting high resolution scrolling in the pointing device feature.

Looking forward to it :)

from qmk_firmware.

george-norton avatar george-norton commented on June 12, 2024

Hello @KarlK90,
Thanks for your guidance. I have started playing around with the suggestions above and I am not really happy with how it is looking. My changes are here:

george-norton@38591d9

  • usb_fs_report_t has a fixed 64 byte buffer, I have replaced this with a pointer and have allocated various storage objects for the different sized reports, the get_report handlers populate an output report object, which I have had to initialize with a pointer to the largest possible report size. Currently this is a magic number, not sure if there is some way to determine the maximum size at compile time. But the whole thing seems a bit messier than the old code.
  • Typically the digitizer is on the shared endpoint, so replacing the get_report handler with a digitizer specific one seems like the wrong approach, it will breakdown as soon as a different feature on the shared endpoint wants its own feature report handlers. I think the handlers should probably be associated with a report id rather than the endpoint (falling back to the endpoint where the default report id is used)?
  • You mentioned that the feature requests arrive on EP0, and this is true, I see it in wireshark. But in usb_get_report_cb the ep is derived from the interface (wIndex), so the callback for the shared endpoint is used. Is this what you expect?

from qmk_firmware.

george-norton avatar george-norton commented on June 12, 2024

I assume there is a good reason the get_report handler needs to return a copy of the report rather than a pointer to the stored report? I guess there is a chance that the data will be altered before the report has been sent over the USB link?

from qmk_firmware.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.