I always want to use my android as my main productivity device, but one thing that really troubled me was that I thought there were no keys for [ ] ~ { } | 'escape', which are essential for programming. I used External Keyboard Helper to remap those keys to get around that, but recently it becomes very buggy.
I decided to fix this today, so I dug a little deeper and I found this...
OH MY F**KING GOD, I actually could type these characters this whole time. There is even an escape key!
Look at the keymap below. The menu key "..." is the "ralt" (right alt) key. You can almost find all the characters you need...
This does not require any system modification or app or anything, it is shipped with stock image.
I really want to share this, in case you are still finding a solution. Cheers!
Code:
# Copyright (C) 2015 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# [licence link hidden due to xda limitation, please google yourself]
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# US key character map for Google Pixel C Keyboard
#
type OVERLAY
### ROW 1
key 1 {
label: '1'
base: '1'
shift: '!'
ralt: replace ESCAPE
}
key 2 {
label: '2'
base: '2'
shift: '@'
ralt: '`'
ralt+shift: '~'
}
key 3 {
label: '3'
base: '3'
shift: '#'
}
key 4 {
label: '4'
base: '4'
shift: '$'
}
key 5 {
label: '5'
base: '5'
shift: '%'
}
key 6 {
label: '6'
base: '6'
shift: '^'
}
key 7 {
label: '7'
base: '7'
shift: '&'
}
key 8 {
label: '8'
base: '8'
shift: '*'
}
key 9 {
label: '9'
base: '9'
shift: '('
ralt: '['
}
key 0 {
label: '0'
base: '0'
shift: ')'
ralt: ']'
}
key MINUS {
label: '-'
base: '-'
shift: '_'
}
### ROW 2
key Q {
label: 'q'
base: 'q'
shift, capslock: 'Q'
}
key W {
label: 'w'
base: 'w'
shift, capslock: 'W'
}
key E {
label: 'e'
base: 'e'
shift, capslock: 'E'
}
key R {
label: 'r'
base: 'r'
shift, capslock: 'R'
}
key T {
label: 't'
base: 't'
shift, capslock: 'T'
}
key Y {
label: 'y'
base: 'y'
shift, capslock: 'Y'
}
key U {
label: 'u'
base: 'u'
shift, capslock: 'U'
}
key I {
label: 'i'
base: 'i'
shift, capslock: 'I'
}
key O {
label: 'O'
base: 'o'
shift, capslock: 'O'
ralt: '['
ralt+shift: '{'
}
key P {
label: 'P'
base: 'p'
shift, capslock: 'P'
ralt: ']'
ralt+shift: '}'
}
key EQUALS {
label: '='
base: '='
shift: '+'
ralt: '\\'
ralt+shift: '|'
}
### ROW 3
key A {
label: 'a'
base: 'a'
shift, capslock: 'A'
}
key S {
label: 's'
base: 's'
shift, capslock: 'S'
}
key D {
label: 'd'
base: 'd'
shift, capslock: 'D'
}
key F {
label: 'f'
base: 'f'
shift, capslock: 'F'
}
key G {
label: 'g'
base: 'g'
shift, capslock: 'G'
}
key H {
label: 'h'
base: 'h'
shift, capslock: 'H'
}
key J {
label: 'j'
base: 'j'
shift, capslock: 'J'
}
key K {
label: 'k'
base: 'k'
shift, capslock: 'K'
}
key L {
label: 'l'
base: 'l'
shift, capslock: 'L'
}
key SEMICOLON {
label: ';'
base: ';'
shift: ':'
}
key APOSTROPHE {
label: '\''
base: '\''
shift: '"'
}
### ROW 4
key Z {
label: 'z'
base: 'z'
shift, capslock: 'Z'
}
key X {
label: 'x'
base: 'x'
shift, capslock: 'X'
}
key C {
label: 'c'
base: 'c'
shift, capslock: 'C'
}
key V {
label: 'v'
base: 'v'
shift, capslock: 'V'
}
key B {
label: 'b'
base: 'b'
shift, capslock: 'B'
}
key N {
label: 'n'
base: 'n'
shift, capslock: 'N'
}
key M {
label: 'm'
base: 'm'
shift, capslock: 'M'
}
key COMMA {
label: ','
base: ','
shift: '<'
}
key PERIOD {
label: '.'
base: '.'
shift: '>'
}
key SLASH {
label: '/'
base: '/'
shift: '?'
}
Keyboard maps for all supported languages https://android.googlesource.com/device/google/dragon/+/oreo-r6-release/DragonKeyboard/res/raw?autodive=0/
I shall wield the power of grep and post just the ralt-mapped keys from the OP.
Code:
# US key character map for Google Pixel C Keyboard
key 1 {
ralt: replace ESCAPE
key 2 {
ralt: '`'
ralt+shift: '~'
key 9 {
ralt: '['
key 0 {
ralt: ']'
key O {
ralt: '['
ralt+shift: '{'
key P {
ralt: ']'
ralt+shift: '}'
key EQUALS {
ralt: '\\'
ralt+shift: '|'
unfortunately i'm not getting these keys in either terminal apk i'm using.
I've found that in lineage os I no longer have several of the old key combinations working. I'm not sure what the underlying issue is or when it first occurred but I do recall that on stock Pixel C firmwares there was a system app for the keyboard and it managed firmware updates and also apparently overrode the system's key layout file because if you ever had a look at that file you might have noticed the keyboard was configured to support several combinations that actually never worked. A delete key for example.
Related
How can I either detect that the onscreen keyboard has popped up and resize/rearrange my form elements, or have the form autoresize when the keyboard is displayed.
Right now my input field is hidden underneath the keyboard.
Andreas
See this excerpt:
Code:
SIPINFO si;
int cx, cy; // Initialize the shell to activate info structure.
memset (&sai, 0, sizeof (sai));
sai.cbSize = sizeof (sai);
// Create a menu bar.
memset(&mbi, 0, sizeof(SHMENUBARINFO)); // zero structure
mbi.cbSize = sizeof(SHMENUBARINFO); // Size field
mbi.hwndParent = hWnd; // Parent window
mbi.dwFlags = SHCMBF_EMPTYBAR; // Flags like hide SIP btn
mbi.nToolBarId = 0; // ID of toolbar resource
mbi.hInstRes = 0; // Inst handle of app
mbi.nBmpId = 0; // ID of bitmap resource
mbi.cBmpImages = 0; // Num of images in bitmap
mbi.hwndMB = 0; // Handle of bar returned
// Create menu bar and check for errors.
if (!SHCreateMenuBar(&mbi)) {
MessageBox (hWnd, TEXT("Couldn\'t create menu bar"), szAppName, MB_OK);
DestroyWindow (hWnd);
}
hwndMenuBar = mbi.hwndMB; // Save the menu bar handle.
// Query the sip state and size our window appropriately.
memset (&si, 0, sizeof (si));
si.cbSize = sizeof (si);
SHSipInfo(SPI_GETSIPINFO, 0, (PVOID)&si, FALSE);
cx = si.rcVisibleDesktop.right - si.rcVisibleDesktop.left;
cy = si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top;
// If the sip is not shown, or showing but not docked, the
// desktop rect doesn't include the height of the menu bar.
if (!(si.fdwFlags & SIPF_ON) ||
((si.fdwFlags & SIPF_ON) && !(si.fdwFlags & SIPF_DOCKED)))
cy -= 26; // Height of menu bar control
SetWindowPos (hWnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER);
A good source for beginners is "Programming Windows CE" by Douglas Boling[/code]
Seems as if I forgot to mention that I was using C# and .NET Compact Framework.
I have found one solution for compact framework:
http://samples.gotdotnet.com/quickstart/CompactFramework/doc/inputpanel.aspx
Hello there!
I've seen a lot of questions on this topic, and just yesterday, my client asked for this feature implemented in the app that we are currently developing...
After a veeeery intensive and long night, i finally found how to disable all these things! The code is written in c# using .net CF 2.0, and has been tested successfully on a HTC Tynt device. The interesting thing is that it will also disable the End Call and Make Call hardware buttons (VK_TEND and VK_TTALK). If you intend to use this in a production environment you might consider improoving it a little bit.
[DllImport("coredll.dll")]
private static extern bool UnregisterFunc1(KeyModifiers modifiers, int keyID);
[DllImport("coredll.dll", SetLastError = true)]
public static extern bool RegisterHotKey(IntPtr hWnd, // handle to window
int id, // hot key identifier
KeyModifiers Modifiers, // key-modifier options
int key //virtual-key code
);
public enum KeyModifiers
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
Modkeyup = 0x1000,
}
private void DeactivateUI()
{
try
{
// deactivate the SIP button
IntPtr hSip = FindWindow("MS_SIPBUTTON", "MS_SIPBUTTON");
EnableWindow(hSip, false);
// deactivate the SIP button
IntPtr hTaskBar = FindWindow("HHTaskBar", null);
EnableWindow(hTaskBar, false);
// deactivate the hardware keys
for (Int32 iCounter = 193; iCounter <= 207; iCounter++)
{
UnregisterFunc1(KeyModifiers.Windows, iCounter);
RegisterHotKey(this.Handle, iCounter, KeyModifiers.Windows, iCounter);
}
UnregisterFunc1(KeyModifiers.None, 0x73); //VK_TEND
RegisterHotKey(this.Handle, 0x73, KeyModifiers.None, 0x73);
UnregisterFunc1(KeyModifiers.None, 0x72);
RegisterHotKey(this.Handle, 0x72, KeyModifiers.None, 0x72); //VK_TTALK
}
catch (Exception ex)
{
Log.WriteError(ex, false);
}
}
Cheers!
Very good, helped me a lot! But how do I unlock the keys again, without rebooting?
Thanks!
gciochina said:
Hello there!
I've seen a lot of questions on this topic, and just yesterday, my client asked for this feature implemented in the app that we are currently developing...
After a veeeery intensive and long night, i finally found how to disable all these things! The code is written in c# using .net CF 2.0, and has been tested successfully on a HTC Tynt device. The interesting thing is that it will also disable the End Call and Make Call hardware buttons (VK_TEND and VK_TTALK). If you intend to use this in a production environment you might consider improoving it a little bit.
[DllImport("coredll.dll")]
private static extern bool UnregisterFunc1(KeyModifiers modifiers, int keyID);
[DllImport("coredll.dll", SetLastError = true)]
public static extern bool RegisterHotKey(IntPtr hWnd, // handle to window
int id, // hot key identifier
KeyModifiers Modifiers, // key-modifier options
int key //virtual-key code
);
public enum KeyModifiers
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
Modkeyup = 0x1000,
}
private void DeactivateUI()
{
try
{
// deactivate the SIP button
IntPtr hSip = FindWindow("MS_SIPBUTTON", "MS_SIPBUTTON");
EnableWindow(hSip, false);
// deactivate the SIP button
IntPtr hTaskBar = FindWindow("HHTaskBar", null);
EnableWindow(hTaskBar, false);
// deactivate the hardware keys
for (Int32 iCounter = 193; iCounter <= 207; iCounter++)
{
UnregisterFunc1(KeyModifiers.Windows, iCounter);
RegisterHotKey(this.Handle, iCounter, KeyModifiers.Windows, iCounter);
}
UnregisterFunc1(KeyModifiers.None, 0x73); //VK_TEND
RegisterHotKey(this.Handle, 0x73, KeyModifiers.None, 0x73);
UnregisterFunc1(KeyModifiers.None, 0x72);
RegisterHotKey(this.Handle, 0x72, KeyModifiers.None, 0x72); //VK_TTALK
}
catch (Exception ex)
{
Log.WriteError(ex, false);
}
}
Cheers!
Click to expand...
Click to collapse
Can u provide the EnableWindow method.I am getting the error in this method
Implement code
Hello!
I have created app to WM 5 - 6.5, but users can close it using END button. I see your code, but i can't implement ( i mean I don't have sufficient knowledge) it to visual studio 2008.
Could you tell me what should I do?
Error 1 'APP.Kiosk' does not contain a definition for 'Handle' and no extension method 'Handle' accepting a first argument of type 'APP.Kiosk' could be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\lupag\Moje dokumenty\Pobieranie\CEKiosk\CEKiosk\Kiosk.cs 155 43 CEKiosk
Handle? wtf
This program is written in C and imports a few python scripts for LCD related actions(a few scripts provided by Adafruit). Basically, the program extends features of the classic Catchphrase Electronic game by allowing a variable number of categories and words for each. An overall synopsis of methods used to drive this program and device are posix threads, signals, PWM, gpio, multi-dimensional array allocation, unix directory commands, and more. Furthermore, the directory of word files is opened (each file formatted as "CATEGORY_.txt"), and the names of each text file (minus the underscore and extension) are loaded in as categories. Next, a three dimensional array is allocated to hold each category and its corresponding words loaded in as strings.
The code is thoroughly commented, and is hopefully understandable. The hardware used was an Adafruit LCD(i2c), four momentary push-button switches, Raspberry Pi, 3V (300-500Hz rated) buzzer, and enclosure (no rechargeable battery added because of the extra money involved but could easily be used as well). The rules are very similar to that of the normal game. During the timer sequence (~55s) when team-mates are guessing a word, pulse width modulation is used to simulate a 400Hz square wave with a 15s period and 50% duty cycle (calculation used to achieve this explained in code). This value is changed over the timer interval to increase the speed of the pulsing to indicate nearing the end of the sequence. Honestly, it probably would have been better to separate some of the functions into other modules, but I decided against it for this release for simplicity sake.
I hope this may be useful for someone interested in creating their own RasPiPhrase device. If you notice any bugs or issues please let me know and I will correct it. The necessary external libraries are wiringPi and python2.7-dev, the rest are a part of unix/C. A makefile that I wrote is included (in the attached zip) as well as all necessary code related files. Some example word files are included too, but you can drop in as many as you want and modify them however you want. The code takes care of the rest. This is the first version and has been tested, though not extensively. Let me know if you have any questions about the code. Enjoy!
-Chris
Code:
/*
============================================================================
Name : RasPiPhrase.c
Author : Christopher B. Harvey
Version : 1.0
Description : Top-level part of program that completes initial setup,
* waits during game, and then cleans up resources at the end.
============================================================================
*/
#include "/usr/include/python2.7/Python.h"
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <wiringPi.h>
#include <malloc.h>
#include <time.h>
#include <string.h>
#include <sys/resource.h>
#include <math.h>
#include <signal.h>
#include <pthread.h>
#include <dirent.h>
#include "lcd.h"
//gpio pin assignments
#define NUM_CAT 3 //number of categories not including "Everything" (modify if add more)
#define BUZZER 1 //buzzer pin for gpio
#define CAT_NXT 6 //category and next switch pin for gpio
#define START 0 //START and STOP switch pin for gpio
#define TEAM_ONE 12 //team one score switch pin for gpio
#define TEAM_TWO 13 //team two score switch pin for gpio
//for importing python script
PyObject *pName, *pModule, *pDict, *pFunc1, *pFunc2, *pFunc3, *pFunc4, *pVal;
//number of files found in words directory
//and therefore the number of categories
int num_fnames=0;
int num_cat=0;
//currently selected category
//default is EVERYTHING
int category_g=0;
//integer array holding number of strings in each category
int *num_strcat=NULL;
//array of strings holding filenames
char **fname_arr=NULL;
//array of category names
char **cat_arr=NULL;
//three dimensional array of strings
//to hold arrays of each category's words
//Example: meta_arr[1][2] would be the third string of the first
// actual category(index 0 holds empy EVERYTHING category)
char ***meta_arr=NULL;
//string to hold msg to be output to lcd
char *lcd_str=NULL;
//one character strings(plus null) to hold converted integer scores
char *t1=NULL;
char *t2=NULL;
//child thread for buzzer timer
pthread_t tim_thread;
pthread_attr_t attr;//attribute for thread stack size
//vars to hold pwm calculations
float clkdiv=0;
float range_per=0;
//veriables for switching between
//different sections of interrupt functions
int irupt1=0;
int irupt2=0;
int irupt3=0;
//vars for keeping up with scores
int team1=0;
int team2=0;
//prototypes
void load_words(void);
void display_word(void);
int get_numstr(char *filename);
int get_rand(int numof);
void rm_fext(char *fname);
void load_fnames_cat(char *dirstr);
void print_cat(void);
void menu(void);
void sighand_timer(int sig);
float clk_div(float freq);
float range(float freq, float period);
void *timer_buzz(void *ptr);
void change_cat_point(void);
void team_one_p(void);
void team_two_p(void);
void start_buzz_stop(void);
void assign_point_buzz(void);
void debounce_sw(int pin);
int main(void) {
//local var declarations
char c;
int i,b,nstr=0;
//load filenames and categories into arrays
load_fnames_cat("./words");
//set 256Mb for stack size to be allocated when
//pthread_create is called for timer thread
size_t stk_alloc = 256*1024*1024;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, stk_alloc);//prevents stack overflow issues
//allocate memory for lcd msg strings and score strings
lcd_str=(char*)malloc(50*sizeof(char));
t1=(char*)malloc(3*sizeof(char));
t2=(char*)malloc(3*sizeof(char));
//load word lists from all proper files in words directory into memory
load_words();
//seed random number generator
srand(time(0));
//start python interpretation
Py_Initialize();
PyEval_InitThreads();
//initialize wiringPi
if (wiringPiSetup() < 0) {
fprintf(stderr, "ERROR! WiringPi was unable to start: %s\n", strerror(errno));
return 1;
}
//set buttons as input
pinMode(CAT_NXT,INPUT);
pinMode(START,INPUT);
pinMode(TEAM_ONE,INPUT);
pinMode(TEAM_TWO,INPUT);
//set all buttons to pull down
pullUpDnControl(CAT_NXT,PUD_DOWN);
pullUpDnControl(START,PUD_DOWN);
pullUpDnControl(TEAM_ONE,PUD_DOWN);
pullUpDnControl(TEAM_TWO,PUD_DOWN);
//load python script file
SCRIPT_LOAD("lcd_funcs");
//startup sequence
LCD_INIT();
LCD_OUT("RasPiPhrase\n Version 1.0");
sleep(2);
LCD_OUT(" Created by\nChris B. Harvey");
sleep(2);
LCD_CLEAR();
//set interrupts
wiringPiISR(CAT_NXT, INT_EDGE_FALLING,change_cat_point);
wiringPiISR(START,INT_EDGE_FALLING,start_buzz_stop);
wiringPiISR(TEAM_ONE, INT_EDGE_FALLING, team_one_p);
wiringPiISR(TEAM_TWO, INT_EDGE_FALLING, team_two_p);
//start game by loading category select menu
menu();
scanf("%c",&c);//wait for key input to end
LCD_CLEAR();
LCD_BLIGHT(OFF);
//dereference python objects
CLEAN_PY();
//end python interpretation
Py_Finalize();
//properly free all dynamically allocated memory
for(i=0;i<num_cat;i++){
nstr=num_strcat[i];
for(b=0;b<nstr;b++){
free(meta_arr[i][b]);
}
free(meta_arr[i]);
}
free(meta_arr);
free(lcd_str);
free(t1);
free(t2);
return 0;
}
//allocate space for string arrays and load file names and categories
//file format should be CATEGORY_.txt
void load_fnames_cat(char *dirstr){
int prev_mem=0,cur_mem=0;
//directory related declarations
DIR *word_direc;
struct dirent *dir;
//open the supplied directory
word_direc = opendir(dirstr);
//if successful read in the directory
if (word_direc){
//inc vars for first allocation
num_fnames++;
cur_mem=18+prev_mem;
//initial allocation for "dummy" EVERYTHING category
fname_arr=realloc(fname_arr,sizeof(char*)*num_fnames);
fname_arr[num_fnames-1]=realloc(fname_arr[num_fnames-1],sizeof(char)*cur_mem);
cat_arr=realloc(cat_arr,sizeof(char*)*num_fnames);
cat_arr[num_fnames-1]=realloc(cat_arr[num_fnames-1],sizeof(char)*cur_mem);
//set vars
prev_mem=cur_mem;
strcpy(fname_arr[num_fnames-1],"EVERYTHING_.txt");//doesn't exist just helps with coding clarity
strcpy(cat_arr[num_fnames-1],"EVERYTHING");
//allocate array of strings for filenames and categories
//and place them into the arrays
while ((dir=readdir(word_direc))!=NULL){
//attempt to insure only correct files are selected and temp files/others are ignored
if((strlen(dir->d_name)>2)&&(rindex(dir->d_name,'_')!=NULL)&&(rindex(dir->d_name,'~')==NULL)){
//inc vars
num_fnames++;
cur_mem=18+prev_mem;
//allocate array mem
fname_arr=realloc(fname_arr,sizeof(char*)*num_fnames);
fname_arr[num_fnames-1]=realloc(fname_arr[num_fnames-1],sizeof(char)*cur_mem);
cat_arr=realloc(cat_arr,sizeof(char*)*num_fnames);
cat_arr[num_fnames-1]=realloc(cat_arr[num_fnames-1],sizeof(char)*cur_mem);
//set vars
prev_mem=cur_mem;
strcpy(fname_arr[num_fnames-1],(dir->d_name));
strcpy(cat_arr[num_fnames-1],fname_arr[num_fnames-1]);
//remove file extension and underscore from filenames
rm_fext(cat_arr[num_fnames-1]);
}
}
//clean up
closedir(word_direc);
//set number of categories
num_cat=num_fnames;
}
}
void load_words(void){
FILE *fp;
int i,b,temp_strnum=0;
char dir[]="./words/";
char str_pathfile[40];
//allocate space for each category for both
meta_arr=(char***)malloc(sizeof(char**)*num_cat);
num_strcat=(int*)malloc(sizeof(int)*num_cat);
for(i=0;i<num_cat;i++){
if(i==0){
//blank for everything category
meta_arr[i]=(char**)malloc(sizeof(char*)*1);
meta_arr[i][i]=(char*)malloc(1*sizeof(char));
meta_arr[i][i][i]='\0';
num_strcat[0]=1;//doesnt matter (EVERYTHING category)
}
else{
//format string to be path to file
strcpy(str_pathfile,dir);
strcat(str_pathfile,fname_arr[i]);
temp_strnum=get_numstr(str_pathfile);
//set number of strings for current category
num_strcat[i]=temp_strnum;
//open file for reading
fp=fopen(str_pathfile,"r");
//allocate memory for pointer to each string and each string itself
meta_arr[i]=(char**)malloc(sizeof(char*)*temp_strnum);
for(b=0;b<temp_strnum;b++){
meta_arr[i][b]=(char*)malloc(16*sizeof(char));
//load in word from file into memory
if((fscanf(fp,"%s",meta_arr[i][b]))!=1){
printf("\n\nERROR loading\nwords from file!\n");
sleep(2);
exit(1);
}
}
fclose(fp);
}
}
}
//output string constructed from current word
//as well as converted team scores
void display_word(void){
char *str=NULL;
int tmp_rand=0;//for use in recursion for everything category
//convert integer score to character
//and put into the correct string
t1[0]=(char)(((int)'0')+team1);
t2[0]=(char)(((int)'0')+team2);
t1[1]='\0';
t2[1]='\0';
if(category_g!=0){
//randomly select string
str=meta_arr[category_g][get_rand(num_strcat[category_g])];
}
else{
//randomly select category and string for EVERYTHING
tmp_rand=get_rand(num_cat);
while(tmp_rand==0){
tmp_rand=get_rand(num_cat);
}
str=meta_arr[tmp_rand][get_rand(num_strcat[tmp_rand])];
}
//construct string from scores and word then output to lcd
strcpy(lcd_str,str);
strcat(lcd_str,"\nTEAM1:");
strcat(lcd_str,t1);
strcat(lcd_str," TEAM2:");
strcat(lcd_str,t2);
LCD_OUT(lcd_str);
}
//prints string constructed from current category and each team's score
void print_cat(void){
//convert ints to characters and put into string
t1[0]=(char)(((int)'0')+team1);
t2[0]=(char)(((int)'0')+team2);
t1[1]='\0';
t2[1]='\0';
//construct string from scores and category name then output to lcd
strcpy(lcd_str,cat_arr[category_g]);
strcat(lcd_str,"\nTEAM1:");
strcat(lcd_str,t1);
strcat(lcd_str," TEAM2:");
strcat(lcd_str,t2);
LCD_OUT(lcd_str);
}
//opens the specified file and
//counts the number of strings
int get_numstr(char *filename){
int fsize=0;
char *string=NULL;
string=(char*)malloc(20*sizeof(char));
FILE *fp;
fp=fopen(filename,"r");
while(fscanf(fp,"%s",string)==1){
fsize++;
}
fclose(fp);
free(string);
return fsize;
}
//gets a random number within range
//specified by number of items
int get_rand(int numof){
int random=rand()%numof;
return random;
}
//function to remove file extension and underscore
void rm_fext(char *fname){
char *ptr_todot=rindex(fname,'_');//find memory where the dot is stored
if(ptr_todot!=NULL){
(*ptr_todot)='\0';//replace with terminator to basically remove extension
}
}
//category select menu
void menu(void){
category_g=0;
LCD_OUT("Please select\n a category.")
sleep(1);
print_cat();
irupt1=1;
}
//function to debounce button on supplied pin
void debounce_sw(int pin){
int cnt=0,wait=1;
while(wait){
usleep(1000);//sleep 10ms
if(digitalRead(pin)==1){
cnt=0;
//continue to wait for bouncing to stop
}
else{
cnt++;
}
if(cnt>=10){
//we can now end loop
wait=0;
}
}
}
//interrupt function for when the start/stop button is pressed
void start_buzz_stop(void){
debounce_sw(START);
//set start/stop button to pulldown
pullUpDnControl(START,PUD_DOWN);
if(irupt1){
irupt1=0;
pthread_create(&tim_thread,&attr,timer_buzz,NULL);
}
else if(irupt2){
irupt2=0;
pthread_kill(tim_thread,SIGUSR1);
pthread_join(tim_thread,NULL);//make sure to wait until child thread terminates
pwmWrite(BUZZER,0);
digitalWrite(BUZZER, LOW);
menu();
}
}
//interrupt function for when the category/next button is pressed
void change_cat_point(void){
debounce_sw(CAT_NXT);
//set category/next button to pull down
pullUpDnControl(CAT_NXT,PUD_DOWN);
if(irupt1){
category_g++;
if(category_g>=num_cat){
category_g=0;//wrap back around
}
print_cat();
}
else if(irupt2){
irupt2=0;
pthread_kill(tim_thread,SIGUSR1);
pthread_join(tim_thread,NULL);//make sure to wait until child thread terminates
pwmWrite(BUZZER,0);
digitalWrite(BUZZER, LOW);
LCD_OUT("Assign point to\nthe proper team.");
irupt3=1;
}
}
//function to assign point after timer expires
void assign_point_buzz(void) {
irupt2=0;
LCD_OUT("Time expired!!!!");
pthread_join(tim_thread,NULL);//make sure to wait until child thread terminates
sleep(1);
LCD_OUT("Assign point to\nthe proper team.");
irupt3=1;
}
//interrupt function to give point when team one button is pressed
void team_one_p(void){
debounce_sw(TEAM_ONE);
//set pull down for score buttons
pullUpDnControl(TEAM_ONE,PUD_DOWN);
pullUpDnControl(TEAM_TWO,PUD_DOWN);
if(irupt3){
irupt3=0;
team1++;
if(team1>=7){
LCD_OUT(" TEAM1 WINS!!!");
sleep(2);
team1=0;
team2=0;
}
menu();
}
}
//interrupt function to give point when team two button is pressed
void team_two_p(void){
debounce_sw(TEAM_TWO);
//set pull down for score buttons
pullUpDnControl(TEAM_ONE,PUD_DOWN);
pullUpDnControl(TEAM_TWO,PUD_DOWN);
if(irupt3){
irupt3=0;
team2++;
if(team2>=7){
LCD_OUT(" TEAM2 WINS!!!");
sleep(2);
team1=0;
team2=0;
}
menu();
}
}
//signal handler for SIGUSR1 signal when
//sent to timer child thread
void sighand_timer(int sig){
pthread_exit(0);//end child thread
}
//function called by child thread to begin timer and buzzer sequence
void *timer_buzz(void *ptr) {
signal(SIGUSR1,sighand_timer);//call function when SIGUSR1 is caught
irupt1=0;
irupt2=1;
display_word();
clk_div(400); //400 Hz, clock_div func supplies correct value
range(400, 15); //15s Period, range func supplies correct value
pinMode(BUZZER, PWM_OUTPUT);
//and set its value to 0
pwmSetMode(PWM_MODE_MS);
pwmWrite(BUZZER, 0);
digitalWrite(BUZZER, LOW);
//bring frequency to 300Hz
//originally 19.2MHz PWM Clock
pwmSetClock(clkdiv);
pwmSetRange(range_per);
//begin pwm writing sequency to produce
//square waves that mimic the catchphrase timer
pwmWrite(BUZZER, (range_per * .25));
sleep(12);
pwmSetRange(range(400, 12));
pwmWrite(BUZZER, (range_per * .50));
sleep(10);
pwmSetRange(range(400, 10));
pwmWrite(BUZZER, (range_per * .75));
sleep(10);
pwmSetRange(range(400, 8));
pwmWrite(BUZZER, (range_per * .90));
sleep(10);
pwmSetRange(range(400, 6));
pwmWrite(BUZZER, (range_per * .90));
sleep(10);
pwmSetClock(clk_div(300));
pwmSetRange(range(300, 15));
pwmWrite(BUZZER, range_per);
sleep(1);
assign_point_buzz();
sleep(1);
pwmWrite(BUZZER, 0);
digitalWrite(BUZZER, LOW);
return 0;
}
//calculates pwm clock divisor for a frequency in Hz
float clk_div(float freq) {
clkdiv = 19.2 * (pow(10, 6)) / freq;
return clkdiv;
}
//calculates pwm range for a period in seconds and a frequency in Hz
float range(float freq, float period) {
range_per = period / (1 / freq);
return range_per;
}
Code:
/*
============================================================================
Name : lcd.h
Author : Christopher B. Harvey
Version : 1.0
Description : Header that contains function-like macro definitions
* for lcd related tasks through use of python scripts.
============================================================================
*/
//functionality defines for lcd backlight function
#define ON 1
#define OFF 0
#define SCRIPT_LOAD(pyfile) \
pName = PyString_FromString(pyfile); \
PyRun_SimpleString("import sys"); \
PyRun_SimpleString("sys.path.append(\"/home/rasppi/src/py_scripts\")"); \
pModule = PyImport_Import(pName); \
pDict = PyModule_GetDict(pModule); \
#define LCD_INIT() \
pFunc1 = PyDict_GetItemString(pDict, "lcdinit"); \
if (PyCallable_Check(pFunc1)){ \
PyObject_CallObject(pFunc1, NULL); \
} else { \
PyErr_Print(); } \
#define LCD_OUT(stri) \
pFunc2 = PyDict_GetItemString(pDict, "lcdout"); \
if (PyCallable_Check(pFunc2)){ \
PyObject_CallFunction(pFunc2, "s", stri); \
} else { \
PyErr_Print(); } \
#define LCD_BLIGHT(i) \
pFunc3 = PyDict_GetItemString(pDict, "lcdbacklight"); \
if (PyCallable_Check(pFunc3)){ \
PyObject_CallFunction(pFunc3, "i", i); \
} else { \
PyErr_Print(); } \
#define LCD_CLEAR() \
pFunc4 = PyDict_GetItemString(pDict, "lcdclear"); \
if (PyCallable_Check(pFunc4)){ \
PyObject_CallObject(pFunc4, NULL); \
} else { \
PyErr_Print(); } \
#define CLEAN_PY() \
Py_DECREF(pModule); \
Py_DECREF(pName); \
Continuing with the theme from my last thread where I posted a simple class for encrypting strings using the SHA-512 hashing algorithm, here is an improved version that generates a random 20 byte salt to add in with the string to be hashed. This is then hashed providing greater security.
Due to the random generation of the salt each time a string is hashed, this makes it pretty much impossible to get the same hash for a string, therefore once the salt has been generated the first time round it is stored in sharedPreferences for future uses so that you can use it for checking matches etc
Method of converting the bytes to hex string adapted from maybeWeCouldStealAVan's method @ stackoverflow.
Code:
public class Crypto {
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
protected static String SHA512(String string, Context context) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-512");
String salt = getSalt(context);
md.update(salt.getBytes());
byte[] bytes = md.digest(string.getBytes());
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private static String getSalt(Context context) throws NoSuchAlgorithmException {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String salt = preferences.getString("salt", null);
if (salt == null) {
byte[] saltBytes = new byte[20];
SecureRandom.getInstance("SHA1PRNG").nextBytes(saltBytes);
salt = new String(saltBytes);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("salt", salt).commit();
}
return salt;
}
}
Usage:
Code:
String example = "example";
try {
example = Crypto.SHA512(example, context);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
Thanks for sharing, it's quite usefull ! I will include it to my project
Jonny said:
Continuing with the theme from my last thread where I posted a simple class for encrypting strings using the SHA-512 hashing algorithm, here is an improved version that generates a random 20 byte salt to add in with the string to be hashed. This is then hashed providing greater security.
Due to the random generation of the salt each time a string is hashed, this makes it pretty much impossible to get the same hash for a string, therefore once the salt has been generated the first time round it is stored in sharedPreferences for future uses so that you can use it for checking matches etc
Method of converting the bytes to hex string adapted from maybeWeCouldStealAVan's method @ stackoverflow.
Code:
public class Crypto {
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
protected static String SHA512(String string, Context context) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-512");
String salt = getSalt(context);
md.update(salt.getBytes());
byte[] bytes = md.digest(string.getBytes());
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private static String getSalt(Context context) throws NoSuchAlgorithmException {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String salt = preferences.getString("salt", null);
if (salt == null) {
byte[] saltBytes = new byte[20];
SecureRandom.getInstance("SHA1PRNG").nextBytes(saltBytes);
salt = new String(saltBytes);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("salt", salt).commit();
}
return salt;
}
}
Usage:
Code:
String example = "example";
try {
example = Crypto.SHA512(example, context);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
Click to expand...
Click to collapse
Thanks
Gesendet von meinem LG-D855 mit Tapatalk
How to add rectangles on top of existing rectangle in canvas
I'm trying to add some red rectangles within my existing canvas on top of specific boxes exactly like the expected result image but they don't appear at all as my code shows the current undesired outcome when I deploy my app. My code is to create 4 rectangles on the top row and 4 rectangles on the bottom row but I only want this to be added on top of boxes 2-6 but I know extra code needs to be added for the red rectangles on top of boxes 1 & 7. Does anyone know what I'm doing wrong and how to fix this? All help would be appreciated. I can't post links on here so please have a look at "How to add rectangles on top of existing rectangle in canvas" on Stack Overflow for the images.
RectangleTextView.java
Code:
public class RectangleTextView extends View {
private final Paint mBlackPaint = new Paint();
private final Paint mRedPaint = new Paint();
private final TextPaint mTextPaint;
public RectangleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
int valueInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
int valueInSp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
mRedPaint.setColor(Color.parseColor("#CC3333"));
mBlackPaint.setAntiAlias(false);
mBlackPaint.setColor(Color.BLACK);
mBlackPaint.setStrokeWidth(valueInDp);
mBlackPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTextSize(valueInSp);
mWindowPaint = new Paint();
mWindowPaint.setColor(Color.parseColor("#CC3333"));
mWindowPaint.setStrokeWidth(valueInDp);
}
private Paint mWindowPaint;
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (getWidth() == 0)
return;
//initialise red rectangles
int w = canvas.getWidth();
int h = canvas.getHeight();
int rectWidth = w / 5;
int space = w / 15;
int topRectHeight = getPaddingTop();
int bottomRectHeight = getPaddingBottom();
//draw end rectangles
int mSideRectWidth = 10;
canvas.drawRect(0, 0, mSideRectWidth, getHeight(), mRedPaint); //draw left end rectangle
canvas.drawRect(getWidth() - mSideRectWidth, 0, getWidth(), getHeight(), mRedPaint); //draw right end rectangle
//draw grey boxes
setBackgroundColor(Color.parseColor("#808080"));
int boxWidth = (getWidth() - mSideRectWidth) / 7;
//draw text views
for (int i = 0; i < 7; i++) {
canvas.drawText(Integer.toString(i + 1), (i * boxWidth + 10) + (boxWidth / 2), ((canvas.getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)), mTextPaint);
}
//draw black lines
for (int i = 1; i < 7; i++) {
canvas.drawLine(mSideRectWidth + boxWidth * i, 0, mSideRectWidth + boxWidth * i, getHeight(), mBlackPaint);
}
//draw red windows
for (int i = 0; i < 4; i++) {
mWindowPaint.setStyle(Paint.Style.STROKE);//add this
int left = i * (rectWidth + space);
int right = left + rectWidth;
if (i == 1){
mWindowPaint.setStyle(Paint.Style.FILL); // change to this
}
Rect rect = new Rect(left, 0, right, topRectHeight);
canvas.drawRect(rect, mWindowPaint);
Rect rect2 = new Rect(left, h - bottomRectHeight, right, h);
canvas.drawRect(rect2, mWindowPaint);
}
}
}