Landfall

Annotated pkg/landfall-examples/letux400_keypad_physical/letux400_keypad_physical.c

273:8f6ff113d000
8 months ago Paul Boddie Removed debugging output. cpm-library-improvements
paul@0 1
/*
paul@0 2
 * Display the physical keypad matrix layout for the Letux 400 notebook
paul@0 3
 * computer.
paul@0 4
 *
paul@142 5
 * Copyright (C) 2018, 2023 Paul Boddie <paul@boddie.org.uk>
paul@0 6
 *
paul@0 7
 * This program is free software; you can redistribute it and/or
paul@0 8
 * modify it under the terms of the GNU General Public License as
paul@0 9
 * published by the Free Software Foundation; either version 2 of
paul@0 10
 * the License, or (at your option) any later version.
paul@0 11
 *
paul@0 12
 * This program is distributed in the hope that it will be useful,
paul@0 13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
paul@0 14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
paul@0 15
 * GNU General Public License for more details.
paul@0 16
 *
paul@0 17
 * You should have received a copy of the GNU General Public License
paul@0 18
 * along with this program; if not, write to the Free Software
paul@0 19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
paul@0 20
 * Boston, MA  02110-1301, USA
paul@0 21
 */
paul@0 22
paul@0 23
#include <l4/re/c/rm.h>
paul@0 24
#include <l4/re/c/util/cap_alloc.h>
paul@0 25
#include <l4/re/env.h>
paul@0 26
#include <l4/util/util.h>
paul@0 27
#include <l4/sys/ipc.h>
paul@0 28
paul@0 29
#include <l4/re/c/util/video/goos_fb.h>
paul@0 30
#include <l4/re/c/video/view.h>
paul@0 31
paul@0 32
#include <stdio.h>
paul@0 33
#include <stdint.h>
paul@0 34
#include <stdlib.h>
paul@0 35
#include <unistd.h>
paul@0 36
paul@0 37
enum Jz4730_keypad_gpio
paul@0 38
{
paul@0 39
  Jz4730_keypad_gpio_inputs_count = 8,
paul@0 40
  Jz4730_keypad_gpio_outputs_count = 17,
paul@0 41
};
paul@0 42
paul@0 43
/* Video abstractions. */
paul@0 44
paul@0 45
static l4re_util_video_goos_fb_t gfb;
paul@0 46
static l4re_video_view_info_t fbi;
paul@0 47
static void *fb;
paul@0 48
paul@0 49
/* Keypad status and dimensions. */
paul@0 50
paul@0 51
uint32_t *keypad = 0;
paul@0 52
void *keymem = 0;
paul@0 53
int columns = Jz4730_keypad_gpio_outputs_count, rows = Jz4730_keypad_gpio_inputs_count;
paul@0 54
paul@0 55
/* Position units: 0.1mm */
paul@0 56
paul@0 57
enum {
paul@0 58
  SPC = 600, CAPS = 240, TAB = 200, LSH = 184, M = 160, S = 136, XS = 120,
paul@0 59
  WIDTH = 2040, HEIGHT = 800, ROWS = 6,
paul@0 60
};
paul@0 61
paul@0 62
/*
paul@0 63
S(15)                         Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 Num Sys Ins Del
paul@0 64
XS(1)/M(12)                   `  1   2   3   4   5   6   7   8   9   0   -   Bsp
paul@0 65
TAB(1)/M(10)/XS(2)            Tab Q   W   E   R   T   Y   U   I   O   P   =  \
paul@0 66
CAPS(1)/M(9)/XS(1)/CAPS(1)    Caps A   S   D   F   G   H   J   K   L   ;   Enter
paul@0 67
LSH(1)/XS(1)/M(7)/XS(4)/S(1)  Sh \  Z   X   C   V   B   N   M   ,   .   /  Up Sh
paul@0 68
XS(5)/SPC(1)/XS(7)            Fn Ctr Zzz Alt Pau Space     Mnu [  ]  '  Lt Dn Rt
paul@0 69
*/
paul@0 70
paul@0 71
enum {
paul@0 72
  SIZE_KEY_ESC = S, SIZE_KEY_F1 = S, SIZE_KEY_F2 = S, SIZE_KEY_F3 = S, SIZE_KEY_F4 = S,
paul@0 73
  SIZE_KEY_F5 = S, SIZE_KEY_F6 = S, SIZE_KEY_F7 = S, SIZE_KEY_F8 = S, SIZE_KEY_F9 = S,
paul@0 74
  SIZE_KEY_F10 = S, SIZE_KEY_NUMLOCK = S, SIZE_KEY_SYSRQ = S, SIZE_KEY_INSERT = S,
paul@0 75
  SIZE_KEY_DELETE = S,
paul@0 76
paul@0 77
  SIZE_KEY_GRAVE = XS, SIZE_KEY_1 = M, SIZE_KEY_2 = M, SIZE_KEY_3 = M, SIZE_KEY_4 = M,
paul@0 78
  SIZE_KEY_5 = M, SIZE_KEY_6 = M, SIZE_KEY_7 = M, SIZE_KEY_8 = M, SIZE_KEY_9 = M,
paul@0 79
  SIZE_KEY_0 = M, SIZE_KEY_MINUS = M, SIZE_KEY_BACKSPACE = M,
paul@0 80
paul@0 81
  SIZE_KEY_TAB = TAB, SIZE_KEY_Q = M, SIZE_KEY_W = M, SIZE_KEY_E = M, SIZE_KEY_R = M,
paul@0 82
  SIZE_KEY_T = M, SIZE_KEY_Y = M, SIZE_KEY_U = M, SIZE_KEY_I = M, SIZE_KEY_O = M,
paul@0 83
  SIZE_KEY_P = M, SIZE_KEY_EQUAL = XS, SIZE_KEY_RIGHTBACKSLASH = XS,
paul@0 84
paul@0 85
  SIZE_KEY_CAPSLOCK = CAPS, SIZE_KEY_A = M, SIZE_KEY_S = M, SIZE_KEY_D = M, SIZE_KEY_F = M,
paul@0 86
  SIZE_KEY_G = M, SIZE_KEY_H = M, SIZE_KEY_J = M, SIZE_KEY_K = M, SIZE_KEY_L = M,
paul@0 87
  SIZE_KEY_SEMICOLON = XS, SIZE_KEY_ENTER = CAPS,
paul@0 88
paul@0 89
  SIZE_KEY_LEFTSHIFT = LSH, SIZE_KEY_LEFTBACKSLASH = XS, SIZE_KEY_Z = M, SIZE_KEY_X = M, SIZE_KEY_C = M,
paul@0 90
  SIZE_KEY_V = M, SIZE_KEY_B = M, SIZE_KEY_N = M, SIZE_KEY_M = M, SIZE_KEY_COMMA = XS,
paul@0 91
  SIZE_KEY_DOT = XS, SIZE_KEY_SLASH = XS, SIZE_KEY_UP = XS, SIZE_KEY_RIGHTSHIFT = S,
paul@0 92
paul@0 93
  SIZE_KEY_FN = XS, SIZE_KEY_LEFTCTRL = XS, SIZE_KEY_SLEEP = XS, SIZE_KEY_LEFTALT = XS, SIZE_KEY_PAUSE = XS,
paul@0 94
  SIZE_KEY_SPACE = SPC, SIZE_KEY_MENU = XS, SIZE_KEY_LEFTBRACE = XS, SIZE_KEY_RIGHTBRACE = XS,
paul@0 95
  SIZE_KEY_APOSTROPHE = XS, SIZE_KEY_LEFT = XS, SIZE_KEY_DOWN = XS, SIZE_KEY_RIGHT = XS,
paul@0 96
};
paul@0 97
paul@0 98
enum {
paul@0 99
  XPOS_KEY_ESC = 0, XPOS_KEY_F1 = S, XPOS_KEY_F2 = 2*S, XPOS_KEY_F3 = 3*S, XPOS_KEY_F4 = 4*S,
paul@0 100
  XPOS_KEY_F5 = 5*S, XPOS_KEY_F6 = 6*S, XPOS_KEY_F7 = 7*S, XPOS_KEY_F8 = 8*S, XPOS_KEY_F9 = 9*S,
paul@0 101
  XPOS_KEY_F10 = 10*S, XPOS_KEY_NUMLOCK = 11*S, XPOS_KEY_SYSRQ = 12*S, XPOS_KEY_INSERT = 13*S,
paul@0 102
  XPOS_KEY_DELETE = 14*S,
paul@0 103
paul@0 104
  XPOS_KEY_GRAVE = 0, XPOS_KEY_1 = XS, XPOS_KEY_2 = XS+M, XPOS_KEY_3 = XS+2*M, XPOS_KEY_4 = XS+3*M,
paul@0 105
  XPOS_KEY_5 = XS+4*M, XPOS_KEY_6 = XS+5*M, XPOS_KEY_7 = XS+6*M, XPOS_KEY_8 = XS+7*M, XPOS_KEY_9 = XS+8*M,
paul@0 106
  XPOS_KEY_0 = XS+9*M, XPOS_KEY_MINUS = XS+10*M, XPOS_KEY_BACKSPACE = XS+11*M,
paul@0 107
paul@0 108
  XPOS_KEY_TAB = 0, XPOS_KEY_Q = TAB, XPOS_KEY_W = TAB+M, XPOS_KEY_E = TAB+2*M, XPOS_KEY_R = TAB+3*M,
paul@0 109
  XPOS_KEY_T = TAB+4*M, XPOS_KEY_Y = TAB+5*M, XPOS_KEY_U = TAB+6*M, XPOS_KEY_I = TAB+7*M, XPOS_KEY_O = TAB+8*M,
paul@0 110
  XPOS_KEY_P = TAB+9*M, XPOS_KEY_EQUAL = TAB+10*M, XPOS_KEY_RIGHTBACKSLASH = TAB+10*M+XS,
paul@0 111
paul@0 112
  XPOS_KEY_CAPSLOCK = 0, XPOS_KEY_A = CAPS, XPOS_KEY_S = CAPS+M, XPOS_KEY_D = CAPS+2*M, XPOS_KEY_F = CAPS+3*M,
paul@0 113
  XPOS_KEY_G = CAPS+4*M, XPOS_KEY_H = CAPS+5*M, XPOS_KEY_J = CAPS+6*M, XPOS_KEY_K = CAPS+7*M, XPOS_KEY_L = CAPS+8*M,
paul@0 114
  XPOS_KEY_SEMICOLON = CAPS+9*M, XPOS_KEY_ENTER = CAPS+9*M+XS,
paul@0 115
paul@0 116
  XPOS_KEY_LEFTSHIFT = 0, XPOS_KEY_LEFTBACKSLASH = LSH, XPOS_KEY_Z = LSH+XS, XPOS_KEY_X = LSH+XS+M, XPOS_KEY_C = LSH+XS+2*M,
paul@0 117
  XPOS_KEY_V = LSH+XS+3*M, XPOS_KEY_B = LSH+XS+4*M, XPOS_KEY_N = LSH+XS+5*M, XPOS_KEY_M = LSH+XS+6*M, XPOS_KEY_COMMA = LSH+XS+7*M,
paul@0 118
  XPOS_KEY_DOT = LSH+XS+7*M+XS, XPOS_KEY_SLASH = LSH+XS+7*M+2*XS, XPOS_KEY_UP = LSH+XS+7*M+3*XS, XPOS_KEY_RIGHTSHIFT = LSH+XS+7*M+4*XS,
paul@0 119
paul@0 120
  XPOS_KEY_FN = 0, XPOS_KEY_LEFTCTRL = XS, XPOS_KEY_SLEEP = 2*XS, XPOS_KEY_LEFTALT = 3*XS, XPOS_KEY_PAUSE = 4*XS,
paul@0 121
  XPOS_KEY_SPACE = 5*XS, XPOS_KEY_MENU = 5*XS+SPC, XPOS_KEY_LEFTBRACE = 5*XS+SPC+XS, XPOS_KEY_RIGHTBRACE = 5*XS+SPC+2*XS,
paul@0 122
  XPOS_KEY_APOSTROPHE = 5*XS+SPC+3*XS, XPOS_KEY_LEFT = 5*XS+SPC+4*XS, XPOS_KEY_DOWN = 5*XS+SPC+5*XS, XPOS_KEY_RIGHT = 5*XS+SPC+6*XS,
paul@0 123
};
paul@0 124
paul@0 125
enum {
paul@0 126
  YPOS_KEY_ESC = 0, YPOS_KEY_F1 = 0, YPOS_KEY_F2 = 0, YPOS_KEY_F3 = 0, YPOS_KEY_F4 = 0,
paul@0 127
  YPOS_KEY_F5 = 0, YPOS_KEY_F6 = 0, YPOS_KEY_F7 = 0, YPOS_KEY_F8 = 0, YPOS_KEY_F9 = 0,
paul@0 128
  YPOS_KEY_F10 = 0, YPOS_KEY_NUMLOCK = 0, YPOS_KEY_SYSRQ = 0, YPOS_KEY_INSERT = 0,
paul@0 129
  YPOS_KEY_DELETE = 0,
paul@0 130
paul@0 131
  YPOS_KEY_GRAVE = 1, YPOS_KEY_1 = 1, YPOS_KEY_2 = 1, YPOS_KEY_3 = 1, YPOS_KEY_4 = 1,
paul@0 132
  YPOS_KEY_5 = 1, YPOS_KEY_6 = 1, YPOS_KEY_7 = 1, YPOS_KEY_8 = 1, YPOS_KEY_9 = 1,
paul@0 133
  YPOS_KEY_0 = 1, YPOS_KEY_MINUS = 1, YPOS_KEY_BACKSPACE = 1,
paul@0 134
paul@0 135
  YPOS_KEY_TAB = 2, YPOS_KEY_Q = 2, YPOS_KEY_W = 2, YPOS_KEY_E = 2, YPOS_KEY_R = 2,
paul@0 136
  YPOS_KEY_T = 2, YPOS_KEY_Y = 2, YPOS_KEY_U = 2, YPOS_KEY_I = 2, YPOS_KEY_O = 2,
paul@0 137
  YPOS_KEY_P = 2, YPOS_KEY_EQUAL = 2, YPOS_KEY_RIGHTBACKSLASH = 2,
paul@0 138
paul@0 139
  YPOS_KEY_CAPSLOCK = 3, YPOS_KEY_A = 3, YPOS_KEY_S = 3, YPOS_KEY_D = 3, YPOS_KEY_F = 3,
paul@0 140
  YPOS_KEY_G = 3, YPOS_KEY_H = 3, YPOS_KEY_J = 3, YPOS_KEY_K = 3, YPOS_KEY_L = 3,
paul@0 141
  YPOS_KEY_SEMICOLON = 3, YPOS_KEY_ENTER = 3,
paul@0 142
paul@0 143
  YPOS_KEY_LEFTSHIFT = 4, YPOS_KEY_LEFTBACKSLASH = 4, YPOS_KEY_Z = 4, YPOS_KEY_X = 4, YPOS_KEY_C = 4,
paul@0 144
  YPOS_KEY_V = 4, YPOS_KEY_B = 4, YPOS_KEY_N = 4, YPOS_KEY_M = 4, YPOS_KEY_COMMA = 4,
paul@0 145
  YPOS_KEY_DOT = 4, YPOS_KEY_SLASH = 4, YPOS_KEY_UP = 4, YPOS_KEY_RIGHTSHIFT = 4,
paul@0 146
paul@0 147
  YPOS_KEY_FN = 5, YPOS_KEY_LEFTCTRL = 5, YPOS_KEY_SLEEP = 5, YPOS_KEY_LEFTALT = 5, YPOS_KEY_PAUSE = 5,
paul@0 148
  YPOS_KEY_SPACE = 5, YPOS_KEY_MENU = 5, YPOS_KEY_LEFTBRACE = 5, YPOS_KEY_RIGHTBRACE = 5,
paul@0 149
  YPOS_KEY_APOSTROPHE = 5, YPOS_KEY_LEFT = 5, YPOS_KEY_DOWN = 5, YPOS_KEY_RIGHT = 5,
paul@0 150
};
paul@0 151
paul@0 152
/* Keypad matrix mapping. */
paul@0 153
paul@0 154
#define PHYS_KEY(X) {XPOS_KEY_##X, YPOS_KEY_##X, SIZE_KEY_##X}
paul@0 155
#define PHYS_NULL   {0, 0, 0}
paul@0 156
paul@0 157
static const uint32_t keypos[Jz4730_keypad_gpio_inputs_count][Jz4730_keypad_gpio_outputs_count][3] = {
paul@0 158
paul@0 159
{PHYS_KEY(PAUSE), PHYS_KEY(Q), PHYS_KEY(W), PHYS_KEY(E), PHYS_KEY(R), PHYS_KEY(U), PHYS_KEY(I), PHYS_KEY(O),
paul@0 160
 PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(P), PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_NULL},
paul@0 161
paul@0 162
{PHYS_NULL, PHYS_KEY(TAB), PHYS_KEY(CAPSLOCK), PHYS_KEY(F3), PHYS_KEY(T), PHYS_KEY(Y), PHYS_KEY(RIGHTBRACE), PHYS_KEY(F7),
paul@0 163
 PHYS_NULL, PHYS_KEY(BACKSPACE), PHYS_NULL, PHYS_KEY(LEFTBRACE), PHYS_KEY(SLEEP), PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(LEFTSHIFT)},
paul@0 164
paul@0 165
{PHYS_NULL, PHYS_KEY(A), PHYS_KEY(S), PHYS_KEY(D), PHYS_KEY(F), PHYS_KEY(J), PHYS_KEY(K), PHYS_KEY(L),
paul@0 166
 PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(SEMICOLON), PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(UP), PHYS_KEY(RIGHTSHIFT)},
paul@0 167
paul@0 168
{PHYS_NULL, PHYS_KEY(ESC), PHYS_KEY(LEFTBACKSLASH), PHYS_KEY(F4), PHYS_KEY(G), PHYS_KEY(H), PHYS_KEY(F6), PHYS_NULL,
paul@0 169
 PHYS_KEY(SPACE), PHYS_NULL, PHYS_KEY(LEFTALT), PHYS_KEY(APOSTROPHE), PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(DOWN), PHYS_NULL},
paul@0 170
paul@0 171
{PHYS_NULL, PHYS_KEY(Z), PHYS_KEY(X), PHYS_KEY(C), PHYS_KEY(V), PHYS_KEY(M), PHYS_KEY(COMMA), PHYS_KEY(DOT),
paul@0 172
 PHYS_KEY(NUMLOCK), PHYS_KEY(ENTER), PHYS_NULL, PHYS_KEY(RIGHTBACKSLASH), PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(LEFT), PHYS_NULL},
paul@0 173
paul@0 174
{PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(B), PHYS_KEY(N), PHYS_NULL, PHYS_KEY(MENU),
paul@0 175
 PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(SLASH), PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(RIGHT), PHYS_NULL},
paul@0 176
paul@0 177
{PHYS_KEY(LEFTCTRL), PHYS_KEY(GRAVE), PHYS_NULL, PHYS_NULL, PHYS_KEY(5), PHYS_KEY(6), PHYS_KEY(EQUAL), PHYS_KEY(F8),
paul@0 178
 PHYS_KEY(DELETE), PHYS_KEY(F9), PHYS_NULL, PHYS_KEY(MINUS), PHYS_NULL, PHYS_KEY(F2), PHYS_KEY(INSERT), PHYS_NULL, PHYS_KEY(F1)},
paul@0 179
paul@0 180
{PHYS_KEY(F5), PHYS_KEY(1), PHYS_KEY(2), PHYS_KEY(3), PHYS_KEY(4), PHYS_KEY(7), PHYS_KEY(8), PHYS_KEY(9),
paul@0 181
 PHYS_NULL, PHYS_NULL, PHYS_KEY(SYSRQ), PHYS_KEY(0), PHYS_KEY(F10), PHYS_NULL, PHYS_NULL, PHYS_NULL, PHYS_KEY(FN)}
paul@0 182
};
paul@0 183
paul@0 184
paul@0 185
paul@0 186
static uint32_t bitmask(uint32_t size)
paul@0 187
{
paul@0 188
  return (1 << size) - 1;
paul@0 189
}
paul@0 190
paul@0 191
static uint32_t truncate_channel(uint32_t value, uint32_t size)
paul@0 192
{
paul@0 193
  return (value >> (8 - size)) & bitmask(size);
paul@0 194
}
paul@0 195
paul@0 196
static void set_pixel(uint32_t pos, uint8_t bpp, uint32_t value)
paul@0 197
{
paul@0 198
  if (bpp <= 8) *(uint8_t *) pos = value;
paul@0 199
  else if (bpp <= 16) *(uint16_t *) pos = value;
paul@0 200
  else *(uint32_t *) pos = value;
paul@0 201
}
paul@0 202
paul@0 203
/* Show the state of a key on the display. */
paul@0 204
paul@0 205
static void fill_rectangle(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t rgb)
paul@0 206
{
paul@0 207
  uint8_t bpp = l4re_video_bits_per_pixel(&fbi.pixel_info);
paul@0 208
  uint8_t bytes_per_pixel = fbi.pixel_info.bytes_per_pixel;
paul@0 209
  uint32_t bytes_per_line = fbi.bytes_per_line;
paul@0 210
  uint32_t pos;
paul@0 211
  uint32_t col, row;
paul@0 212
paul@0 213
  rgb = (truncate_channel(rgb >> 16, fbi.pixel_info.r.size) << fbi.pixel_info.r.shift) |
paul@0 214
        (truncate_channel(rgb >> 8, fbi.pixel_info.g.size) << fbi.pixel_info.g.shift) |
paul@0 215
        (truncate_channel(rgb, fbi.pixel_info.b.size) << fbi.pixel_info.b.shift);
paul@0 216
paul@0 217
  for (row = 0; row < h; row++)
paul@0 218
  {
paul@0 219
    pos = (uint32_t) fb + (y + row) * bytes_per_line + x * bytes_per_pixel;
paul@0 220
paul@0 221
    for (col = 0; col < w; col++)
paul@0 222
    {
paul@0 223
      set_pixel(pos, bpp, rgb);
paul@0 224
      pos += bytes_per_pixel;
paul@0 225
    }
paul@0 226
  }
paul@0 227
}
paul@0 228
paul@0 229
/* Show the keypad status on the display. */
paul@0 230
paul@0 231
static void show_keypad(void)
paul@0 232
{
paul@0 233
  uint32_t rowsize = fbi.height / ROWS, colsize;
paul@0 234
  uint8_t column, row;
paul@0 235
  uint32_t mask;
paul@0 236
  const uint32_t *pos;
paul@0 237
paul@0 238
  for (column = 0; column < columns; column++)
paul@0 239
 
paul@0 240
    for (row = 0, mask = 1 << (rows - 1);
paul@0 241
         row < rows;
paul@0 242
         row++, mask >>= 1)
paul@0 243
    {
paul@0 244
      /* Obtain the physical position. */
paul@0 245
paul@0 246
      pos = keypos[row][column];
paul@0 247
paul@0 248
      /* Obtain the width of the key. */
paul@0 249
paul@0 250
      colsize = (pos[2] * fbi.width) / WIDTH;
paul@0 251
paul@0 252
      /* Plot the rectangle for the key. */
paul@0 253
paul@0 254
      fill_rectangle((pos[0] * fbi.width) / WIDTH, pos[1] * rowsize, colsize, rowsize,
paul@0 255
                     keypad[column] & mask ? 0xffffff : 0);
paul@0 256
    }
paul@0 257
paul@0 258
  /* Refresh the display. */
paul@0 259
paul@0 260
  l4re_util_video_goos_fb_refresh(&gfb, 0, 0, fbi.width, fbi.height);
paul@0 261
}
paul@0 262
paul@0 263
paul@0 264
paul@0 265
int main(void)
paul@0 266
{
paul@0 267
  l4_cap_idx_t keypad_server;
paul@0 268
  l4re_ds_t mem;
paul@0 269
  l4_msgtag_t tag;
paul@0 270
paul@0 271
  if (l4re_util_video_goos_fb_setup_name(&gfb, "fb"))
paul@0 272
    return 1;
paul@0 273
paul@0 274
  if (l4re_util_video_goos_fb_view_info(&gfb, &fbi))
paul@0 275
    return 1;
paul@0 276
paul@0 277
  if (!(fb = l4re_util_video_goos_fb_attach_buffer(&gfb)))
paul@0 278
    return 1;
paul@0 279
paul@0 280
  /* Obtain a reference to the keypad. */
paul@0 281
paul@0 282
  keypad_server = l4re_env_get_cap("keypad");
paul@0 283
  if (l4_is_invalid_cap(keypad_server)) return 1;
paul@0 284
paul@0 285
  /* Obtain a capability for the keypad data. */
paul@0 286
paul@0 287
  mem = l4re_util_cap_alloc();
paul@0 288
  if (l4_is_invalid_cap(mem)) return 1;
paul@0 289
paul@0 290
  /* Obtain a reference to the keypad data. */
paul@0 291
paul@0 292
  l4_utcb_br()->bdr = 0;
paul@0 293
  l4_utcb_br()->br[0] = L4_RCV_ITEM_SINGLE_CAP | mem;
paul@0 294
paul@0 295
  tag = l4_ipc_call(keypad_server, l4_utcb(),
paul@0 296
                    l4_msgtag(0, 0, 0, 0), /* label zero, zero words, zero *sent* items */
paul@0 297
                    L4_IPC_NEVER);
paul@0 298
paul@0 299
  if (l4_ipc_error(tag, l4_utcb())) return 1;
paul@0 300
paul@0 301
  /* Attach the keypad data to a region in this task. */
paul@0 302
paul@142 303
  if (l4re_rm_attach(&keymem, l4re_ds_size(mem), L4RE_RM_F_SEARCH_ADDR, mem, 0,
paul@0 304
                     L4_PAGESHIFT))
paul@0 305
    return 1;
paul@0 306
paul@0 307
  /* Show the keypad state. */
paul@0 308
paul@0 309
  keypad = (uint32_t *) keymem;
paul@0 310
paul@0 311
  while (1) show_keypad();
paul@0 312
paul@0 313
  return 0;
paul@0 314
}