Reorganize BBeOS project structure for better maintainability
Some checks failed
CI / markdown-lint (push) Failing after 14s

- Reorganized directory structure following open source best practices
- Created src/ directory for all source code components
- Moved build artifacts to build/ subdirectories
- Organized documentation into phases/, guides/, and api/ subdirectories
- Moved third-party code to vendor/ directory
- Moved downloads to downloads/ directory
- Updated all build scripts to reference new directory structure
- Created comprehensive PROJECT_STRUCTURE.md documentation
- Added DEVELOPMENT_GUIDE.md as main entry point
- Improved separation of concerns and maintainability
- Follows standard open source project conventions
This commit is contained in:
2025-08-01 11:48:06 +02:00
parent 7b53cde2ae
commit 73fb76098e
61 changed files with 560 additions and 1024 deletions

281
PROJECT_STRUCTURE.md Normal file
View File

@ -0,0 +1,281 @@
# BBeOS Project Structure
This document provides a comprehensive overview of the BBeOS project structure and organization.
## 📁 Directory Layout
```
BBeOS/
├── 📚 docs/ # Documentation
│ ├── 📋 phases/ # Phase-by-phase development docs
│ │ ├── PHASE_1_*.md # Research & Feasibility
│ │ ├── PHASE_2_*.md # Bootstrapping
│ │ ├── PHASE_3_*.md # Hardware Support
│ │ ├── PHASE_4_*.md # User Interface
│ │ ├── PHASE_5_*.md # Telephony Stack
│ │ ├── PHASE_6_*.md # Packaging & Updates
│ │ └── PHASE_7_*.md # Community & SDK
│ ├── 📖 guides/ # How-to guides and tutorials
│ │ ├── EMULATION_GUIDE.md # QEMU emulation guide
│ │ └── hardware-testing-guide.md # Hardware testing guide
│ ├── 🔧 api/ # API documentation and design docs
│ │ ├── UI_UX_DESIGN.md # UI/UX design specifications
│ │ └── SECURITY_ANALYSIS.md # Security analysis and recommendations
│ └── DEVELOPMENT_GUIDE.md # Main development guide
├── 💻 src/ # Source code
│ ├── 🖥️ kernel/ # Kernel configuration and patches
│ │ └── msm8960-defconfig # MSM8960 kernel configuration
│ ├── 🔌 drivers/ # Hardware drivers
│ │ ├── display/ # Display drivers
│ │ │ └── q20-panel.c # Q20 LCD panel driver
│ │ ├── input/ # Input device drivers
│ │ │ └── q20-keyboard.c # Q20 keyboard driver
│ │ └── Makefile # Driver build configuration
│ ├── 🖼️ ui/ # User interface components
│ │ ├── compositor/ # Wayland compositor
│ │ │ └── q20-compositor.c # Q20-specific compositor
│ │ ├── applications/ # UI applications
│ │ │ └── home-screen.c # Home screen application
│ │ └── Makefile # UI build configuration
│ ├── 📞 telephony/ # Phone functionality
│ │ ├── modem/ # Modem drivers
│ │ │ └── q20-modem.c # MDM9615 modem driver
│ │ ├── voice/ # Voice call management
│ │ │ └── q20-voice.c # Voice call driver
│ │ ├── sms/ # SMS management
│ │ │ └── q20-sms.c # SMS driver
│ │ └── Makefile # Telephony build configuration
│ ├── 📱 apps/ # Core applications
│ │ ├── core/ # Core system apps
│ │ │ ├── calculator.c # Calculator application
│ │ │ └── text-editor.c # Text editor application
│ │ └── Makefile # Application build configuration
│ ├── 🛠️ sdk/ # Development tools and SDK
│ │ └── tools/ # SDK tools
│ │ └── bbeos-sdk.c # BBeOS SDK main tool
│ └── 📦 packaging/ # System packaging and deployment
│ ├── system/ # System image creation
│ │ └── image-builder.c # System image builder
│ ├── security/ # Security components
│ │ └── secure-boot.c # Secure boot implementation
│ ├── updates/ # Update system
│ │ └── ota-updater.c # OTA update system
│ └── Makefile # Packaging build configuration
├── 🔨 build/ # Build artifacts
│ ├── 🖥️ kernel/ # Kernel builds
│ │ ├── zImage # Kernel image
│ │ ├── *.dtb # Device tree blobs
│ │ └── modules/ # Kernel modules
│ ├── 📁 rootfs/ # Root filesystem
│ │ ├── bin/ # Binary files
│ │ ├── etc/ # Configuration files
│ │ ├── lib/ # Library files
│ │ └── init # Init script
│ ├── 🖼️ images/ # Boot images
│ │ ├── bbeos-boot.img # Bootable system image
│ │ ├── initramfs.img # Initial RAM filesystem
│ │ └── recovery.img # Recovery image
│ ├── 🖼️ ui/ # UI build artifacts
│ │ ├── compositor/ # Compiled compositor
│ │ ├── applications/ # Compiled applications
│ │ └── assets/ # UI assets
│ └── 📦 boot-unpacked/ # Unpacked boot components
├── 🔧 scripts/ # Build automation and tools
│ ├── build-kernel.sh # Full kernel build script
│ ├── build-kernel-minimal.sh # Minimal kernel build script
│ ├── build-rootfs.sh # Root filesystem build script
│ ├── build-boot-image.sh # Boot image creation script
│ ├── build-drivers.sh # Driver build script
│ ├── build-ui.sh # UI build script
│ ├── build-telephony.sh # Telephony build script
│ ├── build-packaging.sh # Packaging build script
│ ├── emulate-simple.sh # Simple QEMU emulation
│ ├── emulate-bbeos.sh # Full BBeOS emulation
│ ├── emulate-terminal.sh # Terminal-based simulation
│ ├── hardware-test.sh # Hardware testing script
│ ├── flash-boot.sh # Device flashing script
│ ├── test-qemu.sh # QEMU testing script
│ └── test-qemu-compatible.sh # Compatible QEMU testing
├── 🧪 tests/ # Test files and test automation
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ └── hardware/ # Hardware tests
├── 📦 vendor/ # Third-party code and dependencies
│ └── kernel-source/ # Linux kernel source
│ ├── arch/arm/boot/dts/qcom/ # Qualcomm device trees
│ └── ... # Other kernel files
├── 📥 downloads/ # External downloads and sources
│ ├── busybox-1.36.1/ # BusyBox source
│ ├── busybox-1.36.1.tar.bz2 # BusyBox archive
│ └── ... # Other downloads
├── 🌐 community/ # Community website and resources
│ └── website/ # Community website
│ └── index.html # Main website page
├── 🔬 research/ # Hardware research and analysis
│ ├── q20-hardware-research.md # Q20 hardware research
│ ├── bootloader-analysis.md # Bootloader analysis
│ ├── driver-compatibility.md # Driver compatibility research
│ └── q20-specs.md # Q20 specifications
├── 📋 .gitea/ # Gitea configuration
│ └── workflows/ # CI/CD workflows
│ └── ci.yml # Continuous integration
├── 📄 Configuration Files
│ ├── README.md # Project overview
│ ├── QUICK_START.md # Quick start guide
│ ├── PROJECT_STRUCTURE.md # This file
│ ├── .gitignore # Git ignore rules
│ ├── config.yaml # Gitea runner configuration
│ └── bbeos-runner.service # Systemd service file
└── 🏗️ hardware/ # Hardware specifications
└── q20-specs.md # BlackBerry Classic Q20 specs
```
## 🎯 Organization Principles
### **1. Separation of Concerns**
- **Source code** (`src/`) is separate from **build artifacts** (`build/`)
- **Documentation** (`docs/`) is organized by type and purpose
- **Scripts** (`scripts/`) handle automation and tooling
- **Third-party code** (`vendor/`) is isolated from project code
### **2. Build System Organization**
- **Build artifacts** are placed in `build/` subdirectories
- **Downloads** are stored in `downloads/` directory
- **Scripts** reference the new directory structure
- **Clean separation** between source and build files
### **3. Documentation Structure**
- **Phase documentation** in `docs/phases/`
- **How-to guides** in `docs/guides/`
- **API documentation** in `docs/api/`
- **Main development guide** at `docs/DEVELOPMENT_GUIDE.md`
### **4. Source Code Organization**
- **Kernel components** in `src/kernel/`
- **Hardware drivers** in `src/drivers/`
- **User interface** in `src/ui/`
- **Telephony stack** in `src/telephony/`
- **Applications** in `src/apps/`
- **Development tools** in `src/sdk/`
- **Packaging tools** in `src/packaging/`
## 🔄 Build Workflow
### **1. Kernel Build**
```bash
./scripts/build-kernel.sh # Full kernel build
./scripts/build-kernel-minimal.sh # Minimal kernel build
```
- **Source**: `vendor/kernel-source/`
- **Output**: `build/kernel/`
### **2. Root Filesystem**
```bash
./scripts/build-rootfs.sh # Build BusyBox rootfs
```
- **Source**: `downloads/busybox-*/`
- **Output**: `build/rootfs/`
### **3. System Components**
```bash
./scripts/build-drivers.sh # Build hardware drivers
./scripts/build-ui.sh # Build UI components
./scripts/build-telephony.sh # Build telephony stack
./scripts/build-packaging.sh # Build system images
```
- **Source**: `src/*/`
- **Output**: `build/*/`
### **4. System Integration**
```bash
./scripts/build-boot-image.sh # Create bootable image
```
- **Input**: `build/kernel/`, `build/rootfs/`
- **Output**: `build/images/`
## 🧪 Testing and Emulation
### **Emulation Options**
```bash
./scripts/emulate-simple.sh # Simple QEMU demo
./scripts/emulate-bbeos.sh # Full BBeOS emulation
./scripts/emulate-terminal.sh # Terminal-based simulation
```
### **Hardware Testing**
```bash
./scripts/hardware-test.sh # Hardware component testing
```
## 📚 Documentation Access
### **Main Guides**
- **Development Guide**: `docs/DEVELOPMENT_GUIDE.md`
- **Project Structure**: `PROJECT_STRUCTURE.md` (this file)
- **Quick Start**: `QUICK_START.md`
### **Phase Documentation**
- **Phase 1**: `docs/phases/PHASE_1_*.md` - Research & Feasibility
- **Phase 2**: `docs/phases/PHASE_2_*.md` - Bootstrapping
- **Phase 3**: `docs/phases/PHASE_3_*.md` - Hardware Support
- **Phase 4**: `docs/phases/PHASE_4_*.md` - User Interface
- **Phase 5**: `docs/phases/PHASE_5_*.md` - Telephony Stack
- **Phase 6**: `docs/phases/PHASE_6_*.md` - Packaging & Updates
- **Phase 7**: `docs/phases/PHASE_7_*.md` - Community & SDK
### **How-to Guides**
- **Emulation**: `docs/guides/EMULATION_GUIDE.md`
- **Hardware Testing**: `docs/guides/hardware-testing-guide.md`
### **API Documentation**
- **UI/UX Design**: `docs/api/UI_UX_DESIGN.md`
- **Security Analysis**: `docs/api/SECURITY_ANALYSIS.md`
## 🔧 Configuration
### **Build Configuration**
- **Kernel config**: `src/kernel/msm8960-defconfig`
- **Device tree**: `vendor/kernel-source/arch/arm/boot/dts/qcom/`
- **Build artifacts**: `build/` directory structure
### **Environment Variables**
- `CROSS_COMPILE`: ARM cross-compilation toolchain
- `KERNEL_DIR`: Kernel source directory (`vendor/kernel-source`)
- `BUILD_DIR`: Build output directory (`build/`)
## 🎯 Benefits of This Structure
### **1. Maintainability**
- **Clear separation** between source, build, and documentation
- **Consistent naming** conventions throughout
- **Modular organization** for easy navigation
### **2. Scalability**
- **Extensible structure** for new components
- **Standard directories** for common project needs
- **Build system** that scales with project growth
### **3. Developer Experience**
- **Intuitive navigation** through logical organization
- **Comprehensive documentation** at every level
- **Clear build workflows** with dedicated scripts
### **4. Open Source Best Practices**
- **Standard directory layout** following open source conventions
- **Proper separation** of concerns
- **Comprehensive documentation** structure
---
*This structure is designed to support the development of a complete operating system while maintaining clarity and organization for developers and contributors.*

