Landfall

pkg/landfall-examples/keypad_ds_client/keypad_ds_client.cc

145:67a6da4b40ea
17 months ago Paul Boddie Incorporated API changes made to the L4Re distribution since Subversion r83. l4re-git-distribution
     1 /*     2  * Display the keypad matrix using the specified dimensions.     3  *     4  * Copyright (C) 2018, 2023 Paul Boddie <paul@boddie.org.uk>     5  *     6  * This program is free software; you can redistribute it and/or     7  * modify it under the terms of the GNU General Public License as     8  * published by the Free Software Foundation; either version 2 of     9  * the License, or (at your option) any later version.    10  *    11  * This program is distributed in the hope that it will be useful,    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    14  * GNU General Public License for more details.    15  *    16  * You should have received a copy of the GNU General Public License    17  * along with this program; if not, write to the Free Software    18  * Foundation, Inc., 51 Franklin Street, Fifth Floor,    19  * Boston, MA  02110-1301, USA    20  */    21     22 #include <l4/devices/keypad-client.h>    23     24 #include <l4/cxx/ipc_server>    25 #include <l4/re/dataspace>    26 #include <l4/re/env>    27 #include <l4/re/rm>    28 #include <l4/re/util/cap_alloc>    29     30 #include <l4/re/c/util/video/goos_fb.h>    31 #include <l4/re/c/video/view.h>    32     33 #include <l4/util/util.h>    34 #include <stdio.h>    35 #include <unistd.h>    36 #include <stdint.h>    37 #include <stdlib.h>    38     39 /* Video abstractions. */    40     41 static l4re_util_video_goos_fb_t gfb;    42 static l4re_video_view_info_t fbi;    43 static void *fb;    44     45 /* Keypad status and dimensions. */    46     47 uint32_t *keypad = 0;    48 void *keymem = 0;    49 int columns, rows;    50     51     52     53 static uint32_t bitmask(uint32_t size)    54 {    55   return (1 << size) - 1;    56 }    57     58 static uint32_t truncate_channel(uint32_t value, uint32_t size)    59 {    60   return (value >> (8 - size)) & bitmask(size);    61 }    62     63 static void set_pixel(uint32_t pos, uint8_t bpp, uint32_t value)    64 {    65   if (bpp <= 8) *(uint8_t *) pos = value;    66   else if (bpp <= 16) *(uint16_t *) pos = value;    67   else *(uint32_t *) pos = value;    68 }    69     70 /* Show the state of a key on the display. */    71     72 static void show_keystate(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t rgb)    73 {    74   uint8_t bpp = l4re_video_bits_per_pixel(&fbi.pixel_info);    75   uint8_t bytes_per_pixel = fbi.pixel_info.bytes_per_pixel;    76   uint32_t bytes_per_line = fbi.bytes_per_line;    77   uint32_t pos;    78   uint32_t col, row;    79     80   rgb = (truncate_channel(rgb >> 16, fbi.pixel_info.r.size) << fbi.pixel_info.r.shift) |    81         (truncate_channel(rgb >> 8, fbi.pixel_info.g.size) << fbi.pixel_info.g.shift) |    82         (truncate_channel(rgb, fbi.pixel_info.b.size) << fbi.pixel_info.b.shift);    83     84   for (row = 0; row < h; row++)    85   {    86     pos = (uint32_t) fb + (y + row) * bytes_per_line + x * bytes_per_pixel;    87     88     for (col = 0; col < w; col++)    89     {    90       set_pixel(pos, bpp, rgb);    91       pos += bytes_per_pixel;    92     }    93   }    94 }    95     96 /* Show the keypad status on the display. */    97     98 static void show_keypad(void)    99 {   100   uint32_t colsize = fbi.width / columns,   101            rowsize = fbi.height / rows;   102   uint8_t column, row;   103   uint32_t mask;   104    105   for (column = 0; column < columns; column++)   106    107     for (row = 0, mask = 1 << (rows - 1);   108          row < rows;   109          row++, mask >>= 1)   110    111       show_keystate(column * colsize, row * rowsize, colsize, rowsize,   112                     keypad[column] & mask ? 0xffffff : 0);   113    114   /* Refresh the display. */   115    116   l4re_util_video_goos_fb_refresh(&gfb, 0, 0, fbi.width, fbi.height);   117 }   118    119    120    121 int main(int argc, char *argv[])   122 {   123   L4::Cap<Keypad_device_interface> keypad_server;   124   L4::Cap<L4Re::Dataspace> mem;   125    126   /* Obtain the keypad matrix dimensions. */   127    128   if (argc < 3)   129     return 1;   130    131   columns = atoi(argv[1]);   132   rows = atoi(argv[2]);   133    134   if (l4re_util_video_goos_fb_setup_name(&gfb, "fb"))   135     return 1;   136    137   if (l4re_util_video_goos_fb_view_info(&gfb, &fbi))   138     return 1;   139    140   if (!(fb = l4re_util_video_goos_fb_attach_buffer(&gfb)))   141     return 1;   142    143   /* Obtain a reference to the keypad. */   144    145   keypad_server = L4Re::Env::env()->get_cap<Keypad_device_interface>("keypad");   146   if (!keypad_server.is_valid()) return 1;   147    148   /* Obtain a capability for the keypad data. */   149    150   mem = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();   151   if (!mem.is_valid()) return 1;   152    153   /* Obtain a reference to the keypad data. */   154    155   if (keypad_server->get_keypad_data(mem)) return 1;   156    157   /* Attach the keypad data to a region in this task. */   158    159   if (L4Re::Env::env()->rm()->attach(&keymem, mem->size(),   160                                      L4Re::Rm::F::Search_addr |   161                                      L4Re::Rm::F::R,   162                                      L4::Ipc::make_cap_rw(mem)))   163     return 1;   164    165   /* Show the keypad state. */   166    167   keypad = (uint32_t *) keymem;   168    169   while (1) show_keypad();   170    171   return 0;   172 }