From 2cd9b268a871b0763e2d1715b489dcbe7db16ece Mon Sep 17 00:00:00 2001 From: "Elf M. Sternberg" Date: Thu, 24 Feb 2022 15:59:43 -0800 Subject: [PATCH] Innteresting. It seems that the `output` collection is much more reliable as a source of truth about which monitors and screens are actually in use. Each one comes with its own collection of `crtc`, but you can just skip the ones that return `null`, giving you a reliable list of the "active and visible" screens that the user is currently looking at. Excellent! This means that I'm one step closer to having a viable solution! I also discovered the [xcb_util](https://xcb.freedesktop.org/XcbUtil/) library of helpful utilities has a function called `xcb_aux_get_screen` for getting the root screen because everyone was weirded out by that list traversal algorithm. The source code to [xedgewarp](https://github.com/Airblader/xedgewarp) was invaluable in revealing these secrets to me. So far this little toy compiles down to only 35KB, and that includes using `std::cout` and `std::vector`! I wonder how big the Rust version will be. Yeah, yeah, I know, it cheats by having lots of itself hidden in the kernel. Next up: Actually knowing what the rotation status is. --- .clang-format | 178 ++++++++++++++++++++++++++++++++++++++ Makefile | 3 + README.md | 5 +- docs/Progress.md | 40 +++++++++ notes.md | 8 ++ src/xrandr.cpp | 162 +++++++++++++++++++++++++++++++--- studies/xcb_good_usage | Bin 0 -> 16456 bytes studies/xcb_good_usage.cc | 54 ++++++++++++ studies/xcb_poor_usage | Bin 0 -> 16456 bytes studies/xcb_poor_usage.cc | 44 ++++++++++ studies/xlib_demo | Bin 0 -> 16400 bytes studies/xlib_demo.cc | 43 +++++++++ 12 files changed, 525 insertions(+), 12 deletions(-) create mode 100644 .clang-format create mode 100644 docs/Progress.md create mode 100644 notes.md create mode 100755 studies/xcb_good_usage create mode 100644 studies/xcb_good_usage.cc create mode 100755 studies/xcb_poor_usage create mode 100644 studies/xcb_poor_usage.cc create mode 100755 studies/xlib_demo create mode 100644 studies/xlib_demo.cc diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..6c1ca06 --- /dev/null +++ b/.clang-format @@ -0,0 +1,178 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +PPIndentWidth: -1 +ReferenceAlignment: Pointer +ReflowComments: true +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/Makefile b/Makefile index 92f8917..e114f3f 100644 --- a/Makefile +++ b/Makefile @@ -12,3 +12,6 @@ build/xrandr: build/Makefile src/xrandr.cpp CMakeLists.txt clean: rm -fr build + +run: build/xrandr + ./build/xrandr diff --git a/README.md b/README.md index 73508cd..8ead3da 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,10 @@ obviously X Windows. In progress. -**DETAILS:** +DETAILS: + +**Notes:** + **BUILDING:** diff --git a/docs/Progress.md b/docs/Progress.md new file mode 100644 index 0000000..1395462 --- /dev/null +++ b/docs/Progress.md @@ -0,0 +1,40 @@ +Resources used in the production of this program: + +- [The XCB Reference from FreeDesktop](https://xcb.freedesktop.org/manual/index.html) +- [The Xorg Basic Programming with the XCB + Library](https://www.x.org/releases/X11R7.6/doc/libxcb/tutorial/index.html), +- [The KDE Source Code for + XCBWrapper](https://github.com/KDE/libkscreen/tree/master/backends), +- [xedgewarp](https://github.com/Airblader/xedgewarp) + [Vlad Zahorodnii](https://github.com/zzag) et. al., ongoing. +- [C++ in a + Nutshell](https://www.oreilly.com/library/view/c-in-a/059600298X/) + Ray Lischner, O'Reilly Publishing, 2003 + +The sheer variety of sources I needed to cobble together an +understanding how the XCB library works is an example of what teachers +call [extrinsic +load](https://betterhumans.pub/skyrocket-your-learning-top-3-studying-techniques-based-on-cognitive-load-theory-1641b5e56508), +an unnecessary extra load on learning because the documentation is +poorly organized and lacks instruction. *Basic Programming with XCB* +is a +*[tutorial](https://www.writethedocs.org/videos/eu/2017/the-four-kinds-of-documentation-and-why-you-need-to-understand-what-they-are-daniele-procida/)* +oriented toward commonplace tasks, but peters out before getting to an +XCB extensions such as RandR. The reference is a *reference*; it +doesn't help you understand how to use the library. `XCBWrapper` is +an excellent example of how to use XCB, but it uses some fairly +high-level C++ to accomplish all that it does, and untangling the +relationship between the wrapper template, the macro that does wrapper +declarations, and the XCB Reference; once you find the insight that +XCB's declarations are all derived from a massive XML file, you can +start to understand that XCBWrapper exploits the patterns produced by +the derivative file, but it requires insight and effort that's +unrelated to understanding XCB in the first place. + +This project does show the usual trajectory of one of my learning +exercises, especially since I'm fond of delving in places where no man +has documented before. I've dumped a ton of stuff into my brain and +now it's all starting to make sense. I also note that I'm doing +_better_ than a lot of the open-source examples, in that I'm batching +many of my requests before processing them. I'm not batching storing +the replies yet, but I don't see why that couldn't happen. diff --git a/notes.md b/notes.md new file mode 100644 index 0000000..9ae2e6f --- /dev/null +++ b/notes.md @@ -0,0 +1,8 @@ +- A Display has Screens +- A Screen has Monitors & Windows +- The root Screen is accessed by traversing to the head of the list of + screens using an interator. +- The root screen's root window is used as the parameter for + 'get_screen_resources'. +- The screen_resources object is contains 'screen_resources_crtcs', + which you again get via an iterator. These are cookies. diff --git a/src/xrandr.cpp b/src/xrandr.cpp index 5aacce9..89a978a 100644 --- a/src/xrandr.cpp +++ b/src/xrandr.cpp @@ -1,14 +1,154 @@ +#include "xcb/randr.h" +#include "xcb/xcb.h" +#include "xcb/xcb_aux.h" #include -#include +#include +#include -int main(int argc, const char *argv[]) { - xcb_connection_t *xConnection = xcb_connect(nullptr, nullptr); - for (auto iter = xcb_setup_roots_iterator(xcb_get_setup(xConnection)); - iter.rem; xcb_screen_next(&iter)) { - xcb_screen_t *screen = iter.data; - std::cout << "Screen " << iter.index << " (" << screen->width_in_pixels - << ", " << screen->height_in_pixels << ")" << std::endl; - } - xcb_disconnect(xConnection); - return 0; +xcb_randr_get_screen_resources_reply_t* get_screen_resources(xcb_connection_t* connection, + xcb_window_t rootWindow) { + return xcb_randr_get_screen_resources_reply( + connection, xcb_randr_get_screen_resources(connection, rootWindow), nullptr); +} + +std::vector get_crtc_cookies(xcb_randr_get_screen_resources_reply_t* resources) { + std::vector reply; + xcb_randr_crtc_t* crtcs = xcb_randr_get_screen_resources_crtcs(resources); + const int crtcsCount = xcb_randr_get_screen_resources_crtcs_length(resources); + for (int i = 0; i < crtcsCount; ++i) { + reply.push_back(crtcs[i]); + } + return reply; +} + +void display_one_crtc(xcb_randr_get_crtc_info_reply_t* crtc) { + std::cout << "(x: " << crtc->x << ", y: " << crtc->y << ") (width: " << crtc->width + << ", height: " << crtc->height << ") status:" << unsigned(crtc->status) << std::endl; +} + +void display_crtc_info(xcb_connection_t* connection, std::vector& crtc_cs) { + std::vector cookies; + xcb_generic_error_t* error = nullptr; + for (const auto& crtc : crtc_cs) { + cookies.push_back(xcb_randr_get_crtc_info(connection, crtc, XCB_CURRENT_TIME)); + } + for (const auto& cookie : cookies) { + xcb_randr_get_crtc_info_reply_t* reply = + xcb_randr_get_crtc_info_reply(connection, cookie, &error); + if (error) { + free(error); + } else { + display_one_crtc(reply); + free(reply); + } + } +} + +void display_one_output(xcb_connection_t* connection, xcb_randr_get_output_info_reply_t* output, + xcb_timestamp_t timestamp) { + xcb_randr_get_crtc_info_reply_t* crtc = xcb_randr_get_crtc_info_reply( + connection, xcb_randr_get_crtc_info(connection, output->crtc, timestamp), NULL); + if (!crtc) { + return; + } + display_one_crtc(crtc); + free(crtc); +} + +void display_outputs(xcb_connection_t* connection, + xcb_randr_get_screen_resources_reply_t* resources, xcb_timestamp_t timestamp) { + std::vector cookies; + xcb_generic_error_t* error = nullptr; + + int len = xcb_randr_get_screen_resources_outputs_length(resources); + xcb_randr_output_t* randr_outputs = xcb_randr_get_screen_resources_outputs(resources); + + for (int i = 0; i < len; ++i) { + cookies.push_back(xcb_randr_get_output_info(connection, randr_outputs[i], timestamp)); + } + + for (const auto& cookie : cookies) { + xcb_randr_get_output_info_reply_t* reply = + xcb_randr_get_output_info_reply(connection, cookie, &error); + if (error) { + free(error); + continue; + } else { + display_one_output(connection, reply, timestamp); + free(reply); + } + } +} + +// Lesson of the day: All _reply_t* objects must be freed. +// +// xcb_randr_rotation_t) +// } +// get_rotation(xcb_connection_t* connection, xcb_randr_crtc_t crtc) { +// xcb_generic_error_t* error = nullptr; +// xcb_randr_get_crtc_info_cookie_t cookie = +// xcb_randr_get_crtc_info(connection, crtc, XCB_CURRENT_TIME); +// xcb_randr_get_crtc_info_reply_t* reply = +// xcb_randr_get_crtc_info_reply(connection, cookie, &error); +// xcb_randr_rotation_t rotation = +// (xcb_randr_rotation_t)reply->rotation; free(reply); return rotation; +// } +// + +xcb_randr_query_version_reply_t* getVersion(xcb_connection_t* connection) { + xcb_generic_error_t* error = nullptr; + xcb_randr_query_version_reply_t* version = xcb_randr_query_version_reply( + connection, + xcb_randr_query_version(connection, XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION), + &error); + if (error) { + std::cout << "Error code:" << error->error_code << std::endl; + free(error); + return NULL; + } + + if (!version) { + return NULL; + } + + return version; +} + +void display_screen_info(int screen_id, xcb_screen_t* screen) { + std::cout << "Screen " << screen_id << " (" << screen->width_in_pixels << ", " + << screen->height_in_pixels << ")" << std::endl; +} + +void display_randr_version(xcb_randr_query_version_reply_t* version) { + if (!version) { + std::cout << "Something went wrong retrieving the version number" << std::endl; + exit(0); + } + + std::cout << "Server reports RandR version (" << version->major_version << "." + << version->minor_version << ")" << std::endl; +} + +// This gives us a connection and a screen object. + +int main(int argc, const char* argv[]) { + int default_screen_id; + xcb_connection_t* xConnection = xcb_connect(nullptr, &default_screen_id); + + auto screen = xcb_aux_get_screen(xConnection, default_screen_id); + display_screen_info(default_screen_id, screen); + + xcb_randr_query_version_reply_t* version = getVersion(xConnection); + display_randr_version(version); + + xcb_randr_get_screen_resources_reply_t* screen_resources = + get_screen_resources(xConnection, screen->root); + + xcb_timestamp_t timestamp = screen_resources->config_timestamp; + + display_outputs(xConnection, screen_resources, timestamp); + + free(screen_resources); + xcb_disconnect(xConnection); + return 0; } diff --git a/studies/xcb_good_usage b/studies/xcb_good_usage new file mode 100755 index 0000000000000000000000000000000000000000..87fa0968e51be7ff46529f0dc18e6b09535d1f2b GIT binary patch literal 16456 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 literal 0 HcmV?d00001 diff --git a/studies/xcb_good_usage.cc b/studies/xcb_good_usage.cc new file mode 100644 index 0000000..d2c3860 --- /dev/null +++ b/studies/xcb_good_usage.cc @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +double get_time(void) { + struct timeval timev; + gettimeofday(&timev, NULL); + return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); +} + +int main() { + int count = 500; + xcb_atom_t* atoms = (xcb_atom_t*)malloc(count * sizeof(atoms)); + xcb_intern_atom_cookie_t* cookies = + (xcb_intern_atom_cookie_t*)malloc(count * sizeof(xcb_intern_atom_cookie_t)); + char** names; + double end, diff_x; + + /* init names */ + names = (char**)malloc(count * sizeof(char*)); + for (int i = 0; i < count; ++i) { + char buf[100]; + sprintf(buf, "NAME%d", i); + names[i] = strdup(buf); + } + + auto start = get_time(); + xcb_connection_t* connection = xcb_connect(NULL, NULL); + for (int i = 0; i < count; ++i) { + cookies[i] = xcb_intern_atom(connection, 0, strlen(names[i]), names[i]); + } + + for (int i = 0; i < count; i++) { + xcb_intern_atom_reply_t* r = xcb_intern_atom_reply(connection, cookies[i], 0); + if (r) { + atoms[i] = r->atom; + free(r); + } + } + xcb_disconnect(connection); + end = get_time(); + + diff_x = end - start; + printf("XCB (good) use time : %f\n", diff_x); + + for (int i = 0; i < count; ++i) + free(names[i]); + free(names); + free(atoms); + free(cookies); + return 0; +} diff --git a/studies/xcb_poor_usage b/studies/xcb_poor_usage new file mode 100755 index 0000000000000000000000000000000000000000..f237f6633b8ff872a4e07ca27aa55e1159f1be6a GIT binary patch literal 16456 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 +#include +#include +#include +#include + +double get_time(void) { + struct timeval timev; + gettimeofday(&timev, NULL); + return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); +} + +int main() { + int count = 500; + xcb_atom_t* atoms = (xcb_atom_t*)malloc(count * sizeof(atoms)); + char** names; + double end, diff_x; + + /* init names */ + names = (char**)malloc(count * sizeof(char*)); + for (int i = 0; i < count; ++i) { + char buf[100]; + sprintf(buf, "NAME%d", i); + names[i] = strdup(buf); + } + + auto start = get_time(); + xcb_connection_t* connection = xcb_connect(NULL, NULL); + for (int i = 0; i < count; ++i) { + atoms[i] = xcb_intern_atom_reply( + connection, xcb_intern_atom(connection, 0, strlen(names[i]), names[i]), NULL) + ->atom; + } + xcb_disconnect(connection); + end = get_time(); + + diff_x = end - start; + printf("XCB (poor) use time : %f\n", diff_x); + + for (int i = 0; i < count; ++i) + free(names[i]); + free(names); + return 0; +} diff --git a/studies/xlib_demo b/studies/xlib_demo new file mode 100755 index 0000000000000000000000000000000000000000..433dbaa62482ff2223f18ca93ad3fa69c0be5929 GIT binary patch literal 16400 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 DrpH&{ literal 0 HcmV?d00001 diff --git a/studies/xlib_demo.cc b/studies/xlib_demo.cc new file mode 100644 index 0000000..dda9217 --- /dev/null +++ b/studies/xlib_demo.cc @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include + +double get_time(void) { + struct timeval timev; + gettimeofday(&timev, NULL); + return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); +} + +int main() { + int count = 500; + Atom* atoms_x = (Atom*)malloc(count * sizeof(atoms_x)); + char** names; + double end, diff_x; + + /* init names */ + names = (char**)malloc(count * sizeof(char*)); + for (int i = 0; i < count; ++i) { + char buf[100]; + sprintf(buf, "NAME%d", i); + names[i] = strdup(buf); + } + + auto start = get_time(); + auto disp = XOpenDisplay(getenv("DISPLAY")); + for (int i = 0; i < count; ++i) + atoms_x[i] = XInternAtom(disp, names[i], 0); + end = get_time(); + XCloseDisplay(disp); + + diff_x = end - start; + printf("Xlib use time : %f\n", diff_x); + + free(atoms_x); + + for (int i = 0; i < count; ++i) + free(names[i]); + free(names); + return 0; +}