View File

@ -1,14 +0,0 @@
# BBeOS Boot Script
# For testing with QEMU or other bootloaders
# Load kernel
fatload mmc 0:1 0x80200000 zImage
# Load device tree
fatload mmc 0:1 0x82000000 dtb
# Load initramfs
fatload mmc 0:1 0x83000000 initramfs.img
# Boot kernel
bootz 0x80200000 0x83000000 0x82000000

Binary file not shown.

262
docs/DEVELOPMENT_GUIDE.md Normal file
View File

@ -0,0 +1,262 @@
# BBeOS Development Guide
Welcome to the BBeOS development guide! This document serves as the main entry point for developers working on the BlackBerry Classic Linux OS project.
## 🎯 Project Overview
BBeOS is a lightweight, secure, non-Android, Linux-based operating system for the BlackBerry Classic (Q20) that transforms this iconic device into a modern, privacy-focused smartphone.
### Key Features
- **Native Hardware Support**: Boot on ARMv7 architecture with full hardware integration
- **Security-First Design**: Privacy-focused design with minimal attack surface
- **Physical Interface Optimization**: GUI designed for trackpad navigation and physical QWERTY keyboard
- **Core Telephony**: Complete phone functionality including calling, SMS, Wi-Fi, and GPS
- **Open Source**: Community-driven development with transparent codebase
## 📁 Project Structure
```
BBeOS/
├── docs/ # Documentation
│ ├── phases/ # Phase-by-phase development docs
│ ├── guides/ # How-to guides and tutorials
│ └── api/ # API documentation and design docs
├── src/ # Source code
│ ├── kernel/ # Kernel configuration and patches
│ ├── drivers/ # Hardware drivers
│ ├── ui/ # User interface components
│ ├── telephony/ # Phone functionality
│ ├── apps/ # Core applications
│ ├── sdk/ # Development tools and SDK
│ └── packaging/ # System packaging and deployment
├── build/ # Build artifacts
│ ├── kernel/ # Kernel builds
│ ├── rootfs/ # Root filesystem
│ └── images/ # Boot images
├── scripts/ # Build automation and tools
├── tests/ # Test files and test automation
├── vendor/ # Third-party code and dependencies
├── downloads/ # External downloads and sources
├── community/ # Community website and resources
└── research/ # Hardware research and analysis
```
## 🚀 Quick Start
### Prerequisites
- Linux development environment (Ubuntu 20.04+ recommended)
- Cross-compilation toolchain for ARMv7
- QEMU for emulation testing
- Git for version control
### Building the System
1. **Clone the repository**:
```bash
git clone https://gitea.lab48.be/eliott/BBeOS.git
cd BBeOS
```
2. **Build the kernel**:
```bash
./scripts/build-kernel.sh
```
3. **Build the root filesystem**:
```bash
./scripts/build-rootfs.sh
```
4. **Create boot image**:
```bash
./scripts/build-boot-image.sh
```
5. **Test in emulation**:
```bash
./scripts/emulate-simple.sh
```
## 📋 Development Phases
The project is organized into 7 development phases:
### Phase 1: Research & Feasibility
- Hardware specification analysis
- Bootloader investigation
- Firmware extraction and analysis
- **Documentation**: `docs/phases/PHASE_1_*.md`
### Phase 2: Bootstrapping
- Minimal Linux kernel boot
- Basic hardware access
- Development environment setup
- **Documentation**: `docs/phases/PHASE_2_*.md`
### Phase 3: Hardware Support
- Device drivers development
- Input/output systems
- Display and audio support
- **Documentation**: `docs/phases/PHASE_3_*.md`
### Phase 4: User Interface
- Wayland-based GUI
- Keyboard-centric navigation
- Core applications
- **Documentation**: `docs/phases/PHASE_4_*.md`
### Phase 5: Telephony Stack
- Modem integration
- Call/SMS functionality
- Network connectivity
- **Documentation**: `docs/phases/PHASE_5_*.md`
### Phase 6: Packaging & Updates
- System packaging
- Update mechanisms
- Security hardening
- **Documentation**: `docs/phases/PHASE_6_*.md`
### Phase 7: Community & SDK
- Developer tools
- Application ecosystem
- Documentation
- **Documentation**: `docs/phases/PHASE_7_*.md`
## 🛠️ Development Workflow
### Code Organization
- **Source code** goes in `src/` directory
- **Build artifacts** are placed in `build/` directory
- **Scripts** are in `scripts/` directory
- **Documentation** is organized in `docs/` subdirectories
### Testing
- **Unit tests** in `tests/` directory
- **Hardware testing** with `scripts/hardware-test.sh`
- **Emulation testing** with QEMU scripts
- **Integration testing** for full system
### Building Components
#### Kernel
```bash
./scripts/build-kernel.sh # Full kernel build
./scripts/build-kernel-minimal.sh # Minimal kernel build
```
#### Root Filesystem
```bash
./scripts/build-rootfs.sh # Build BusyBox rootfs
```
#### Drivers
```bash
./scripts/build-drivers.sh # Build Q20-specific drivers
```
#### User Interface
```bash
./scripts/build-ui.sh # Build UI components
```
#### Telephony
```bash
./scripts/build-telephony.sh # Build telephony stack
```
#### Packaging
```bash
./scripts/build-packaging.sh # Build system images
```
## 🧪 Testing and Emulation
### QEMU Emulation
```bash
./scripts/emulate-simple.sh # Simple QEMU demo
./scripts/emulate-bbeos.sh # Full BBeOS emulation
./scripts/emulate-terminal.sh # Terminal-based simulation
```
### Hardware Testing
```bash
./scripts/hardware-test.sh # Hardware component testing
```
## 📚 Documentation
### Guides
- **Emulation Guide**: `docs/guides/EMULATION_GUIDE.md`
- **Hardware Testing**: `docs/guides/hardware-testing-guide.md`
### API Documentation
- **UI/UX Design**: `docs/api/UI_UX_DESIGN.md`
- **Security Analysis**: `docs/api/SECURITY_ANALYSIS.md`
### Phase Documentation
- **Phase 1**: `docs/phases/PHASE_1_*.md`
- **Phase 2**: `docs/phases/PHASE_2_*.md`
- **Phase 3**: `docs/phases/PHASE_3_*.md`
- **Phase 4**: `docs/phases/PHASE_4_*.md`
- **Phase 5**: `docs/phases/PHASE_5_*.md`
- **Phase 6**: `docs/phases/PHASE_6_*.md`
- **Phase 7**: `docs/phases/PHASE_7_*.md`
## 🔧 Configuration
### Build Configuration
- **Kernel config**: `src/kernel/msm8960-defconfig`
- **Device tree**: `vendor/kernel-source/arch/arm/boot/dts/qcom/`
### Environment Variables
- `CROSS_COMPILE`: ARM cross-compilation toolchain
- `KERNEL_DIR`: Kernel source directory
- `BUILD_DIR`: Build output directory
## 🤝 Contributing
### Code Style
- Follow Linux kernel coding style for kernel code
- Use consistent indentation and naming conventions
- Add comments for complex logic
- Include error handling
### Commit Messages
- Use descriptive commit messages
- Reference issue numbers when applicable
- Follow conventional commit format
### Pull Requests
- Create feature branches for new development
- Include tests for new functionality
- Update documentation as needed
- Ensure all tests pass
## 🐛 Troubleshooting
### Common Issues
1. **Build failures**: Check toolchain installation
2. **Emulation issues**: Verify QEMU installation
3. **Hardware problems**: Review device tree configuration
### Getting Help
- Check the documentation in `docs/`
- Review phase-specific guides
- Test with emulation first
- Use hardware testing scripts
## 📄 License
BBeOS is open source software licensed under the GPL v3 License. See LICENSE file for details.
## 🔗 Resources
- **Repository**: https://gitea.lab48.be/eliott/BBeOS
- **Community Website**: `community/website/index.html`
- **Hardware Specs**: `hardware/q20-specs.md`
- **Research**: `research/` directory
---
*This guide is maintained by the BBeOS development team. For questions or contributions, please refer to the project repository.*

