1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 10:47:36 +00:00

WindowServer: Support PNG wallpapers.

Fix up /bin/pape so it tells the WindowServer which wallpaper file to use.
This commit is contained in:
Andreas Kling 2019-03-21 15:54:19 +01:00
parent fe25f957e5
commit e4dfd5a3a4
15 changed files with 150 additions and 12890 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

34
LibGUI/GDesktop.cpp Normal file
View file

@ -0,0 +1,34 @@
#include <LibGUI/GDesktop.h>
#include <LibGUI/GEventLoop.h>
#include <string.h>
GDesktop& GDesktop::the()
{
static GDesktop* s_the;
if (!s_the)
s_the = new GDesktop;
return *s_the;
}
GDesktop::GDesktop()
{
}
bool GDesktop::set_wallpaper(const String& path)
{
WSAPI_ClientMessage message;
message.type = WSAPI_ClientMessage::Type::SetWallpaper;
ASSERT(path.length() < (int)sizeof(message.text));
strncpy(message.text, path.characters(), path.length());
message.text_length = path.length();
auto response = GEventLoop::current().sync_request(message, WSAPI_ServerMessage::Type::DidSetWallpaper);
return response.value;
}
String GDesktop::wallpaper() const
{
WSAPI_ClientMessage message;
message.type = WSAPI_ClientMessage::Type::GetWallpaper;
auto response = GEventLoop::current().sync_request(message, WSAPI_ServerMessage::Type::DidGetWallpaper);
return String(response.text, response.text_length);
}

17
LibGUI/GDesktop.h Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include <AK/AKString.h>
#include <SharedGraphics/Rect.h>
class GDesktop {
public:
static GDesktop& the();
String wallpaper() const;
bool set_wallpaper(const String& path);
private:
GDesktop();
Rect m_rect;
};

View file

@ -35,7 +35,7 @@ public:
void quit(int); void quit(int);
bool post_message_to_server(const WSAPI_ClientMessage&); static bool post_message_to_server(const WSAPI_ClientMessage&);
bool wait_for_specific_event(WSAPI_ServerMessage::Type, WSAPI_ServerMessage&); bool wait_for_specific_event(WSAPI_ServerMessage::Type, WSAPI_ServerMessage&);
WSAPI_ServerMessage sync_request(const WSAPI_ClientMessage& request, WSAPI_ServerMessage::Type response_type); WSAPI_ServerMessage sync_request(const WSAPI_ClientMessage& request, WSAPI_ServerMessage::Type response_type);

View file

@ -46,6 +46,7 @@ LIBGUI_OBJS = \
GMessageBox.o \ GMessageBox.o \
GInputBox.o \ GInputBox.o \
GDialog.o \ GDialog.o \
GDesktop.o \
GWindow.o GWindow.o
OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS) OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)

View file

