flipperdevices / flipperzero-firmware

Flipper Zero firmware source code
https://flipperzero.one
GNU General Public License v3.0
12.66k stars 2.7k forks source link

UTF-8 implementation + AZERTY remote keyboard #3398

Closed KaliStudio closed 8 months ago

KaliStudio commented 8 months ago

Description of the feature you're suggesting.

Hello, I have just purchased a Flipper zero and I would like to translate the firmware into French. I started with the remote keyboard, I modified the flipperzero-firmware/applications/system/hid_app/views file /hid_keyboard.c so that the keyboard is in AZERTY, the problem is that the characters éèçਣ§ùµ° are not displayed

#define MARGIN_TOP 0
#define MARGIN_LEFT 4
#define KEY_WIDTH 9
#define KEY_HEIGHT 12
#define KEY_PADDING 1
#define ROW_COUNT 7
#define COLUMN_COUNT 14

// 0 width items are not drawn, but there value is used
const HidKeyboardKey hid_keyboard_keyset[ROW_COUNT][COLUMN_COUNT] = {
    {
        {.width = 1, .icon = &I_ButtonF1_5x8, .value = HID_KEYBOARD_F1},
        {.width = 1, .icon = &I_ButtonF2_5x8, .value = HID_KEYBOARD_F2},
        {.width = 1, .icon = &I_ButtonF3_5x8, .value = HID_KEYBOARD_F3},
        {.width = 1, .icon = &I_ButtonF4_5x8, .value = HID_KEYBOARD_F4},
        {.width = 1, .icon = &I_ButtonF5_5x8, .value = HID_KEYBOARD_F5},
        {.width = 1, .icon = &I_ButtonF6_5x8, .value = HID_KEYBOARD_F6},
        {.width = 1, .icon = &I_ButtonF7_5x8, .value = HID_KEYBOARD_F7},
        {.width = 1, .icon = &I_ButtonF8_5x8, .value = HID_KEYBOARD_F8},
        {.width = 1, .icon = &I_ButtonF9_5x8, .value = HID_KEYBOARD_F9},
        {.width = 1, .icon = &I_ButtonF10_5x8, .value = HID_KEYBOARD_F10},
        {.width = 1, .icon = &I_ButtonF11_5x8, .value = HID_KEYBOARD_F11},
        {.width = 1, .icon = &I_ButtonF12_5x8, .value = HID_KEYBOARD_F12},
    },
    {
        {.width = 1, .icon = NULL, .key = "&", .shift_key = "1", .value = HID_KEYBOARD_1},
        {.width = 1, .icon = NULL, .key = "é", .shift_key = "2", .value = HID_KEYBOARD_2},
        {.width = 1, .icon = NULL, .key = "\"", .shift_key = "3", .value = HID_KEYBOARD_3},
        {.width = 1, .icon = NULL, .key = "'", .shift_key = "4", .value = HID_KEYBOARD_4},
        {.width = 1, .icon = NULL, .key = "(", .shift_key = "5", .value = HID_KEYBOARD_5},
        {.width = 1, .icon = NULL, .key = "-", .shift_key = "6", .value = HID_KEYBOARD_6},
        {.width = 1, .icon = NULL, .key = "è", .shift_key = "7", .value = HID_KEYBOARD_7},
        {.width = 1, .icon = NULL, .key = "_", .shift_key = "8", .value = HID_KEYBOARD_8},
        {.width = 1, .icon = NULL, .key = "ç", .shift_key = "9", .value = HID_KEYBOARD_9},
        {.width = 1, .icon = NULL, .key = "à", .shift_key = "0", .value = HID_KEYBOARD_0},  
        {.width = 2, .icon = &I_Pin_arrow_left_9x7, .value = HID_KEYBOARD_DELETE},
        {.width = 0, .value = HID_KEYBOARD_DELETE}, 
    },
    {
        {.width = 1, .icon = NULL, .key = "a", .shift_key = "A", .value = HID_KEYBOARD_Q},
        {.width = 1, .icon = NULL, .key = "z", .shift_key = "Z", .value = HID_KEYBOARD_W},
        {.width = 1, .icon = NULL, .key = "e", .shift_key = "E", .value = HID_KEYBOARD_E},
        {.width = 1, .icon = NULL, .key = "r", .shift_key = "R", .value = HID_KEYBOARD_R},
        {.width = 1, .icon = NULL, .key = "t", .shift_key = "T", .value = HID_KEYBOARD_T},
        {.width = 1, .icon = NULL, .key = "y", .shift_key = "Y", .value = HID_KEYBOARD_Y},  
        {.width = 1, .icon = NULL, .key = "u", .shift_key = "U", .value = HID_KEYBOARD_U},
        {.width = 1, .icon = NULL, .key = "i", .shift_key = "I", .value = HID_KEYBOARD_I},
        {.width = 1, .icon = NULL, .key = "o", .shift_key = "O", .value = HID_KEYBOARD_O},
        {.width = 1, .icon = NULL, .key = "p", .shift_key = "P", .value = HID_KEYBOARD_P},  
        {.width = 1, .icon = NULL, .key = "^", .shift_key = "¨", .value = HID_KEYBOARD_OPEN_BRACKET},
        {.width = 1, .icon = NULL, .key = "$", .shift_key = "£", .value = HID_KEYBOARD_CLOSE_BRACKET},
    },  
    {
        {.width = 1, .icon = NULL, .key = "q", .shift_key = "Q", .value = HID_KEYBOARD_A},
        {.width = 1, .icon = NULL, .key = "s", .shift_key = "S", .value = HID_KEYBOARD_S},
        {.width = 1, .icon = NULL, .key = "d", .shift_key = "D", .value = HID_KEYBOARD_D},
        {.width = 1, .icon = NULL, .key = "f", .shift_key = "F", .value = HID_KEYBOARD_F},
        {.width = 1, .icon = NULL, .key = "g", .shift_key = "G", .value = HID_KEYBOARD_G},
        {.width = 1, .icon = NULL, .key = "h", .shift_key = "H", .value = HID_KEYBOARD_H},
        {.width = 1, .icon = NULL, .key = "j", .shift_key = "J", .value = HID_KEYBOARD_J},
        {.width = 1, .icon = NULL, .key = "k", .shift_key = "K", .value = HID_KEYBOARD_K},
        {.width = 1, .icon = NULL, .key = "l", .shift_key = "L", .value = HID_KEYBOARD_L},
        {.width = 1, .icon = NULL, .key = "m", .shift_key = "M", .value = HID_KEYBOARD_SEMICOLON}, 
        {.width = 2, .icon = &I_Pin_arrow_right_9x7, .value = HID_KEYBOARD_RETURN}, 
        {.width = 0, .value = HID_KEYBOARD_RETURN}, 
    },
    {
        {.width = 1, .icon = &I_Pin_arrow_up_7x9, .value = HID_KEYBOARD_L_SHIFT},
        {.width = 1, .icon = NULL, .key = "w", .shift_key = "W", .value = HID_KEYBOARD_Z},
        {.width = 1, .icon = NULL, .key = "x", .shift_key = "X", .value = HID_KEYBOARD_X},
        {.width = 1, .icon = NULL, .key = "c", .shift_key = "C", .value = HID_KEYBOARD_C},
        {.width = 1, .icon = NULL, .key = "v", .shift_key = "V", .value = HID_KEYBOARD_V},
        {.width = 1, .icon = NULL, .key = "b", .shift_key = "B", .value = HID_KEYBOARD_B},
        {.width = 1, .icon = NULL, .key = "n", .shift_key = "N", .value = HID_KEYBOARD_N},
        {.width = 1, .icon = NULL, .key = ",", .shift_key = "?", .value = HID_KEYBOARD_M},
        {.width = 1, .icon = NULL, .key = ";", .shift_key = ".", .value = HID_KEYBOARD_COMMA},
        {.width = 1, .icon = &I_ButtonUp_7x4, .value = HID_KEYBOARD_UP_ARROW},
        {.width = 1, .icon = NULL, .key = ":", .shift_key = "/", .value = HID_KEYBOARD_DOT}, 
        {.width = 1, .icon = NULL, .key = "!", .shift_key = "§", .value = HID_KEYBOARD_SLASH},                          
    },
    {
        {.width = 1, .icon = NULL, .key = "ù", .shift_key = "%", .value = HID_KEYBOARD_APOSTROPHE},
        {.width = 1, .icon = NULL, .key = "*", .shift_key = "µ", .value = HID_KEYBOARD_BACKSLASH},
        {.width = 4, .icon = NULL, .key = " ", .value = HID_KEYBOARD_SPACEBAR},
        {.width = 0, .value = HID_KEYBOARD_SPACEBAR},
        {.width = 0, .value = HID_KEYBOARD_SPACEBAR},
        {.width = 0, .value = HID_KEYBOARD_SPACEBAR},
        {.width = 1, .icon = NULL, .key = ")", .shift_key = "°", .value = HID_KEYBOARD_MINUS}, 
        {.width = 1, .icon = NULL, .key = "=", .shift_key = "+", .value = HID_KEYBOARD_EQUAL_SIGN}, 
        {.width = 1, .icon = &I_ButtonLeft_4x7, .value = HID_KEYBOARD_LEFT_ARROW},
        {.width = 1, .icon = &I_ButtonDown_7x4, .value = HID_KEYBOARD_DOWN_ARROW},
        {.width = 1, .icon = &I_ButtonRight_4x7, .value = HID_KEYBOARD_RIGHT_ARROW}, 
    },
    {
        {.width = 2, .icon = &I_Ctrl_17x10, .value = HID_KEYBOARD_L_CTRL},
        {.width = 0, .value = HID_KEYBOARD_L_CTRL},
        {.width = 2, .icon = &I_Alt_17x10, .value = HID_KEYBOARD_L_ALT},
        {.width = 0, .value = HID_KEYBOARD_L_ALT},
        {.width = 2, .icon = &I_Cmd_17x10, .value = HID_KEYBOARD_L_GUI},
        {.width = 0, .value = HID_KEYBOARD_L_GUI},
        {.width = 2, .icon = &I_Tab_17x10, .value = HID_KEYBOARD_TAB},
        {.width = 0, .value = HID_KEYBOARD_TAB},
        {.width = 2, .icon = &I_Esc_17x10, .value = HID_KEYBOARD_ESCAPE},
        {.width = 0, .value = HID_KEYBOARD_ESCAPE},
        {.width = 2, .icon = &I_Del_17x10, .value = HID_KEYBOARD_DELETE_FORWARD},
        {.width = 0, .value = HID_KEYBOARD_DELETE_FORWARD},
    },
};

