Linux emulator code cleanup and refactoring

This commit is contained in:
Silvano Seva 2021-12-05 18:16:22 +01:00 committed by Niccolò Izzo
parent 18fb916834
commit 9dc0819b8b
4 changed files with 279 additions and 267 deletions

View File

@ -1,11 +0,0 @@
style=allman
indent=spaces=4
pad-comma
pad-oper
add-braces
keep-one-line-blocks
keep-one-line-statements
add-one-line-braces
align-pointer=name
align-reference=name
verbose

View File

@ -72,20 +72,20 @@ void _dump_skq()
} }
void shellkeyq_put(keyboard_t keys) void shellkeyq_put(keyboard_t keys)
{ {
//note - we must allow keys == 0 to be inserted because otherwise a queue full of // note - we must allow keys == 0 to be inserted because otherwise a queue
// [1,1,1,1,1] is simulating HOLDING 1, and we sometimes (well, often) want // full of [1,1,1,1,1] is simulating HOLDING 1, and we sometimes
// [1,0,1,0,1,0] to simulate separate keypresses // (well, often) want [1,0,1,0,1,0] to simulate separate keypresses
// this, of course, relies on the kbd_thread getting just one element off the queue // this, of course, relies on the kbd_thread getting just one element off
// for every kbd_getKeys(). // the queue for every kbd_getKeys().
if(_skq_in > _skq_out + _skq_cap) if(_skq_in > _skq_out + _skq_cap)
{ {
printf("too many keys!\n"); printf("too many keys!\n");
return; return;
} }
_shellkeyq[ _skq_tail ] = keys; _shellkeyq[ _skq_tail ] = keys;
_skq_in++; _skq_in++;
_skq_tail = (_skq_tail + 1) % _skq_cap; _skq_tail = (_skq_tail + 1) % _skq_cap;
/*printf("head: %d tail: %d in %d out %d\n", _skq_head, _skq_tail, _skq_in, _skq_out);*/
} }
keyboard_t shellkeyq_get() keyboard_t shellkeyq_get()
{ {
@ -96,8 +96,6 @@ keyboard_t shellkeyq_get()
_shellkeyq[ _skq_head ] = 0; _shellkeyq[ _skq_head ] = 0;
_skq_out++; _skq_out++;
_skq_head = (_skq_head + 1) % _skq_cap; _skq_head = (_skq_head + 1) % _skq_cap;
/*printf("head: %d tail: %d in %d out %d\n", _skq_head, _skq_tail, _skq_in, _skq_out);*/
/*_dump_skq();*/
return out; return out;
} }
else else
@ -132,41 +130,50 @@ int shell_ready(void *_self, int _argc, char **_argv)
keyboard_t keyname2keyboard(char *name) keyboard_t keyname2keyboard(char *name)
{ {
/* The line noise at the end of this comment is a vim macro for taking the keyboard.h /* The line noise at the end of this comment is a vim macro for taking the
interface and putting it into the format further below * keyboard.h interface and putting it into the format further below.
You can load it into vim register k with "kyy * You can load it into vim register k with "kyy and run the macro with @k
and run the macro with @k (and then you can repeat a macro register application with @@ ) * (and then you can repeat a macro register application with @@ )
(substitute k with any register you like) * (substitute k with any register you like)
Once you've got all the names quoted, you can J them all together into a nice block. * Once you've got all the names quoted, you can J them all together into
* a nice block.
_i"ElC", *
* _i"ElC",
*/ *
*/
char *names[] = char *names[] =
{ {
"KEY_0", "KEY_1", "KEY_2", "KEY_3", "KEY_4", "KEY_5", "KEY_6", "KEY_7", "KEY_0", "KEY_1", "KEY_2", "KEY_3", "KEY_4", "KEY_5", "KEY_6", "KEY_7",
"KEY_8", "KEY_9", "KEY_STAR", "KEY_HASH", "KEY_ENTER", "KEY_ESC", "KEY_UP", "KEY_8", "KEY_9", "KEY_STAR", "KEY_HASH", "KEY_ENTER", "KEY_ESC",
"KEY_DOWN", "KEY_LEFT", "KEY_RIGHT", "KEY_MONI", "KEY_F1", "KEY_F2", "KEY_F3", "KEY_UP","KEY_DOWN", "KEY_LEFT", "KEY_RIGHT", "KEY_MONI", "KEY_F1",
"KEY_F4", "KEY_F5", "KEY_F6", "KEY_F7", "KEY_F8", "KNOB_LEFT", "KNOB_RIGHT", "KEY_F2", "KEY_F3", "KEY_F4", "KEY_F5", "KEY_F6", "KEY_F7", "KEY_F8",
"KNOB_LEFT", "KNOB_RIGHT",
}; };
int numnames = sizeof(names) / sizeof(char *); int numnames = sizeof(names) / sizeof(char *);
for(int i = 0; i < numnames; i++) for(int i = 0; i < numnames; i++)
{ {
if(strcasecmp(name, names[i] + 4) == 0 || strcasecmp(name, names[i]) == 0) //notice case insensitive /*
{ * +4 to skip the KEY_ on all the names, non +4 to allow for KNOB_LEFT.
/*printf("MATCH with %s\n", names[i]);*/ * This also means you can write KEY_LEFT as "KEY_LEFT", or "LEFT" and
//+4 to skip the KEY_ on all the names, non +4 to allow for KNOB_LEFT. * KNOB_LEFT as "KNOB_LEFT" or "_LEFT"
//This also means you can write KEY_LEFT as "KEY_LEFT", or "LEFT" and KNOB_LEFT as "KNOB_LEFT" or "_LEFT" *
* so if name == "2", this whole function will return equivalent to KEY_2 cpp define
* and if name=="LEFT", then you get equivalent to KEY_LEFT cpp define
* and if name=="_LEFT", then you get equivalent to KNOB_LEFT cpp define
* and if name=="KNOB_LEFT", then you get equivalent to KNOB_LEFT cpp define
* and if name=="KEY_2", then you get equivalent to KEY_2 cpp define.
*
* Of course order matters a great deal in names array, has to match the
* bit field generated in interface/keyboard.h so double check that with
* every update
*/
//so if name == "2", this whole function will return equivalent to KEY_2 cpp define if((strcasecmp(name, names[i] + 4) == 0) ||
//and if name=="LEFT", then you get equivalent to KEY_LEFT cpp define (strcasecmp(name, names[i]) == 0)) //notice case insensitive
//and if name=="_LEFT", then you get equivalent to KNOB_LEFT cpp define {
//and if name=="KNOB_LEFT", then you get equivalent to KNOB_LEFT cpp define
//and if name=="KEY_2", then you get equivalent to KEY_2 cpp define of course
return (1 << i); return (1 << i);
//order matters a great deal in names array, has to match
//the bit field generated in interface/keyboard.h
//so double check that with every update
} }
} }
return 0; return 0;
@ -175,10 +182,10 @@ keyboard_t keyname2keyboard(char *name)
int pressKey(void *_self, int _argc, char **_argv) int pressKey(void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
//press a couple keys in sequence
/*_climenu_option * self = (_climenu_option*) _self;*/
printf("Press Keys: [\n"); printf("Press Keys: [\n");
keyboard_t last = 0; keyboard_t last = 0;
for(int i = 0; i < _argc; i++) for(int i = 0; i < _argc; i++)
{ {
if(_argv[i] != NULL) if(_argv[i] != NULL)
@ -187,13 +194,14 @@ int pressKey(void *_self, int _argc, char **_argv)
keyboard_t press = keyname2keyboard(_argv[i]); keyboard_t press = keyname2keyboard(_argv[i]);
if(press == last) if(press == last)
{ {
//otherwise if you send key ENTER DOWN DOWN DOWN DOWN DOWN /* otherwise if you send key ENTER DOWN DOWN DOWN DOWN DOWN
//it will just hold DOWN for (5/(kbd_task_hz)) seconds * it will just hold DOWN for (5/(kbd_task_hz)) seconds
//so we need to give it a 0 value to get a 'release' * so we need to give it a 0 value to get a 'release'
//so the next input is recognized as separate * so the next input is recognized as separate
//we only need to do this if we have two identical keys back to back, * we only need to do this if we have two identical keys back
//because keyboard_t will have a zero for this key's * to back, because keyboard_t will have a zero for this key's
//flag on other keys, which gives us the release we need * flag on other keys, which gives us the release we need
*/
shellkeyq_put(0); shellkeyq_put(0);
} }
shellkeyq_put(press); shellkeyq_put(press);
@ -204,13 +212,15 @@ int pressKey(void *_self, int _argc, char **_argv)
shell_ready(NULL, 0, NULL); shell_ready(NULL, 0, NULL);
return SH_CONTINUE; // continue return SH_CONTINUE; // continue
} }
// pressMultiKeys allows for key combos by sending all the keys specified in
// one keyboard_t
int pressMultiKeys(void *_self, int _argc, char **_argv) int pressMultiKeys(void *_self, int _argc, char **_argv)
{ {
//pressMultiKeys allows for key combos by sending all the keys specified in one keyboard_t
/*_climenu_option * self = (_climenu_option*) _self;*/
(void) _self; (void) _self;
printf("Press Keys: [\n"); printf("Press Keys: [\n");
keyboard_t combo = 0; keyboard_t combo = 0;
for(int i = 0; i < _argc; i++) for(int i = 0; i < _argc; i++)
{ {
if(_argv[i] != NULL) if(_argv[i] != NULL)
@ -219,15 +229,12 @@ int pressMultiKeys(void *_self, int _argc, char **_argv)
combo |= keyname2keyboard(_argv[i]); combo |= keyname2keyboard(_argv[i]);
} }
} }
shellkeyq_put(combo); shellkeyq_put(combo);
printf("\t]\n"); printf("\t]\n");
shell_ready(NULL, 0, NULL); shell_ready(NULL, 0, NULL);
return SH_CONTINUE; // continue return SH_CONTINUE; // continue
} }
//need another function to press them in sequence by loading up a queue for keypress_from_shell to pull from
int template(void *_self, int _argc, char **_argv) int template(void *_self, int _argc, char **_argv)
{ {
@ -241,6 +248,7 @@ int template(void *_self, int _argc, char **_argv)
printf("\tArgs:\t%s\n", _argv[i]); printf("\tArgs:\t%s\n", _argv[i]);
} }
} }
return SH_CONTINUE; // continue return SH_CONTINUE; // continue
} }
@ -248,6 +256,7 @@ int screenshot(void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
char *filename = "screenshot.bmp"; char *filename = "screenshot.bmp";
if(_argc && _argv[0] != NULL) if(_argc && _argv[0] != NULL)
{ {
filename = _argv[0]; filename = _argv[0];
@ -261,24 +270,7 @@ int screenshot(void *_self, int _argc, char **_argv)
return SDL_PushEvent(&e) == 1 ? SH_CONTINUE : SH_ERR; return SDL_PushEvent(&e) == 1 ? SH_CONTINUE : SH_ERR;
} }
/*
int record_start(void * _self, int _argc, char ** _argv ){
char * filename = "screen.mkv";
if( _argc && _argv[0] != NULL ){
filename = _argv[0];
}
//id="xwininfo -name 'OpenRTX' | grep id: |cut -d ' ' -f 4";
//system("ffmpeg -f x11grab -show_region 1 -region_border 10 -window_id 0x2600016 -i :0.0 out.mkv");
//https://stackoverflow.com/questions/14764873/how-do-i-detect-when-the-contents-of-an-x11-window-have-changed
return SH_ERR;
}
int record_stop(
void * _self,
int _argc,
char ** _argv ){
return SH_ERR;
}
*/
int setFloat(void *_self, int _argc, char **_argv) int setFloat(void *_self, int _argc, char **_argv)
{ {
_climenu_option *self = (_climenu_option *) _self; _climenu_option *self = (_climenu_option *) _self;
@ -292,39 +284,47 @@ int setFloat(void *_self, int _argc, char **_argv)
sscanf(_argv[0], "%f", (float *)self->var); sscanf(_argv[0], "%f", (float *)self->var);
printf("%s is %f\n", self->name, *(float *)(self->var)); printf("%s is %f\n", self->name, *(float *)(self->var));
} }
return SH_CONTINUE; // continue return SH_CONTINUE; // continue
} }
int toggleVariable(void *_self, int _argc, char **_argv) int toggleVariable(void *_self, int _argc, char **_argv)
{ {
(void) _argc; (void) _argc;
(void) _argv; (void) _argv;
_climenu_option *self = (_climenu_option *) _self; _climenu_option *self = (_climenu_option *) _self;
*(int *)self->var = ! *(int *)self->var; //yeah, maybe this got a little out of hand *(int *)self->var = ! *(int *)self->var; //yeah, maybe this got a little out of hand
return SH_CONTINUE; // continue
return SH_CONTINUE; // continue
} }
int shell_sleep(void *_self, int _argc, char **_argv) int shell_sleep(void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
if(! _argc || _argv[0] == NULL) if(! _argc || _argv[0] == NULL)
{ {
printf("Provide a number in milliseconds to sleep as an argument\n"); printf("Provide a number in milliseconds to sleep as an argument\n");
return SH_ERR; return SH_ERR;
} }
useconds_t sleepus = atoi(_argv[0]) * 1000; useconds_t sleepus = atoi(_argv[0]) * 1000;
usleep(sleepus); usleep(sleepus);
return SH_CONTINUE; return SH_CONTINUE;
} }
int shell_quit( void *_self, int _argc, char **_argv) int shell_quit( void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
(void) _argc; (void) _argc;
(void) _argv; (void) _argv;
printf("QUIT: 73!\n"); printf("QUIT: 73!\n");
//could remove history entries here, if we wanted //could remove history entries here, if we wanted
return SH_EXIT_OK; //normal quit return SH_EXIT_OK; //normal quit
} }
int printState( void *_self, int _argc, char **_argv) int printState( void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
@ -339,6 +339,7 @@ int printState( void *_self, int _argc, char **_argv)
printf("PTT : %s\n\n", Radio_State.PttStatus ? "true" : "false"); printf("PTT : %s\n\n", Radio_State.PttStatus ? "true" : "false");
return SH_CONTINUE; return SH_CONTINUE;
} }
int shell_nop( void *_self, int _argc, char **_argv) int shell_nop( void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
@ -348,64 +349,50 @@ int shell_nop( void *_self, int _argc, char **_argv)
return SH_CONTINUE; return SH_CONTINUE;
} }
int shell_help(void *_self, int _argc, char **_argv); // Forward declaration needed to include function pointer in the table below
int shell_help( void *_self, int _argc, char **_argv);
_climenu_option _options[] = _climenu_option _options[] =
{ {
/* name/shortcut description var reference, if available method to call */ /* name/shortcut description var reference, if available method to call */
{"rssi", "Set rssi", (void *) &Radio_State.RSSI, setFloat }, {"rssi", "Set rssi", (void *) &Radio_State.RSSI, setFloat },
{"vbat", "Set vbat", (void *) &Radio_State.Vbat, setFloat }, {"vbat", "Set vbat", (void *) &Radio_State.Vbat, setFloat },
{"mic", "Set miclevel", (void *) &Radio_State.micLevel, setFloat }, {"mic", "Set miclevel", (void *) &Radio_State.micLevel, setFloat },
{"volume", "Set volume", (void *) &Radio_State.volumeLevel, setFloat }, {"volume", "Set volume", (void *) &Radio_State.volumeLevel, setFloat },
{"channel", "Set channel", (void *) &Radio_State.chSelector, setFloat }, {"channel", "Set channel", (void *) &Radio_State.chSelector, setFloat },
{"ptt", "Toggle PTT", (void *) &Radio_State.PttStatus, toggleVariable }, {"ptt", "Toggle PTT", (void *) &Radio_State.PttStatus, toggleVariable },
{ {"key", "Press keys in sequence (e.g. 'key ENTER DOWN ENTER' will descend through two menus)",
"key", "Press keys in sequence (e.g. 'key ENTER DOWN ENTER' will descend through two menus)", NULL, pressKey
NULL, pressKey
}, },
{ {"keycombo", "Press a bunch of keys simultaneously", NULL, pressMultiKeys },
"keycombo", "Press a bunch of keys simultaneously ", {"show", "Show current radio state (ptt, rssi, etc)", NULL, printState},
NULL, pressMultiKeys {"screenshot", "[screenshot.bmp] Save screenshot to first arg or screenshot.bmp if none given",
}, NULL, screenshot
{
"show", "Show current radio state (ptt, rssi, etc)",
NULL, printState
},
{
"screenshot", "[screenshot.bmp] Save screenshot to first arg or screenshot.bmp if none given",
NULL, screenshot
},
/*{"record_start", "[screen.mkv] Automatically save a video of the remaining session (or until record_stop is called)",*/
/*NULL, record_start },*/
/*{"record_stop", "Stop the running recording, or no-op if none started",*/
/*NULL, record_stop },*/
{"sleep", "Wait some number of ms", NULL, shell_sleep },
{"help", "Print this help", NULL, shell_help },
{
"nop", "Do nothing (useful for comments)",
NULL, shell_nop
}, },
{"sleep", "Wait some number of ms", NULL, shell_sleep },
{"help", "Print this help", NULL, shell_help },
{"nop", "Do nothing (useful for comments)", NULL, shell_nop},
{"quit", "Quit, close the emulator", NULL, shell_quit },
/*{"ready", */ /*{"ready", */
/*"Wait until ready. Currently supports keyboard, so will wait until all keyboard events are processed,"*/ /*"Wait until ready. Currently supports keyboard, so will wait until all keyboard events are processed,"*/
/*"but is already implied by key and keycombo so there's not much direct use for it right now",*/ /*"but is already implied by key and keycombo so there's not much direct use for it right now",*/
/*NULL, shell_ready },*/ /*NULL, shell_ready },*/
{"quit", "Quit, close the emulator", NULL, shell_quit },
}; };
int num_options = (sizeof(_options) / sizeof(_climenu_option)); int num_options = (sizeof(_options) / sizeof(_climenu_option));
int shell_help( void *_self, int _argc, char **_argv) int shell_help( void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
(void) _argc; (void) _argc;
(void) _argv; (void) _argv;
printf("OpenRTX emulator shell\n\n"); printf("OpenRTX emulator shell\n\n");
for(int i = 0; i < num_options; i++) for(int i = 0; i < num_options; i++)
{ {
_climenu_option *o = &_options[i]; _climenu_option *o = &_options[i];
printf("%10s -> %s\n", o->name, o->description); printf("%10s -> %s\n", o->name, o->description);
} }
return SH_CONTINUE; return SH_CONTINUE;
} }
@ -415,15 +402,19 @@ _climenu_option *findMenuOption(char *tok)
for(int i = 0; i < num_options; i++) for(int i = 0; i < num_options; i++)
{ {
_climenu_option *o = &_options[i]; _climenu_option *o = &_options[i];
/*
* strncmp like this allows for typing shortcuts like just "r" instead
* of the full "rssi". Priority for conflicts (like if there's "s"
* which could mean either "show" or "screenshot" ) is set by ordering
* in the _options array
*/
if(strncmp(tok, o->name, strlen(tok)) == 0) if(strncmp(tok, o->name, strlen(tok)) == 0)
{ {
//strncmp like this allows for typing shortcuts like just "r" instead of the full "rssi"
//priority for conflicts (like if there's "s" which could mean
// either "show" or "screenshot" )
//is set by ordering in the _options array
return o; return o;
} }
} }
return NULL; return NULL;
} }
@ -437,17 +428,21 @@ void striptoken(char *token)
} }
} }
} }
int process_line(char *line) int process_line(char *line)
{ {
char *token = strtok(line, " "); char *token = strtok(line, " ");
if(token == NULL) if(token == NULL)
{ {
return SH_ERR; return SH_ERR;
} }
striptoken(token); striptoken(token);
_climenu_option *o = findMenuOption(token); _climenu_option *o = findMenuOption(token);
char *args[12] = {NULL}; char *args[12] = {NULL};
int i = 0; int i = 0;
for(i = 0; i < 12; i++) for(i = 0; i < 12; i++)
{ {
//immediately strtok again since first is a command rest are args //immediately strtok again since first is a command rest are args
@ -459,10 +454,12 @@ int process_line(char *line)
striptoken(token); striptoken(token);
args[i] = token; args[i] = token;
} }
if(token != NULL) if(token != NULL)
{ {
printf("\nGot too many arguments, args truncated \n"); printf("\nGot too many arguments, args truncated \n");
} }
if(o != NULL) if(o != NULL)
{ {
if(o->fn != NULL) if(o->fn != NULL)
@ -480,18 +477,18 @@ int process_line(char *line)
return SH_WHAT; //not understood return SH_WHAT; //not understood
} }
} }
void *startCLIMenu() void *startCLIMenu()
{ {
printf("\n\n"); printf("\n\n");
char *histfile = ".emulatorsh_history"; char *histfile = ".emulatorsh_history";
shell_help(NULL, 0, NULL); shell_help(NULL, 0, NULL);
/*printf("\n> ");*/
int ret = SH_CONTINUE; int ret = SH_CONTINUE;
using_history(); using_history();
read_history(histfile); read_history(histfile);
do do
{ {
/*char * r = fgets(shellbuf, 255, stdin);*/
char *r = readline(">"); char *r = readline(">");
if(r == NULL) if(r == NULL)
{ {
@ -506,31 +503,37 @@ void *startCLIMenu()
{ {
ret = SH_CONTINUE; ret = SH_CONTINUE;
} }
switch(ret) switch(ret)
{ {
default: default:
fflush(stdout); fflush(stdout);
break; break;
case SH_WHAT:
printf("?\n(type h or help for help)\n"); case SH_WHAT:
ret = SH_CONTINUE; //i'd rather just fall through, but the compiler warns. blech. printf("?\n(type h or help for help)\n");
/*printf("\n>");*/ ret = SH_CONTINUE;
break; /*printf("\n>");*/
case SH_CONTINUE: break;
/*printf("\n>");*/
break; case SH_CONTINUE:
case SH_EXIT_OK: /*printf("\n>");*/
//normal quit break;
break;
case SH_ERR: case SH_EXIT_OK:
//error //normal quit
printf("Error running that command\n"); break;
ret = SH_CONTINUE;
break; case SH_ERR:
//error
printf("Error running that command\n");
ret = SH_CONTINUE;
break;
} }
free(r); //free the string allocated by readline free(r); //free the string allocated by readline
} }
while(ret == SH_CONTINUE); while(ret == SH_CONTINUE);
fflush(stdout); fflush(stdout);
write_history(histfile); write_history(histfile);
Radio_State.PowerOff = true; Radio_State.PowerOff = true;

View File

@ -39,91 +39,115 @@ pthread_mutex_t mu;
bool ready = false; /* Signal if the main loop is ready */ bool ready = false; /* Signal if the main loop is ready */
keyboard_t sdl_keys; /* Store the keyboard status */ keyboard_t sdl_keys; /* Store the keyboard status */
bool sdk_key_code_to_key(SDL_KeyCode sym, keyboard_t *key) bool sdk_key_code_to_key(SDL_Keycode sym, keyboard_t *key)
{ {
switch (sym) switch (sym)
{ {
case SDLK_0: case SDLK_0:
*key = KEY_0; *key = KEY_0;
return true; return true;
case SDLK_1:
*key = KEY_1; case SDLK_1:
return true; *key = KEY_1;
case SDLK_2: return true;
*key = KEY_2;
return true; case SDLK_2:
case SDLK_3: *key = KEY_2;
*key = KEY_3; return true;
return true;
case SDLK_4: case SDLK_3:
*key = KEY_4; *key = KEY_3;
return true; return true;
case SDLK_5:
*key = KEY_5; case SDLK_4:
return true; *key = KEY_4;
case SDLK_6: return true;
*key = KEY_6;
return true; case SDLK_5:
case SDLK_7: *key = KEY_5;
*key = KEY_7; return true;
return true;
case SDLK_8: case SDLK_6:
*key = KEY_8; *key = KEY_6;
return true; return true;
case SDLK_9:
*key = KEY_9; case SDLK_7:
return true; *key = KEY_7;
case SDLK_ASTERISK: return true;
*key = KEY_STAR;
return true; case SDLK_8:
case SDLK_ESCAPE: *key = KEY_8;
*key = KEY_ESC; return true;
return true;
case SDLK_LEFT: case SDLK_9:
*key = KEY_LEFT; *key = KEY_9;
return true; return true;
case SDLK_RIGHT:
*key = KEY_RIGHT; case SDLK_ASTERISK:
return true; *key = KEY_STAR;
case SDLK_RETURN: return true;
*key = KEY_ENTER;
return true; case SDLK_ESCAPE:
case SDLK_HASH: *key = KEY_ESC;
*key = KEY_HASH; return true;
return true;
case SDLK_n: case SDLK_LEFT:
*key = KEY_F1; *key = KEY_LEFT;
return true; return true;
case SDLK_m:
*key = KEY_MONI; case SDLK_RIGHT:
return true; *key = KEY_RIGHT;
case SDLK_PAGEUP: return true;
*key = KNOB_LEFT;
return true; case SDLK_RETURN:
case SDLK_PAGEDOWN: *key = KEY_ENTER;
*key = KNOB_RIGHT; return true;
return true;
case SDLK_UP: case SDLK_HASH:
*key = KEY_UP; *key = KEY_HASH;
return true; return true;
case SDLK_DOWN:
*key = KEY_DOWN; case SDLK_n:
return true; *key = KEY_F1;
default: return true;
return false;
case SDLK_m:
*key = KEY_MONI;
return true;
case SDLK_PAGEUP:
*key = KNOB_LEFT;
return true;
case SDLK_PAGEDOWN:
*key = KNOB_RIGHT;
return true;
case SDLK_UP:
*key = KEY_UP;
return true;
case SDLK_DOWN:
*key = KEY_DOWN;
return true;
default:
return false;
} }
} }
int screenshot_display(const char *filename) int screenshot_display(const char *filename)
{ {
//https://stackoverflow.com/a/48176678 /*
//user1902824 * https://stackoverflow.com/a/48176678
//modified to keep renderer and display texture references in the body rather than as a parameter * user1902824
SDL_Renderer * ren = renderer; * modified to keep renderer and display texture references in the body
SDL_Texture * tex = displayTexture; * rather than as a parameter
*/
SDL_Renderer *ren = renderer;
SDL_Texture *tex = displayTexture;
int err = 0; int err = 0;
SDL_Texture *ren_tex; SDL_Texture *ren_tex;
SDL_Surface *surf; SDL_Surface *surf;
int st; int st;
@ -139,6 +163,7 @@ int screenshot_display(const char *filename)
/* Get information about texture we want to save */ /* Get information about texture we want to save */
st = SDL_QueryTexture(tex, NULL, NULL, &w, &h); st = SDL_QueryTexture(tex, NULL, NULL, &w, &h);
if (st != 0) if (st != 0)
{ {
SDL_Log("Failed querying texture: %s\n", SDL_GetError()); SDL_Log("Failed querying texture: %s\n", SDL_GetError());
@ -147,6 +172,7 @@ int screenshot_display(const char *filename)
} }
ren_tex = SDL_CreateTexture(ren, format, SDL_TEXTUREACCESS_TARGET, w, h); ren_tex = SDL_CreateTexture(ren, format, SDL_TEXTUREACCESS_TARGET, w, h);
if (!ren_tex) if (!ren_tex)
{ {
SDL_Log("Failed creating render texture: %s\n", SDL_GetError()); SDL_Log("Failed creating render texture: %s\n", SDL_GetError());
@ -159,52 +185,66 @@ int screenshot_display(const char *filename)
* can access * can access
*/ */
st = SDL_SetRenderTarget(ren, ren_tex); st = SDL_SetRenderTarget(ren, ren_tex);
if (st != 0) if (st != 0)
{ {
SDL_Log("Failed setting render target: %s\n", SDL_GetError()); SDL_Log("Failed setting render target: %s\n", SDL_GetError());
err++; err++;
goto cleanup; goto cleanup;
} }
SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0x00, 0x00); SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0x00, 0x00);
SDL_RenderClear(ren); SDL_RenderClear(ren);
st = SDL_RenderCopy(ren, tex, NULL, NULL); st = SDL_RenderCopy(ren, tex, NULL, NULL);
if (st != 0) if (st != 0)
{ {
SDL_Log("Failed copying texture data: %s\n", SDL_GetError()); SDL_Log("Failed copying texture data: %s\n", SDL_GetError());
err++; err++;
goto cleanup; goto cleanup;
} }
/* Create buffer to hold texture data and load it */ /* Create buffer to hold texture data and load it */
pixels = malloc(w * h * SDL_BYTESPERPIXEL(format)); pixels = malloc(w * h * SDL_BYTESPERPIXEL(format));
if (!pixels) if (!pixels)
{ {
SDL_Log("Failed allocating memory\n"); SDL_Log("Failed allocating memory\n");
err++; err++;
goto cleanup; goto cleanup;
} }
st = SDL_RenderReadPixels(ren, NULL, format, pixels, w * SDL_BYTESPERPIXEL(format));
st = SDL_RenderReadPixels(ren, NULL, format, pixels,
w * SDL_BYTESPERPIXEL(format));
if (st != 0) if (st != 0)
{ {
SDL_Log("Failed reading pixel data: %s\n", SDL_GetError()); SDL_Log("Failed reading pixel data: %s\n", SDL_GetError());
err++; err++;
goto cleanup; goto cleanup;
} }
/* Copy pixel data over to surface */ /* Copy pixel data over to surface */
surf = SDL_CreateRGBSurfaceWithFormatFrom(pixels, w, h, SDL_BITSPERPIXEL(format), w * SDL_BYTESPERPIXEL(format), format); surf = SDL_CreateRGBSurfaceWithFormatFrom(pixels, w, h,
SDL_BITSPERPIXEL(format),
w * SDL_BYTESPERPIXEL(format),
format);
if (!surf) if (!surf)
{ {
SDL_Log("Failed creating new surface: %s\n", SDL_GetError()); SDL_Log("Failed creating new surface: %s\n", SDL_GetError());
err++; err++;
goto cleanup; goto cleanup;
} }
/* Save result to an image */ /* Save result to an image */
st = SDL_SaveBMP(surf, filename); st = SDL_SaveBMP(surf, filename);
if (st != 0) if (st != 0)
{ {
SDL_Log("Failed saving image: %s\n", SDL_GetError()); SDL_Log("Failed saving image: %s\n", SDL_GetError());
err++; err++;
goto cleanup; goto cleanup;
} }
SDL_Log("Saved texture as BMP to \"%s\"\n", filename); SDL_Log("Saved texture as BMP to \"%s\"\n", filename);
cleanup: cleanup:
@ -242,6 +282,7 @@ void sdl_task()
pthread_mutex_unlock(&mu); pthread_mutex_unlock(&mu);
SDL_Event ev = { 0 }; SDL_Event ev = { 0 };
while (!Radio_State.PowerOff) while (!Radio_State.PowerOff)
{ {
keyboard_t key = 0; keyboard_t key = 0;
@ -249,25 +290,27 @@ void sdl_task()
{ {
switch (ev.type) switch (ev.type)
{ {
case SDL_QUIT: case SDL_QUIT:
Radio_State.PowerOff = true; Radio_State.PowerOff = true;
break; break;
case SDL_KEYDOWN:
if (sdk_key_code_to_key(ev.key.keysym.sym, &key)) case SDL_KEYDOWN:
{ if (sdk_key_code_to_key(ev.key.keysym.sym, &key))
pthread_mutex_lock(&mu); {
sdl_keys |= key; pthread_mutex_lock(&mu);
pthread_mutex_unlock(&mu); sdl_keys |= key;
} pthread_mutex_unlock(&mu);
break; }
case SDL_KEYUP: break;
if (sdk_key_code_to_key(ev.key.keysym.sym, &key))
{ case SDL_KEYUP:
pthread_mutex_lock(&mu); if (sdk_key_code_to_key(ev.key.keysym.sym, &key))
sdl_keys ^= key; {
pthread_mutex_unlock(&mu); pthread_mutex_lock(&mu);
} sdl_keys ^= key;
break; pthread_mutex_unlock(&mu);
}
break;
} }
if (ev.type == SDL_Screenshot_Event) if (ev.type == SDL_Screenshot_Event)
{ {
@ -282,6 +325,7 @@ void sdl_task()
{ {
PIXEL_SIZE *pixels; PIXEL_SIZE *pixels;
int pitch = 0; int pitch = 0;
if (SDL_LockTexture(displayTexture, NULL, if (SDL_LockTexture(displayTexture, NULL,
(void **) &pixels, &pitch) < 0) (void **) &pixels, &pitch) < 0)
{ {
@ -295,7 +339,7 @@ void sdl_task()
SDL_RenderCopy(renderer, displayTexture, NULL, NULL); SDL_RenderCopy(renderer, displayTexture, NULL, NULL);
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }
} /* while(!Radio_State.PowerOff) */ }
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
SDL_Quit(); SDL_Quit();

View File

@ -26,10 +26,10 @@ hwInfo_t hwInfo;
void platform_init() void platform_init()
{ {
//printf("Platform init\n");
// Fill hwinfo struct // Fill hwinfo struct
memset(&hwInfo, 0x00, sizeof(hwInfo)); memset(&hwInfo, 0x00, sizeof(hwInfo));
snprintf(hwInfo.name, 10, "Linux"); snprintf(hwInfo.name, 10, "Linux");
// Frequencies are in MHz // Frequencies are in MHz
hwInfo.vhf_maxFreq = 174; hwInfo.vhf_maxFreq = 174;
hwInfo.vhf_minFreq = 136; hwInfo.vhf_minFreq = 136;
@ -49,9 +49,9 @@ void platform_terminate()
exit(0); exit(0);
} }
void platform_setBacklightLevel(__attribute__((unused)) uint8_t level) void platform_setBacklightLevel(uint8_t level)
{ {
//printf("platform_setBacklightLevel(%u)\n", level); (void) level;
} }
// Simulate a fully charged lithium battery // Simulate a fully charged lithium battery
@ -63,7 +63,6 @@ uint16_t platform_getVbat()
return ((uint16_t) voltage); return ((uint16_t) voltage);
} }
uint8_t platform_getMicLevel() uint8_t platform_getMicLevel()
{ {
float level = Radio_State.micLevel; float level = Radio_State.micLevel;
@ -73,7 +72,6 @@ uint8_t platform_getMicLevel()
return ((uint8_t) level); return ((uint8_t) level);
} }
uint8_t platform_getVolumeLevel() uint8_t platform_getVolumeLevel()
{ {
float level = Radio_State.volumeLevel; float level = Radio_State.volumeLevel;
@ -83,17 +81,16 @@ uint8_t platform_getVolumeLevel()
return ((uint8_t) level); return ((uint8_t) level);
} }
int8_t platform_getChSelector() int8_t platform_getChSelector()
{ {
return Radio_State.chSelector; return Radio_State.chSelector;
} }
bool platform_getPttStatus() bool platform_getPttStatus()
{ {
// Read P key status from SDL // Read P key status from SDL
const uint8_t *state = SDL_GetKeyboardState(NULL); const uint8_t *state = SDL_GetKeyboardState(NULL);
if (state[SDL_SCANCODE_P]) if (state[SDL_SCANCODE_P])
return true; return true;
else else
@ -106,42 +103,21 @@ bool platform_pwrButtonStatus()
return !Radio_State.PowerOff; return !Radio_State.PowerOff;
} }
void platform_ledOn(__attribute__((unused)) led_t led) void platform_ledOn(led_t led)
{ {
// Commented to reduce verbosity on Linux (void) led;
//char* str;
//switch(led)
//{
// case 0:
// str = "GREEN";
// break;
// case 1:
// str = "RED";
// break;
// case 2:
// str = "YELLOW";
// break;
// case 3:
// str = "WHITE";
// break;
//}
//printf("platform_ledOn(%s)\n", str);
} }
void platform_ledOff(led_t led)
void platform_ledOff(__attribute__((unused)) led_t led)
{ {
// Commented to reduce verbosity on Linux (void) led;
//printf("platform_ledOff()\n");
} }
void platform_beepStart(uint16_t freq) void platform_beepStart(uint16_t freq)
{ {
printf("platform_beepStart(%u)\n", freq); printf("platform_beepStart(%u)\n", freq);
} }
void platform_beepStop() void platform_beepStop()
{ {
printf("platform_beepStop()\n"); printf("platform_beepStop()\n");