@ -82,11 +82,14 @@ struct WSAPI_ServerMessage {
DidGetClipboardContents, DidGetClipboardContents,
DidSetClipboardContents, DidSetClipboardContents,
DidSetWindowBackingStore, DidSetWindowBackingStore,
DidSetWallpaper,
DidGetWallpaper,
}; };
Type type { Invalid }; Type type { Invalid };
int window_id { -1 }; int window_id { -1 };
int text_length { 0 }; int text_length { 0 };
char text[256]; char text[256];
int value { 0 };
union { union {
struct { struct {
@ -159,6 +162,8 @@ struct WSAPI_ClientMessage {
GetClipboardContents, GetClipboardContents,
SetClipboardContents, SetClipboardContents,
Greeting, Greeting,
SetWallpaper,
GetWallpaper,
}; };
Type type { Invalid }; Type type { Invalid };
int window_id { -1 }; int window_id { -1 };

View file

@ -241,6 +241,26 @@ void WSClientConnection::handle_request(WSAPISetWindowOpacityRequest& request)
window.set_opacity(request.opacity()); window.set_opacity(request.opacity());
} }
void WSClientConnection::handle_request(WSAPISetWallpaperRequest& request)
{
bool success = WSWindowManager::the().set_wallpaper(request.wallpaper());
WSAPI_ServerMessage response;
response.type = WSAPI_ServerMessage::Type::DidSetWallpaper;
response.value = success;
post_message(response);
}
void WSClientConnection::handle_request(WSAPIGetWallpaperRequest& request)
{
auto path = WSWindowManager::the().wallpaper_path();
WSAPI_ServerMessage response;
response.type = WSAPI_ServerMessage::Type::DidGetWallpaper;
ASSERT(path.length() < (int)sizeof(response.text));
strncpy(response.text, path.characters(), path.length());
response.text_length = path.length();
post_message(response);
}
void WSClientConnection::handle_request(WSAPISetWindowTitleRequest& request) void WSClientConnection::handle_request(WSAPISetWindowTitleRequest& request)
{ {
int window_id = request.window_id(); int window_id = request.window_id();
@ -518,6 +538,10 @@ void WSClientConnection::on_request(WSAPIClientRequest& request)
return handle_request(static_cast<WSAPISetWindowOpacityRequest&>(request)); return handle_request(static_cast<WSAPISetWindowOpacityRequest&>(request));
case WSMessage::APISetWindowBackingStoreRequest: case WSMessage::APISetWindowBackingStoreRequest:
return handle_request(static_cast<WSAPISetWindowBackingStoreRequest&>(request)); return handle_request(static_cast<WSAPISetWindowBackingStoreRequest&>(request));
case WSMessage::APISetWallpaperRequest:
return handle_request(static_cast<WSAPISetWallpaperRequest&>(request));
case WSMessage::APIGetWallpaperRequest:
return handle_request(static_cast<WSAPIGetWallpaperRequest&>(request));
default: default:
break; break;
} }

View file

@ -62,6 +62,8 @@ private:
void handle_request(WSAPISetWindowBackingStoreRequest&); void handle_request(WSAPISetWindowBackingStoreRequest&);
void handle_request(WSAPISetGlobalCursorTrackingRequest&); void handle_request(WSAPISetGlobalCursorTrackingRequest&);
void handle_request(WSAPISetWindowOpacityRequest&); void handle_request(WSAPISetWindowOpacityRequest&);
void handle_request(WSAPISetWallpaperRequest&);
void handle_request(WSAPIGetWallpaperRequest&);
void post_error(const String&); void post_error(const String&);

View file

@ -47,6 +47,8 @@ public:
APISetWindowBackingStoreRequest, APISetWindowBackingStoreRequest,
APISetClipboardContentsRequest, APISetClipboardContentsRequest,
APIGetClipboardContentsRequest, APIGetClipboardContentsRequest,
APISetWallpaperRequest,
APIGetWallpaperRequest,
__End_API_Client_Requests, __End_API_Client_Requests,
}; };
@ -227,6 +229,37 @@ private:
int m_menu_id { 0 }; int m_menu_id { 0 };
}; };
class WSAPISetWallpaperRequest final : public WSAPIClientRequest {
public:
explicit WSAPISetWallpaperRequest(int client_id, String&& wallpaper)
: WSAPIClientRequest(WSMessage::APISetWallpaperRequest, client_id)
, m_client_id(client_id)
, m_wallpaper(move(wallpaper))
{
}
int client_id() const { return m_client_id; }
String wallpaper() const { return m_wallpaper; }
private:
int m_client_id { 0 };
String m_wallpaper;
};
class WSAPIGetWallpaperRequest final : public WSAPIClientRequest {
public:
explicit WSAPIGetWallpaperRequest(int client_id)
: WSAPIClientRequest(WSMessage::APIGetWallpaperRequest, client_id)
, m_client_id(client_id)
{
}
int client_id() const { return m_client_id; }
private:
int m_client_id { 0 };
};
class WSAPISetWindowTitleRequest final : public WSAPIClientRequest { class WSAPISetWindowTitleRequest final : public WSAPIClientRequest {
public: public:
explicit WSAPISetWindowTitleRequest(int client_id, int window_id, String&& title) explicit WSAPISetWindowTitleRequest(int client_id, int window_id, String&& title)

View file

@ -329,6 +329,12 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess
case WSAPI_ClientMessage::Type::SetGlobalCursorTracking: case WSAPI_ClientMessage::Type::SetGlobalCursorTracking:
post_message(client, make<WSAPISetGlobalCursorTrackingRequest>(client_id, message.window_id, message.value)); post_message(client, make<WSAPISetGlobalCursorTrackingRequest>(client_id, message.window_id, message.value));
break; break;
case WSAPI_ClientMessage::Type::SetWallpaper:
ASSERT(message.text_length < (ssize_t)sizeof(message.text));
post_message(client, make<WSAPISetWallpaperRequest>(client_id, String(message.text, message.text_length)));
break;
case WSAPI_ClientMessage::Type::GetWallpaper:
post_message(client, make<WSAPIGetWallpaperRequest>(client_id));
default: default:
break; break;
} }

View file