I think I'm going to have the same problem in different parts of other code, so I'd like to fix the problem from the start if possible. thanks in advance

Anything else?

No response

skotopes commented 8 months ago

It's a little bit more complex, take a look on bad usb app. It uses special translation maps for keyboard mappings. That is basically how any keyboard works on low level.

At this point we are not planning to implement international keyboards in hid app, but we can assist if someone would like to do so.

KaliStudio commented 8 months ago

screen clavier 1 screen clavier 2

modify the file flipperzero-firmware\applications\system\hid_app\views\hid_keyboard.c

#define MARGIN_TOP 0
#define MARGIN_LEFT 4
#define KEY_WIDTH 9
#define KEY_HEIGHT 12
#define KEY_PADDING 1
#define ROW_COUNT 7
#define COLUMN_COUNT 14

// 0 width items are not drawn, but there value is used
const HidKeyboardKey hid_keyboard_keyset[ROW_COUNT][COLUMN_COUNT] = {
    {
        {.width = 1, .icon = &I_ButtonF1_5x8, .value = HID_KEYBOARD_F1},
        {.width = 1, .icon = &I_ButtonF2_5x8, .value = HID_KEYBOARD_F2},
        {.width = 1, .icon = &I_ButtonF3_5x8, .value = HID_KEYBOARD_F3},
        {.width = 1, .icon = &I_ButtonF4_5x8, .value = HID_KEYBOARD_F4},
        {.width = 1, .icon = &I_ButtonF5_5x8, .value = HID_KEYBOARD_F5},
        {.width = 1, .icon = &I_ButtonF6_5x8, .value = HID_KEYBOARD_F6},
        {.width = 1, .icon = &I_ButtonF7_5x8, .value = HID_KEYBOARD_F7},
        {.width = 1, .icon = &I_ButtonF8_5x8, .value = HID_KEYBOARD_F8},
        {.width = 1, .icon = &I_ButtonF9_5x8, .value = HID_KEYBOARD_F9},
        {.width = 1, .icon = &I_ButtonF10_5x8, .value = HID_KEYBOARD_F10},
        {.width = 1, .icon = &I_ButtonF11_5x8, .value = HID_KEYBOARD_F11},
        {.width = 1, .icon = &I_ButtonF12_5x8, .value = HID_KEYBOARD_F12},
    },
    {
        {.width = 1, .icon = NULL, .key = "&", .shift_key = "1", .value = HID_KEYBOARD_1},
        {.width = 1, .icon = &I_Buttoneaigu_7x10, .key = "é", .shift_key = "2", .value = HID_KEYBOARD_2},
        {.width = 1, .icon = NULL, .key = "\"", .shift_key = "3", .value = HID_KEYBOARD_3},
        {.width = 1, .icon = NULL, .key = "'", .shift_key = "4", .value = HID_KEYBOARD_4},
        {.width = 1, .icon = NULL, .key = "(", .shift_key = "5", .value = HID_KEYBOARD_5},
        {.width = 1, .icon = NULL, .key = "-", .shift_key = "6", .value = HID_KEYBOARD_6},
        {.width = 1, .icon = &I_Buttonegrave_7x10, .key = "è", .shift_key = "7", .value = HID_KEYBOARD_7}, 
        {.width = 1, .icon = NULL, .key = "_", .shift_key = "8", .value = HID_KEYBOARD_8},
        {.width = 1, .icon = &I_Buttoncced_7x10, .key = "ç", .shift_key = "9", .value = HID_KEYBOARD_9}, 
        {.width = 1, .icon = &I_Buttonagrave_7x10, .key = "à", .shift_key = "0", .value = HID_KEYBOARD_0},  
        {.width = 2, .icon = &I_Pin_arrow_left_9x7, .value = HID_KEYBOARD_DELETE},
        {.width = 0, .value = HID_KEYBOARD_DELETE}, 
    },
    {
        {.width = 1, .icon = NULL, .key = "a", .shift_key = "A", .value = HID_KEYBOARD_Q},
        {.width = 1, .icon = NULL, .key = "z", .shift_key = "Z", .value = HID_KEYBOARD_W},
        {.width = 1, .icon = NULL, .key = "e", .shift_key = "E", .value = HID_KEYBOARD_E},
        {.width = 1, .icon = NULL, .key = "r", .shift_key = "R", .value = HID_KEYBOARD_R},
        {.width = 1, .icon = NULL, .key = "t", .shift_key = "T", .value = HID_KEYBOARD_T},
        {.width = 1, .icon = NULL, .key = "y", .shift_key = "Y", .value = HID_KEYBOARD_Y},  
        {.width = 1, .icon = NULL, .key = "u", .shift_key = "U", .value = HID_KEYBOARD_U},
        {.width = 1, .icon = NULL, .key = "i", .shift_key = "I", .value = HID_KEYBOARD_I},
        {.width = 1, .icon = NULL, .key = "o", .shift_key = "O", .value = HID_KEYBOARD_O},
        {.width = 1, .icon = NULL, .key = "p", .shift_key = "P", .value = HID_KEYBOARD_P},  
        {.width = 1, .icon = &I_Buttontrema_7x10, .key = "^", .shift_key = "¨", .value = HID_KEYBOARD_OPEN_BRACKET},     //¨ ne s'affiche pas 
        {.width = 1, .icon = &I_ButtonLivreSterling_7x10, .key = "$", .shift_key = "£", .value = HID_KEYBOARD_CLOSE_BRACKET},    //£ ne s'affiche pas   //12
    },  
    {
        {.width = 1, .icon = NULL, .key = "q", .shift_key = "Q", .value = HID_KEYBOARD_A},
        {.width = 1, .icon = NULL, .key = "s", .shift_key = "S", .value = HID_KEYBOARD_S},
        {.width = 1, .icon = NULL, .key = "d", .shift_key = "D", .value = HID_KEYBOARD_D},
        {.width = 1, .icon = NULL, .key = "f", .shift_key = "F", .value = HID_KEYBOARD_F},
        {.width = 1, .icon = NULL, .key = "g", .shift_key = "G", .value = HID_KEYBOARD_G},
        {.width = 1, .icon = NULL, .key = "h", .shift_key = "H", .value = HID_KEYBOARD_H},
        {.width = 1, .icon = NULL, .key = "j", .shift_key = "J", .value = HID_KEYBOARD_J},
        {.width = 1, .icon = NULL, .key = "k", .shift_key = "K", .value = HID_KEYBOARD_K},
        {.width = 1, .icon = NULL, .key = "l", .shift_key = "L", .value = HID_KEYBOARD_L},
        {.width = 1, .icon = NULL, .key = "m", .shift_key = "M", .value = HID_KEYBOARD_SEMICOLON}, 
        {.width = 2, .icon = &I_Pin_arrow_right_9x7, .value = HID_KEYBOARD_RETURN}, 
        {.width = 0, .value = HID_KEYBOARD_RETURN}, 
    },
    {
        {.width = 1, .icon = &I_Pin_arrow_up_7x9, .value = HID_KEYBOARD_L_SHIFT},
        {.width = 1, .icon = NULL, .key = "w", .shift_key = "W", .value = HID_KEYBOARD_Z},
        {.width = 1, .icon = NULL, .key = "x", .shift_key = "X", .value = HID_KEYBOARD_X},
        {.width = 1, .icon = NULL, .key = "c", .shift_key = "C", .value = HID_KEYBOARD_C},
        {.width = 1, .icon = NULL, .key = "v", .shift_key = "V", .value = HID_KEYBOARD_V},
        {.width = 1, .icon = NULL, .key = "b", .shift_key = "B", .value = HID_KEYBOARD_B},
        {.width = 1, .icon = NULL, .key = "n", .shift_key = "N", .value = HID_KEYBOARD_N},
        {.width = 1, .icon = NULL, .key = ",", .shift_key = "?", .value = HID_KEYBOARD_M},
        {.width = 1, .icon = NULL, .key = ";", .shift_key = ".", .value = HID_KEYBOARD_COMMA},
        {.width = 1, .icon = &I_ButtonUp_7x4, .value = HID_KEYBOARD_UP_ARROW},
        {.width = 1, .icon = NULL, .key = ":", .shift_key = "/", .value = HID_KEYBOARD_DOT}, 
        {.width = 1, .icon = &I_ButtonParagrapheg_7x10, .key = "!", .shift_key = "§", .value = HID_KEYBOARD_SLASH}, //§ ne s'affiche pas //12           
    },
    {
        {.width = 1, .icon = &I_Buttonugrave_7x10, .key = "ù", .shift_key = "%", .value = HID_KEYBOARD_APOSTROPHE}, //ù ne s'affiche pas
        {.width = 1, .icon = &I_ButtonMu_7x10, .key = "*", .shift_key = "µ", .value = HID_KEYBOARD_BACKSLASH},  //µ ne s'affiche pas    
        {.width = 4, .icon = NULL, .key = " ", .value = HID_KEYBOARD_SPACEBAR},
        {.width = 0, .value = HID_KEYBOARD_SPACEBAR},
        {.width = 0, .value = HID_KEYBOARD_SPACEBAR},
        {.width = 0, .value = HID_KEYBOARD_SPACEBAR},
        {.width = 1, .icon = &I_ButtonDegre_7x10, .key = ")", .shift_key = "°", .value = HID_KEYBOARD_MINUS}, //° ne s'affiche pas 
        {.width = 1, .icon = NULL, .key = "=", .shift_key = "+", .value = HID_KEYBOARD_EQUAL_SIGN}, 
        {.width = 1, .icon = &I_ButtonLeft_4x7, .value = HID_KEYBOARD_LEFT_ARROW},
        {.width = 1, .icon = &I_ButtonDown_7x4, .value = HID_KEYBOARD_DOWN_ARROW},
        {.width = 1, .icon = &I_ButtonRight_4x7, .value = HID_KEYBOARD_RIGHT_ARROW}, 
    },
    {
        {.width = 2, .icon = &I_Ctrl_17x10, .value = HID_KEYBOARD_L_CTRL},
        {.width = 0, .value = HID_KEYBOARD_L_CTRL},
        {.width = 2, .icon = &I_Alt_17x10, .value = HID_KEYBOARD_L_ALT},
        {.width = 0, .value = HID_KEYBOARD_L_ALT},
        {.width = 2, .icon = &I_Cmd_17x10, .value = HID_KEYBOARD_L_GUI},
        {.width = 0, .value = HID_KEYBOARD_L_GUI},
        {.width = 2, .icon = &I_Tab_17x10, .value = HID_KEYBOARD_TAB},
        {.width = 0, .value = HID_KEYBOARD_TAB},
        {.width = 2, .icon = &I_Esc_17x10, .value = HID_KEYBOARD_ESCAPE},
        {.width = 0, .value = HID_KEYBOARD_ESCAPE},
        {.width = 2, .icon = &I_Del_17x10, .value = HID_KEYBOARD_DELETE_FORWARD},
        {.width = 0, .value = HID_KEYBOARD_DELETE_FORWARD},
    },
};