View File

@ -1,244 +0,0 @@
/dts-v1/;
/ {
model = "BlackBerry Classic Q20";
compatible = "blackberry,q20", "qcom,msm8960";
interrupt-parent = <&intc>;
chosen {
stdout-path = "serial0:115200n8";
bootargs = "console=ttyMSM0,115200n8 root=/dev/mmcblk0p2 rw rootwait";
};
memory {
device_type = "memory";
reg = <0x00000000 0x80000000>; // 2GB RAM
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
// Reserved for modem
modem@0x00000000 {
reg = <0x00000000 0x40000000>;
no-map;
};
// Reserved for display
display@0x40000000 {
reg = <0x40000000 0x10000000>;
no-map;
};
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
next-level-cache = <&L2>;
operating-points-v2 = <&cpu_opp_table>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
next-level-cache = <&L2>;
operating-points-v2 = <&cpu_opp_table>;
};
};
cpu_opp_table: opp_table {
compatible = "operating-points-v2";
opp-shared;
opp-384000000 {
opp-hz = /bits/ 64 <384000000>;
opp-microvolt = <1050000>;
clock-latency-ns = <256000>;
};
opp-1026000000 {
opp-hz = /bits/ 64 <1026000000>;
opp-microvolt = <1150000>;
clock-latency-ns = <256000>;
};
opp-1500000000 {
opp-hz = /bits/ 64 <1500000000>;
opp-microvolt = <1250000>;
clock-latency-ns = <256000>;
};
};
soc {
#address-cells = <1>;
#size-cells = <1>;
ranges;
compatible = "simple-bus";
intc: interrupt-controller@2000000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
#size-cells = <0>;
#address-cells = <1>;
interrupt-controller;
reg = <0x02000000 0x1000>,
<0x02002000 0x1000>;
};
L2: l2-cache@2010000 {
compatible = "arm,pl310-cache";
reg = <0x02010000 0x1000>;
arm,data-latency = <3 3 3>;
arm,tag-latency = <2 2 2>;
cache-unified;
cache-level = <2>;
};
// Serial console
serial@16440000 {
compatible = "qcom,msm-uartdm";
reg = <0x16440000 0x1000>;
interrupts = <0 154 0>;
clocks = <&gcc 108>, <&gcc 109>;
clock-names = "core", "iface";
status = "okay";
};
// Display controller
mdp@5100000 {
compatible = "qcom,mdp5";
reg = <0x05100000 0x90000>;
reg-names = "mdp_phys";
interrupts = <0 75 0>;
clocks = <&gcc 20>, <&gcc 21>;
clock-names = "iface", "core";
status = "okay";
};
// Audio system
sound {
compatible = "qcom,msm8960-snd-card";
qcom,model = "blackberry-q20-snd-card";
qcom,audio-routing = "RX_BIAS", "MCLK",
"LDO_H", "MCLK";
qcom,cdc-mclk-gpios = <&pm8941_gpios 15 0>;
};
// Keyboard controller
keyboard@78 {
compatible = "blackberry,q20-keyboard";
reg = <0x78>;
interrupts = <0 123 0>;
gpio-controller;
#gpio-cells = <2>;
status = "okay";
};
// Trackpad
trackpad@5d {
compatible = "blackberry,q20-trackpad";
reg = <0x5d>;
interrupts = <0 124 0>;
status = "okay";
};
// Battery management
battery {
compatible = "blackberry,q20-battery";
voltage-min-design-microvolt = <3200000>;
voltage-max-design-microvolt = <4200000>;
energy-full-design-microwatt-hours = <9500000>;
charge-full-design-microamp-hours = <2515000>;
};
// Charger
charger {
compatible = "blackberry,q20-charger";
qcom,fast-charge-current = <1000000>;
qcom,fast-charge-voltage = <4200000>;
};
// USB OTG
usb@12500000 {
compatible = "qcom,ci-hdrc";
reg = <0x12500000 0x200>,
<0x12500200 0x200>;
interrupts = <0 134 0>;
status = "okay";
dr_mode = "otg";
};
// MMC/SD card
mmc@12400000 {
compatible = "qcom,msm-sdcc";
reg = <0x12400000 0x1000>;
interrupts = <0 81 0>;
clocks = <&gcc 80>, <&gcc 81>;
clock-names = "core", "iface";
status = "okay";
bus-width = <4>;
cap-sd-highspeed;
cap-mmc-highspeed;
};
// Wi-Fi
wifi@0 {
compatible = "qcom,ath6kl";
reg = <0x0 0x0>;
interrupts = <0 70 0>;
status = "okay";
};
// Bluetooth
bluetooth@0 {
compatible = "qcom,wcn3660";
reg = <0x0 0x0>;
interrupts = <0 71 0>;
status = "okay";
};
};
// Display panel
panel@0 {
compatible = "blackberry,q20-panel";
reg = <0>;
// Panel specifications
width-mm = <89>;
height-mm = <89>;
// Display timing
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <72000000>;
hactive = <720>;
vactive = <720>;
hfront-porch = <10>;
hsync-len = <10>;
hback-porch = <10>;
vfront-porch = <10>;
vsync-len = <10>;
vback-porch = <10>;
};
};
// Backlight
backlight {
compatible = "pwm-backlight";
pwms = <&pwm 0 1000000>;
brightness-levels = <0 1 2 3 4 5 6 7 8 9 10>;
default-brightness-level = <10>;
};
};
};

