--- rxvt-unicode/src/xdefaults.C 2016/07/14 05:33:26 1.192 +++ rxvt-unicode/src/xdefaults.C 2022/12/23 21:46:46 1.200 @@ -136,6 +136,7 @@ BOOL (Rs_mouseWheelScrollPage, "mouseWheelScrollPage", NULL, Opt_mouseWheelScrollPage, 0, NULL), #endif #if ENABLE_FRILLS + BOOL (Rs_disablePasteBrackets, "disablePasteBrackets", "dpb", Opt_disablePasteBrackets, 0, "paste bracket suppression"), BOOL (Rs_tripleclickwords, "tripleclickwords", "tcw", Opt_tripleclickwords, 0, "triple click word selection"), BOOL (Rs_insecure, "insecure", "insecure", Opt_insecure, 0, "enable possibly insecure escape sequences"), BOOL (Rs_cursorUnderline, "cursorUnderline", "uc", Opt_cursorUnderline, 0, "underline cursor"), @@ -221,10 +222,11 @@ BOOL (Rs_buffered, "buffered", NULL, Opt_buffered, 0, NULL), #endif #if ENABLE_FRILLS + STRG (Rs_refreshRate, "refreshRate", "fps", "number", "refresh rate / frames per second"), STRG (Rs_depth, "depth", "depth", "number", "depth of visual to request"), STRG (Rs_visual, "visual", "visual", "number", "visual id to request"), RSTRG (Rs_transient_for, "transient-for", "windowid"), - BOOL (Rs_override_redirect, "override-redirect", "override-redirect", Opt_override_redirect, 0, "set override-redirect on the terminal window"), + BOOL (Rs_override_redirect, "override-redirect", "override-redirect", Opt_override_redirect, 0, "override-redirect on the terminal window"), STRG (Rs_pty_fd, NULL, "pty-fd", "fileno", "file descriptor of pty to use"), BOOL (Rs_hold, "hold", "hold", Opt_hold, 0, "retain window after shell exit"), STRG (Rs_ext_bwidth, "externalBorder", "w", "number", "external border in pixels"), @@ -236,7 +238,7 @@ STRG (Rs_letterSpace, "letterSpace", "letsp", "number", "letter spacing adjustment"), #endif #ifdef BUILTIN_GLYPHS - BOOL (Rs_skipBuiltinGlyphs, "skipBuiltinGlyphs", "sbg", Opt_skipBuiltinGlyphs, 0, "do not use internal glyphs"), + BOOL (Rs_skipBuiltinGlyphs, "skipBuiltinGlyphs", "sbg", Opt_skipBuiltinGlyphs, 0, "use of font glyphs instead of internal glyphs"), #endif #ifdef POINTER_BLANK RSTRG (Rs_pointerBlankDelay, "pointerBlankDelay", "number"), @@ -254,8 +256,11 @@ RSTRG (Rs_cutchars, "cutchars", "string"), RSTRG (Rs_answerbackstring, "answerbackString", "string"), #ifndef NO_SECONDARY_SCREEN - BOOL (Rs_secondaryScreen, "secondaryScreen", "ssc", Opt_secondaryScreen, 0, "enable secondary screen"), - BOOL (Rs_secondaryScroll, "secondaryScroll", "ssr", Opt_secondaryScroll, 0, "enable secondary screen scroll"), + BOOL (Rs_secondaryScreen, "secondaryScreen", "ssc", Opt_secondaryScreen, 0, "secondary screen"), + BOOL (Rs_secondaryScroll, "secondaryScroll", "ssr", Opt_secondaryScroll, 0, "secondary screen scroll"), +#endif +#if ENABLE_FRILLS + STRG (Rs_rewrapMode, "rewrapMode", "rm", "string", "rewrap mode (auto, always, never)"), #endif #if ENABLE_PERL RSTRG (Rs_perl_lib, "perl-lib", "string"), //, "colon-separated directories with extension scripts"),TODO @@ -629,37 +634,6 @@ } /* - * Define key from XrmEnumerateDatabase. - * quarks will be something like - * "rxvt" "keysym" "0xFF01" - * value will be a string - */ -static int -rxvt_enumerate_helper ( - XrmDatabase *database ecb_unused, - XrmBindingList bindings ecb_unused, - XrmQuarkList quarks, - XrmRepresentation *type ecb_unused, - XrmValue *value, - XPointer closure -) -{ - int last; - - for (last = 0; quarks[last] != NULLQUARK; last++) /* look for last quark in list */ - ; - - rxvt_term *term = (rxvt_term *)(((void **)closure)[0]); - void (*cb)(rxvt_term *, const char *, const char *) - = (void (*)(rxvt_term *, const char *, const char *)) - (((void **)closure)[1]); - - cb (term, XrmQuarkToString (quarks[last - 1]), (char *)value->addr); - - return False; -} - -/* * look for something like this (XK_Delete) * rxvt*keysym.0xFFFF: "\177" */ @@ -849,17 +823,93 @@ #endif /* NO_RESOURCES */ } +struct rxvt_enumerate_closure +{ + rxvt_term *term; + void (*cb)(rxvt_term *, const char *, const char *); + int specific; // iterate over only a specific subhierarchy +}; + +/* + * Define key from XrmEnumerateDatabase. + * quarks will be something like + * "rxvt" "keysym" "0xFF01" + * value will be a string + */ +static int +rxvt_enumerate_helper ( + XrmDatabase *database ecb_unused, + XrmBindingList bindings ecb_unused, + XrmQuarkList quarks, + XrmRepresentation *type ecb_unused, + XrmValue *value, + XPointer closure +) +{ + const rxvt_enumerate_closure *data = (const rxvt_enumerate_closure *)closure; + + if (*quarks == NULLQUARK) return False; + + // if the quark list starts with a tightly bound quark, we skip it, + // as it exactly matched the prefix. Otherwise, it matched because + // it started with "*", in which case we assume the prefix is part + // of the "*". + if (*bindings == XrmBindTightly) + { + ++quarks, ++bindings; // skip if this is a fixed prefix, rather than a *-match + if (*quarks == NULLQUARK) return False; + } + + // specific, a bit misleadingly named, is used when a specific "subclass" + // is iterated over, e.g. "keysym", and is used to skip one more + // component, as well as all generic prefixes + // this is a bit of a hack, ideally, keysym (the only user) should use its + // own iteration function, but this ought to be less bloated + if (data->specific) + { + ++quarks, ++bindings; + if (*quarks == NULLQUARK) return False; + } + + char *pattern; + if (quarks[1] == NULLQUARK) + pattern = XrmQuarkToString (quarks[0]); // single component, fast path + else + { + // multiple components, slow path - should be rare, don't optimize for speed + int size = 0; + + for (int i = 0; quarks[i] != NULLQUARK; ++i) + size += strlen (XrmQuarkToString (quarks[i])) + 1; + + pattern = rxvt_temp_buf (size + 1); + + // now print all components + { + char *cur = pattern; + + for (int i = 0; quarks[i] != NULLQUARK; ++i) + cur += sprintf (cur, ".%s", XrmQuarkToString (quarks[i])); + } + + ++pattern; // skip initial dot + } + + data->cb (data->term, pattern, (char *)value->addr); + + return False; +} + void rxvt_term::enumerate_resources (void (*cb)(rxvt_term *, const char *, const char *), const char *name_p, const char *class_p) { /* * [R5 or later]: enumerate the resource database */ + assert (!name_p == !class_p); // both must be specified, or missing + #ifdef KEYSYM_RESOURCE - void *closure[2] = { - (void *)this, - (void *)cb, - }; + rxvt_enumerate_closure closure = { this, cb, name_p ? 1 : 0 }; XrmDatabase database = XrmGetDatabase (dpy); XrmName name_prefix[3]; @@ -872,18 +922,17 @@ # ifdef RESFALLBACK name_prefix[0] = class_prefix[0] = XrmStringToName (RESFALLBACK); - /* XXX: Need to check sizeof (rxvt_t) == sizeof (XPointer) */ XrmEnumerateDatabase (database, name_prefix, class_prefix, - XrmEnumOneLevel, rxvt_enumerate_helper, (XPointer)closure); + XrmEnumAllLevels, rxvt_enumerate_helper, (XPointer)&closure); # endif name_prefix[0] = class_prefix[0] = XrmStringToName (RESCLASS); XrmEnumerateDatabase (database, name_prefix, class_prefix, - XrmEnumOneLevel, rxvt_enumerate_helper, (XPointer)closure); + XrmEnumAllLevels, rxvt_enumerate_helper, (XPointer)&closure); name_prefix[0] = class_prefix[0] = XrmStringToName (rs[Rs_name]); XrmEnumerateDatabase (database, name_prefix, class_prefix, - XrmEnumOneLevel, rxvt_enumerate_helper, (XPointer)closure); + XrmEnumAllLevels, rxvt_enumerate_helper, (XPointer)&closure); #endif }