Ver código fonte

WindowServer: Add a WSCursor class (a bitmap and a hotspot.)

Also import a bunch of cursors I drew. Only the default ("arrow") cursor is
ever used so far.
Andreas Kling 6 anos atrás
pai
commit
2334ffcbf8

BIN
Base/res/cursors/arrow.png


BIN
Base/res/cursors/disallowed.png


BIN
Base/res/cursors/i-beam.png


BIN
Base/res/cursors/resize-diagonal-bltr.png


BIN
Base/res/cursors/resize-diagonal-tlbr.png


BIN
Base/res/cursors/resize-horizontal.png


BIN
Base/res/cursors/resize-vertical.png


+ 2 - 1
Servers/WindowServer/Makefile

@@ -21,12 +21,13 @@ WINDOWSERVER_OBJS = \
     WSClientConnection.o \
     WSWindowSwitcher.o \
     WSClipboard.o \
+    WSCursor.o \
     main.o
 
 APP = WindowServer
 OBJS = $(SHAREDGRAPHICS_OBJS) $(WINDOWSERVER_OBJS)
 
-STANDARD_FLAGS = -std=c++17
+STANDARD_FLAGS = -std=c++17 -Wno-sized-deallocation
 WARNING_FLAGS = -Wextra -Wall -Wundef -Wcast-qual -Wwrite-strings -Wimplicit-fallthrough
 FLAVOR_FLAGS = -fno-exceptions -fno-rtti
 OPTIMIZATION_FLAGS = -Os

+ 21 - 0
Servers/WindowServer/WSCursor.cpp

@@ -0,0 +1,21 @@
+#include <WindowServer/WSCursor.h>
+
+WSCursor::WSCursor(Retained<GraphicsBitmap>&& bitmap, const Point& hotspot)
+    : m_bitmap(move(bitmap))
+    , m_hotspot(hotspot)
+{
+}
+
+WSCursor::~WSCursor()
+{
+}
+
+Retained<WSCursor> WSCursor::create(Retained<GraphicsBitmap>&& bitmap)
+{
+    return adopt(*new WSCursor(move(bitmap), bitmap->rect().center()));
+}
+
+Retained<WSCursor> WSCursor::create(Retained<GraphicsBitmap>&& bitmap, const Point& hotspot)
+{
+    return adopt(*new WSCursor(move(bitmap), hotspot));
+}

+ 22 - 0
Servers/WindowServer/WSCursor.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include <SharedGraphics/GraphicsBitmap.h>
+
+class WSCursor : public Retainable<WSCursor> {
+public:
+    static Retained<WSCursor> create(Retained<GraphicsBitmap>&&, const Point& hotspot);
+    static Retained<WSCursor> create(Retained<GraphicsBitmap>&&);
+    ~WSCursor();
+
+    Point hotspot() const { return m_hotspot; }
+    const GraphicsBitmap& bitmap() const { return *m_bitmap; }
+
+    Rect rect() const { return m_bitmap->rect(); }
+    Size size() const { return m_bitmap->size(); }
+
+private:
+    WSCursor(Retained<GraphicsBitmap>&&, const Point&);
+
+    RetainPtr<GraphicsBitmap> m_bitmap;
+    Point m_hotspot;
+};

+ 17 - 11
Servers/WindowServer/WSWindowManager.cpp

@@ -16,6 +16,7 @@
 #include <time.h>
 #include <SharedGraphics/StylePainter.h>
 #include <SharedGraphics/PNGLoader.h>
+#include "WSCursor.h"
 
 #ifdef KERNEL
 #include <Kernel/ProcFS.h>
@@ -199,8 +200,13 @@ WSWindowManager::WSWindowManager()
     m_highlight_window_border_color2 = Color::from_rgb(0xfabbbb);
     m_highlight_window_title_color = Color::White;
 
-    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_arrow_cursor = WSCursor::create(*GraphicsBitmap::load_from_file("/res/cursors/arrow.png"), { 2, 2 });
+    m_resize_horizontally_cursor = WSCursor::create(*GraphicsBitmap::load_from_file("/res/cursors/resize-horizontal.png"));
+    m_resize_vertically_cursor = WSCursor::create(*GraphicsBitmap::load_from_file("/res/cursors/resize-vertical.png"));
+    m_resize_diagonally_tlbr_cursor = WSCursor::create(*GraphicsBitmap::load_from_file("/res/cursors/resize-diagonal-tlbr.png"));
+    m_resize_diagonally_bltr_cursor = WSCursor::create(*GraphicsBitmap::load_from_file("/res/cursors/resize-diagonal-bltr.png"));
+    m_i_beam_cursor = WSCursor::create(*GraphicsBitmap::load_from_file("/res/cursors/i-beam.png"));
+    m_disallowed_cursor = WSCursor::create(*GraphicsBitmap::load_from_file("/res/cursors/disallowed.png"));
 
     m_wallpaper_path = "/res/wallpapers/retro.rgb";
     m_wallpaper = GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, m_wallpaper_path, { 1024, 768 });