View File

@ -12,7 +12,7 @@ export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf- export CROSS_COMPILE=arm-linux-gnueabihf-
# Go to kernel source directory # Go to kernel source directory
cd kernel-source cd vendor/kernel-source
# Clean previous build # Clean previous build
echo "Cleaning previous build..." echo "Cleaning previous build..."

View File

@ -7,8 +7,8 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
KERNEL_DIR="$PROJECT_ROOT/kernel" KERNEL_DIR="$PROJECT_ROOT/vendor/kernel-source"
BUILD_DIR="$PROJECT_ROOT/build" BUILD_DIR="$PROJECT_ROOT/build/kernel"
TOOLCHAIN_DIR="$PROJECT_ROOT/toolchain" TOOLCHAIN_DIR="$PROJECT_ROOT/toolchain"
# Colors for output # Colors for output

View File

@ -8,7 +8,7 @@ set -e
echo "Building minimal root filesystem for BBeOS..." echo "Building minimal root filesystem for BBeOS..."
# Configuration # Configuration
ROOTFS_DIR="rootfs" ROOTFS_DIR="build/rootfs"
BUSYBOX_VERSION="1.36.1" BUSYBOX_VERSION="1.36.1"
BUSYBOX_URL="https://busybox.net/downloads/busybox-${BUSYBOX_VERSION}.tar.bz2" BUSYBOX_URL="https://busybox.net/downloads/busybox-${BUSYBOX_VERSION}.tar.bz2"
BUSYBOX_DIR="busybox-${BUSYBOX_VERSION}" BUSYBOX_DIR="busybox-${BUSYBOX_VERSION}"
@ -24,16 +24,16 @@ mkdir -p ${ROOTFS_DIR}/{bin,dev,etc,lib,proc,sys,tmp,usr/bin,usr/sbin}
# Download and build BusyBox # Download and build BusyBox
echo "Downloading BusyBox ${BUSYBOX_VERSION}..." echo "Downloading BusyBox ${BUSYBOX_VERSION}..."
if [ ! -f "${BUSYBOX_DIR}.tar.bz2" ]; then if [ ! -f "downloads/${BUSYBOX_DIR}.tar.bz2" ]; then
wget ${BUSYBOX_URL} wget -O downloads/${BUSYBOX_DIR}.tar.bz2 ${BUSYBOX_URL}
fi fi
if [ ! -d "${BUSYBOX_DIR}" ]; then if [ ! -d "downloads/${BUSYBOX_DIR}" ]; then
tar xf ${BUSYBOX_DIR}.tar.bz2 tar xf downloads/${BUSYBOX_DIR}.tar.bz2 -C downloads/
fi fi
echo "Building BusyBox..." echo "Building BusyBox..."
cd ${BUSYBOX_DIR} cd downloads/${BUSYBOX_DIR}
# Configure BusyBox # Configure BusyBox
make defconfig make defconfig
@ -47,8 +47,8 @@ make install
# Copy BusyBox to rootfs # Copy BusyBox to rootfs
echo "Installing BusyBox to rootfs..." echo "Installing BusyBox to rootfs..."
cp busybox ../${ROOTFS_DIR}/bin/ cp busybox ../../${ROOTFS_DIR}/bin/
cd .. cd ../..
# Create init script # Create init script
echo "Creating init script..." echo "Creating init script..."

