OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [mw/] [src/] [demos/] [nxkbd/] [nxkbd.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * nxkbd.c - Software popup keyboard for Nano-X
3
 *
4
 * Copyright (C) 2000 by Greg Haerr <greg@censoft.com>
5
 *      linked-in bitmaps, redrawn keymaps
6
 *      enhanced shift/control function, fnkeys
7
 *      supports all ascii values 1-127
8
 * Copyright (C) 2000 by VTech Informations LTD.
9
 * Vladimir Cotfas <vladimircotfas@vtech.ca> Aug 31, 2000
10
 *   initial port to Nano-X
11
 * Copyright (C) 2000 by Jay Carlson
12
 *   initial soft kbd for W
13
 *
14
 * This code is licensed with the same license as Microwindows.
15
 *
16
 * #define KBDPIPE in srvconn.c for named pipe keyboard driver.
17
 * Otherwise, the GrInjectKeyboardEvent method is used.
18
 */
19
#include <stdio.h>
20
#include <stdlib.h>
21
#define MWINCLUDECOLORS
22
#include "nano-X.h"
23
 
24
#define TITLE           "Soft Keyboard"
25
#define DISKIMAGES      0                /* =0 use linked-in images*/
26
#define _SOFTKBD_DEBUG  0
27
 
28
/* kbd states, each with unique bitmap*/
29
#define NORM            1000
30
#define CNTRL           1001
31
#define SHIFT           1002
32
#define NUM             1003
33
#define INTL            1004
34
 
35
/* special chars*/
36
#define BS              '\b'            /* value of <- on kbd*/
37
#define F1              2000
38
#define NONE            3000
39
 
40
/* number of charcodes per bitmap*/
41
#define SCANCODES       41
42
 
43
/* size of bitmaps*/
44
#define BM_WIDTH        160
45
#define BM_HEIGHT       61
46
 
47
struct keycolumn {
48
        short xoffset;
49
        short scancode;
50
};
51
 
52
struct keyrow {
53
        short yoffset;
54
        short height;
55
        struct keycolumn columns[12];
56
};
57
 
58
/* fixed layout for each scancode location*/
59
struct keyrow keyrows[4] = {
60
        {0, 15,
61
         {{0, 0}, {14, 1}, {28, 2}, {42, 3}, {56, 4}, {70, 5}, {84, 6}, {98, 7}, {112, 8}, {126, 9}, {140, 10}, {999, -1}}},
62
        {15, 15,
63
         {{0, 11}, {14, 12}, {28, 13}, {42, 14}, {56, 15}, {70, 16}, {84, 17}, {98, 18}, {112, 19}, {126, 20}, {140, 21}, {999, -1}}},
64
        {30, 15,
65
         {{0, 22}, {19, 23}, {33, 24}, {47, 25}, {61, 26}, {75, 27}, {89, 28}, {103, 29}, {117, 30}, {131, 31}, {145, 32}, {999, -1}} },
66
        {45, 15,
67
         {{0, 33}, {21, 34}, {36, 35}, {85, 36}, {103, 37}, {117, 38}, {131, 39}, {145, 40}, {999, -1}}}
68
};
69
 
70
#define C(x)    ((x)&0x1f)
71
 
72
/* charcode mappings per kbd state*/
73
static short normal[SCANCODES] = {
74
 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', BS,
75
 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '-', '\r',
76
 CNTRL, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', ';',
77
 SHIFT, INTL, ' ', NUM, '\'', '=', '\\', '/'
78
};
79
 
80
static short control[SCANCODES] = {
81
 C('q'),C('w'),C('e'),C('r'),C('t'),C('y'),C('u'),C('i'),C('o'),C('p'),'\033',
82
 C('a'),C('s'),C('d'),C('f'),C('g'),C('h'),C('j'),C('k'),C('l'),C('_'),'\r',
83
 CNTRL,C('z'),C('x'),C('c'),C('v'),C('b'),C('n'),C('m'),C('\\'),C(']'),C('^'),
84
 SHIFT,INTL,' ',NUM,NONE,NONE,NONE,'\177'
85
};
86
 
87
static short shift[SCANCODES] = {
88
 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', BS,
89
 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '_', '\r',
90
 CNTRL, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', ':',
91
 SHIFT, INTL, ' ', NUM, '"', '+', '|', '?'
92
};
93
 
94
static short num[SCANCODES] = {
95
 '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', BS,
96
 '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '\r',
97
 CNTRL, F1, F1+1, F1+2, F1+3, F1+4, F1+5, F1+6, F1+7, '`', '~',
98
 SHIFT, INTL, ' ', NUM, '[', ']', '{', '}'};
99
 
100
static char *fnkey[] = {
101
        "\033OP", "\033OQ", "\033OR", "\033OS", "\03315~",
102
        "\03317~", "\03318~", "\03319~", "\03320~", "\03321~"
103
};
104
 
105
struct layout_state {
106
        char *filename;
107
        GR_IMAGE_HDR *imagehdr;
108
        short *scancode_translations;
109
        short sshift;
110
        short ctrl_layout, shift_layout, num_layout;
111
};
112
 
113
/* auto-converted .bmp files for internal linking*/
114
extern GR_IMAGE_HDR image_keynorm;
115
extern GR_IMAGE_HDR image_keyctrl;
116
extern GR_IMAGE_HDR image_keyshft;
117
extern GR_IMAGE_HDR image_keynum;
118
 
119
static struct layout_state layout_states[] = {
120
        { /* 0 */
121
                "keynorm.bmp",
122
                &image_keynorm,
123
                normal,
124
                0,
125
                2, 1, 3
126
        },
127
        { /* 1 */
128
                "keyshft.bmp",
129
                &image_keyshft,
130
                shift,
131
                0,
132
                2, 0, 3
133
        },
134
        { /* 2 */
135
                "keyctrl.bmp",
136
                &image_keyctrl,
137
                control,
138
                1,              /* ctrl is single shift*/
139
                0, 1, 3
140
        },
141
        { /* 3 */
142
                "keynum.bmp",
143
                &image_keynum,
144
                num,
145
                0,
146
                2, 1, 0
147
        }
148
};
149
#define N_LAYOUT_STATES (sizeof(layout_states) / sizeof(layout_states[0]))
150
 
151
static GR_WINDOW_ID     w;
152
static GR_GC_ID         gc;            /* graphics context for text */
153
static int              current_layout = 0;
154
#if DISKIMAGES
155
static GR_IMAGE_ID      layout_images[N_LAYOUT_STATES];
156
static int              layout_images_loaded[N_LAYOUT_STATES];
157
#endif
158
 
159
extern int KbdWrite(int c);
160
extern int KbdOpen(void);
161
extern void KbdClose(void);
162
 
163
static void
164
push_character(int c)
165
{
166
#if _SOFTKBD_DEBUG
167
        fprintf(stderr, "pushed %d (0x%x) '%c'\n", c, c, c);
168
#endif
169
        KbdWrite(c);
170
}
171
 
172
static void
173
display_layout(int layout)
174
{
175
#if DISKIMAGES
176
#define LIBDIR "."      /* "/etc/nxkbd.d" */
177
        if (!layout_images_loaded[layout] ) {
178
                char buf[128];
179
 
180
                /*
181
                 * OK, load image on the server-side ;-)
182
                 * DON'T check for errors ;(
183
                 */
184
                sprintf(buf, "%s/%s", LIBDIR, layout_states[layout].filename);
185
                layout_images[layout] = GrLoadImageFromFile(buf, 0);
186
                layout_images_loaded[layout] = 1;
187
        }
188
        GrDrawImageToFit(w, gc, 0, 0, -1, -1, layout_images[layout]);
189
#else
190
        GrDrawImageBits(w, gc, 0, 0, layout_states[layout].imagehdr);
191
#endif
192
}
193
 
194
static void
195
process_scancode(int scancode)
196
{
197
        int c;
198
 
199
        c = layout_states[current_layout].scancode_translations[scancode];
200
#if _SOFTKBD_DEBUG
201
        printf("scancode = %d ", scancode);
202
        printf("current_layout = %d ('%s'), scancode (translated) = %d\n",
203
                current_layout, layout_states[current_layout].filename, c);
204
#endif
205
 
206
        switch (c) {
207
        default:
208
                if (c < 256)            /* normal character*/
209
                        break;
210
 
211
                /* handle special functions*/
212
                if (c >= F1 && c < F1+10) {
213
                        char *p = fnkey[c-F1];
214
                        while (*p)
215
                                push_character(*p++);
216
                        return;
217
                }
218
 
219
                /* no action for NONE*/
220
                if (c == NONE)
221
                        return;
222
                fprintf(stderr, "nxkbd: key with unknown translation pressed\n");
223
                return;
224
        case CNTRL:
225
                current_layout = layout_states[current_layout].ctrl_layout;
226
                display_layout(current_layout);
227
                return;
228
        case SHIFT:
229
                current_layout = layout_states[current_layout].shift_layout;
230
                display_layout(current_layout);
231
                return;
232
        case NUM:
233
                current_layout = layout_states[current_layout].num_layout;
234
                display_layout(current_layout);
235
                return;
236
        case INTL:
237
#if _SOFTKBD_DEBUG
238
                printf("INTL not yet implemented\n");
239
#endif
240
                return;
241
        }
242
 
243
        if (layout_states[current_layout].sshift) {
244
                current_layout = 0;
245
                display_layout(current_layout);
246
        }
247
 
248
        push_character(c);
249
}
250
 
251
 
252
static void
253
mouse_hit(int x, int y)
254
{
255
        int row, column;
256
 
257
        for (row = 0; row < 4; row++) {
258
                if (y >= keyrows[row].yoffset &&
259
                    y < keyrows[row].yoffset+keyrows[row].height) {
260
                        for (column = 0; column < 12; column++) {
261
                                if (keyrows[row].columns[column].xoffset == 999) {
262
                                        fprintf(stderr, "off end of row\n");
263
                                        return;
264
                                }
265
                                if (x < keyrows[row].columns[column + 1].xoffset) {
266
                                        int scancode = keyrows[row].columns[column].scancode;
267
                                        process_scancode(scancode);
268
                                        return;
269
                                }
270
                        }
271
                }
272
        }
273
 
274
        fprintf(stderr, "nxkbd: off bottom\n");
275
}
276
 
277
int
278
main(int argc, char* argv[])
279
{
280
        GR_EVENT        event;          /* current event */
281
        GR_WM_PROPERTIES props;
282
 
283
        if (GrOpen() < 0) {
284
                fprintf(stderr, "nxkbd: cannot open graphics\n");
285
                exit(1);
286
        }
287
 
288
        if (KbdOpen() < 0) {
289
                fprintf(stderr, "nxkbd: cannot open kbd named pipe\n");
290
#if 0
291
                exit(1);
292
#endif
293
        }
294
 
295
#if !DISKIMAGES
296
        GrReqShmCmds(4096);             /* fast image copy*/
297
#endif
298
        w = GrNewWindow(GR_ROOT_WINDOW_ID,
299
                        0, 0, BM_WIDTH, BM_HEIGHT,
300
                        0, WHITE, BLACK);
301
 
302
        GrSelectEvents(w, GR_EVENT_MASK_CLOSE_REQ |
303
                          GR_EVENT_MASK_EXPOSURE |
304
                          /*GR_EVENT_MASK_FOCUS_IN |*/
305
                          /*GR_EVENT_MASK_KEY_DOWN |*/  /* required for focus*/
306
                          GR_EVENT_MASK_BUTTON_DOWN);
307
 
308
#if 0   /* this code fails when link-app-into-server */
309
        //if (props.title)      // can't free with link-into-server
310
                //free(props.title);
311
 
312
        /* title must be alloc'd and copied*/
313
        //props.title = malloc(18);
314
        //if (props.title)
315
                //strcpy(props.title, TITLE);
316
 
317
        props.flags =
318
                GR_WM_FLAG_NORESIZE   | /* don't let user resize window */
319
                GR_WM_FLAG_NOBORDERS  | /* don't draw any window borders */
320
                GR_WM_FLAG_NOTITLEBAR | /* don't draw a title bar */
321
                GR_WM_FLAG_NOFOCUS;     /* don't set focus to this window*/
322
#endif
323
 
324
        props.flags = GR_WM_FLAGS_PROPS | GR_WM_FLAGS_TITLE;
325
        props.props = GR_WM_PROPS_NOFOCUS;
326
        props.props |= /*GR_WM_PROPS_NOMOVE |*/ GR_WM_PROPS_NORAISE |
327
                GR_WM_PROPS_BORDER | GR_WM_PROPS_CAPTION | GR_WM_PROPS_CLOSEBOX;
328
        props.title = TITLE;
329
        GrSetWMProperties(w, &props);
330
 
331
        GrMapWindow(w);
332
 
333
        gc = GrNewGC();
334
 
335
        current_layout = 0;
336
        for (;;) {
337
                GrGetNextEvent(&event);
338
 
339
                switch(event.type) {
340
                        case GR_EVENT_TYPE_CLOSE_REQ:
341
#if DISKIMAGES
342
                                {
343
                                        int i;
344
 
345
                                        for(i=0; i < N_LAYOUT_STATES; i++) {
346
                                                if( !layout_images_loaded[i] )
347
                                                        continue;
348
                                                GrFreeImage(layout_images[i]);
349
                                        }
350
                                }
351
#endif
352
                                GrClose();
353
                                exit(0);
354
                                /* no return*/
355
                        case GR_EVENT_TYPE_EXPOSURE:
356
                                display_layout(current_layout);
357
                                break;
358
                        case GR_EVENT_TYPE_BUTTON_DOWN:
359
                                mouse_hit(event.button.x, event.button.y);
360
                                break;
361
#if 0
362
                        case GR_EVENT_TYPE_FOCUS_IN:
363
                                if (event.general.otherid != 1) {
364
                                        int lastfocus = event.general.otherid;
365
                                        GrSetFocus(lastfocus);
366
                                }
367
                                break;
368
#endif
369
                }
370
        }
371
 
372
        /*NOTREACHED*/
373
        return 0;
374
 }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.