revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / kms / openkeymap.c
blobb27729da3ef57bd2ad17da1690564db30c8c3008
1 #include <libraries/kms.h>
2 #include <proto/dos.h>
3 #include <proto/exec.h>
5 #include <string.h>
7 #include "kms_intern.h"
9 /*****************************************************************************
11 NAME */
12 #include <proto/kms.h>
14 AROS_LH1(struct KeyMapNode *, OpenKeymap,
16 /* SYNOPSIS */
17 AROS_LHA(STRPTR, name, A0),
19 /* LOCATION */
20 struct KMSLibrary *, KMSBase, 5, Kms)
22 /* FUNCTION
23 Open a keymap by name.
25 INPUTS
26 name - Keymap name. Can be a full pathname or just a name.
27 In the latter case DEVS:Keymaps is assumed to be a
28 path to the file.
30 RESULT
31 A pointer to the loaded keymap.
33 NOTES
34 This function automatically keeps track of loaded keymaps
35 via keymap.resource. No more than a single copy of the keymap
36 will be loaded.
38 EXAMPLE
40 BUGS
42 SEE ALSO
44 INTERNALS
46 HISTORY
48 *****************************************************************************/
50 AROS_LIBFUNC_INIT
52 struct KeyMapNode *kmn = NULL, *kmn2 = NULL;
53 ULONG buflen = 0;
54 STRPTR km_name;
55 BPTR km_seg;
56 struct KeyMapResource *kmr = ((struct kms_base *)KMSBase)->kmr;
58 km_name = FilePart(name);
59 if (km_name == name)
61 if (kmr)
64 * A short name was given.
65 * Check if the keymap is already resident.
66 * Unfortunately we still have to use Forbid()/Permit() locking
67 * because there can be lots of software which does the same.
68 * AmigaOS(tm) never provided a centralized semaphore for this.
70 Forbid();
71 kmn = (struct KeyMapNode *)FindName(&kmr->kr_List, name);
72 Permit();
75 /* If found, return it */
76 if (kmn)
77 return kmn;
79 /* Prepend DEVS:Keymaps to the supplied name */
80 buflen = strlen(name) + PREFIX_LEN;
81 name = AllocMem(buflen, MEMF_ANY);
82 if (!name)
83 return NULL;
85 strcpy(name, PREFIX_STR);
86 AddPart(name, km_name, buflen);
90 * Currently keymaps are still loaded using LoadSeg().
91 * In future we can extend this. For example we can add
92 * support for AmigaOS4(tm)-compatible keymaps which are plain text files.
93 * ELF keymaps have one strong disadvantage: they are CPU-dependent.
95 km_seg = LoadSeg(name);
96 if (buflen)
97 FreeMem(name, buflen);
99 if (!km_seg)
100 return NULL;
102 kmn = BADDR(km_seg) + sizeof(APTR);
104 if (kmr)
106 Forbid();
109 * Check if this keymap is already loaded once more before installing it.
110 * Now use name contained in the KeyMapNode instead of user-supplied one.
111 * This is needed for two cases:
112 * 1. Several programs running concurrently tried to load and install
113 * the same keymap (rare but theoretically possible case).
114 * 2. We are given full file path. We need to load the file and take
115 * keymap name from it.
117 kmn2 = (struct KeyMapNode *)FindName(&kmr->kr_List, kmn->kn_Node.ln_Name);
118 if (!kmn2)
119 Enqueue(&kmr->kr_List, &kmn->kn_Node);
121 Permit();
124 /* If the keymap was already loaded, use the resident copy and drop our one */
125 if (kmn2)
127 UnLoadSeg(km_seg);
128 kmn = kmn2;
131 return kmn;
133 AROS_LIBFUNC_EXIT