{"action":"created","comment":{"url":"https://api.github.com/repos/libratbag/libratbag/pulls/comments/204448268","pull_request_review_id":139530325,"id":204448268,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwNDQ0ODI2OA==","diff_hunk":"@@ -0,0 +1,793 @@\n+/*\n+ * Copyright © 2017 Thomas Hindoe Paaboel Andersen.\n+ *\n+ * Permission is hereby granted, free of charge, to any person obtaining a\n+ * copy of this software and associated documentation files (the \"Software\"),\n+ * to deal in the Software without restriction, including without limitation\n+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n+ * and/or sell copies of the Software, and to permit persons to whom the\n+ * Software is furnished to do so, subject to the following conditions:\n+ *\n+ * The above copyright notice and this permission notice (including the next\n+ * paragraph) shall be included in all copies or substantial portions of the\n+ * Software.\n+ *\n+ * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n+ * DEALINGS IN THE SOFTWARE.\n+ */\n+\n+#include \"config.h\"\n+#include <assert.h>\n+#include <errno.h>\n+#include <libevdev/libevdev.h>\n+#include <linux/input.h>\n+#include <stdlib.h>\n+#include <stdint.h>\n+#include <string.h>\n+\n+#include \"libratbag-private.h\"\n+#include \"libratbag-hidraw.h\"\n+#include \"libratbag-data.h\"\n+#include \"hidpp-generic.h\"\n+\n+#define CMSTORM_NUM_BUTTONS\t9\n+#define CMSTORM_NUM_LEDS\t\t3\n+#define CMSTORM_NUM_PROFILES\t4\n+#define CMSTORM_NUM_DPI\t\t4\n+\n+#define CMSTORM_REPORT_ID\t\t\t0x03\n+\n+#define CMSTORM_REPORT_SIZE\t\t\t64\n+#define CMSTORM_BLOCK_SIZE\t\t\t56\n+#define CMSTORM_PROFILE_SIZE\t\t0x69\n+\n+#define CMSTORM_CMD_SELECT_PROFILE\t0xc1\n+#define CMSTORM_CMD_CURRENT_PROFILE\t0xc2\n+#define CMSTORM_CMD_RELOAD_PROFILES\t0xc5\n+#define CMSTORM_CMD_WRITE_BLOCK\t\t0xd1\n+#define CMSTORM_CMD_READ_BLOCK\t\t0xd2\n+#define CMSTORM_CMD_ENABLE_PROG\t\t0xea\n+#define CMSTORM_CMD_DISABLE_PROG\t0xed\n+\n+#define CMSTORM_BUTTON_TYPE_MOUSE\t\t0x00\n+#define CMSTORM_BUTTON_TYPE_KEYBOARD\t0x02\n+#define CMSTORM_BUTTON_TYPE_MACRO\t\t0x03\n+#define CMSTORM_BUTTON_TYPE_PROFILE\t\t0x08\n+#define CMSTORM_BUTTON_TYPE_DPI\t\t\t0x09\n+#define CMSTORM_BUTTON_TYPE_CONSUMER\t0x20\n+\n+#define CMSTORM_MACRO_TYPE_END\t\t0x00\n+#define CMSTORM_MACRO_TYPE_MOUSE\t0x01\n+#define CMSTORM_MACRO_TYPE_KEYBOARD\t0x03\n+\n+\n+#pragma pack(push,1)\n+struct cmstorm_button\n+{\n+\tuint8_t repetitions;\n+\tuint8_t response_time;\n+\tuint8_t type;\n+\tuint16_t function;\n+};\n+\n+struct cmstorm_dpi\n+{\n+\tuint8_t enabled;\n+\tuint8_t dpi;\n+\tuint8_t lod;\n+\tuint8_t usb_rate;\n+};\n+\n+struct cmstorm_led\n+{\n+\tuint8_t mode;\n+\tuint8_t red, green, blue;\n+\tuint8_t intensity;\n+};\n+\n+struct cmstorm_macro\n+{\n+\tuint8_t type;\n+\tuint8_t unknown; //part of button?\n+\tuint8_t button;\n+\tuint8_t pressed_released;\n+\tuint8_t unknown2;\n+\tuint16_t delay;\n+};\n+\n+struct cmstorm_profile\n+{\n+\tuint8_t index;\n+\tuint8_t name[24]; //UTF-16BE\n+\tuint8_t length;\n+\tuint16_t macro_length;\n+\tstruct cmstorm_button buttons[9];\n+\tstruct cmstorm_dpi dpi[4];\n+\tstruct cmstorm_led leds[3];\n+\tstruct cmstorm_macro *macros;\n+};\n+#pragma pack(pop)\n+\n+static uint32_t DPIS[] = {800, 1600, 3200, 4000};\n+#define DPI_COUNT 4\n+\n+uint32_t dpiIndexToDpi(uint8_t dpiIndex);\n+uint8_t dpiToDpiIndex(uint32_t dpi);\n+int send_command(struct ratbag_device *device, int cmd_length, uint8_t *cmd, int out_length, uint8_t *out);\n+int reload_profiles(struct ratbag_device *device);\n+int enable_profile_writing(struct ratbag_device *device);\n+int disable_profile_writing(struct ratbag_device *device);\n+int set_selected_profile(struct ratbag_device *device, int profile_idx);\n+int read_chunk(struct ratbag_device *device, int profile, int offset, int length, uint8_t *out);\n+int write_chunk(struct ratbag_device *device, int profile, int offset, int length, uint8_t *out);\n+int read_chunks(struct ratbag_device *device, int profile, int offset, int length, uint8_t *out);\n+int write_chunks(struct ratbag_device *device, int profile, int offset, int length, uint8_t *buf);\n+int read_profile(struct ratbag_device *device, int profile, struct cmstorm_profile *out);\n+int write_profile(struct ratbag_device *device, int profile, struct cmstorm_profile *out);","path":"src/driver-cmstorm.c","position":131,"original_position":131,"commit_id":"c7cdcffe96901abc8b63027621db1617375013a2","original_commit_id":"61143e6ccda5b6ac0bedf23017b7b89e5ead30ed","user":{"login":"bentiss","id":2705518,"node_id":"MDQ6VXNlcjI3MDU1MTg=","avatar_url":"https://avatars0.githubusercontent.com/u/2705518?v=4","gravatar_id":"","url":"https://api.github.com/users/bentiss","html_url":"https://github.com/bentiss","followers_url":"https://api.github.com/users/bentiss/followers","following_url":"https://api.github.com/users/bentiss/following{/other_user}","gists_url":"https://api.github.com/users/bentiss/gists{/gist_id}","starred_url":"https://api.github.com/users/bentiss/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bentiss/subscriptions","organizations_url":"https://api.github.com/users/bentiss/orgs","repos_url":"https://api.github.com/users/bentiss/repos","events_url":"https://api.github.com/users/bentiss/events{/privacy}","received_events_url":"https://api.github.com/users/bentiss/received_events","type":"User","site_admin":false},"body":"I am not a big fan of forward declarations of every function. It's usually a useless duplication, and you can reshuffle the code so you don't need it.","created_at":"2018-07-23T15:34:43Z","updated_at":"2018-07-23T15:41:48Z","html_url":"https://github.com/libratbag/libratbag/pull/498#discussion_r204448268","pull_request_url":"https://api.github.com/repos/libratbag/libratbag/pulls/498","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/libratbag/libratbag/pulls/comments/204448268"},"html":{"href":"https://github.com/libratbag/libratbag/pull/498#discussion_r204448268"},"pull_request":{"href":"https://api.github.com/repos/libratbag/libratbag/pulls/498"}}},"pull_request":{"url":"https://api.github.com/repos/libratbag/libratbag/pulls/498","id":202999418,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAyOTk5NDE4","html_url":"https://github.com/libratbag/libratbag/pull/498","diff_url":"https://github.com/libratbag/libratbag/pull/498.diff","patch_url":"https://github.com/libratbag/libratbag/pull/498.patch","issue_url":"https://api.github.com/repos/libratbag/libratbag/issues/498","number":498,"state":"open","locked":false,"title":"Initial CMStorm Recon work","user":{"login":"elFarto","id":2325080,"node_id":"MDQ6VXNlcjIzMjUwODA=","avatar_url":"https://avatars2.githubusercontent.com/u/2325080?v=4","gravatar_id":"","url":"https://api.github.com/users/elFarto","html_url":"https://github.com/elFarto","followers_url":"https://api.github.com/users/elFarto/followers","following_url":"https://api.github.com/users/elFarto/following{/other_user}","gists_url":"https://api.github.com/users/elFarto/gists{/gist_id}","starred_url":"https://api.github.com/users/elFarto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elFarto/subscriptions","organizations_url":"https://api.github.com/users/elFarto/orgs","repos_url":"https://api.github.com/users/elFarto/repos","events_url":"https://api.github.com/users/elFarto/events{/privacy}","received_events_url":"https://api.github.com/users/elFarto/received_events","type":"User","site_admin":false},"body":"This is the initial work on cmstorm based mice, specifically the CMStorm Recon. There are other mice in the CMStorm range, I'm not sure how reusable this driver will be for them.\r\n\r\nI still need to do the artwork for this mouse, but I think the rest is complete. \r\n\r\nInterestingly this mouse supports placing mouse presses/releases within it's macros, something which I believe isn't supported yet.","created_at":"2018-07-21T08:10:02Z","updated_at":"2018-07-23T15:41:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"71954a45a9740ddb2914497422c370f63df56dc1","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/libratbag/libratbag/pulls/498/commits","review_comments_url":"https://api.github.com/repos/libratbag/libratbag/pulls/498/comments","review_comment_url":"https://api.github.com/repos/libratbag/libratbag/pulls/comments{/number}","comments_url":"https://api.github.com/repos/libratbag/libratbag/issues/498/comments","statuses_url":"https://api.github.com/repos/libratbag/libratbag/statuses/c7cdcffe96901abc8b63027621db1617375013a2","head":{"label":"elFarto:coolermaster","ref":"coolermaster","sha":"c7cdcffe96901abc8b63027621db1617375013a2","user":{"login":"elFarto","id":2325080,"node_id":"MDQ6VXNlcjIzMjUwODA=","avatar_url":"https://avatars2.githubusercontent.com/u/2325080?v=4","gravatar_id":"","url":"https://api.github.com/users/elFarto","html_url":"https://github.com/elFarto","followers_url":"https://api.github.com/users/elFarto/followers","following_url":"https://api.github.com/users/elFarto/following{/other_user}","gists_url":"https://api.github.com/users/elFarto/gists{/gist_id}","starred_url":"https://api.github.com/users/elFarto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elFarto/subscriptions","organizations_url":"https://api.github.com/users/elFarto/orgs","repos_url":"https://api.github.com/users/elFarto/repos","events_url":"https://api.github.com/users/elFarto/events{/privacy}","received_events_url":"https://api.github.com/users/elFarto/received_events","type":"User","site_admin":false},"repo":{"id":137561914,"node_id":"MDEwOlJlcG9zaXRvcnkxMzc1NjE5MTQ=","name":"libratbag","full_name":"elFarto/libratbag","owner":{"login":"elFarto","id":2325080,"node_id":"MDQ6VXNlcjIzMjUwODA=","avatar_url":"https://avatars2.githubusercontent.com/u/2325080?v=4","gravatar_id":"","url":"https://api.github.com/users/elFarto","html_url":"https://github.com/elFarto","followers_url":"https://api.github.com/users/elFarto/followers","following_url":"https://api.github.com/users/elFarto/following{/other_user}","gists_url":"https://api.github.com/users/elFarto/gists{/gist_id}","starred_url":"https://api.github.com/users/elFarto/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elFarto/subscriptions","organizations_url":"https://api.github.com/users/elFarto/orgs","repos_url":"https://api.github.com/users/elFarto/repos","events_url":"https://api.github.com/users/elFarto/events{/privacy}","received_events_url":"https://api.github.com/users/elFarto/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/elFarto/libratbag","description":"A DBus daemon to configure gaming mice","fork":true,"url":"https://api.github.com/repos/elFarto/libratbag","forks_url":"https://api.github.com/repos/elFarto/libratbag/forks","keys_url":"https://api.github.com/repos/elFarto/libratbag/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elFarto/libratbag/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elFarto/libratbag/teams","hooks_url":"https://api.github.com/repos/elFarto/libratbag/hooks","issue_events_url":"https://api.github.com/repos/elFarto/libratbag/issues/events{/number}","events_url":"https://api.github.com/repos/elFarto/libratbag/events","assignees_url":"https://api.github.com/repos/elFarto/libratbag/assignees{/user}","branches_url":"https://api.github.com/repos/elFarto/libratbag/branches{/branch}","tags_url":"https://api.github.com/repos/elFarto/libratbag/tags","blobs_url":"https://api.github.com/repos/elFarto/libratbag/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elFarto/libratbag/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elFarto/libratbag/git/refs{/sha}","trees_url":"https://api.github.com/repos/elFarto/libratbag/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elFarto/libratbag/statuses/{sha}","languages_url":"https://api.github.com/repos/elFarto/libratbag/languages","stargazers_url":"https://api.github.com/repos/elFarto/libratbag/stargazers","contributors_url":"https://api.github.com/repos/elFarto/libratbag/contributors","subscribers_url":"https://api.github.com/repos/elFarto/libratbag/subscribers","subscription_url":"https://api.github.com/repos/elFarto/libratbag/subscription","commits_url":"https://api.github.com/repos/elFarto/libratbag/commits{/sha}","git_commits_url":"https://api.github.com/repos/elFarto/libratbag/git/commits{/sha}","comments_url":"https://api.github.com/repos/elFarto/libratbag/comments{/number}","issue_comment_url":"https://api.github.com/repos/elFarto/libratbag/issues/comments{/number}","contents_url":"https://api.github.com/repos/elFarto/libratbag/contents/{+path}","compare_url":"https://api.github.com/repos/elFarto/libratbag/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elFarto/libratbag/merges","archive_url":"https://api.github.com/repos/elFarto/libratbag/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elFarto/libratbag/downloads","issues_url":"https://api.github.com/repos/elFarto/libratbag/issues{/number}","pulls_url":"https://api.github.com/repos/elFarto/libratbag/pulls{/number}","milestones_url":"https://api.github.com/repos/elFarto/libratbag/milestones{/number}","notifications_url":"https://api.github.com/repos/elFarto/libratbag/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elFarto/libratbag/labels{/name}","releases_url":"https://api.github.com/repos/elFarto/libratbag/releases{/id}","deployments_url":"https://api.github.com/repos/elFarto/libratbag/deployments","created_at":"2018-06-16T07:20:07Z","updated_at":"2018-06-30T15:03:05Z","pushed_at":"2018-07-21T08:03:52Z","git_url":"git://github.com/elFarto/libratbag.git","ssh_url":"git@github.com:elFarto/libratbag.git","clone_url":"https://github.com/elFarto/libratbag.git","svn_url":"https://github.com/elFarto/libratbag","homepage":"","size":2967,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"libratbag:master","ref":"master","sha":"d81c68d94f653d3dd8e6c217da58ee67d39d2412","user":{"login":"libratbag","id":13972444,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEzOTcyNDQ0","avatar_url":"https://avatars1.githubusercontent.com/u/13972444?v=4","gravatar_id":"","url":"https://api.github.com/users/libratbag","html_url":"https://github.com/libratbag","followers_url":"https://api.github.com/users/libratbag/followers","following_url":"https://api.github.com/users/libratbag/following{/other_user}","gists_url":"https://api.github.com/users/libratbag/gists{/gist_id}","starred_url":"https://api.github.com/users/libratbag/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/libratbag/subscriptions","organizations_url":"https://api.github.com/users/libratbag/orgs","repos_url":"https://api.github.com/users/libratbag/repos","events_url":"https://api.github.com/users/libratbag/events{/privacy}","received_events_url":"https://api.github.com/users/libratbag/received_events","type":"Organization","site_admin":false},"repo":{"id":41394739,"node_id":"MDEwOlJlcG9zaXRvcnk0MTM5NDczOQ==","name":"libratbag","full_name":"libratbag/libratbag","owner":{"login":"libratbag","id":13972444,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEzOTcyNDQ0","avatar_url":"https://avatars1.githubusercontent.com/u/13972444?v=4","gravatar_id":"","url":"https://api.github.com/users/libratbag","html_url":"https://github.com/libratbag","followers_url":"https://api.github.com/users/libratbag/followers","following_url":"https://api.github.com/users/libratbag/following{/other_user}","gists_url":"https://api.github.com/users/libratbag/gists{/gist_id}","starred_url":"https://api.github.com/users/libratbag/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/libratbag/subscriptions","organizations_url":"https://api.github.com/users/libratbag/orgs","repos_url":"https://api.github.com/users/libratbag/repos","events_url":"https://api.github.com/users/libratbag/events{/privacy}","received_events_url":"https://api.github.com/users/libratbag/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/libratbag/libratbag","description":"A DBus daemon to configure gaming mice","fork":false,"url":"https://api.github.com/repos/libratbag/libratbag","forks_url":"https://api.github.com/repos/libratbag/libratbag/forks","keys_url":"https://api.github.com/repos/libratbag/libratbag/keys{/key_id}","collaborators_url":"https://api.github.com/repos/libratbag/libratbag/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/libratbag/libratbag/teams","hooks_url":"https://api.github.com/repos/libratbag/libratbag/hooks","issue_events_url":"https://api.github.com/repos/libratbag/libratbag/issues/events{/number}","events_url":"https://api.github.com/repos/libratbag/libratbag/events","assignees_url":"https://api.github.com/repos/libratbag/libratbag/assignees{/user}","branches_url":"https://api.github.com/repos/libratbag/libratbag/branches{/branch}","tags_url":"https://api.github.com/repos/libratbag/libratbag/tags","blobs_url":"https://api.github.com/repos/libratbag/libratbag/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/libratbag/libratbag/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/libratbag/libratbag/git/refs{/sha}","trees_url":"https://api.github.com/repos/libratbag/libratbag/git/trees{/sha}","statuses_url":"https://api.github.com/repos/libratbag/libratbag/statuses/{sha}","languages_url":"https://api.github.com/repos/libratbag/libratbag/languages","stargazers_url":"https://api.github.com/repos/libratbag/libratbag/stargazers","contributors_url":"https://api.github.com/repos/libratbag/libratbag/contributors","subscribers_url":"https://api.github.com/repos/libratbag/libratbag/subscribers","subscription_url":"https://api.github.com/repos/libratbag/libratbag/subscription","commits_url":"https://api.github.com/repos/libratbag/libratbag/commits{/sha}","git_commits_url":"https://api.github.com/repos/libratbag/libratbag/git/commits{/sha}","comments_url":"https://api.github.com/repos/libratbag/libratbag/comments{/number}","issue_comment_url":"https://api.github.com/repos/libratbag/libratbag/issues/comments{/number}","contents_url":"https://api.github.com/repos/libratbag/libratbag/contents/{+path}","compare_url":"https://api.github.com/repos/libratbag/libratbag/compare/{base}...{head}","merges_url":"https://api.github.com/repos/libratbag/libratbag/merges","archive_url":"https://api.github.com/repos/libratbag/libratbag/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/libratbag/libratbag/downloads","issues_url":"https://api.github.com/repos/libratbag/libratbag/issues{/number}","pulls_url":"https://api.github.com/repos/libratbag/libratbag/pulls{/number}","milestones_url":"https://api.github.com/repos/libratbag/libratbag/milestones{/number}","notifications_url":"https://api.github.com/repos/libratbag/libratbag/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/libratbag/libratbag/labels{/name}","releases_url":"https://api.github.com/repos/libratbag/libratbag/releases{/id}","deployments_url":"https://api.github.com/repos/libratbag/libratbag/deployments","created_at":"2015-08-26T00:18:46Z","updated_at":"2018-07-20T05:38:04Z","pushed_at":"2018-07-21T08:10:02Z","git_url":"git://github.com/libratbag/libratbag.git","ssh_url":"git@github.com:libratbag/libratbag.git","clone_url":"https://github.com/libratbag/libratbag.git","svn_url":"https://github.com/libratbag/libratbag","homepage":"","size":2927,"stargazers_count":210,"watchers_count":210,"language":"C","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":39,"mirror_url":null,"archived":false,"open_issues_count":62,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":39,"open_issues":62,"watchers":210,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/libratbag/libratbag/pulls/498"},"html":{"href":"https://github.com/libratbag/libratbag/pull/498"},"issue":{"href":"https://api.github.com/repos/libratbag/libratbag/issues/498"},"comments":{"href":"https://api.github.com/repos/libratbag/libratbag/issues/498/comments"},"review_comments":{"href":"https://api.github.com/repos/libratbag/libratbag/pulls/498/comments"},"review_comment":{"href":"https://api.github.com/repos/libratbag/libratbag/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/libratbag/libratbag/pulls/498/commits"},"statuses":{"href":"https://api.github.com/repos/libratbag/libratbag/statuses/c7cdcffe96901abc8b63027621db1617375013a2"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"bentiss"}}