and

static void hid_keyboard_draw_key(
    Canvas* canvas,
    HidKeyboardModel* model,
    uint8_t x,
    uint8_t y,
    HidKeyboardKey key,
    bool selected) {
    if(!key.width) return;

    canvas_set_color(canvas, ColorBlack);
    uint8_t keyWidth = KEY_WIDTH * key.width + KEY_PADDING * (key.width - 1);
    if(selected) {
        // Draw a filled box
        elements_slightly_rounded_box(
            canvas,
            MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING),
            MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING),
            keyWidth,
            KEY_HEIGHT);
        canvas_set_color(canvas, ColorWhite);
    } else {
        // Draw a framed box
        elements_slightly_rounded_frame(
            canvas,
            MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING),
            MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING),
            keyWidth,
            KEY_HEIGHT);
    }

        //Ajout
    if (model->shift && key.shift_key && strcmp(key.shift_key, "2") == 0) { //é
        key.icon = NULL;
    }
    if (model->shift && key.shift_key && strcmp(key.shift_key, "7") == 0) { //è
        key.icon = NULL;
    }
    if (model->shift && key.shift_key && strcmp(key.shift_key, "9") == 0) { //ç
        key.icon = NULL;
    }
    if (model->shift && key.shift_key && strcmp(key.shift_key, "0") == 0) { //à
        key.icon = NULL;
    }

    if (!model->shift && key.key && strcmp(key.key, "^") == 0) { //¨
        key.icon = NULL;
    }
    if (!model->shift && key.key && strcmp(key.key, "$") == 0) { //£
        key.icon = NULL;
    }

    if (!model->shift && key.key && strcmp(key.key, "!") == 0) { //§
        key.icon = NULL;
    }

    if (model->shift && key.shift_key && strcmp(key.shift_key, "%") == 0) { //ù
        key.icon = NULL;
    }
    if (!model->shift && key.key && strcmp(key.key, "*") == 0) { //µ
        key.icon = NULL;
    }
    if (!model->shift && key.key && strcmp(key.key, ")") == 0) { //°
        key.icon = NULL;
    }

    /////////////////

    if(key.icon != NULL) {
        // Draw the icon centered on the button
        canvas_draw_icon(
            canvas,
            MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 - key.icon->width / 2,
            MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2 - key.icon->height / 2,
            key.icon);
    } else {
        // If shift is toggled use the shift key when available
        strcpy(model->key_string, (model->shift && key.shift_key != 0) ? key.shift_key : key.key);
        // Upper case if ctrl or alt was toggled true
        if((model->ctrl && key.value == HID_KEYBOARD_L_CTRL) ||
           (model->alt && key.value == HID_KEYBOARD_L_ALT) ||
           (model->gui && key.value == HID_KEYBOARD_L_GUI)) {
            hid_keyboard_to_upper(model->key_string);
        }
        canvas_draw_str_aligned(
            canvas,
            MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 + 1,
            MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2,
            AlignCenter,
            AlignCenter,
            model->key_string);
    }
}

and added images in flipperzero-firmware\applications\system\hid_app\assets : ButtonDegre_7x10 ButtonMu_7x10 Buttonugrave_7x10 ButtonParagrapheg_7x10 ButtonLivreSterling_7x10 Buttontrema_7x10 Buttonagrave_7x10 Buttoncced_7x10 Buttonegrave_7x10 Buttoneaigu_7x10 then compile : ./fbt COMPACT=1 DEBUG=0 updater_package