Files
BBeOS/ui-build/applications/home-screen.c
Eliott 7b53cde2ae
Some checks failed
CI / markdown-lint (push) Failing after 14s
Complete BBeOS project implementation with BlackBerry-inspired website
- Updated .gitignore with comprehensive exclusions for build artifacts, IDE files, and OS-specific files
- Created BlackBerry-inspired website with Heroicons and Gitea integration
- Added complete project structure with all 7 phases implemented
- Included kernel drivers, UI components, telephony stack, and packaging tools
- Added emulation scripts for testing and development
- Comprehensive documentation for all development phases
- Security analysis and hardware testing guides
- SDK and application framework for third-party development
2025-08-01 10:20:28 +02:00

266 lines
7.9 KiB
C

/*
* 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;
}