Table des matières

Tablette Athesi AP1001CL — MX Linux (Le Pain d'Antan)

Procédure complète pour installer, configurer et cloner les tablettes Athesi AP1001CL utilisées au Pain d'Antan.

1. Pourquoi MX Linux et pas NixOS

NixOS a d'abord été essayé (installation reproductible par flake). Il a été abandonné à cause de gels répétés :

Vérification sur une tablette :

grep DESIGNWARE_BAYTRAIL /boot/config-$(uname -r)   # doit afficher =y

2. Installation de MX sur la tablette modèle

2.1 Démarrer sur la clé USB

  1. Redémarrer la tablette en appuyant sur F7 (menu de démarrage du BIOS) ; choisir UEFI: USB DISK….
  2. Dans le menu GRUB de la clé, sélectionner l'entrée (systemd), appuyer sur e et ajouter à la ligne linux :
lang=fr_BE kbd=be tz=Europe/Brussels intel_idle.max_cstate=1 reboot=hard
  1. Démarrer avec F10.

2.2 Installateur MX

Les options intel_idle.max_cstate=1 reboot=hard saisies au démarrage live sont reprises dans le GRUB installé.

2.3 Premier démarrage avec le PiKVM

Avec l'HDMI branché, MX place l'HDMI à côté de l'écran de la tablette (bureau étendu). Si le panneau ou le menu disparaît : débrancher puis rebrancher l'HDMI et choisir Écran en miroir dans la fenêtre qui s'ouvre.

<WRAP important> Ne pas éteindre l'écran intégré (xrandr –output DSI-1 –off) pendant la session : le panneau XFCE s'y perd et l'affichage HDMI devient inexploitable. </WRAP>

Connecter ensuite le Wi-Fi PainAntan via l'icône réseau.

3. Script d'installation

3.1 Préparer le dossier

Dans ~/tablette-mx/ :

Fichier Rôle Obligatoire
installer-tablette.sh le script oui
wallpaper.png fond d'écran 1920×1200 non
bootloader.png logo affiché dans le menu GRUB non
jeton-rustdesk.txt jeton API de la console RustDesk Pro non (sans lui, pas d'inscription automatique au carnet)

<WRAP important> Le jeton RustDesk ne va jamais dans git. Un .gitignore l'exclut. </WRAP>

Depuis une clé USB (montée sous /media/tablette/<NOM>/) :

cd ~/tablette-mx
U=/media/tablette/MX-LIVE
cp $U/wallpaper.png $U/bootloader.png .
tr -d '\r\n ' < $U/RUSTDESK_TOKEN.TXT > jeton-rustdesk.txt && chmod 600 jeton-rustdesk.txt

3.2 Lancer

cd ~/tablette-mx && sudo ./installer-tablette.sh 2>&1 | tee ~/installation.log

Puis redémarrer. Le script est relançable sans risque : il ne réécrit que ce qui change (lignes « ecrit : … »). Pour modifier un réglage : corriger le script, le relancer, redémarrer.

3.3 Ce que fait le script

Étape Détail
Paquets onboard, iio-sensor-proxy, xinput, xdotool, yad, v4l-utils, dconf-cli…
GRUB quiet intel_idle.max_cstate=1 reboot=hard pcie_aspm=off — pas de splash (bloquait l'interface)
Wi-Fi Intel options iwlwifi power_save=0 11n_disable=1 bt_coex_active=0 swcrypto=1
Caméra firmware shisp_2401a0_v21.bin (vérifié par SHA-256) dans /lib/firmware/intel/ipu/ ; intel_atomisp2_pm mis en liste noire
Xorg pilote modesetting en DRI2 (capture RustDesk) ; matrice tactile ; aucune mise en veille de l'écran
Session connexion automatique LightDM ; variables MOZ_USE_XINPUT2, GNOME_ACCESSIBILITY, QT_ACCESSIBILITY ; curseur 48
Firefox (politiques) accessibilité forcée (clavier visuel) ; VA-API ; 2 processus ; pas de cache disque ; mots de passe non révélables ; outils de développement et about:config bloqués
Clavier visuel onboard en AZERTY belge, ouverture automatique dans les champs texte, bouton flottant
Interface (tablette-ui) rotation paysage, raccourcis Boucom / Shyfter / Infos PDA, DPI 144, thème de fenêtre Default-xhdpi, panneaux et icônes agrandis, pas de veille, fond d'écran
Rotation (tablette-rotation) accéléromètre → rotation de l'écran et du tactile ; bloquée en paysage si HDMI branché
Thème Greybird + accents caramel, panneau brun foncé, dossiers Papirus bruns ; icônes MX par défaut retirées du bureau ; horloge (conky) désactivée
Performances zram (zstd, 50 %, prioritaire), vm.swappiness=100, pilote vidéo i965, cups/ModemManager coupés, notificateur de mises à jour MX coupé, noatime, TRIM hebdomadaire, journal limité à 64 Mo
GRUB graphique bootloader.png centré sur fond brun, tourné d'un quart de tour (dalle en portrait natif)
RustDesk dernière version .deb, serveur rust.makeitsimple.be, mot de passe permanent aléatoire, inscription au carnet PainAntan
Clonage installe tablette-preparer-clonage et le mécanisme de premier démarrage

4. Clonage

4.1 Ordre

  1. Sur la tablette modèle : script d'installation (§3), redémarrage, tests (§6).
  2. Sur la modèle :
    sudo tablette-preparer-clonage

    Efface l'identité (ID et mot de passe RustDesk, clés SSH, machine-id), crée /etc/tablette/a-personnaliser et éteint.

  3. Clonezilla : image du disque mmcblk0, puis restauration sur chaque tablette.
  4. Premier démarrage de chaque tablette (et de la modèle) :
    • une fenêtre demande le nom (minuscules, chiffres, tirets — ex. pa-ixl-tab-02), clavier visuel affiché ;
    • nouvelle identité : machine-id, clés SSH, nouvel ID RustDesk, nouveau mot de passe RustDesk ;
    • inscription dans le carnet PainAntan sous ce nom ;
    • redémarrage.

4.2 Fonctionnement interne

Élément Rôle
tablette-premier-demarrage.service si /etc/tablette/a-personnaliser existe : machine-id, clés SSH, crée /run/tablette
tablette-demander-nom (autostart) demande le nom (yad) et l'écrit dans /run/tablette/nom
tablette-nommer.path / .service dès que le nom est déposé : hostnamectl, /etc/hosts, RustDesk, suppression du témoin, redémarrage
tablette-rustdesk config / motdepasse / enregistrer NOM

5. RustDesk et sécurité

5.1 Jeton de la console

Console RustDesk Pro → Paramètres → Jetons → Créer :

Le jeton est stocké dans /etc/rustdesk/token (root, 600) et se retrouve dans l'image Clonezilla.

5.2 Mots de passe

5.3 Recommandations

5.4 Firefox

Politiques dans /etc/firefox/policies/policies.json : DisablePasswordReveal, DisableDeveloperTools, BlockAboutConfig, DisableAppUpdate. Les mots de passe enregistrés restent utilisables en remplissage automatique mais ne peuvent pas être affichés.

6. Tests après installation

7. Problèmes rencontrés et solutions

Symptôme Cause Solution
Gels, i2c_designware … timeout, écran DSI noir après rotation (NixOS) noyau sans I2C_DESIGNWARE_BAYTRAIL passer à MX (noyau Liquorix)
Écran noir avec seulement le curseur au démarrage sans HDMI commande xrandr commune DSI + HDMI qui échoue si l'HDMI est absent ; rotation dans Xorg dès le démarrage rotation faite par la session, commande séparée pour l'HDMI
Écran noir puis gel en tournant la tablette avec l'HDMI branché rotation + recopie HDMI trop lourde pour le GPU Cherry Trail rotation bloquée en paysage quand l'HDMI est branché
Clavier visuel qui ne s'ouvre jamais seul onboard attend un « mode tablette » que la tablette ne signale pas tablet-mode-detection-enabled=false (dconf), redémarrer onboard
onboard en QWERTY lancé avant la disposition belge autostart d'origine masqué ; lancement différé avec setxkbmap be
Icône de raccourci invisible sur le bureau fichier ajouté après le démarrage du bureau xfdesktop –reload
zram inactif service zramswap masqué par MX systemctl unmask zramswap
Image Plymouth : écran noir (NixOS) i915 chargé trop tôt (initrd) avant le pilote du rétroéclairage pas de Plymouth ; image dans GRUB à la place
Panneau XFCE disparu écran intégré éteint pendant la session rebrancher l'HDMI et choisir « miroir »

8. Maintenance

9. Script complet

installer-tablette.sh
#!/bin/bash
# =============================================================================
#  Tablette Athesi AP1001CL (Cherry Trail x5-Z8350) - MX Linux 25 (systemd)
#  Installation / mise a jour de tous les reglages. Relancable sans risque.
#
#  Usage :  sudo ./installer-tablette.sh
#  Fichiers optionnels a cote du script :
#    wallpaper.png         fond d'ecran
#    jeton-rustdesk.txt    jeton API de la console RustDesk Pro (jamais dans git)
# =============================================================================
set -euo pipefail
[ "$(id -u)" = 0 ] || exec sudo "$0" "$@"
 
ICI=$(cd "$(dirname "$0")" && pwd)
UTIL=tablette
RD_SERVEUR=rust.makeitsimple.be
RD_CLE='OhOcYR3xOjsI+4EInYR74DB3Ot1dd0aAl5W0odZXNVk='
RD_CARNET=PainAntan
PART=/usr/local/share/tablette          # fichiers partages (fond d'ecran, raccourcis)
 
etape() { echo; echo "=== $* ==="; }
# Ecrit un fichier seulement si son contenu change (stdin -> chemin, mode)
ecrire() { local f=$1 m=${2:-644} t; t=$(mktemp); cat >"$t"
  if ! cmp -s "$t" "$f" 2>/dev/null; then install -D -m "$m" "$t" "$f"; echo "  ecrit : $f"; fi; rm -f "$t"; }
# Fixe VAR=valeur dans /etc/environment
env_var() { sed -i "/^$1=/d" /etc/environment; echo "$1=$2" >> /etc/environment; }
 
id "$UTIL" >/dev/null 2>&1 || { echo "Utilisateur $UTIL absent : cree-le pendant l'installation de MX."; exit 1; }
HOME_U=$(getent passwd "$UTIL" | cut -d: -f6)
 
# -----------------------------------------------------------------------------
etape "Paquets"
export DEBIAN_FRONTEND=noninteractive
apt-get update -q
apt-get install -y -q onboard iio-sensor-proxy xinput xdotool x11-xserver-utils \
  v4l-utils yad curl ca-certificates dconf-cli at-spi2-core
 
# -----------------------------------------------------------------------------
etape "Demarrage (GRUB)"
# Cherry Trail : C-states profonds -> gels ; reboot ACPI qui ne redemarre pas.
# Pas de 'splash' : il bloquait l'interface graphique sur cette tablette.
CMDLINE="quiet intel_idle.max_cstate=1 reboot=hard pcie_aspm=off"
if ! grep -q "^GRUB_CMDLINE_LINUX_DEFAULT=\"$CMDLINE\"" /etc/default/grub; then
  sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=\"$CMDLINE\"|" /etc/default/grub
  update-grub
fi
 
# -----------------------------------------------------------------------------
etape "Wi-Fi Intel (iwlwifi)"
ecrire /etc/modprobe.d/tablette-iwlwifi.conf <<'EOF'
# Stabilite Wi-Fi : pas d'economie d'energie, pas de 802.11n, pas de coexistence BT,
# chiffrement logiciel
options iwlwifi power_save=0 11n_disable=1 bt_coex_active=0 swcrypto=1
EOF
 
# -----------------------------------------------------------------------------
etape "Firmware camera (atomisp / OV2680)"
FW_SHA=e89359f4e4934c410c83d525e283f34c5fcce9cb5caa75ad8a32d66d3842d95c
FW=/lib/firmware/intel/ipu/shisp_2401a0_v21.bin
if ! echo "$FW_SHA  $FW" | sha256sum -c --quiet 2>/dev/null; then
  t=$(mktemp)
  curl -fsSL -o "$t" https://raw.githubusercontent.com/intel-aero/meta-intel-aero-base/master/recipes-kernel/linux/linux-yocto/shisp_2401a0_v21.bin
  echo "$FW_SHA  $t" | sha256sum -c --quiet
  install -D -m644 "$t" "$FW"; ln -sf intel/ipu/shisp_2401a0_v21.bin /lib/firmware/shisp_2401a0_v21.bin
  rm -f "$t"
fi
# intel_atomisp2_pm s'accroche a l'ISP et empeche le pilote atomisp de le prendre
ecrire /etc/modprobe.d/tablette-camera.conf <<'EOF'
blacklist intel_atomisp2_pm
EOF
 
# -----------------------------------------------------------------------------
etape "Affichage et tactile (Xorg)"
ecrire /etc/X11/xorg.conf.d/20-tablette.conf <<'EOF'
# Pilote modesetting en DRI2 : necessaire pour la capture d'ecran RustDesk
Section "Device"
    Identifier "Intel"
    Driver     "modesetting"
    Option     "DRI" "2"
    Option     "Monitor-DSI-1"  "DSI-1"
    Option     "Monitor-HDMI-2" "HDMI-2"
EndSection
# Dalle native en portrait (1200x1920). La rotation en paysage est faite par la session
# (tablette-ui) : tournee des le demarrage de X, la dalle restait noire avec seulement
# le curseur jusqu'a la premiere rotation.
Section "Monitor"
    Identifier "DSI-1"
    Option     "Primary" "true"
EndSection
# HDMI (PiKVM) superpose a l'ecran integre
Section "Monitor"
    Identifier "HDMI-2"
    Option     "Position" "0 0"
EndSection
# Ecran tactile Goodix : meme rotation que l'affichage
Section "InputClass"
    Identifier "tactile tourne"
    MatchIsTouchscreen "on"
    Option     "TransformationMatrix" "0 1 0 -1 0 1 0 0 1"
EndSection
# Libre-service : jamais de mise en veille de l'ecran
Section "ServerFlags"
    Option "BlankTime"   "0"
    Option "StandbyTime" "0"
    Option "SuspendTime" "0"
    Option "OffTime"     "0"
EndSection
EOF
 
# -----------------------------------------------------------------------------
etape "Session : connexion automatique, variables, Firefox, onboard"
groupadd -rf autologin; usermod -aG autologin,video,audio,input,netdev "$UTIL" 2>/dev/null || true
ecrire /etc/lightdm/lightdm.conf.d/50-tablette.conf <<EOF
[Seat:*]
autologin-user=$UTIL
autologin-user-timeout=0
EOF
 
env_var MOZ_USE_XINPUT2 1                   # defilement tactile Firefox
env_var GNOME_ACCESSIBILITY 1               # AT-SPI force : onboard voit les champs texte
env_var QT_ACCESSIBILITY 1
env_var QT_LINUX_ACCESSIBILITY_ALWAYS_ON 1
env_var XCURSOR_SIZE 48
 
ecrire /etc/firefox/policies/policies.json <<'EOF'
{ "policies": {
    "Preferences": {
      "accessibility.force_disabled": { "Value": 0, "Status": "default" },
      "media.ffmpeg.vaapi.enabled": { "Value": true, "Status": "default" },
      "dom.ipc.processCount": { "Value": 2, "Status": "default" },
      "browser.cache.disk.enable": { "Value": false, "Status": "default" },
      "browser.sessionstore.interval": { "Value": 60000, "Status": "default" }
    },
    "DisableAppUpdate": true,
    "DisablePasswordReveal": true,
    "DisableDeveloperTools": true,
    "BlockAboutConfig": true
} }
EOF
 
# Clavier visuel : s'ouvre seul dans les champs texte ; bouton flottant de secours
ecrire /etc/dconf/profile/user <<'EOF'
user-db:user
system-db:local
EOF
ecrire /etc/dconf/db/local.d/00-tablette <<'EOF'
[org/gnome/desktop/a11y/applications]
screen-keyboard-enabled=true
 
[org/gnome/desktop/interface]
toolkit-accessibility=true
 
[org/onboard/auto-show]
enabled=true
# La tablette ne signale pas de "mode tablette" : sans ceci, onboard ne s'affiche jamais seul
tablet-mode-detection-enabled=false
 
[org/onboard/icon-palette]
in-use=true
EOF
dconf update
 
# L'autostart livre par onboard demarre trop tot (avant la disposition belge) : on le masque
# pour l'utilisateur et on lance le notre, apres un setxkbmap be
install -d -o "$UTIL" -g "$UTIL" "$HOME_U/.config" "$HOME_U/.config/autostart"
for a in onboard-autostart xfce4-screensaver light-locker conky; do
  printf '[Desktop Entry]\nType=Application\nName=%s\nHidden=true\n' "$a" \
    | ecrire "$HOME_U/.config/autostart/$a.desktop"
  chown "$UTIL:" "$HOME_U/.config/autostart/$a.desktop"
done
ecrire /etc/xdg/autostart/tablette-onboard.desktop <<'EOF'
[Desktop Entry]
Type=Application
Name=Clavier visuel (tablette)
Exec=sh -c "sleep 10; setxkbmap be; exec onboard"
X-GNOME-Autostart-enabled=true
EOF
 
# -----------------------------------------------------------------------------
etape "Fond d'ecran et raccourcis"
if [ -f "$ICI/wallpaper.png" ]; then install -D -m644 "$ICI/wallpaper.png" "$PART/wallpaper.png"; fi
raccourci() { # id nom url [icone]
  ecrire "$PART/raccourcis/$1.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=$2
Exec=firefox --new-window "$3"
Icon=${4:-applications-internet}
Terminal=false
EOF
}
raccourci boucom    "Boucom"    "https://lepaindantan.quadrabee.com"
raccourci shyfter   "Shyfter"   "https://pos.shyfter.co"
raccourci infos-pda "Infos PDA" "https://painantan.sharepoint.com/:f:/s/PDAAdmin2/Ev_ASDVTxTxNszW6JAxCSpsBiUlDROPC28Ml7upK4BF8yg?e=phZYsd" folder-remote
 
# -----------------------------------------------------------------------------
etape "Reglages d'interface appliques a chaque ouverture de session"
ecrire /usr/local/bin/tablette-ui 755 <<'EOF'
#!/bin/bash
# Interface tactile : tout en plus grand, fond d'ecran, raccourcis. Lance a chaque session.
sleep 5   # laisser xfconfd, le panneau et le bureau demarrer
q() { xfconf-query "$@"; }
PART=/usr/local/share/tablette
# Ecran integre en paysage, sans mise a l'echelle. Commande separee pour l'HDMI : si l'HDMI
# est debranche, une commande commune echoue entierement et l'ecran reste noir.
xrandr --output DSI-1 --primary --mode 1200x1920 --rotate right --transform none --scale 1x1 --pos 0x0 || true
if xrandr | grep -q '^HDMI-2 connected'; then xrandr --output HDMI-2 --same-as DSI-1 || true; fi
# Raccourcis du bureau, approuves (sinon alerte 'lanceur non sur' d'XFCE)
desk=$(xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Bureau"); mkdir -p "$desk"
for f in "$PART"/raccourcis/*.desktop; do
  dst="$desk/$(basename "$f")"; install -m755 "$f" "$dst"
  gio set "$dst" metadata::xfce-exe-checksum "$(sha256sum "$dst" | cut -d' ' -f1)" 2>/dev/null || true
done
xfdesktop --reload 2>/dev/null || true   # sinon une icone ajoutee apres son demarrage reste invisible
# Fenetres : pas de compositeur (perfs), theme a gros boutons
q -c xfwm4 -p /general/use_compositing -n -t bool -s false
q -c xfwm4 -p /general/theme -n -t string -s Default-xhdpi
q -c xfwm4 -p /general/title_font -n -t string -s "Sans Bold 11"
# Polices / DPI / curseur
q -c xsettings -p /Xft/DPI -n -t int -s 144
q -c xsettings -p /Gtk/CursorThemeSize -n -t int -s 48
# Tableaux de bord et icones plus grands
for p in $(q -c xfce4-panel -l | grep -oE '^/panels/panel-[0-9]+' | sort -u); do
  q -c xfce4-panel -p "$p/size" -n -t uint -s 56
  q -c xfce4-panel -p "$p/icon-size" -n -t uint -s 40
done
q -c xfce4-desktop -p /desktop-icons/icon-size -n -t uint -s 72
# Jamais de mise en veille ni de verrouillage
pm=/xfce4-power-manager
q -c xfce4-power-manager -p $pm/dpms-enabled -n -t bool -s false
q -c xfce4-power-manager -p $pm/blank-on-ac -n -t int -s 0
q -c xfce4-power-manager -p $pm/blank-on-battery -n -t int -s 0
q -c xfce4-power-manager -p $pm/lock-screen-suspend-hibernate -n -t bool -s false
xset s off -dpms 2>/dev/null || true
# Fond d'ecran sur chaque sortie connectee
if [ -f "$PART/wallpaper.png" ]; then
  for out in $(xrandr --query | awk '/ connected/{print $1}'); do
    b=/backdrop/screen0/monitor$out/workspace0
    q -c xfce4-desktop -p $b/last-image -n -t string -s "$PART/wallpaper.png"
    q -c xfce4-desktop -p $b/image-style -n -t int -s 5
  done
fi
EOF
ecrire /etc/xdg/autostart/tablette-ui.desktop <<'EOF'
[Desktop Entry]
Type=Application
Name=Reglages tablette
Exec=/usr/local/bin/tablette-ui
X-GNOME-Autostart-enabled=true
EOF
 
# -----------------------------------------------------------------------------
etape "Rotation automatique (accelerometre)"
ecrire /usr/local/bin/tablette-rotation 755 <<'EOF'
#!/bin/bash
# Orientation physique (iio-sensor-proxy) -> rotation xrandr + matrice du tactile Goodix
touch="Goodix Capacitive TouchScreen"
last=
apply() {
  case "$1" in
    # Correspondance validee sur la tablette (capteur monte tete-beche)
    normal)    rot=inverted; m="-1 0 1 0 -1 1 0 0 1" ;;
    left-up)   rot=left;     m="0 -1 1 1 0 0 0 0 1" ;;
    right-up)  rot=right;    m="0 1 0 -1 0 1 0 0 1" ;;
    bottom-up) rot=normal;   m="1 0 0 0 1 0 0 0 1" ;;
    *) return ;;
  esac
  # HDMI branche (PiKVM) : on reste en paysage. Tourner l'ecran integre tout en le
  # recopiant sur l'HDMI a donne ecran noir et gels sur cette puce.
  if xrandr | grep -q '^HDMI-2 connected'; then rot=right; m="0 1 0 -1 0 1 0 0 1"; fi
  [ "$rot" = "$last" ] && return
  last=$rot
  xrandr --output DSI-1 --rotate "$rot" --transform none --scale 1x1
  for id in $(xinput list | grep -F "$touch" | grep -o 'id=[0-9]*' | cut -d= -f2); do
    xinput set-prop "$id" "Coordinate Transformation Matrix" $m 2>/dev/null
  done
}
sleep 8   # apres les reglages de session
monitor-sensor | while read -r line; do
  case "$line" in
    *"orientation changed:"*|*"Has accelerometer"*orientation:*)
      apply "$(echo "$line" | grep -oE '(normal|left-up|right-up|bottom-up)' | tail -1)" ;;
  esac
done
EOF
ecrire /etc/xdg/autostart/tablette-rotation.desktop <<'EOF'
[Desktop Entry]
Type=Application
Name=Rotation automatique
Exec=/usr/local/bin/tablette-rotation
X-GNOME-Autostart-enabled=true
EOF
 
# -----------------------------------------------------------------------------
etape "Theme aux couleurs Le Pain d'Antan"
# Icones Papirus avec des dossiers bruns (au lieu du bleu) : on repointe les liens
# symboliques des dossiers *-blue* vers leur equivalent *-brown* livre avec Papirus
for d in /usr/share/icons/Papirus/*/places; do
  for l in "$d"/*.svg; do
    [ -L "$l" ] || continue
    c=$(readlink "$l")
    case "$c" in *-blue*) n=${c//-blue/-brown}; [ -e "$d/$n" ] && ln -sfn "$n" "$l" ;; esac
  done
done
gtk-update-icon-cache -qf /usr/share/icons/Papirus 2>/dev/null || true
# Brun fonce du fond d'ecran, creme du logo, caramel pour les selections
install -d -o "$UTIL" -g "$UTIL" "$HOME_U/.config/gtk-3.0"
ecrire "$HOME_U/.config/gtk-3.0/gtk.css" <<'EOF'
/* Couleurs Le Pain d'Antan (tablette) */
@define-color theme_selected_bg_color #9a6a45;
@define-color theme_selected_fg_color #ffffff;
*:selected, selection, menuitem:hover, row:selected, treeview:selected {
  background-color: #9a6a45; color: #ffffff; }
progressbar progress, scale highlight { background-color: #9a6a45; border-color: #6e4a30; }
#XfcePanelWindow, .xfce4-panel { background-color: #2e1d15; color: #f3e9d8; }
#XfcePanelWindow button, #XfcePanelWindow label, .xfce4-panel button, .xfce4-panel label { color: #f3e9d8; }
#XfcePanelWindow button:hover, #XfcePanelWindow button:checked { background-color: #4a2e20; }
EOF
chown "$UTIL:" "$HOME_U/.config/gtk-3.0/gtk.css"
ecrire /usr/local/bin/tablette-theme 755 <<'EOF'
#!/bin/bash
# Theme neutre + accents bruns ; retrait des icones MX par defaut du bureau
sleep 6
xfconf-query -c xsettings -p /Net/ThemeName -n -t string -s Greybird
xfconf-query -c xsettings -p /Net/IconThemeName -n -t string -s Papirus
xfconf-query -c xfce4-panel -p /panels/panel-1/background-style -n -t uint -s 0 2>/dev/null
desk=$(xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Bureau")
rm -f "$desk/FAQ.desktop" "$desk/Help.desktop" "$desk/Quick_System_Info.desktop"
EOF
ecrire /etc/xdg/autostart/tablette-theme.desktop <<'EOF'
[Desktop Entry]
Type=Application
Name=Theme tablette
Exec=/usr/local/bin/tablette-theme
X-GNOME-Autostart-enabled=true
EOF
 
# -----------------------------------------------------------------------------
etape "Performances (memoire, services, eMMC, video)"
apt-get install -y -q zram-tools i965-va-driver python3-pil
# Memoire compressee : moins d'echanges avec l'eMMC, lente
ecrire /etc/default/zramswap <<'EOF'
ALGO=zstd
PERCENT=50
PRIORITY=100
EOF
systemctl unmask zramswap >/dev/null 2>&1 || true; systemctl enable zramswap >/dev/null 2>&1 || true; systemctl restart zramswap || true
ecrire /etc/sysctl.d/90-tablette.conf <<'EOF'
vm.swappiness=100
EOF
sysctl -q --system || true
env_var LIBVA_DRIVER_NAME i965              # decodage video materiel (Cherry Trail)
# Services inutiles sur la tablette (Bluetooth conserve)
for s in cups cups-browsed ModemManager; do systemctl disable --now "$s" >/dev/null 2>&1 || true; done
# Pas de verification des mises a jour MX en arriere-plan (mises a jour faites a la main)
for f in /etc/xdg/autostart/*.desktop; do
  if grep -qiE 'apt-notifier|mx-updater' "$f"; then
    a=$(basename "$f")
    printf '[Desktop Entry]\nType=Application\nName=%s\nHidden=true\n' "$a" | ecrire "$HOME_U/.config/autostart/$a"
    chown "$UTIL:" "$HOME_U/.config/autostart/$a"
  fi
done
# eMMC : pas d'ecriture a chaque lecture (noatime), TRIM hebdomadaire, journal limite
if ! awk '$2=="/" {print $4}' /etc/fstab | grep -q noatime; then
  cp /etc/fstab /etc/fstab.avant-tablette
  awk 'BEGIN{OFS="\t"} $1 !~ /^#/ && $2=="/" {$4=$4",noatime"} {print}' /etc/fstab.avant-tablette > /etc/fstab
fi
systemctl enable fstrim.timer >/dev/null 2>&1 || true
ecrire /etc/systemd/journald.conf.d/tablette.conf <<'EOF'
[Journal]
SystemMaxUse=64M
EOF
 
# -----------------------------------------------------------------------------
etape "Image du menu de demarrage (GRUB)"
# GRUB s'affiche sur la dalle en portrait natif : l'image est composee en paysage
# (logo centre sur le brun du fond d'ecran) puis tournee d'un quart de tour.
if [ -f "$ICI/bootloader.png" ]; then
  python3 - "$ICI/bootloader.png" /boot/grub/tablette-fond.png <<'PY'
import sys
from PIL import Image
src = Image.open(sys.argv[1]).convert("RGBA")
fond = Image.new("RGBA", (1920, 1200), (74, 46, 32, 255))
boite = (1920, 1200) if src.width >= 1600 else (1150, 720)
src.thumbnail(boite)
fond.alpha_composite(src, ((1920 - src.width) // 2, (1200 - src.height) // 2))
fond.convert("RGB").transpose(Image.Transpose.ROTATE_270).save(sys.argv[2])
PY
  sed -i -e '/^GRUB_THEME=/s/^/#/' -e '/^GRUB_BACKGROUND=/d' /etc/default/grub
  echo 'GRUB_BACKGROUND="/boot/grub/tablette-fond.png"' >> /etc/default/grub
  update-grub
fi
 
# -----------------------------------------------------------------------------
etape "RustDesk"
if ! command -v rustdesk >/dev/null; then
  url=$(curl -fsSL https://api.github.com/repos/rustdesk/rustdesk/releases/latest \
        | grep -oE '"browser_download_url": *"[^"]+x86_64\.deb"' | tail -n1 | cut -d'"' -f4)
  t=$(mktemp --suffix=.deb); curl -fsSL -o "$t" "$url"
  apt-get install -y -q "$t"; rm -f "$t"
fi
install -d -m700 /etc/rustdesk
[ -f "$ICI/jeton-rustdesk.txt" ] && install -m600 "$ICI/jeton-rustdesk.txt" /etc/rustdesk/token
 
ecrire /usr/local/sbin/tablette-rustdesk 755 <<EOF
#!/bin/bash
# tablette-rustdesk config        : serveur Make IT Simple pour root et l'utilisateur
# tablette-rustdesk motdepasse    : mot de passe permanent (genere s'il n'existe pas)
# tablette-rustdesk enregistrer N : inscription dans le carnet $RD_CARNET sous le nom N
set -u
SERVEUR=$RD_SERVEUR; CLE='$RD_CLE'; CARNET=$RD_CARNET; UTIL=$UTIL
EOF
cat >>/usr/local/sbin/tablette-rustdesk <<'EOF'
toml() { cat <<T
rendezvous_server = '$SERVEUR:21116'
nat_type = 1
serial = 0
 
[options]
custom-rendezvous-server = '$SERVEUR'
relay-server = '$SERVEUR'
key = '$CLE'
api-server = 'https://$SERVEUR'
T
}
attendre_service() { # la commande --password passe par l'IPC du service
  for i in $(seq 1 30); do
    out=$(rustdesk --password "$1" 2>&1) && case "$out" in *refused*|*rror*) ;; *) return 0 ;; esac
    sleep 2
  done; return 1
}
case "${1:-}" in
  config)
    systemctl stop rustdesk 2>/dev/null || true
    h=$(getent passwd "$UTIL" | cut -d: -f6)
    for d in /root/.config/rustdesk "$h/.config/rustdesk"; do
      install -d -m700 "$d"; toml > "$d/RustDesk2.toml"; chmod 600 "$d/RustDesk2.toml"
    done
    chown -R "$UTIL:" "$h/.config/rustdesk"
    systemctl enable --now rustdesk ;;
  motdepasse)
    [ -s /etc/rustdesk/password ] || ( umask 077; tr -dc 'A-Za-z0-9' </dev/urandom | head -c 20 > /etc/rustdesk/password )
    attendre_service "$(cat /etc/rustdesk/password)" && echo "mot de passe permanent applique" ;;
  enregistrer)
    nom=${2:?nom}
    [ -s /etc/rustdesk/token ] || { echo "pas de jeton (/etc/rustdesk/token) : enregistrement ignore"; exit 0; }
    sleep 10   # laisser le service s'annoncer aupres du serveur
    out=$(rustdesk --assign --token "$(cat /etc/rustdesk/token)" --address_book_name "$CARNET" \
          --address_book_alias "$nom" --address_book_password "$(cat /etc/rustdesk/password)" 2>&1)
    echo "$out"; case "$out" in *rror*|*ailed*) exit 1 ;; esac
    echo "ID RustDesk : $(rustdesk --get-id)" ;;
  *) echo "usage : $0 config|motdepasse|enregistrer NOM"; exit 2 ;;
esac
EOF
chmod 755 /usr/local/sbin/tablette-rustdesk
tablette-rustdesk config
tablette-rustdesk motdepasse || echo "  (mot de passe : le service n'a pas repondu, relancer le script)"
 
# -----------------------------------------------------------------------------
etape "Clonage : preparation et premier demarrage"
# 1) tablette-preparer-clonage : a lancer sur la tablette modele juste avant l'image Clonezilla
ecrire /usr/local/sbin/tablette-preparer-clonage 755 <<'EOF'
#!/bin/bash
# Efface l'identite de cette tablette puis l'eteint. Au prochain demarrage (modele ou clone),
# un nom est demande a l'ecran et une nouvelle identite est creee.
set -e
[ "$(id -u)" = 0 ] || exec sudo "$0" "$@"
[ -s /etc/rustdesk/token ] || echo "ATTENTION : pas de jeton RustDesk, les clones ne s'inscriront pas dans le carnet."
read -r -p "Effacer l'identite de cette tablette et l'eteindre ? [o/N] " r; [ "$r" = o ] || exit 1
systemctl stop rustdesk || true
rm -f /root/.config/rustdesk/RustDesk.toml /home/*/.config/rustdesk/RustDesk.toml   # -> nouvel ID
rm -f /etc/rustdesk/password                                                        # -> nouveau mot de passe
rm -f /etc/ssh/ssh_host_*                                                           # -> nouvelles cles SSH
truncate -s0 /etc/machine-id; rm -f /var/lib/dbus/machine-id                        # -> nouveau machine-id
install -d /etc/tablette; touch /etc/tablette/a-personnaliser
journalctl --rotate >/dev/null 2>&1 && journalctl --vacuum-time=1s >/dev/null 2>&1 || true
echo "Prete pour l'image Clonezilla. Extinction."; sleep 2; poweroff
EOF
 
# 2) Au demarrage (root) : nouvelle identite, puis attente du nom saisi dans la session
ecrire /usr/local/sbin/tablette-premier-demarrage 755 <<'EOF'
#!/bin/bash
set -u
[ -s /var/lib/dbus/machine-id ] || ln -sf /etc/machine-id /var/lib/dbus/machine-id
ls /etc/ssh/ssh_host_*_key >/dev/null 2>&1 || ssh-keygen -A 2>/dev/null || true
install -d -m 770 -o root -g tablette /run/tablette      # le nom y sera depose par la session
EOF
ecrire /etc/systemd/system/tablette-premier-demarrage.service <<'EOF'
[Unit]
Description=Tablette : nouvelle identite apres clonage
ConditionPathExists=/etc/tablette/a-personnaliser
Before=display-manager.service ssh.service rustdesk.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/tablette-premier-demarrage
[Install]
WantedBy=multi-user.target
EOF
 
# 3) Dans la session : demande du nom (clavier visuel affiche)
ecrire /usr/local/bin/tablette-demander-nom 755 <<'EOF'
#!/bin/bash
[ -e /etc/tablette/a-personnaliser ] || exit 0
sleep 12; pgrep -x onboard >/dev/null || (setxkbmap be; onboard &)
while :; do
  nom=$(yad --entry --center --on-top --title "Nouvelle tablette" --width 600 \
        --text "<big>Nom de cette tablette ?</big>\n(minuscules, chiffres et tirets - ex. pa-ixl-tab-02)" \
        --button="Valider:0") || continue
  nom=$(echo "$nom" | tr 'A-Z' 'a-z')
  if [[ "$nom" =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ ]]; then break; fi
  yad --error --center --text "Nom invalide : $nom" --button=OK:0
done
echo "$nom" > /run/tablette/nom
yad --info --center --no-buttons --timeout 120 --text "<big>Configuration de '$nom'...</big>\nLa tablette va redemarrer." &
EOF
ecrire /etc/xdg/autostart/tablette-demander-nom.desktop <<'EOF'
[Desktop Entry]
Type=Application
Name=Nom de la tablette
Exec=/usr/local/bin/tablette-demander-nom
X-GNOME-Autostart-enabled=true
EOF
 
# 4) Des que le nom est depose (root) : nom de machine, RustDesk, puis redemarrage
ecrire /usr/local/sbin/tablette-nommer 755 <<'EOF'
#!/bin/bash
set -u
nom=$(head -c 63 /run/tablette/nom | tr -cd 'a-z0-9-'); rm -f /run/tablette/nom
[ -n "$nom" ] || exit 1
hostnamectl set-hostname "$nom"
sed -i "/^127\.0\.1\.1/d" /etc/hosts; echo -e "127.0.1.1\t$nom" >> /etc/hosts
systemctl restart rustdesk; sleep 5
tablette-rustdesk motdepasse
if tablette-rustdesk enregistrer "$nom"; then
  echo "Inscrite dans le carnet RustDesk sous '$nom'"
else
  echo "Inscription RustDesk echouee : relancer 'sudo tablette-rustdesk enregistrer $nom'"
fi
rm -f /etc/tablette/a-personnaliser
sleep 3; systemctl reboot
EOF
ecrire /etc/systemd/system/tablette-nommer.path <<'EOF'
[Unit]
Description=Tablette : nom saisi au premier demarrage
ConditionPathExists=/etc/tablette/a-personnaliser
[Path]
PathExists=/run/tablette/nom
[Install]
WantedBy=multi-user.target
EOF
ecrire /etc/systemd/system/tablette-nommer.service <<'EOF'
[Unit]
Description=Tablette : nom, RustDesk, redemarrage
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/tablette-nommer
EOF
systemctl daemon-reload
systemctl enable tablette-premier-demarrage.service tablette-nommer.path
 
# -----------------------------------------------------------------------------
etape "Inscription RustDesk de cette tablette"
tablette-rustdesk enregistrer "$(hostname)" || echo "  (a relancer plus tard : sudo tablette-rustdesk enregistrer $(hostname))"
 
etape "Termine"
echo "ID RustDesk : $(rustdesk --get-id 2>/dev/null)"
echo "Mot de passe permanent : sudo cat /etc/rustdesk/password"
echo "Redemarre la tablette pour appliquer GRUB, Xorg et la session."