View File

@ -8,10 +8,10 @@ set -e
echo "Building BBeOS telephony components..." echo "Building BBeOS telephony components..."
# Configuration # Configuration
TELEPHONY_DIR="telephony" TELEPHONY_DIR="src/telephony"
BUILD_DIR="telephony-build" BUILD_DIR="build/telephony"
ROOTFS_DIR="rootfs" ROOTFS_DIR="build/rootfs"
KERNEL_SRC="kernel-source" KERNEL_SRC="vendor/kernel-source"
# Set up environment # Set up environment
export ARCH=arm export ARCH=arm

View File

@ -8,8 +8,8 @@ set -e
echo "Building BBeOS UI components..." echo "Building BBeOS UI components..."
# Configuration # Configuration
UI_DIR="ui" UI_DIR="src/ui"
BUILD_DIR="ui-build" BUILD_DIR="build/ui"
ROOTFS_DIR="rootfs" ROOTFS_DIR="rootfs"
# Set up environment # Set up environment

Binary file not shown.

View File

@ -1,9 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("Q20 Home Screen (stub)\n");
printf("This is a placeholder for the home screen application\n");
printf("Full implementation requires Cairo and Wayland libraries\n");
return 0;
}

View File

@ -1,23 +0,0 @@
# BBeOS Theme Configuration
# BlackBerry Classic Q20 UI Theme
[colors]
background=#1a1a1a
foreground=#ffffff
accent=#0066cc
highlight=#3399ff
error=#cc3333
success=#33cc33
warning=#cc9933
[fonts]
default=Sans 12
title=Sans Bold 16
status=Sans 10
help=Sans 9
[layout]
status_bar_height=40
app_grid_size=4
app_icon_size=80
app_icon_spacing=20

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="720" height="720" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="#333333" stroke-width="1"/>
</pattern>
</defs>
<rect width="720" height="720" fill="#1a1a1a"/>
<rect width="720" height="720" fill="url(#grid)"/>
</svg>

Before

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

View File

@ -1,9 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("Q20 Compositor (stub)\n");
printf("This is a placeholder for the Wayland compositor\n");
printf("Full implementation requires wlroots library\n");
return 0;
}

View File

