… | |
… | |
626 | rxvt_define_key (rxvt_term *term, const char *k, const char *v) |
626 | rxvt_define_key (rxvt_term *term, const char *k, const char *v) |
627 | { |
627 | { |
628 | term->bind_action (k, v); |
628 | term->bind_action (k, v); |
629 | } |
629 | } |
630 | |
630 | |
|
|
631 | struct rxvt_enumerate_closure |
|
|
632 | { |
|
|
633 | rxvt_term *term; |
|
|
634 | void (*cb)(rxvt_term *, const char *, const char *); |
|
|
635 | int specific; // iterate over only a specific subhierarchy |
|
|
636 | }; |
|
|
637 | |
631 | /* |
638 | /* |
632 | * Define key from XrmEnumerateDatabase. |
639 | * Define key from XrmEnumerateDatabase. |
633 | * quarks will be something like |
640 | * quarks will be something like |
634 | * "rxvt" "keysym" "0xFF01" |
641 | * "rxvt" "keysym" "0xFF01" |
635 | * value will be a string |
642 | * value will be a string |
… | |
… | |
642 | XrmRepresentation *type ecb_unused, |
649 | XrmRepresentation *type ecb_unused, |
643 | XrmValue *value, |
650 | XrmValue *value, |
644 | XPointer closure |
651 | XPointer closure |
645 | ) |
652 | ) |
646 | { |
653 | { |
647 | int last; |
654 | const rxvt_enumerate_closure *data = (const rxvt_enumerate_closure *)closure; |
648 | |
655 | |
649 | for (last = 0; quarks[last] != NULLQUARK; last++) /* look for last quark in list */ |
656 | if (*quarks == NULLQUARK) return False; |
|
|
657 | |
|
|
658 | // if the quark list starts with a tighly bound quark, we skip it, |
|
|
659 | // as it is the exactly matched the prefix. Otherwise, it matched because |
|
|
660 | // it started with "*", in which case we assuime the prefix is part |
|
|
661 | // of the "*". |
|
|
662 | if (*bindings == XrmBindTightly) |
650 | ; |
663 | { |
|
|
664 | ++quarks, ++bindings; // skip if this is a fixed prefix, rather than a *-match |
|
|
665 | if (*quarks == NULLQUARK) return False; |
|
|
666 | } |
651 | |
667 | |
652 | rxvt_term *term = (rxvt_term *)(((void **)closure)[0]); |
668 | // specific, a bit misleadingly named, is used when a specific "subclass" |
653 | void (*cb)(rxvt_term *, const char *, const char *) |
669 | // is iterated over, e.g. "keysym", and is used to skip one more |
654 | = (void (*)(rxvt_term *, const char *, const char *)) |
670 | // component, as well as all generic prefixes |
655 | (((void **)closure)[1]); |
671 | // this is a bit of a hack, ideally, keysym (the only user) should use its |
|
|
672 | // own iteration function, but this ought to be less bloated |
|
|
673 | if (data->specific) |
|
|
674 | { |
|
|
675 | if (*bindings != XrmBindTightly) |
|
|
676 | return False; |
656 | |
677 | |
657 | cb (term, XrmQuarkToString (quarks[last - 1]), (char *)value->addr); |
678 | ++quarks, ++bindings; // skip if this is a fixed prefix, rather than a *-match |
|
|
679 | if (*quarks == NULLQUARK) return False; |
|
|
680 | } |
|
|
681 | |
|
|
682 | char *pattern; |
|
|
683 | if (quarks[1] == NULLQUARK) |
|
|
684 | pattern = XrmQuarkToString (quarks[0]); // single component, fats path |
|
|
685 | else |
|
|
686 | { |
|
|
687 | // multiple components, slow path - should be rare, to don't optimize for speed |
|
|
688 | int size = 0; |
|
|
689 | |
|
|
690 | for (int i = 0; quarks[i] != NULLQUARK; ++i) |
|
|
691 | size += strlen (XrmQuarkToString (quarks[i])) + 1; |
|
|
692 | |
|
|
693 | pattern = rxvt_temp_buf<char> (size + 1); |
|
|
694 | |
|
|
695 | // now print all components |
|
|
696 | { |
|
|
697 | char *cur = pattern; |
|
|
698 | |
|
|
699 | for (int i = 0; quarks[i] != NULLQUARK; ++i) |
|
|
700 | cur += sprintf (cur, ".%s", XrmQuarkToString (quarks[i])); |
|
|
701 | } |
|
|
702 | |
|
|
703 | ++pattern; // skip initial dot |
|
|
704 | } |
|
|
705 | |
|
|
706 | data->cb (data->term, pattern, (char *)value->addr); |
658 | |
707 | |
659 | return False; |
708 | return False; |
660 | } |
709 | } |
661 | |
710 | |
662 | /* |
711 | /* |
… | |
… | |
853 | rxvt_term::enumerate_resources (void (*cb)(rxvt_term *, const char *, const char *), const char *name_p, const char *class_p) |
902 | rxvt_term::enumerate_resources (void (*cb)(rxvt_term *, const char *, const char *), const char *name_p, const char *class_p) |
854 | { |
903 | { |
855 | /* |
904 | /* |
856 | * [R5 or later]: enumerate the resource database |
905 | * [R5 or later]: enumerate the resource database |
857 | */ |
906 | */ |
|
|
907 | assert (!name_p == !class_p); // both must be specified, or missing |
|
|
908 | |
858 | #ifdef KEYSYM_RESOURCE |
909 | #ifdef KEYSYM_RESOURCE |
859 | void *closure[2] = { |
910 | rxvt_enumerate_closure closure = { this, cb, name_p ? 1 : 0 }; |
860 | (void *)this, |
|
|
861 | (void *)cb, |
|
|
862 | }; |
|
|
863 | |
911 | |
864 | XrmDatabase database = XrmGetDatabase (dpy); |
912 | XrmDatabase database = XrmGetDatabase (dpy); |
865 | XrmName name_prefix[3]; |
913 | XrmName name_prefix[3]; |
866 | XrmClass class_prefix[3]; |
914 | XrmClass class_prefix[3]; |
867 | |
915 | |
… | |
… | |
870 | class_prefix[1] = class_p ? XrmStringToName (class_p) : NULLQUARK; |
918 | class_prefix[1] = class_p ? XrmStringToName (class_p) : NULLQUARK; |
871 | class_prefix[2] = NULLQUARK; |
919 | class_prefix[2] = NULLQUARK; |
872 | |
920 | |
873 | # ifdef RESFALLBACK |
921 | # ifdef RESFALLBACK |
874 | name_prefix[0] = class_prefix[0] = XrmStringToName (RESFALLBACK); |
922 | name_prefix[0] = class_prefix[0] = XrmStringToName (RESFALLBACK); |
875 | /* XXX: Need to check sizeof (rxvt_t) == sizeof (XPointer) */ |
|
|
876 | XrmEnumerateDatabase (database, name_prefix, class_prefix, |
923 | XrmEnumerateDatabase (database, name_prefix, class_prefix, |
877 | XrmEnumOneLevel, rxvt_enumerate_helper, (XPointer)closure); |
924 | XrmEnumAllLevels, rxvt_enumerate_helper, (XPointer)&closure); |
878 | # endif |
925 | # endif |
879 | |
926 | |
880 | name_prefix[0] = class_prefix[0] = XrmStringToName (RESCLASS); |
927 | name_prefix[0] = class_prefix[0] = XrmStringToName (RESCLASS); |
881 | XrmEnumerateDatabase (database, name_prefix, class_prefix, |
928 | XrmEnumerateDatabase (database, name_prefix, class_prefix, |
882 | XrmEnumOneLevel, rxvt_enumerate_helper, (XPointer)closure); |
929 | XrmEnumAllLevels, rxvt_enumerate_helper, (XPointer)&closure); |
883 | |
930 | |
884 | name_prefix[0] = class_prefix[0] = XrmStringToName (rs[Rs_name]); |
931 | name_prefix[0] = class_prefix[0] = XrmStringToName (rs[Rs_name]); |
885 | XrmEnumerateDatabase (database, name_prefix, class_prefix, |
932 | XrmEnumerateDatabase (database, name_prefix, class_prefix, |
886 | XrmEnumOneLevel, rxvt_enumerate_helper, (XPointer)closure); |
933 | XrmEnumAllLevels, rxvt_enumerate_helper, (XPointer)&closure); |
887 | #endif |
934 | #endif |
888 | } |
935 | } |
889 | |
936 | |
890 | void |
937 | void |
891 | rxvt_term::extract_keysym_resources () |
938 | rxvt_term::extract_keysym_resources () |