@@ -880,9 +886,8 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& event_
 void WSWindowManager::compose()
 {
     auto dirty_rects = move(m_dirty_rects);
-    auto cursor_location = m_screen.cursor_location();
     dirty_rects.add(m_last_cursor_rect);
-    dirty_rects.add({ cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() });
+    dirty_rects.add(current_cursor_rect());
 #ifdef DEBUG_COUNTERS
     dbgprintf("[WM] compose #%u (%u rects)\n", ++m_compose_count, dirty_rects.rects().size());
 #endif
@@ -988,11 +993,14 @@ void WSWindowManager::compose()
         flush(r);
 }
 
+Rect WSWindowManager::current_cursor_rect() const
+{
+    return { m_screen.cursor_location().translated(-active_cursor().hotspot()), active_cursor().size() };
+}
+
 void WSWindowManager::invalidate_cursor()
 {
-    auto cursor_location = m_screen.cursor_location();
-    Rect cursor_rect { cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() };
-    invalidate(cursor_rect);
+    invalidate(current_cursor_rect());
 }
 
 Rect WSWindowManager::menubar_rect() const
@@ -1073,14 +1081,12 @@ void WSWindowManager::draw_window_switcher()
 
 void WSWindowManager::draw_cursor()
 {
-    auto cursor_location = m_screen.cursor_location();
-    Rect cursor_rect { cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() };
+    Rect cursor_rect = current_cursor_rect();
     Color inner_color = Color::White;
     Color outer_color = Color::Black;
     if (m_screen.mouse_button_state() & (unsigned)MouseButton::Left)
         swap(inner_color, outer_color);
-    m_back_painter->draw_bitmap(cursor_location, *m_cursor_bitmap_inner, inner_color);
-    m_back_painter->draw_bitmap(cursor_location, *m_cursor_bitmap_outer, outer_color);
+    m_back_painter->blit(cursor_rect.location(), active_cursor().bitmap(), active_cursor().rect());
     m_last_cursor_rect = cursor_rect;
 }
 

+ 11 - 3
Servers/WindowServer/WSWindowManager.h

@@ -13,6 +13,7 @@
 #include <WindowServer/WSWindowSwitcher.h>
 #include <WindowServer/WSWindowType.h>
 #include <WindowServer/WSWindow.h>
+#include <WindowServer/WSCursor.h>
 #include <AK/CircularQueue.h>
 
 class WSAPIClientRequest;
@@ -23,7 +24,6 @@ class WSClientWantsToPaintMessage;
 class WSWindow;
 class WSClientConnection;
 class WSWindowSwitcher;
-class CharacterBitmap;
 class GraphicsBitmap;
 
 enum class ResizeDirection { None, Left, UpLeft, Up, UpRight, Right, DownRight, Down, DownLeft };
@@ -84,6 +84,9 @@ public:
     bool set_wallpaper(const String& path);
     String wallpaper_path() const { return m_wallpaper_path; }
 
+    const WSCursor& active_cursor() const { return *m_arrow_cursor; }
+    Rect current_cursor_rect() const;
+
 private:
     void process_mouse_event(WSMouseEvent&, WSWindow*& event_window);
     bool process_ongoing_window_resize(WSMouseEvent&, WSWindow*& event_window);
@@ -154,8 +157,13 @@ private:
 
     bool m_pending_compose_event { false };
 
-    RetainPtr<CharacterBitmap> m_cursor_bitmap_inner;
-    RetainPtr<CharacterBitmap> m_cursor_bitmap_outer;
+    RetainPtr<WSCursor> m_arrow_cursor;
+    RetainPtr<WSCursor> m_resize_horizontally_cursor;
+    RetainPtr<WSCursor> m_resize_vertically_cursor;
+    RetainPtr<WSCursor> m_resize_diagonally_tlbr_cursor;
+    RetainPtr<WSCursor> m_resize_diagonally_bltr_cursor;
+    RetainPtr<WSCursor> m_i_beam_cursor;
+    RetainPtr<WSCursor> m_disallowed_cursor;
 
     OwnPtr<Painter> m_back_painter;
     OwnPtr<Painter> m_front_painter;

+ 7 - 0
SharedGraphics/Point.h

@@ -28,6 +28,13 @@ public:
         move_by(delta.x(), delta.y());
     }
 
+    Point translated(const Point& delta) const
+    {
+        Point point = *this;
+        point.move_by(delta);
+        return point;
+    }
+
     Point translated(int dx, int dy) const
     {
         Point point = *this;