Prefs/ScreenMode: change the way depth is selected
[AROS.git] / workbench / libs / kms / openkeymap.c
blob8aa7760940221e4994d759ac7bc23d374abb57e4
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, *kmn2;
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)
62 * A short name was given.
63 * Check if the keymap is already resident.
64 * Unfortunately we still have to use Forbid()/Permit() locking
65 * because there can be lots of software which does the same.
66 * AmigaOS(tm) never provided a centralized semaphore for this.
68 Forbid();
69 kmn = (struct KeyMapNode *)FindName(&kmr->kr_List, name);
70 Permit();
72 /* If found, return it */
73 if (kmn)
74 return kmn;
76 /* Prepend DEVS:Keymaps to the supplied name */
77 buflen = strlen(name) + PREFIX_LEN;
78 name = AllocMem(buflen, MEMF_ANY);
79 if (!name)
80 return NULL;
82 strcpy(name, PREFIX_STR);
83 AddPart(name, km_name, buflen);
87 * Currently keymaps are still loaded using LoadSeg().
88 * In future we can extend this. For example we can add
89 * support for AmigaOS4(tm)-compatible keymaps which are plain text files.
90 * ELF keymaps have one strong disadvantage: they are CPU-dependent.
92 km_seg = LoadSeg(name);
93 if (buflen)
94 FreeMem(name, buflen);
96 if (!km_seg)
97 return NULL;
99 kmn = BADDR(km_seg) + sizeof(APTR);
101 Forbid();
104 * Check if this keymap is already loaded once more before installing it.
105 * Now use name contained in the KeyMapNode instead of user-supplied one.
106 * This is needed for two cases:
107 * 1. Several programs running concurrently tried to load and install
108 * the same keymap (rare but theoretically possible case).
109 * 2. We are given full file path. We need to load the file and take
110 * keymap name from it.
112 kmn2 = (struct KeyMapNode *)FindName(&kmr->kr_List, kmn->kn_Node.ln_Name);
113 if (!kmn2)
114 Enqueue(&kmr->kr_List, &kmn->kn_Node);
116 Permit();
118 /* If the keymap was already loaded, use the resident copy and drop our one */
119 if (kmn2)
121 UnLoadSeg(km_seg);
122 kmn = kmn2;
125 return kmn;
127 AROS_LIBFUNC_EXIT