@ -1,71 +0,0 @@
# BBeOS UI Build System
# Builds UI components for BlackBerry Classic Q20
# Configuration
CC = arm-linux-gnueabihf-gcc
CFLAGS = -Wall -Wextra -O2 -g
LDFLAGS =
# Libraries
WAYLAND_LIBS = -lwayland-client -lwayland-server
WLROOTS_LIBS = -lwlr -lwlr-util
CAIRO_LIBS = -lcairo -lpango-1.0 -lpangocairo-1.0
XKB_LIBS = -lxkbcommon
MATH_LIBS = -lm
# Directories
COMPOSITOR_DIR = compositor
APPLICATIONS_DIR = applications
FRAMEWORK_DIR = framework
ASSETS_DIR = assets
# Targets
all: compositor applications
compositor: $(COMPOSITOR_DIR)/q20-compositor
applications: $(APPLICATIONS_DIR)/home-screen
# Compositor
$(COMPOSITOR_DIR)/q20-compositor: $(COMPOSITOR_DIR)/q20-compositor.c
$(CC) $(CFLAGS) -o $@ $< $(WAYLAND_LIBS) $(WLROOTS_LIBS) $(XKB_LIBS) $(MATH_LIBS)
# Applications
$(APPLICATIONS_DIR)/home-screen: $(APPLICATIONS_DIR)/home-screen.c
$(CC) $(CFLAGS) -o $@ $< $(WAYLAND_LIBS) $(CAIRO_LIBS) $(MATH_LIBS)
# Framework (placeholder for future components)
framework:
@echo "Building UI framework components..."
# TODO: Add framework components
# Assets
assets:
@echo "Processing UI assets..."
# TODO: Add asset processing
# Installation
install: all
@echo "Installing UI components..."
mkdir -p $(DESTDIR)/usr/bin
mkdir -p $(DESTDIR)/usr/share/bbeos/ui
cp $(COMPOSITOR_DIR)/q20-compositor $(DESTDIR)/usr/bin/
cp $(APPLICATIONS_DIR)/home-screen $(DESTDIR)/usr/bin/
cp -r $(ASSETS_DIR)/* $(DESTDIR)/usr/share/bbeos/ui/ 2>/dev/null || true
# Clean
clean:
rm -f $(COMPOSITOR_DIR)/q20-compositor
rm -f $(APPLICATIONS_DIR)/home-screen
rm -f $(FRAMEWORK_DIR)/*.o
rm -f $(FRAMEWORK_DIR)/*.a
# Development targets
dev: CFLAGS += -DDEBUG -g3
dev: all
# Release targets
release: CFLAGS += -DNDEBUG -O3
release: all
.PHONY: all compositor applications framework assets install clean dev release

View File

@ -1,266 +0,0 @@
/*
* Q20 Home Screen Application
* BlackBerry Classic Q20 Main Interface
*
* A keyboard-optimized home screen with app launcher,
* status bar, and navigation system.
*/
#include <wayland-client.h>
#include <cairo/cairo.h>
#include <pango/pango.h>
#include <pango/pangocairo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#define Q20_WIDTH 720
#define Q20_HEIGHT 720
#define STATUS_BAR_HEIGHT 40
#define APP_GRID_SIZE 4
#define APP_ICON_SIZE 80
#define APP_ICON_SPACING 20
struct q20_home_screen {
struct wl_display *display;
struct wl_compositor *compositor;
struct wl_surface *surface;
struct wl_shell *shell;
struct wl_shell_surface *shell_surface;
cairo_surface_t *cairo_surface;
cairo_t *cairo;
int selected_app;
int app_count;
char *app_names[16];
char *app_commands[16];
time_t last_update;
};
static void draw_status_bar(struct q20_home_screen *home) {
cairo_t *cr = home->cairo;
char time_str[64];
time_t now = time(NULL);
struct tm *tm_info = localtime(&now);
strftime(time_str, sizeof(time_str), "%H:%M", tm_info);
// Draw status bar background
cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
cairo_rectangle(cr, 0, 0, Q20_WIDTH, STATUS_BAR_HEIGHT);
cairo_fill(cr);
// Draw time
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr, 16);
cairo_text_extents_t extents;
cairo_text_extents(cr, time_str, &extents);
cairo_move_to(cr, Q20_WIDTH - extents.width - 10, STATUS_BAR_HEIGHT / 2 + extents.height / 2);
cairo_show_text(cr, time_str);
// Draw "BBeOS" title
cairo_move_to(cr, 10, STATUS_BAR_HEIGHT / 2 + extents.height / 2);
cairo_show_text(cr, "BBeOS");
}
static void draw_app_grid(struct q20_home_screen *home) {
cairo_t *cr = home->cairo;
int start_y = STATUS_BAR_HEIGHT + 20;
int start_x = (Q20_WIDTH - (APP_GRID_SIZE * APP_ICON_SIZE + (APP_GRID_SIZE - 1) * APP_ICON_SPACING)) / 2;
for (int i = 0; i < home->app_count; i++) {
int row = i / APP_GRID_SIZE;
int col = i % APP_GRID_SIZE;
int x = start_x + col * (APP_ICON_SIZE + APP_ICON_SPACING);
int y = start_y + row * (APP_ICON_SIZE + APP_ICON_SPACING + 30);
// Draw selection highlight
if (i == home->selected_app) {
cairo_set_source_rgb(cr, 0.2, 0.6, 1.0);
cairo_rectangle(cr, x - 5, y - 5, APP_ICON_SIZE + 10, APP_ICON_SIZE + 35);
cairo_fill(cr);
}
// Draw app icon background
cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
cairo_rectangle(cr, x, y, APP_ICON_SIZE, APP_ICON_SIZE);
cairo_fill(cr);
// Draw app icon border
cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
cairo_set_line_width(cr, 2);
cairo_rectangle(cr, x, y, APP_ICON_SIZE, APP_ICON_SIZE);
cairo_stroke(cr);
// Draw app name
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, 12);
cairo_text_extents_t extents;
cairo_text_extents(cr, home->app_names[i], &extents);
cairo_move_to(cr, x + (APP_ICON_SIZE - extents.width) / 2, y + APP_ICON_SIZE + 15);
cairo_show_text(cr, home->app_names[i]);
}
}
static void draw_help_text(struct q20_home_screen *home) {
cairo_t *cr = home->cairo;
cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, 10);
const char *help_text[] = {
"Arrow Keys: Navigate",
"Enter: Launch App",
"F1: Settings",
"F2: Terminal",
"Esc: Exit"
};
int y = Q20_HEIGHT - 80;
for (int i = 0; i < 5; i++) {
cairo_move_to(cr, 10, y + i * 12);
cairo_show_text(cr, help_text[i]);
}
}
static void redraw(struct q20_home_screen *home) {
cairo_t *cr = home->cairo;
// Clear background
cairo_set_source_rgb(cr, 0.15, 0.15, 0.15);
cairo_paint(cr);
// Draw components
draw_status_bar(home);
draw_app_grid(home);
draw_help_text(home);
// Commit the surface
wl_surface_damage(home->surface, 0, 0, Q20_WIDTH, Q20_HEIGHT);
wl_surface_commit(home->surface);
}
static void handle_keyboard_input(struct q20_home_screen *home, uint32_t key) {
switch (key) {
case 111: // Up arrow
if (home->selected_app >= APP_GRID_SIZE) {
home->selected_app -= APP_GRID_SIZE;
}
break;
case 116: // Down arrow
if (home->selected_app + APP_GRID_SIZE < home->app_count) {
home->selected_app += APP_GRID_SIZE;
}
break;
case 113: // Left arrow
if (home->selected_app > 0) {
home->selected_app--;
}
break;
case 114: // Right arrow
if (home->selected_app < home->app_count - 1) {
home->selected_app++;
}
break;
case 36: // Enter
if (home->selected_app < home->app_count) {
// Launch the selected app
printf("Launching: %s\n", home->app_commands[home->selected_app]);
// TODO: Actually launch the app
}
break;
case 9: // Escape
printf("Exiting home screen\n");
exit(0);
break;
}
redraw(home);
}
static void init_apps(struct q20_home_screen *home) {
home->app_count = 0;
// Add default apps
home->app_names[home->app_count] = "Terminal";
home->app_commands[home->app_count] = "weston-terminal";
home->app_count++;
home->app_names[home->app_count] = "Settings";
home->app_commands[home->app_count] = "weston-settings";
home->app_count++;
home->app_names[home->app_count] = "File Manager";
home->app_commands[home->app_count] = "weston-file-manager";
home->app_count++;
home->app_names[home->app_count] = "Calculator";
home->app_commands[home->app_count] = "weston-calculator";
home->app_count++;
home->app_names[home->app_count] = "Notes";
home->app_commands[home->app_count] = "weston-notes";
home->app_count++;
home->app_names[home->app_count] = "Calendar";
home->app_commands[home->app_count] = "weston-calendar";
home->app_count++;
home->selected_app = 0;
}
int main(int argc, char *argv[]) {
struct q20_home_screen home = {0};
// Connect to Wayland display
home.display = wl_display_connect(NULL);
if (!home.display) {
fprintf(stderr, "Failed to connect to Wayland display\n");
return 1;
}
// Get registry and bind to interfaces
struct wl_registry *registry = wl_display_get_registry(home.display);
// TODO: Add proper registry listener to bind to compositor, shell, etc.
// For now, we'll create a simple surface
// Create Cairo surface
home.cairo_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, Q20_WIDTH, Q20_HEIGHT);
home.cairo = cairo_create(home.cairo_surface);
// Initialize apps
init_apps(&home);
// Initial draw
redraw(&home);
printf("Q20 Home Screen started\n");
printf("Use arrow keys to navigate, Enter to launch apps\n");
// Main event loop
while (1) {
wl_display_dispatch(home.display);
// Handle keyboard input (simplified for now)
// TODO: Add proper Wayland keyboard input handling
usleep(100000); // 100ms
}
// Cleanup
cairo_destroy(home.cairo);
cairo_surface_destroy(home.cairo_surface);
wl_display_disconnect(home.display);
return 0;
}

