2 * kdmapop.c - export getscrnmap(), loadscrnmap(),
3 * loaduniscrnmap(), loadunimap()
5 * Hide the ioctl use in this file.
10 #include <sys/ioctl.h>
17 * Linux pre-0.96 defined GIO_SCRNMAP, PIO_SCRNMAP:
18 typedef char scrnmap_t;
20 #define GIO_SCRNMAP 0x4B40
21 #define PIO_SCRNMAP 0x4B41
22 * and Linux 0.99.14y first implemented them.
24 scrnmap_t map[E_TABSZ];
25 ioctl(fd,GIO_SCRNMAP,map);
26 ioctl(fd,PIO_SCRNMAP,map);
27 * to read or write the kernel translation table that is
28 * applied to user application output before displaying.
30 * Before 1.3.1, the character set was completely undetermined,
31 * and if the font was in an order different from the character
32 * set in use, the user screen map was used to map application
33 * codes to font indices. (To be more precise: there were four
34 * translation tables, and this ioctl would get/set the fourth
35 * table, while the other three tables are built-in and constant.)
38 getscrnmap(int fd, char *map) {
39 if (ioctl(fd,GIO_SCRNMAP,map)) {
40 perror("GIO_SCRNMAP");
47 loadscrnmap(int fd, char *map) {
48 if (ioctl(fd,PIO_SCRNMAP,map)) {
49 perror("PIO_SCRNMAP");
56 * Linux 1.3.1 introduces GIO_UNISCRNMAP, PIO_UNISCRNMAP:
57 #define GIO_UNISCRNMAP 0x4B69
58 #define PIO_UNISCRNMAP 0x4B6A
60 unsigned short umap[E_TABSZ];
61 ioctl(fd,GIO_UNISCRNMAP,umap);
62 ioctl(fd,PIO_UNISCRNMAP,umap);
63 * to read or write the kernel translation table that is
64 * applied to user application output before displaying.
65 * (When the console is not in utf8 mode.)
67 * The idea is that the umap values are 16-bit unicode (ucs2)
68 * values, and that the fonts will have an index giving the
69 * unicode value for each glyph, so that the kernel can match up
70 * application codes to font positions.
71 #define UNI_DIRECT_BASE 0xF000
72 #define UNI_DIRECT_MASK 0x01FF
73 * For compatibility, and for fonts without table, the unicode
74 * values 0xF000+n, 0 <= n <= 0x01FF, acts as direct font indices.
75 * In the new scheme, the old PIO_SCRNMAP fills the kernel umap
76 * table with such direct-to-font values.
80 getuniscrnmap(int fd, unsigned short *map) {
81 if (ioctl(fd,GIO_UNISCRNMAP,map)) {
82 perror("GIO_UNISCRNMAP");
89 loaduniscrnmap(int fd, unsigned short *map) {
90 if (ioctl(fd,PIO_UNISCRNMAP,map)) {
91 perror("PIO_UNISCRNMAP");
98 * Linux 1.1.63 introduces GIO_UNIMAP, PIO_UNIMAP, PIO_UNIMAPCLR:
99 #define GIO_UNIMAP 0x4B66
100 #define PIO_UNIMAP 0x4B67
101 #define PIO_UNIMAPCLR 0x4B68
102 * And Linux 1.1.92 implements them.
105 unsigned short advised_hashsize;
106 unsigned short advised_hashstep;
107 unsigned short advised_hashlevel;
109 ioctl(fd, PIO_UNIMAPCLR, &ui);
110 * to clear the unimap table and advise about the kind of
111 * hash setup appropriate to what one is going to load
112 * (with 0 for "don't care").
114 unsigned short unicode;
115 unsigned short fontpos;
118 unsigned short entry_ct;
119 struct unipair *entries;
121 ioctl(fd, PIO_UNIMAP, &ud);
122 ioctl(fd, GIO_UNIMAP, &ud);
123 * to add the indicated pairs to the kernel unimap table
124 * or to read the kernel unimap table, where in the latter case
125 * ud.entry_ct indicated the room available.
127 * In Linux 1.3.28 the hash table was replaced by a 3-level
128 * paged table, so the contents of a struct unimapinit are
129 * no longer meaningful.
132 getunimap(int fd, struct unimapdesc *ud0) {
133 struct unimapdesc ud;
138 if (ioctl(fd, GIO_UNIMAP, &ud)) {
139 if(errno != ENOMEM || ud.entry_ct == 0) {
140 perror("GIO_UNIMAP(0)");
144 ud.entries = (struct unipair *)
145 malloc(ct * sizeof(struct unipair));
146 if (ud.entries == NULL) {
147 fprintf(stderr, _("%s: out of memory\n"), progname);
150 if (ioctl(fd, GIO_UNIMAP, &ud)) {
151 perror("GIO_UNIMAP");
154 if (ct != ud.entry_ct)
156 _("strange... ct changed from %d to %d\n"),
158 /* someone could change the unimap between our
159 first and second ioctl, so the above errors
160 are not impossible */
167 loadunimap(int fd, struct unimapinit *ui, struct unimapdesc *ud) {
168 struct unimapinit advice;
173 advice.advised_hashsize = 0;
174 advice.advised_hashstep = 0;
175 advice.advised_hashlevel = 0;
178 if (ioctl(fd, PIO_UNIMAPCLR, &advice)) {
180 if (errno == ENOIOCTLCMD) {
182 _("It seems this kernel is older than 1.1.92\n"
183 "No Unicode mapping table loaded.\n"));
186 perror("PIO_UNIMAPCLR");
192 if (ioctl(fd, PIO_UNIMAP, ud)) {
193 if (errno == ENOMEM && advice.advised_hashlevel < 100) {
194 advice.advised_hashlevel++;
197 perror("PIO_UNIMAP");