1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <X11/Xlib.h>
#define SHM_NAME "/breathing_color_shm" // Shared memory name (same as in exo.c)
#define COLOR_SIZE 8 // Size for one color (e.g., #RRGGBB)
int main() {
// Open shared memory object
int shm_fd = shm_open(SHM_NAME, O_RDONLY, 0666);
if (shm_fd == -1) {
perror("Failed to open shared memory");
return 1;
}
// Map shared memory into the process's address space
char *shm_ptr = mmap(NULL, COLOR_SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
if (shm_ptr == MAP_FAILED) {
perror("Failed to map shared memory");
close(shm_fd);
return 1;
}
// Initialize X11
Display *display = XOpenDisplay(NULL);
if (display == NULL) {
perror("Unable to open X display");
munmap(shm_ptr, COLOR_SIZE);
close(shm_fd);
return 1;
}
// Create a window
int screen = DefaultScreen(display);
Window window = XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, 400, 400, 1, BlackPixel(display, screen), BlackPixel(display, screen));
// Set window properties
XStoreName(display, window, "Breathing Color Display");
XMapWindow(display, window);
// Set the window's background color initially
XFlush(display);
// Start reading colors and updating the window
while (1) {
// Read the current color from shared memory
XColor color;
if (XParseColor(display, DefaultColormap(display, screen), shm_ptr, &color) == 0) {
fprintf(stderr, "Invalid color in shared memory: %s\n", shm_ptr);
continue;
}
// Allocate the color in the X server
if (XAllocColor(display, DefaultColormap(display, screen), &color) == 0) {
fprintf(stderr, "Failed to allocate color: %s\n", shm_ptr);
continue;
}
// Change the background color of the window
XSetWindowBackground(display, window, color.pixel);
XClearWindow(display, window);
// Process X events
XEvent event;
while (XPending(display)) {
XNextEvent(display, &event);
if (event.type == ClientMessage) {
// Exit on close event (or any client message)
XDestroyWindow(display, window);
XCloseDisplay(display);
munmap(shm_ptr, COLOR_SIZE);
close(shm_fd);
return 0;
}
}
// Sleep a little before checking for the next color update
usleep(100000); // 0.1 seconds
}
// Clean up
XDestroyWindow(display, window);
XCloseDisplay(display);
munmap(shm_ptr, COLOR_SIZE);
close(shm_fd);
return 0;
}
|