@ -14,6 +14,7 @@
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include <SharedGraphics/PNGLoader.h>
#ifdef KERNEL #ifdef KERNEL
#include <Kernel/ProcFS.h> #include <Kernel/ProcFS.h>
@ -22,7 +23,6 @@
//#define DEBUG_COUNTERS //#define DEBUG_COUNTERS
//#define DEBUG_WID_IN_TITLE_BAR //#define DEBUG_WID_IN_TITLE_BAR
//#define RESIZE_DEBUG //#define RESIZE_DEBUG
#define USE_WALLPAPER
static const int window_titlebar_height = 18; static const int window_titlebar_height = 18;
@ -199,18 +199,8 @@ WSWindowManager::WSWindowManager()
m_cursor_bitmap_inner = CharacterBitmap::create_from_ascii(cursor_bitmap_inner_ascii, 12, 17); m_cursor_bitmap_inner = CharacterBitmap::create_from_ascii(cursor_bitmap_inner_ascii, 12, 17);
m_cursor_bitmap_outer = CharacterBitmap::create_from_ascii(cursor_bitmap_outer_ascii, 12, 17); m_cursor_bitmap_outer = CharacterBitmap::create_from_ascii(cursor_bitmap_outer_ascii, 12, 17);
#ifdef USE_WALLPAPER
m_wallpaper_path = "/res/wallpapers/retro.rgb"; m_wallpaper_path = "/res/wallpapers/retro.rgb";
m_wallpaper = GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, m_wallpaper_path, { 1024, 768 }); m_wallpaper = GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, m_wallpaper_path, { 1024, 768 });
#endif
#ifdef KERNEL
ProcFS::the().add_sys_bool("wm_flash_flush", m_flash_flush);
ProcFS::the().add_sys_string("wm_wallpaper", m_wallpaper_path, [this] {
m_wallpaper = GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, m_wallpaper_path, m_screen_rect.size());
invalidate(m_screen_rect);
});
#endif
m_username = getlogin(); m_username = getlogin();
@ -351,6 +341,18 @@ void WSWindowManager::tick_clock()
invalidate(menubar_rect()); invalidate(menubar_rect());
} }
bool WSWindowManager::set_wallpaper(const String& path)
{
auto bitmap = load_png(path);
if (!bitmap)
return false;
m_wallpaper_path = path;
m_wallpaper = move(bitmap);
invalidate();
return true;
}
void WSWindowManager::set_resolution(int width, int height) void WSWindowManager::set_resolution(int width, int height)
{ {
if (m_screen_rect.width() == width && m_screen_rect.height() == height) if (m_screen_rect.width() == width && m_screen_rect.height() == height)

View file

@ -81,6 +81,9 @@ public:
void set_resolution(int width, int height); void set_resolution(int width, int height);
bool set_wallpaper(const String& path);
String wallpaper_path() const { return m_wallpaper_path; }
private: private:
void process_mouse_event(WSMouseEvent&, WSWindow*& event_window); void process_mouse_event(WSMouseEvent&, WSWindow*& event_window);
void handle_menu_mouse_event(WSMenu&, WSMouseEvent&); void handle_menu_mouse_event(WSMenu&, WSMouseEvent&);

View file

@ -173,7 +173,7 @@ sysctl: sysctl.o
$(LD) -o $@ $(LDFLAGS) $< -lc $(LD) -o $@ $(LDFLAGS) $< -lc
pape: pape.o pape: pape.o
$(LD) -o $@ $(LDFLAGS) $< -lc $(LD) -o $@ $(LDFLAGS) -L../LibGUI $< -lgui -lc
cp: cp.o cp: cp.o
$(LD) -o $@ $(LDFLAGS) $< -lc $(LD) -o $@ $(LDFLAGS) $< -lc

View file

@ -10,6 +10,8 @@
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <AK/FileSystemPath.h> #include <AK/FileSystemPath.h>
#include <LibGUI/GDesktop.h>
#include <LibGUI/GApplication.h>
static bool flag_show_all = false; static bool flag_show_all = false;
static int show_all(); static int show_all();
@ -23,6 +25,8 @@ static void usage()
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
GApplication app(argc, argv);
int opt; int opt;
while ((opt = getopt(argc, argv, "a")) != -1) { while ((opt = getopt(argc, argv, "a")) != -1) {
switch (opt) { switch (opt) {
@ -67,50 +71,9 @@ int show_all()
return 0; return 0;
} }
static String read_var(const String& name)
{
StringBuilder builder;
builder.append("/proc/sys/");
builder.append(name);
auto path = builder.to_string();
int fd = open(path.characters(), O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
char buffer[BUFSIZ];
int nread = read(fd, buffer, sizeof(buffer));
close(fd);
if (nread < 0) {
perror("read");
exit(1);
}
return String(buffer, nread, Chomp);
}
static void write_var(const String& name, const String& value)
{
StringBuilder builder;
builder.append("/proc/sys/");
builder.append(name);
auto path = builder.to_string();
int fd = open(path.characters(), O_WRONLY);
if (fd < 0) {
perror("open");
exit(1);
}
int nwritten = write(fd, value.characters(), value.length());
if (nwritten < 0) {
perror("read");
exit(1);
}
close(fd);
}
int show_current() int show_current()
{ {
FileSystemPath path(read_var("wm_wallpaper")); printf("%s\n", GDesktop::the().wallpaper().characters());
printf("%s\n", path.basename().characters());
return 0; return 0;
} }
@ -119,7 +82,10 @@ int set_pape(const char* name)
StringBuilder builder; StringBuilder builder;
builder.append("/res/wallpapers/"); builder.append("/res/wallpapers/");
builder.append(name); builder.append(name);
String path = builder.to_string();
write_var("wm_wallpaper", builder.to_string()); if (!GDesktop::the().set_wallpaper(path)) {
fprintf(stderr, "pape: Failed to set wallpaper %s\n", path.characters());
return 1;
}
return 0; return 0;
} }