View File

@ -1,361 +0,0 @@
/*
* Q20 Wayland Compositor
* BlackBerry Classic Q20 Display Server
*
* A lightweight Wayland compositor optimized for the Q20's
* 720x720 square display and keyboard navigation.
*/
#include <wayland-server.h>
#include <wlr/backend.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/log.h>
#include <xkbcommon/xkbcommon.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
struct q20_server {
struct wl_display *wl_display;
struct wlr_backend *backend;
struct wlr_renderer *renderer;
struct wlr_compositor *compositor;
struct wlr_seat *seat;
struct wlr_output *output;
struct wlr_xdg_shell *xdg_shell;
struct wl_listener new_output;
struct wl_listener new_input;
struct wl_listener new_xdg_surface;
struct wl_list views;
struct wl_list keyboards;
struct wlr_view *focused_view;
struct wlr_keyboard *focused_keyboard;
};
struct q20_view {
struct wl_list link;
struct q20_server *server;
struct wlr_xdg_surface *xdg_surface;
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener destroy;
struct wl_listener request_move;
struct wl_listener request_resize;
struct wl_listener request_maximize;
struct wl_listener request_fullscreen;
int x, y;
bool maximized;
bool fullscreen;
};
struct q20_keyboard {
struct wl_list link;
struct q20_server *server;
struct wlr_input_device *device;
struct wl_listener key;
struct wl_listener modifiers;
struct wl_listener destroy;
struct xkb_state *xkb_state;
xkb_keycode_t repeat_keycode;
uint32_t repeat_time;
struct wl_event_source *repeat_source;
};
static void focus_view(struct q20_server *server, struct q20_view *view) {
if (server->focused_view == view) {
return;
}
if (server->focused_view) {
struct wlr_xdg_surface *previous_surface = server->focused_view->xdg_surface;
wlr_xdg_toplevel_set_activated(previous_surface, false);
}
server->focused_view = view;
if (view) {
wlr_xdg_toplevel_set_activated(view->xdg_surface, true);
wlr_seat_keyboard_notify_enter(server->seat, view->xdg_surface->surface,
NULL, 0, NULL);
}
}
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
struct q20_keyboard *keyboard = wl_container_of(listener, keyboard, key);
struct q20_server *server = keyboard->server;
struct wlr_event_keyboard_key *event = data;
struct wlr_seat *seat = server->seat;
// Get the keycode and translate it to a keysym
xkb_keycode_t keycode = event->keycode + 8;
xkb_keysym_t sym = xkb_state_key_get_one_sym(keyboard->xkb_state, keycode);
// Handle Q20-specific key combinations
if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
switch (sym) {
case XKB_KEY_Escape:
// Exit compositor
wl_display_terminate(server->wl_display);
break;
case XKB_KEY_F1:
// Switch to next view
// TODO: Implement view switching
break;
case XKB_KEY_F2:
// Toggle maximize
if (server->focused_view) {
server->focused_view->maximized = !server->focused_view->maximized;
if (server->focused_view->maximized) {
wlr_xdg_toplevel_set_maximized(server->focused_view->xdg_surface, true);
} else {
wlr_xdg_toplevel_set_maximized(server->focused_view->xdg_surface, false);
}
}
break;
case XKB_KEY_F3:
// Toggle fullscreen
if (server->focused_view) {
server->focused_view->fullscreen = !server->focused_view->fullscreen;
if (server->focused_view->fullscreen) {
wlr_xdg_toplevel_set_fullscreen(server->focused_view->xdg_surface, true);
} else {
wlr_xdg_toplevel_set_fullscreen(server->focused_view->xdg_surface, false);
}
}
break;
}
}
wlr_seat_keyboard_notify_key(seat, event->time_msec, event->keycode, event->state);
}
static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) {
struct q20_keyboard *keyboard = wl_container_of(listener, keyboard, modifiers);
struct q20_server *server = keyboard->server;
wlr_seat_keyboard_notify_modifiers(server->seat, &keyboard->device->keyboard->modifiers);
}
static void keyboard_destroy_notify(struct wl_listener *listener, void *data) {
struct q20_keyboard *keyboard = wl_container_of(listener, keyboard, destroy);
wl_list_remove(&keyboard->link);
free(keyboard);
}
static void server_new_keyboard(struct q20_server *server, struct wlr_input_device *device) {
struct q20_keyboard *keyboard = calloc(1, sizeof(struct q20_keyboard));
keyboard->server = server;
keyboard->device = device;
// Get the keymap
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);
keyboard->xkb_state = xkb_state_new(keymap);
xkb_keymap_unref(keymap);
xkb_context_unref(context);
wlr_keyboard_set_keymap(device->keyboard, keymap);
wlr_keyboard_set_repeat_info(device->keyboard, 25, 600);
keyboard->key.notify = keyboard_key_notify;
wl_signal_add(&device->keyboard->events.key, &keyboard->key);
keyboard->modifiers.notify = keyboard_modifiers_notify;
wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers);
keyboard->destroy.notify = keyboard_destroy_notify;
wl_signal_add(&device->events.destroy, &keyboard->destroy);
wl_list_insert(&server->keyboards, &keyboard->link);
// Set this keyboard as the current one
wlr_seat_set_keyboard(server->seat, device);
}
static void server_new_input_notify(struct wl_listener *listener, void *data) {
struct q20_server *server = wl_container_of(listener, server, new_input);
struct wlr_input_device *device = data;
switch (device->type) {
case WLR_INPUT_DEVICE_KEYBOARD:
server_new_keyboard(server, device);
break;
default:
break;
}
}
static void view_map_notify(struct wl_listener *listener, void *data) {
struct q20_view *view = wl_container_of(listener, view, map);
struct q20_server *server = view->server;
// Center the view on the 720x720 display
view->x = (720 - view->xdg_surface->surface->current.width) / 2;
view->y = (720 - view->xdg_surface->surface->current.height) / 2;
focus_view(server, view);
}
static void view_unmap_notify(struct wl_listener *listener, void *data) {
struct q20_view *view = wl_container_of(listener, view, unmap);
struct q20_server *server = view->server;
if (server->focused_view == view) {
focus_view(server, NULL);
}
}
static void view_destroy_notify(struct wl_listener *listener, void *data) {
struct q20_view *view = wl_container_of(listener, view, destroy);
wl_list_remove(&view->link);
free(view);
}
static void server_new_xdg_surface_notify(struct wl_listener *listener, void *data) {
struct q20_server *server = wl_container_of(listener, server, new_xdg_surface);
struct wlr_xdg_surface *xdg_surface = data;
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
return;
}
struct q20_view *view = calloc(1, sizeof(struct q20_view));
view->server = server;
view->xdg_surface = xdg_surface;
view->map.notify = view_map_notify;
wl_signal_add(&xdg_surface->events.map, &view->map);
view->unmap.notify = view_unmap_notify;
wl_signal_add(&xdg_surface->events.unmap, &view->unmap);
view->destroy.notify = view_destroy_notify;
wl_signal_add(&xdg_surface->events.destroy, &view->destroy);
wl_list_insert(&server->views, &view->link);
}
static void output_frame_notify(struct wl_listener *listener, void *data) {
struct q20_server *server = wl_container_of(listener, server, output_frame);
struct wlr_output *output = data;
struct wlr_renderer *renderer = server->renderer;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
wlr_output_make_current(output, NULL);
wlr_renderer_begin(renderer, output->width, output->height);
float color[4] = {0.1f, 0.1f, 0.1f, 1.0f};
wlr_renderer_clear(renderer, color);
// Render all views
struct q20_view *view;
wl_list_for_each_reverse(view, &server->views, link) {
if (!view->xdg_surface->mapped) {
continue;
}
struct wlr_box box = {
.x = view->x,
.y = view->y,
.width = view->xdg_surface->surface->current.width,
.height = view->xdg_surface->surface->current.height,
};
wlr_renderer_scissor(renderer, &box);
wlr_render_texture(renderer, view->xdg_surface->surface->texture, output->transform_matrix, box.x, box.y, 1.0f);
}
wlr_renderer_scissor(renderer, NULL);
wlr_renderer_end(renderer);
wlr_output_swap_buffers(output, NULL, NULL);
}
static void server_new_output_notify(struct wl_listener *listener, void *data) {
struct q20_server *server = wl_container_of(listener, server, new_output);
struct wlr_output *output = data;
if (!wl_list_empty(&output->modes)) {
struct wlr_output_mode *mode = wl_container_of(output->modes.prev, mode, link);
wlr_output_set_mode(output, mode);
}
// Configure for Q20's 720x720 display
wlr_output_set_custom_mode(output, 720, 720, 60000);
wlr_output_create_global(output);
server->output = output;
output->frame.notify = output_frame_notify;
wl_signal_add(&output->events.frame, &output->frame);
}
int main(int argc, char *argv[]) {
wlr_log_init(WLR_DEBUG, NULL);
struct q20_server server = {0};
server.wl_display = wl_display_create();
server.backend = wlr_backend_autocreate(server.wl_display);
server.renderer = wlr_renderer_autocreate(server.backend);
wlr_renderer_init_wl_display(server.renderer, server.wl_display);
server.compositor = wlr_compositor_create(server.wl_display, server.renderer);
wlr_export_dmabuf_manager_v1_create(server.wl_display);
wlr_screencopy_manager_v1_create(server.wl_display);
wlr_data_device_manager_create(server.wl_display);
server.seat = wlr_seat_create(server.wl_display, "seat0");
server.xdg_shell = wlr_xdg_shell_create(server.wl_display);
server.new_xdg_surface.notify = server_new_xdg_surface_notify;
wl_signal_add(&server.xdg_shell->events.new_surface, &server.new_xdg_surface);
wl_list_init(&server.views);
wl_list_init(&server.keyboards);
server.new_output.notify = server_new_output_notify;
wl_signal_add(&server.backend->events.new_output, &server.new_output);
server.new_input.notify = server_new_input_notify;
wl_signal_add(&server.backend->events.new_input, &server.new_input);
const char *socket = wl_display_add_socket_auto(server.wl_display);
if (!socket) {
wlr_backend_destroy(server.backend);
return 1;
}
if (!wlr_backend_start(server.backend)) {
wlr_backend_destroy(server.backend);
wl_display_destroy(server.wl_display);
return 1;
}
setenv("WAYLAND_DISPLAY", socket, true);
wlr_log(WLR_INFO, "Running Q20 compositor on WAYLAND_DISPLAY=%s", socket);
wl_display_run(server.wl_display);
wl_display_destroy(server.wl_display);
return 0;
}