Add callscreen DWM plugin for incoming and active voice calls

This commit is contained in:
Luxferre
2026-10-22 10:17:24 +03:00
parent cbac6743bc
commit 6e58218e10
38 changed files with 2120 additions and 38 deletions
+3 -3
View File
@@ -11,8 +11,8 @@ It uses a pure **X11 (`Xlibre` + `sxmo-de-dwm`)** stack (no Wayland) optimized f
- `src/dwm-plugins/`: Preloaded C++20 `240x320` DWM plugins and shared headers:
- `theme.h`: Unified `.Xresources` / `~/.xthemes/*.xth` parser, proportional font sizing (`theme.baseFontSize`), automatic shade derivation, and live Xft/Pango theme reloading (`PluginTheme`).
- `phone_data.h`: Shared X11 geometry (`240x296` below the 24px bar), FIFO IPC (`/tmp/dwm_plugin_<name>.fifo`), softkey chord detection, Sxmo TSV contact/call/SMS parsers, and `libjpeg`/`libpng` helpers.
- `dialer_plugin.cpp` (`dialer.so` / `xdialer`), `calllog_plugin.cpp` (`calllog.so` / `xcalllog`), `contacts_plugin.cpp` (`contacts.so` / `xcontacts`), `sms_plugin.cpp` (`sms.so` / `xsms`), `files_plugin.cpp` (`files.so` / `xfiles`), `camera_plugin.cpp` (`camera.so` / `xcamera`), `themes_plugin.cpp` (`themes.so` / `xthemes`).
- `dwm_plugin_runner.c`: Lightweight `/usr/bin/dwm-plugin` launcher symlinked by `xdrawer`, `xdialer`, `xcalllog`, `xcontacts`, `xsms`, `xfiles`, `xcamera`, `xthemes`, `dmenu`, and `xdmenu`.
- `dialer_plugin.cpp` (`dialer.so` / `xdialer`), `calllog_plugin.cpp` (`calllog.so` / `xcalllog`), `callscreen_plugin.cpp` (`callscreen.so` / `xcallscreen`), `contacts_plugin.cpp` (`contacts.so` / `xcontacts`), `sms_plugin.cpp` (`sms.so` / `xsms`), `files_plugin.cpp` (`files.so` / `xfiles`), `camera_plugin.cpp` (`camera.so` / `xcamera`), `themes_plugin.cpp` (`themes.so` / `xthemes`).
- `dwm_plugin_runner.c`: Lightweight `/usr/bin/dwm-plugin` launcher symlinked by `xdrawer`, `xdialer`, `xcalllog`, `xcallscreen`, `xcontacts`, `xsms`, `xfiles`, `xcamera`, `xthemes`, `dmenu`, and `xdmenu`.
- `src/xdrawer/`: Global phone controls overlay (`xdrawer.so` / `xdrawer`), toggled by pressing both softkeys simultaneously.
- `src/sxmo-st/`: Patched `st` terminal with HarfBuzz OpenType ligatures (`Fira Code`), `XIM` (`fcitx5-t9`), and live `SIGUSR1` `.Xresources` reload.
- `src/fcitx5-t9/`: 6-mode keypad input method (`abc`, `Abc`, `ABC`, `Sym`, `Ctl`, `123` + `*` long-press `Ctrl+` latch) with fixed bottom preedit bar (`Y=290, H=30`).
@@ -23,7 +23,7 @@ It uses a pure **X11 (`Xlibre` + `sxmo-de-dwm`)** stack (no Wayland) optimized f
## 3. Build & Image Generation Commands
All cross-compilation scripts run inside rootless Docker (`alpine:3.24` `armv7` sysroot) and automatically update both `prebuilt/` and `overlay/rootfs/`:
- `./scripts/build-sxmo-x11.sh` — Builds `st`, `dmenu.so`, `dwm`, `dwm-plugin`, and all C++ `.so` plugins (`xdrawer`, `dialer`, `calllog`, `contacts`, `sms`, `files`, `camera`, `themes`).
- `./scripts/build-sxmo-x11.sh` — Builds `st`, `dmenu.so`, `dwm`, `dwm-plugin`, and all C++ `.so` plugins (`xdrawer`, `dialer`, `calllog`, `callscreen`, `contacts`, `sms`, `files`, `camera`, `themes`).
- `./scripts/build-fcitx5-t9.sh` — Builds `src/fcitx5-t9` (`libt9.so` / `t9.so`).
- `./scripts/build-kernel-audio.sh` — Builds `6.12.1-msm8916` QDSP6 audio, torch LED, camera `.ko` modules, and device `.dtb` files.
- `./scripts/build-xlibre.sh` — Builds Xlibre `Xorg` and `libinput`/`fbdev` DDX drivers.
+19 -8
View File
@@ -29,7 +29,7 @@ This manual covers flashing, operating, and customizing **Bananarchy Linux** (`v
- **Patched `sxmo-st` (`st`) with HarfBuzz ligatures & XIM**: patched with `libharfbuzz` (`hb.c`/`hb.h`) shaping (`liga`, `calt`, `clig`, `dlig`) so multi-character programming operators (`->`, `=>`, `!=`, `<=`, `>=`, `===`, `::`, `//`, `/*`) render as continuous ligatures at `pixelsize=18`, alongside full `XIM` (`fcitx5-t9`) input support.
- **Patched `sxmo-dmenu` plugin (`dmenu.so` / `dmenu` / `xdmenu`) (`< 2 ms` popup/close)**: preloaded resident DWM plugin rendering a full-screen `240x296` 10-line vertical menu (positioned flush at `Y = 24..320` right below the 24px `dwm` bar, with a `26px` search bar and ten `27px` item rows) with a `#383838` top search bar, `#005577` prompt badge, `#1c1c1c` item list, `XIM` (`XSetLocaleModifiers("")`, `XSetICFocus`, `Xutf8LookupString`) for live `fcitx5-t9` search filtering and `#` mode switching, C-level focus preservation (`prevfocuswin`), built-in `< 0.5 ms` in-place Sxmo menu transitions (`Sys`, `Apps`, `Scripts`, `Modem`, `Config`, `Power`, `St`, `Nano`), and a `/tmp/dwm_plugin_dmenu.sock` IPC server for all `/usr/bin/dmenu` and `sxmo_dmenu.sh` calls.
- **Patched `sxmo-dwm` (`dwm`) (`< 2 ms` display wake/unlock & native plugin system)**: configured for `240x320` (`bh = 24`, `#323232` top bar, `#005577` active tag/border, vertical `bstack` layout default, overflow-protected Pango status bar rendering keeping the right-aligned clock always visible, and a transparent-backgrounded bottom desktop softkey bar displaying `"Menu"` and `"Names"` over the wallpaper). Directly polls `/dev/input/by-path/platform-gpio-keys-event` (`SW_LID`) and intercepts locked-state wake keys (`XF86PowerOff`, `XF86PickupPhone`, `XF86KbdLcdMenu1`, `XF86KbdLcdMenu2`) in C to toggle `/sys/class/backlight/backlight/brightness` and `/sys/class/leds/white:kbd_backlight/brightness` in `< 2 ms` before running Sxmo state hooks asynchronously.
- **Preloaded DWM plugins (`src/sxmo-dmenu/`, `src/dwm-plugins/` & `src/xdrawer/`, `< 2 ms` FIFO/socket wakeup & unified `.Xresources` theming)**: `dwm` dynamically loads `.so` plugins from `/usr/lib/dwm/plugins/` and `~/.local/lib/dwm/plugins/` (`dmenu.so`, `xdrawer.so`, `dialer.so`, `calllog.so`, `contacts.so`, `sms.so`, `files.so`, `camera.so`, `themes.so`) and preloads them as resident background daemons (`dwm-plugin <name> --preload`) at startup. Each daemon keeps its X11 window, offscreen `Pixmap`, Xft/Pango layouts, and `stat()`-cached Sxmo TSV state initialized in memory while sleeping at 0% CPU on `/tmp/dwm_plugin_<name>.fifo`. Every UI element across `dwm`, `dmenu`, `st`, and all C++ plugins obeys a single unified color and font scheme configured via `~/.Xresources` (`theme.*`, `dwm.*`, `dmenu.*`, `st.*`), with proportional font sizing derived from `theme.baseFontSize` (`12px` / `15px` / `16px` / `18px` at default `15`) and instant live reload via `xthemes`.
- **Preloaded DWM plugins (`src/sxmo-dmenu/`, `src/dwm-plugins/` & `src/xdrawer/`, `< 2 ms` FIFO/socket wakeup & unified `.Xresources` theming)**: `dwm` dynamically loads `.so` plugins from `/usr/lib/dwm/plugins/` and `~/.local/lib/dwm/plugins/` (`dmenu.so`, `xdrawer.so`, `dialer.so`, `calllog.so`, `callscreen.so`, `contacts.so`, `sms.so`, `files.so`, `camera.so`, `themes.so`) and preloads them as resident background daemons (`dwm-plugin <name> --preload`) at startup. Each daemon keeps its X11 window, offscreen `Pixmap`, Xft/Pango layouts, and `stat()`-cached Sxmo TSV state initialized in memory while sleeping at 0% CPU on `/tmp/dwm_plugin_<name>.fifo`. Every UI element across `dwm`, `dmenu`, `st`, and all C++ plugins obeys a single unified color and font scheme configured via `~/.Xresources` (`theme.*`, `dwm.*`, `dmenu.*`, `st.*`), with proportional font sizing derived from `theme.baseFontSize` (`12px` / `15px` / `16px` / `18px` at default `15`) and instant live reload via `xthemes`.
2. **Multi-mode `fcitx5-t9` keypad engine (`src/fcitx5-t9/`)**:
- Supports 6 input modes cycled with `#` (`XF86NumericPound`): `abc`, `Abc`, `ABC`, `Sym`, `Ctl`, and `123`, updating the live top-bar status indicator (`[abc]`, `[Abc]`, `[ABC]`, `[Sym]`, `[Ctl]`, `[123]`) in real time.
- Locks the candidate popup bar to the bottom of the screen (`X = 1, Y = 290, W = 238, H = 30`) with fixed-width 28-character monospace formatting (`Fira Code 9.5`), so neither the popup window nor individual letters ever jump when cycling through candidates.
@@ -141,8 +141,8 @@ You can switch between **vertical stack (`TTT`, `bstack`)**, **horizontal tile (
- `Mod4+1`..`4`: switch to workspace tag `1`..`4`
- `Mod4+Shift+q`: close focused window
#### 3.1.2 Preloaded DWM plugins (`DMenu`, `XDrawer`, `Dialer`, `Call Log`, `Contacts`, `SMS`, `Files`, `Camera`, `Themes`)
All nine core phone overlays are compiled as shared-object plugins (`/usr/lib/dwm/plugins/*.so`), preloaded at `dwm` startup (`dwm-plugin <name> --preload` with an exclusive `/tmp/dwm_plugin_<name>.lock` single-instance guard), and awakened over `/tmp/dwm_plugin_<name>.fifo` in `< 2 ms`:
#### 3.1.2 Preloaded DWM plugins (`DMenu`, `XDrawer`, `Dialer`, `Call Log`, `Call Screen`, `Contacts`, `SMS`, `Files`, `Camera`, `Themes`)
All ten core phone overlays are compiled as shared-object plugins (`/usr/lib/dwm/plugins/*.so`), preloaded at `dwm` startup (`dwm-plugin <name> --preload` with an exclusive `/tmp/dwm_plugin_<name>.lock` single-instance guard), and awakened over `/tmp/dwm_plugin_<name>.fifo` in `< 2 ms`:
1. **`DMenu` (`dmenu.so` / `dmenu` / `xdmenu`) — Zero-Lag System & Context Menus**:
- **Open / Close**: Press **Left softkey (`Menu`)** for the **System menu** (`sys`) or **Right softkey (`Back`)** inside an application for its **Context menu** (`ctx`); press the same softkey or `Escape` to close.
@@ -162,29 +162,40 @@ All nine core phone overlays are compiled as shared-object plugins (`/usr/lib/dw
- **Open**: On the empty desktop, press **Call (green)** (`XF86PickupPhone` / `XF86Phone`), or select **Call Log** from the Sxmo menu or Dialer.
- **Controls**: `Left`/`Right` switches between **`All`**, **`Missed`**, **`In`**, and **`Out`** filter tabs; `Up`/`Down` scrolls through call entries (showing direction icon, resolved contact name or number, timestamp, and call duration); **Call (green)** or **Center `OK` (`Return`)** dials the selected entry; **Left softkey (`Dialer`)** opens the selected number in the Dialer; **Right softkey (`Close`)** or `Escape` closes the Call Log.
5. **`Contacts` (`contacts.so` / `xcontacts` / `sxmo_contactmenu.sh`) — Full-Featured Phonebook**:
5. **`Call Screen` (`callscreen.so` / `xcallscreen`) — Incoming & Active Call Manager**:
- **Automatic Invocation**: Automatically wakes the display and opens on incoming calls (`sxmo_modem.sh checkforincomingcalls` -> `xcallscreen incoming <callid> <number>`) and outgoing calls (`sxmo_modemdial.sh` / `placePhoneCall()` -> `xcallscreen outgoing <callid> <number>`). Pressing **Call (green)** while a call is active reopens `xcallscreen` from anywhere.
- **Incoming Call Controls**: Displays the resolved contact name from `~/.config/sxmo/contacts.tsv`, phone number, `INCOMING CALL` badge, and ring timer. Press **Call (green)**, **Left softkey (`Accept`)**, **`1`**, or **Center `OK` (`Return`)** (on `Answer Call`) to accept the call; press **`*`** or **`0`** (or `OK` on `Silence Ring`) to mute the ringtone and vibration while keeping the call screen open; press **End (red)**, **Right softkey (`Reject`)**, **`#`**, or `OK` on `Reject Call` to decline the call.
- **In-Call Controls & Call Recording**: Displays live `MM:SS` call duration and four interactive control rows (`Up`/`Down` + `OK` or direct hotkeys):
- **`[1]` / `*` — Microphone Mute**: toggles hardware QDSP6 (`DEC1 MUX`, `ADC3 Volume`, `VoiceMMode1 Capture Mixer`) and PipeWire microphone mute (`ON` / `MUTED`).
- **`[2]` / `#` — Call Recording**: starts/stops recording call audio via `pw-record` (`16 kHz` mono WAV) to `~/Recordings/call_<caller>_YYYYMMDD_HHMMSS.wav` with a live `REC MM:SS` indicator, automatically finalizing the recording when the call ends.
- **`[3]` — Audio Route**: switches call audio between **`EARPIECE`** and **`SPEAKER`** (`sxmo_audio.sh` + ALSA `EAR_S` / `SPK DAC Switch`).
- **`Left` / `Right` — Call Volume**: adjusts in-call volume in `5%` increments (`5%`–`100%`).
- **`[0]` / `Left softkey (`DTMF`)` — DTMF Keypad Mode**: toggles DTMF tone mode where pressing `0`–`9`, `*`, or `#` sends DTMF tones via `mmcli --send-dtmf`.
- **End (red)** or **Right softkey (`Hangup`)**: hangs up the active call (`sxmo_modemcall.sh hangup`).
6. **`Contacts` (`contacts.so` / `xcontacts` / `sxmo_contactmenu.sh`) — Full-Featured Phonebook**:
- **Open**: On the empty desktop, press the **Right softkey (`Names`)**, or select **Contacts** from the Sxmo menu.
- **Phonebook List & Live Search**: Typing `0`–`9` filters contacts in real time by T9 name or phone number; `Up`/`Down` scrolls; **Call (green)** immediately calls the selected contact; **Center `OK` (`Return`)** opens the contact's details & actions card; **Left softkey (`Options`)** opens the options menu (**New Contact**, **Add from Recent**, **Call Contact**, **Send SMS**, **Edit Contact**, **Delete Contact**).
- **Contact Details View**: Provides one-click actions for **Call Contact**, **Send SMS**, **Read Messages**, **Open in Dialer**, **Edit Contact**, and **Delete Contact**.
- **Built-in Contact Editor**: Supports adding new contacts or editing existing contacts directly in the `240x320` UI. In the **Name** field, keypad keys `0`–`9` provide multi-tap character entry (`#` cycles case mode `[Abc]` -> `[ABC]` -> `[abc]` -> `[123]`, `*` inserts space). In the **Number** field, hold `0` or press `Right` to insert `+`, or select **Use Recent Number** to pick from recent unknown callers in `modemlog.tsv`. Press **Left softkey (`Save`)** or select **Save Contact** to write directly to `~/.config/sxmo/contacts.tsv`.
6. **`SMS Manager / Editor` (`sms.so` / `xsms` / `sxmo_modemtext.sh`) — Conversations & Composer**:
7. **`SMS Manager / Editor` (`sms.so` / `xsms` / `sxmo_modemtext.sh`) — Conversations & Composer**:
- **Open**: Select **Texts** from the Sxmo system menu (`Left softkey`), or choose **Send SMS** / **Read Messages** from Contacts.
- **Conversations List**: Shows all SMS threads and drafts from `~/.local/share/sxmo/modem/<number>/sms.txt` with contact name resolution, message previews, and timestamps. Press `0`–`9` for live T9/number search, `*` for a new message, **Center `OK` (`Return`)** to open the conversation, **Call (green)** to call the sender, or **Left softkey (`Options`)** for **New Message**, **Open Thread**, **Reply / Compose**, **Call Number**, **Save/View Contact**, and **Delete Thread**.
- **Thread View**: Displays incoming (`Recv`, green left accent) and outgoing (`Sent`, blue/gold right accent) message bubbles; `Up`/`Down` scrolls; **Center `OK` (`Return`)** opens the reply composer; **Call (green)** calls the contact.
- **Multi-Tap SMS Composer**: Supports picking a recipient from Contacts/Recents or entering a number directly (hold `0` for `+`), multi-tap text entry on keys `0`–`9` and `*` (`#` cycles `[Abc]` -> `[ABC]` -> `[abc]` -> `[123]`), live character and SMS segment counter (`0/160`), automatic draft persistence (`draft.txt`), dynamic center softkey action (`Send` when focused on Recipient/Message vs. `Draft` when focused on the `Save Draft` button), and asynchronous sending via `sxmo_modemsendsms.sh` (`Call` key, `Send SMS` button, or `Left softkey`).
7. **`File Manager` (`files.so` / `xfiles` / `sxmo_files.sh`) — Graphical Directory Browser & Viewer**:
8. **`File Manager` (`files.so` / `xfiles` / `sxmo_files.sh`) — Graphical Directory Browser & Viewer**:
- **Open**: Select **Files** from the Sxmo system menu (`Left softkey`) or press `Mod4+d`.
- **Browser Controls**: `Up`/`Down` navigates files and directories; `Return`/`Right` enters a directory or opens the selected file; `Left`/`BackSpace` ascends to the parent directory (`..`); `0`–`9` filters items in real time; `*` toggles hidden dotfiles (`.*`); `#` cycles sort order (**Name** -> **Date** -> **Size**).
- **Built-in Viewers & File Actions (`Left softkey`)**: Text files and scripts open in a fast built-in scrollable viewer (with `Left softkey` shortcut to edit in `st -e nano`); JPEG and PNG images open in a built-in `libjpeg`/`libpng` previewer (`Left`/`Right` steps through images in the folder, `Left softkey` opens full screen in `feh`). The **Actions** menu supports **Open**, **Edit in Nano**, **New Folder**, **New File**, **Rename**, **Copy**, **Cut / Move**, **Paste Here**, **Properties**, **Toggle Hidden (`*`)**, **Cycle Sort (`#`)**, **Open Terminal Here**, and **Delete**.
8. **`Camera` (`camera.so` / `xcamera`) — Live Viewfinder & Photo Gallery**:
9. **`Camera` (`camera.so` / `xcamera`) — Live Viewfinder & Photo Gallery**:
- **Open**: Select **Camera** from the Sxmo system menu (`Left softkey`) or run `xcamera` / `bananarchy-photo --menu`.
- **Live Viewfinder**: Streams `800x600` `RGB24` frames directly from `/dev/video0` (`msm8905-cam` / `GC2395`) into a `240x180` 4:3 viewfinder with a center reticle and a 1-second V4L2 `poll()` frame watchdog. Press **Center `OK` (`Return`)**, **`5`**, or **Call (green)** to snap a JPEG photo to `~/Pictures/photo-YYYYMMDD-HHMMSS.jpg`; `*` or `1` toggles **Auto-Flash**; `0` or `2` toggles continuous **Torch** (`white:torch`); `Up`/`Down` adjusts **Digital Zoom** (`1.0x` / `2.0x` / `4.0x`); `#` or `3` toggles the **3-second Self-Timer**; **Left softkey (`Gallery`)** opens the built-in photo gallery.
- **Built-in Photo Gallery**: Browse captured photos with `Left`/`Right` or `Up`/`Down`, press `Return` to open full-screen in `feh`, or press **Left softkey (`Delete`)** to delete a photo.
9. **`Theme Manager` (`themes.so` / `xthemes`) — Unified `.Xresources` Theme Browser & Customizer (`~/.xthemes/*.xth`)**:
10. **`Theme Manager` (`themes.so` / `xthemes`) — Unified `.Xresources` Theme Browser & Customizer (`~/.xthemes/*.xth`)**:
- **Open**: Select **Themes** from the Sxmo **System menu**, **Apps** menu, or **Config** menu, or run `xthemes`.
- **Theme Files (`~/.xthemes/*.xth`)**: Every `.xth` file in `~/.xthemes/` is a standard `Xresources` file defining `theme.name`, `theme.fontFace`, `theme.iconFontFace`, `theme.baseFontSize` (from which `sizeSmall`, `sizeMain`, `sizeIcon`, and `sizeLarge` are proportionally derived across all UI elements), core and surface colors (`theme.bgMain`, `theme.bgBar`, `theme.bgHeader`, `theme.selBg`, `theme.selFg`, `theme.accent`, `theme.fgMain`, `theme.fgMuted`, etc.), and synchronized `dwm.*`, `dmenu.*`, `st.*`, and `svkbd.*` resources. Pre-installed themes include **`Default.xth`**, **`BananaGold.xth`**, **`MatrixGreen.xth`**, **`NordFrost.xth`**, and **`SolarizedLight.xth`**.
- **Controls & Live Switching**: `Up`/`Down` browses installed themes with live color swatches and typography details; **Center `OK` (`Return`)**, **Call (green)**, or keys **`1`–`9`** immediately writes `~/.Xresources`, runs `xrdb -load ~/.Xresources`, and broadcasts `RELOAD_THEME` to `dwm`, `dmenu`, `st`, and all resident DWM plugins for zero-restart live theme switching.
+4 -3
View File
@@ -10,11 +10,12 @@ Bananarchy targets an ultra-lightweight **Sxmo X11 (`sxmo-de-dwm`)** environment
- **Cross-compiled Xlibre (`X11Libre/xserver` 25.2.0) display server**: `modesetting` KMS + `ShadowFB` Damage partial-rectangle SPI transfers, software cursor fallback, and rootless `elogind` integration.
- **Patched `sxmo-dwm` with native C/C++ plugin architecture**: `240x320` vertical `bstack` layout, 24px Pango status bar with an overflow-protected right-aligned clock, transparent-backgrounded `"Menu"` and `"Names"` desktop softkey labels, direct C `SW_LID` slider and locked-key wake handling in `< 2 ms`, and a dynamic `.so` plugin API (`dwm_plugin.h`) with preloaded resident daemons (`--preload`) and non-blocking FIFO IPC (`< 10 ms` wakeup latency).
- **Preloaded `240x320` keypad-driven DWM plugins (`dmenu`, `xdrawer`, `dialer`, `calllog`, `contacts`, `sms`, `files`, `camera`, `themes`)**:
- **Preloaded `240x320` keypad-driven DWM plugins (`dmenu`, `xdrawer`, `dialer`, `calllog`, `callscreen`, `contacts`, `sms`, `files`, `camera`, `themes`)**:
- **`DMenu` (`dmenu.so` / `dmenu` / `xdmenu`)**: zero-lag (`< 2 ms` popup/close) resident `240x320` full-screen 10-line vertical menu (`240x296` flush below the 24px top bar) with a `#383838` search bar, `#005577` prompt badge, `XIM` `fcitx5-t9` text input, in-place `< 0.5 ms` native Sxmo submenu transitions (`Sys`, `Apps`, `Scripts`, `Modem`, `Config`, `Power`, `St`, `Nano`), and a `/tmp/dwm_plugin_dmenu.sock` client interface serving all `/usr/bin/dmenu` and `sxmo_dmenu.sh` pipes instantaneously.
- **`XDrawer` (`xdrawer.so` / `xdrawer`)**: global phone controls overlay invoked from anywhere by pressing **both softkeys simultaneously**, providing instant sliders and toggles for speaker volume, earpiece volume, flashlight, sound mute, microphone mute, screen brightness, and keypad backlight.
- **`Dialer` (`dialer.so` / `xdialer`)**: opens automatically from the idle desktop when pressing any **`0`–`9`, `*`, or `#` key** (inserting that character immediately), with live T9/number contact filtering, hold-`0` for `+`, and single-press **Call** dialing.
- **`Call Log` (`calllog.so` / `xcalllog`)**: opens automatically from the idle desktop when pressing the **Call (green)** button, with `All` / `Missed` / `In` / `Out` tabs, contact resolution, call durations, and instant redial.
- **`Call Screen` (`callscreen.so` / `xcallscreen`)**: dedicated incoming, outgoing, and in-call screen integrated with Sxmo's `ModemManager` call lifecycle (`sxmo_modem.sh`, `sxmo_modemcall.sh`, `sxmo_modemdial.sh`), displaying resolved caller name and phone number, accepting/rejecting incoming calls via physical **Call (green)** and **End (red)** buttons (plus `*`/`0` ringtone silence), live `MM:SS` call timer, microphone mute/unmute (`1`/`*`), live call recording to `~/Recordings/call_<caller>_<timestamp>.wav` (`2`/`#`), earpiece/speaker audio routing (`3`), volume control (`Left`/`Right`), and DTMF tone keypad mode (`0` / `Left softkey`).
- **`Contacts` (`contacts.so` / `xcontacts`)**: full-featured phonebook application opened from the idle desktop via the **Right softkey (`Names`)** or from the Sxmo menu, integrated with `~/.config/sxmo/contacts.tsv` (live T9/number search, call/SMS/dialer actions, built-in contact editor with keypad multi-tap name entry and recent-caller number picker, and contact deletion).
- **`SMS Manager` (`sms.so` / `xsms`)**: conversation thread manager, bubble message history reader, and multi-tap keypad SMS composer/draft editor (with dynamic `Send` / `Draft` center softkey action) integrated with `$SXMO_LOGDIR/<number>/sms.txt`, `draft.txt`, `modemlog.tsv`, and `sxmo_modemsendsms.sh`.
- **`File Manager` (`files.so` / `xfiles`)**: graphical directory browser with live T9/number filtering, dotfiles toggle (`*`), sort mode cycle (`#`), file operations (new folder/file, rename, copy, cut/move, paste, delete, properties, edit in `nano`, open terminal here), built-in text viewer, and built-in `libjpeg`/`libpng` image previewer.
@@ -94,7 +95,7 @@ bananarchy/
│ └── 0001-bananarchy-multimode-t9-and-fcitx5-5.1.19.patch
├── src/
│ ├── sxmo-dwm/ # Patched sxmo-dwm (240x320 bstack, Pango bar, desktop softkey bar & plugin API)
│ ├── dwm-plugins/ # DWM plugins (dialer, calllog, contacts, sms, files, camera, themes), theme.h & runner
│ ├── dwm-plugins/ # DWM plugins (dialer, calllog, callscreen, contacts, sms, files, camera, themes), theme.h & runner
│ ├── xdrawer/ # XDrawer global phone controls DWM plugin (xdrawer.so / xdrawer)
│ ├── sxmo-dmenu/ # Patched sxmo-dmenu zero-lag DWM plugin (dmenu.so) & client/fallback (dmenu / xdmenu)
│ ├── sxmo-st/ # Patched sxmo-st terminal with HarfBuzz Fira Code ligature shaping & XIM
@@ -107,7 +108,7 @@ bananarchy/
│ └── rootfs/ # Complete Bananarchy rootfs overlay (OS branding, Sxmo X11, audio, camera, T9, .xthemes)
├── prebuilt/
│ ├── xlibre/ # Prebuilt armv7 Xlibre Xorg binary and modesetting/libinput/fbdev DDX modules
│ ├── sxmo-x11/ # Prebuilt armv7 patched dwm, dmenu.so/dmenu, 8 C++ DWM plugins, and st (HarfBuzz ligatures)
│ ├── sxmo-x11/ # Prebuilt armv7 patched dwm, dmenu.so/dmenu, 9 C++ DWM plugins, and st (HarfBuzz ligatures)
│ ├── kernel-6.12.1-msm8916/ # Prebuilt QDSP6/Q6Voice .ko, torch .ko, camera .ko, and 5 device DTBs
│ ├── fcitx5-t9/ # Prebuilt armv7 libt9.so and fcitx5 addon/inputmethod configs
│ └── bantam/ # Prebuilt armv7 bantam AI agent binary
@@ -401,8 +401,14 @@ case "$ACTION" in
exit 0
;;
"enter_one")
if pidof -s sxmo_RepeatRing.sh >/dev/null; then
sxmo_hook_pickup.sh
if [ -e /tmp/sxmo_call_ringing ] || [ -e "$XDG_RUNTIME_DIR/sxmo_jobs/ringing" ] || pidof -s sxmo_RepeatRing.sh >/dev/null; then
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen accept
else
sxmo_hook_pickup.sh
fi
elif [ -e /tmp/sxmo_active_call ] && command -v xcallscreen >/dev/null 2>&1; then
xcallscreen
else
sxmo_appmenu.sh "$WMCLASS" "$WMNAME"
fi
@@ -401,8 +401,14 @@ case "$ACTION" in
exit 0
;;
"enter_one")
if pidof -s sxmo_RepeatRing.sh >/dev/null; then
sxmo_hook_pickup.sh
if [ -e /tmp/sxmo_call_ringing ] || [ -e "$XDG_RUNTIME_DIR/sxmo_jobs/ringing" ] || pidof -s sxmo_RepeatRing.sh >/dev/null; then
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen accept
else
sxmo_hook_pickup.sh
fi
elif [ -e /tmp/sxmo_active_call ] && command -v xcallscreen >/dev/null 2>&1; then
xcallscreen
else
sxmo_appmenu.sh "$WMCLASS" "$WMNAME"
fi
Binary file not shown.
+13 -1
View File
@@ -113,6 +113,9 @@ checkforfinishedcalls() {
fi
sxmo_jobs.sh stop incall_menu
sxmo_jobs.sh stop proximity_lock
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen ended >/dev/null 2>&1 || true
fi
sxmo_hook_statusbar.sh state &
if ! sxmo_modemaudio.sh reset_audio; then
@@ -157,6 +160,15 @@ checkforincomingcalls() {
mkdir -p "$SXMO_LOGDIR"
printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
if sxmo_state.sh get | grep -qE "screenoff|lock"; then
sxmo_wm.sh display on >/dev/null 2>&1 || true
sxmo_state.sh set unlock &
fi
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen incoming "$VOICECALLID" "$INCOMINGNUMBER" >/dev/null 2>&1 || true
fi
sxmo_jobs.sh start proximity_lock sxmo_proximitylock.sh
sxmo_hook_statusbar.sh state &
@@ -167,7 +179,7 @@ checkforincomingcalls() {
# Refresh the incall menu
sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incall_menu
else
# Or fire the incomming call menu
# Or fire the incoming call menu
sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incoming_call_menu "$VOICECALLID"
fi
+192
View File
@@ -0,0 +1,192 @@
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# include common definitions
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
. sxmo_hook_icons.sh
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
# We use this directory to store states, so it must exist
mkdir -p "$XDG_RUNTIME_DIR/sxmo_calls"
set -e
vid_to_number() {
mmcli -m any -o "$1" -K | \
grep call.properties.number | \
cut -d ':' -f2 | \
tr -d ' '
}
log_event() {
EVT_HANDLE="$1"
EVT_VID="$2"
NUM="$(vid_to_number "$EVT_VID")"
TIME="$(date +%FT%H:%M:%S%z)"
mkdir -p "$SXMO_LOGDIR"
printf %b "$TIME\t$EVT_HANDLE\t$NUM\n" >> "$SXMO_LOGDIR/modemlog.tsv"
}
pickup() {
CALLID="$1"
NUM="$(vid_to_number "$CALLID" 2>/dev/null || true)"
DIRECTION="$(
mmcli --voice-status -o "$CALLID" -K |
grep call.properties.direction |
cut -d: -f2 |
tr -d " "
)"
case "$DIRECTION" in
outgoing)
if ! sxmo_modemaudio.sh setup_audio; then
sxmo_notify_user.sh --urgency=critical "We failed to setup call audio"
return 1
fi
if ! mmcli -m any -o "$CALLID" --start; then
sxmo_notify_user.sh --urgency=critical "We failed to start the call"
return 1
fi
sxmo_notify_user.sh "Started call"
touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.initiatedcall"
log_event "call_start" "$CALLID"
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen outgoing "$CALLID" "$NUM" >/dev/null 2>&1 || true
fi
;;
incoming)
sxmo_log "Invoking pickup hook"
sxmo_hook_pickup.sh
if ! sxmo_modemaudio.sh setup_audio; then
sxmo_notify_user.sh --urgency=critical "We failed to setup call audio"
return 1
fi
if ! mmcli -m any -o "$CALLID" --accept; then
sxmo_notify_user.sh --urgency=critical "We failed to accept the call"
return 1
fi
sxmo_notify_user.sh "Picked up call"
touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.pickedupcall"
log_event "call_pickup" "$CALLID"
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen active "$CALLID" "$NUM" >/dev/null 2>&1 || true
fi
;;
*)
sxmo_notify_user.sh --urgency=critical "Couldn't initialize call with callid <$CALLID>; unknown direction <$DIRECTION>"
rm "$XDG_RUNTIME_DIR/sxmo_calls/"* 2>/dev/null || true
rm -f "$XDG_RUNTIME_DIR"/sxmo.ring.pid 2>/dev/null
rm -f "$SXMO_NOTIFDIR"/incomingcall* 2>/dev/null
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen ended >/dev/null 2>&1 || true
fi
return 1
;;
esac
}
hangup() {
CALLID="$1"
if [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.pickedupcall" ] || \
[ -f "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.initiatedcall" ]; then
rm -f "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.pickedupcall" \
"$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.initiatedcall"
touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.hangedupcall"
log_event "call_hangup" "$CALLID"
sxmo_log "sxmo_modemcall: Invoking hangup hook"
sxmo_hook_hangup.sh
else
# this call was never picked up and hung up immediately, so it is a discarded call
touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.discardedcall"
log_event "call_discard" "$CALLID"
sxmo_log "sxmo_modemcall: Invoking discard hook"
sxmo_hook_discard.sh
fi
if ! mmcli -m any -o "$CALLID" --hangup; then
# we ignore already closed calls
if list_active_calls | grep -q "/$CALLID "; then
sxmo_notify_user.sh --urgency=critical "We failed to hangup the call"
return 1
fi
fi
}
# We shallow muted/blocked and terminated calls
list_active_calls() {
mmcli -m any --voice-list-calls | \
awk '$1=$1' | \
grep -v terminated | \
grep -v "No calls were found" | while read -r line; do
CALLID="$(printf "%s\n" "$line" | awk '$1=$1' | cut -d" " -f1 | xargs basename)"
if [ -e "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.mutedring" ]; then
continue # we shallow muted calls
fi
printf "%s\n" "$line"
done
}
incall_menu() {
if command -v xcallscreen >/dev/null 2>&1; then
ACTIVE_LINE="$(list_active_calls | head -n1)"
if [ -n "$ACTIVE_LINE" ]; then
CALLID="$(printf %s "$ACTIVE_LINE" | cut -d" " -f1 | xargs basename)"
NUMBER="$(vid_to_number "$CALLID" 2>/dev/null || true)"
case "$ACTIVE_LINE" in
*"(ringing-in)"*)
xcallscreen incoming "$CALLID" "$NUMBER" >/dev/null 2>&1 || true
;;
*"(dialing)"*|*"(ringing-out)"*)
xcallscreen outgoing "$CALLID" "$NUMBER" >/dev/null 2>&1 || true
;;
*)
xcallscreen active "$CALLID" "$NUMBER" >/dev/null 2>&1 || true
;;
esac
else
xcallscreen >/dev/null 2>&1 || true
fi
return 0
fi
}
mute() {
CALLID="$1"
# this signals that we muted this ring
touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.mutedring"
sxmo_log "Invoking mute_ring hook"
sxmo_hook_mute_ring.sh
log_event "ring_mute" "$1"
}
incoming_call_menu() {
NUMBER="$(vid_to_number "$1")"
NUMBER="$(sxmo_modem.sh cleanupnumber "$NUMBER")"
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen incoming "$1" "$NUMBER" >/dev/null 2>&1 || true
return 0
fi
}
killed() {
sxmo_dmenu.sh close
}
if [ "$1" = "incall_menu" ] || [ "$1" = "incoming_call_menu" ]; then
trap 'killed' TERM INT
fi
"$@"
+15
View File
@@ -28,12 +28,18 @@ EOF
fi
sxmo_log "Attempting to dial: $NUMBER"
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen outgoing "-" "$NUMBER" >/dev/null 2>&1 || true
fi
if ! CALLID="$(
mmcli -m any --voice-create-call "number=$NUMBER" |
grep -Eo "Call/[0-9]+" |
grep -oE "[0-9]+"
)"; then
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen ended >/dev/null 2>&1 || true
fi
sxmo_notify_user.sh --urgency=critical "We failed to initiate call"
return 1
fi
@@ -41,17 +47,26 @@ EOF
# cleanup all dangling event files, ignore errors
rm "$XDG_RUNTIME_DIR/sxmo_calls/$CALLID."* 2>/dev/null || true
sxmo_log "Starting call with CALLID: $CALLID"
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen outgoing "$CALLID" "$NUMBER" >/dev/null 2>&1 || true
fi
sxmo_log "Invoking dial hook"
sxmo_hook_dial.sh
if ! sxmo_modemaudio.sh setup_audio; then
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen ended >/dev/null 2>&1 || true
fi
sxmo_notify_user.sh --urgency=critical "We failed to setup call audio"
mmcli -m any --voice-delete-call="$CALLID"
return 1
fi
if ! sxmo_modemcall.sh pickup "$CALLID"; then
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen ended >/dev/null 2>&1 || true
fi
sxmo_modemaudio.sh reset_audio
mmcli -m any --voice-delete-call="$CALLID"
return 1
+1
View File
@@ -0,0 +1 @@
dwm-plugin
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,4 +3,8 @@
# This script is executed after the last call finished
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen ended >/dev/null 2>&1 || true
fi
sxmo_playerctl.sh resume_all
@@ -401,8 +401,14 @@ case "$ACTION" in
exit 0
;;
"enter_one")
if pidof -s sxmo_RepeatRing.sh >/dev/null; then
sxmo_hook_pickup.sh
if [ -e /tmp/sxmo_call_ringing ] || [ -e "$XDG_RUNTIME_DIR/sxmo_jobs/ringing" ] || pidof -s sxmo_RepeatRing.sh >/dev/null; then
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen accept
else
sxmo_hook_pickup.sh
fi
elif [ -e /tmp/sxmo_active_call ] && command -v xcallscreen >/dev/null 2>&1; then
xcallscreen
else
sxmo_appmenu.sh "$WMCLASS" "$WMNAME"
fi
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
dwm-plugin
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7 -1
View File
@@ -100,7 +100,7 @@ EOF
dwm.c drw.c util.c $DWM_LIBS -o /bananarchy/prebuilt/sxmo-x11/usr/bin/dwm
$STRIP --strip-unneeded /bananarchy/prebuilt/sxmo-x11/usr/bin/dwm
echo "[6/6] Compiling DWM Plugins (xdrawer, dialer, calllog, contacts, sms, files, camera, themes) and dwm-plugin runner..."
echo "[6/6] Compiling DWM Plugins (xdrawer, dialer, calllog, callscreen, contacts, sms, files, camera, themes) and dwm-plugin runner..."
mkdir -p /bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins
PLUG_INCS="$(pkgconf --cflags x11 xft fontconfig freetype2 pango pangoxft alsa libjpeg libpng)"
PLUG_LIBS="$(pkgconf --libs x11 xft fontconfig freetype2 pango pangoxft alsa)"
@@ -118,6 +118,10 @@ EOF
/bananarchy/src/dwm-plugins/calllog_plugin.cpp $PLUG_LIBS \
-o /bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so
$CXX $OPT_CFLAGS -fPIC -shared -std=c++17 -Wall -Wextra $PLUG_INCS \
/bananarchy/src/dwm-plugins/callscreen_plugin.cpp $PLUG_LIBS \
-o /bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/callscreen.so
$CXX $OPT_CFLAGS -fPIC -shared -std=c++17 -Wall -Wextra $PLUG_INCS \
/bananarchy/src/dwm-plugins/contacts_plugin.cpp $PLUG_LIBS \
-o /bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/contacts.so
@@ -142,6 +146,7 @@ EOF
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/xdrawer.so \
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dialer.so \
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so \
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/callscreen.so \
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/contacts.so \
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/sms.so \
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/files.so \
@@ -159,6 +164,7 @@ EOF
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/XDrawer
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xdialer
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xcalllog
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xcallscreen
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xcontacts
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xsms
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xfiles
+17 -8
View File
@@ -631,16 +631,20 @@ int calllog_plugin_init(const DwmHostApi* host) {
int calllog_on_global_key(const DwmHostApi* host, KeySym keysym,
unsigned int keycode, unsigned int state,
int is_press) {
(void)host;
if (!is_press || state != 0) {
return 0;
}
if (keysym == XF86XK_Phone || keysym == XF86XK_PickupPhone || keycode == 177) {
if (isCallRingingFast()) {
const char* const argv[] = {"sxmo_hook_pickup.sh", nullptr};
if (host && host->spawn_command) {
host->spawn_command(argv);
} else {
runAsyncArgv("sxmo_hook_pickup.sh");
if (!sendPluginCommand("callscreen", "ACCEPT")) {
runAsyncArgv("xcallscreen", "accept");
}
return 1;
}
if (isCallActiveOrRingingFast()) {
if (!sendPluginCommand("callscreen", "OPEN")) {
runAsyncArgv("xcallscreen");
}
return 1;
}
@@ -655,9 +659,14 @@ int calllog_on_idle_key(const DwmHostApi* host, KeySym keysym,
}
if (keysym == XF86XK_Phone || keysym == XF86XK_PickupPhone || keycode == 177) {
if (isCallRingingFast()) {
const char* const argv[] = {"sxmo_hook_pickup.sh", nullptr};
if (host->spawn_command) {
host->spawn_command(argv);
if (!sendPluginCommand("callscreen", "ACCEPT")) {
runAsyncArgv("xcallscreen", "accept");
}
return 1;
}
if (isCallActiveOrRingingFast()) {
if (!sendPluginCommand("callscreen", "OPEN")) {
runAsyncArgv("xcallscreen");
}
return 1;
}
File diff suppressed because it is too large Load Diff
+36
View File
@@ -160,6 +160,39 @@ static int try_send_plugin_fifo(const char *plugin_name, int sub_argc, char **su
} else if (strcmp(plugin_name, "dmenu") == 0 && sub_argc >= 2 && sub_argv[1] &&
strcmp(sub_argv[1], "close") == 0) {
len = snprintf(cmd, sizeof(cmd), "CLOSE\n");
} else if (strcmp(plugin_name, "callscreen") == 0) {
if (sub_argc >= 2 && sub_argv[1] && sub_argv[1][0]) {
const char *verb = sub_argv[1];
const char *a1 = (sub_argc >= 3 && sub_argv[2]) ? sub_argv[2] : "";
const char *a2 = (sub_argc >= 4 && sub_argv[3]) ? sub_argv[3] : "";
if (strcasecmp(verb, "incoming") == 0) {
len = snprintf(cmd, sizeof(cmd), "INCOMING %s %s\n", a1[0] ? a1 : "-", a2);
} else if (strcasecmp(verb, "outgoing") == 0) {
len = snprintf(cmd, sizeof(cmd), "OUTGOING %s %s\n", a1[0] ? a1 : "-", a2);
} else if (strcasecmp(verb, "active") == 0) {
len = snprintf(cmd, sizeof(cmd), "ACTIVE %s %s\n", a1[0] ? a1 : "-", a2);
} else if (strcasecmp(verb, "accept") == 0 || strcasecmp(verb, "pickup") == 0) {
len = snprintf(cmd, sizeof(cmd), "ACCEPT\n");
} else if (strcasecmp(verb, "hangup") == 0 || strcasecmp(verb, "reject") == 0) {
len = snprintf(cmd, sizeof(cmd), "HANGUP\n");
} else if (strcasecmp(verb, "mute") == 0 || strcasecmp(verb, "mute_ring") == 0 ||
strcasecmp(verb, "ignore") == 0) {
len = snprintf(cmd, sizeof(cmd), "MUTE_RING\n");
} else if (strcasecmp(verb, "ended") == 0 || strcasecmp(verb, "end") == 0) {
len = a1[0] ? snprintf(cmd, sizeof(cmd), "ENDED %s\n", a1)
: snprintf(cmd, sizeof(cmd), "ENDED\n");
} else if (strcasecmp(verb, "close") == 0) {
len = snprintf(cmd, sizeof(cmd), "CLOSE\n");
} else if (strcasecmp(verb, "record") == 0 || strcasecmp(verb, "toggle_rec") == 0) {
len = snprintf(cmd, sizeof(cmd), "TOGGLE_REC\n");
} else if (strcasecmp(verb, "mic") == 0 || strcasecmp(verb, "toggle_mic") == 0) {
len = snprintf(cmd, sizeof(cmd), "TOGGLE_MIC\n");
} else {
len = snprintf(cmd, sizeof(cmd), "OPEN %s\n", verb);
}
} else {
len = snprintf(cmd, sizeof(cmd), "OPEN\n");
}
} else if (sub_argc >= 2 && sub_argv[1] && strcmp(sub_argv[1], "newcontact") == 0) {
const char *num = (sub_argc >= 3 && sub_argv[2]) ? sub_argv[2] : "";
len = snprintf(cmd, sizeof(cmd), "OPEN new:%s\n", num);
@@ -203,6 +236,9 @@ static const char *resolve_plugin_name_from_argv0(const char *argv0) {
if (strcasecmp(base, "xcalllog") == 0 || strcasecmp(base, "calllog") == 0) {
return "calllog";
}
if (strcasecmp(base, "xcallscreen") == 0 || strcasecmp(base, "callscreen") == 0) {
return "callscreen";
}
if (strcasecmp(base, "xcontacts") == 0 || strcasecmp(base, "contacts") == 0) {
return "contacts";
}
+51 -3
View File
@@ -72,6 +72,12 @@ constexpr const char* kIconRefresh = "\xef\x80\xa1"; // U+F021 refresh
constexpr const char* kIconSort = "\xef\x83\x9c"; // U+F0DC sort
constexpr const char* kIconEye = "\xef\x81\xae"; // U+F06E eye/view
constexpr const char* kIconPalette = "\xef\x87\xbc"; // U+F1FC paint-brush / theme
constexpr const char* kIconSpeaker = "\xef\x80\xa8"; // U+F028 speaker
constexpr const char* kIconEarpiece = "\xef\x8a\xa0"; // U+F2A0 earpiece
constexpr const char* kIconSoundOff = "\xef\x91\xa6"; // U+F466 mute
constexpr const char* kIconMicOn = "\xf3\xb0\x8d\xac"; // U+F036C mic on
constexpr const char* kIconMicOff = "\xf3\xb0\x8d\xad"; // U+F036D mic off
constexpr const char* kIconRecord = "\xef\x84\x91"; // U+F111 circle / record dot
inline int64_t nowMs() {
struct timespec ts {};
@@ -211,7 +217,37 @@ inline bool isCallRingingFast() {
}
std::string ringPidFile = getRuntimeFile("sxmo.ring.pid");
int pid = readIntFile(ringPidFile, -1);
return (pid > 0 && ::kill(pid, 0) == 0);
if (pid > 0 && ::kill(pid, 0) == 0) {
return true;
}
if (::access("/tmp/sxmo_call_ringing", F_OK) == 0) {
return true;
}
return false;
}
inline bool isCallActiveOrRingingFast() {
if (isCallRingingFast()) {
return true;
}
if (::access("/tmp/sxmo_active_call", F_OK) == 0) {
return true;
}
std::string callsDir = getRuntimeFile("sxmo_calls");
DIR* d = ::opendir(callsDir.c_str());
if (!d) {
return false;
}
bool found = false;
struct dirent* ent;
while ((ent = ::readdir(d)) != nullptr) {
if (ent->d_name[0] != '.' && ent->d_name[0] != '\0') {
found = true;
break;
}
}
::closedir(d);
return found;
}
struct FileStamp {
@@ -299,7 +335,8 @@ inline void runAsyncCmd(const std::string& cmd) {
inline void runAsyncArgv(const char* prog,
const char* arg1 = nullptr,
const char* arg2 = nullptr) {
const char* arg2 = nullptr,
const char* arg3 = nullptr) {
pid_t pid = ::fork();
if (pid == 0) {
::setsid();
@@ -312,7 +349,13 @@ inline void runAsyncArgv(const char* prog,
::close(nullfd);
}
}
if (arg1 && arg2) {
if (arg1 && arg2 && arg3) {
execlp(prog, prog, arg1, arg2, arg3, static_cast<char*>(nullptr));
std::string localBin = std::string("/home/user/.local/bin/") + prog;
execl(localBin.c_str(), prog, arg1, arg2, arg3, static_cast<char*>(nullptr));
std::string usrBin = std::string("/usr/bin/") + prog;
execl(usrBin.c_str(), prog, arg1, arg2, arg3, static_cast<char*>(nullptr));
} else if (arg1 && arg2) {
execlp(prog, prog, arg1, arg2, static_cast<char*>(nullptr));
std::string localBin = std::string("/home/user/.local/bin/") + prog;
execl(localBin.c_str(), prog, arg1, arg2, static_cast<char*>(nullptr));
@@ -949,6 +992,9 @@ inline void placePhoneCall(const std::string& rawNumber) {
if (num.empty()) {
return;
}
if (!sendPluginCommand("callscreen", "OUTGOING - " + num)) {
runAsyncArgv("xcallscreen", "outgoing", "-", num.c_str());
}
runAsyncArgv("sxmo_modemdial.sh", num.c_str());
}
@@ -961,6 +1007,7 @@ inline void closeOtherPlugins(const char* selfPluginName) {
{"xdrawer.pid", "xdrawer"},
{"xdialer.pid", "dialer"},
{"xcalllog.pid", "calllog"},
{"xcallscreen.pid", "callscreen"},
{"xcontacts.pid", "contacts"},
{"xsms.pid", "sms"},
{"xfiles.pid", "files"},
@@ -986,6 +1033,7 @@ inline void broadcastThemeReload(const char* selfPluginName = nullptr) {
"xdrawer",
"dialer",
"calllog",
"callscreen",
"contacts",
"sms",
"files",
+5 -5
View File
@@ -1596,15 +1596,14 @@ append_active_call_entries(void)
*sp = '\0';
char *slash = strrchr(line, '/');
snprintf(callid, sizeof(callid), "%s", slash ? (slash + 1) : line);
char label[256], act[256];
char label[256];
snprintf(label, sizeof(label), "%s Incoming call %s", ICON_PHN, callid);
snprintf(act, sizeof(act), "sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incoming_call_menu %s", callid);
add_menu_item(label, act, 0);
add_menu_item(label, "@plugin:callscreen", 0);
} else if (!shown_incall) {
shown_incall = 1;
char label[128];
snprintf(label, sizeof(label), "%s Incall Menu", ICON_PHN);
add_menu_item(label, "sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incall_menu", 0);
snprintf(label, sizeof(label), "%s Call Screen", ICON_PHN);
add_menu_item(label, "@plugin:callscreen", 0);
}
}
pclose(fp);
@@ -1952,6 +1951,7 @@ close_other_active_plugins(void)
{ "xdrawer.pid", "/tmp/dwm_plugin_xdrawer.fifo" },
{ "xdialer.pid", "/tmp/dwm_plugin_dialer.fifo" },
{ "xcalllog.pid", "/tmp/dwm_plugin_calllog.fifo" },
{ "xcallscreen.pid", "/tmp/dwm_plugin_callscreen.fifo" },
{ "xcontacts.pid", "/tmp/dwm_plugin_contacts.fifo" },
{ "xsms.pid", "/tmp/dwm_plugin_sms.fifo" },
{ "xfiles.pid", "/tmp/dwm_plugin_files.fifo" },