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.
			
			
							
								
								
									
										
											BIN
										
									
								
								Base/res/cursors/arrow.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 466 B | 
							
								
								
									
										
											BIN
										
									
								
								Base/res/cursors/disallowed.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 500 B | 
							
								
								
									
										
											BIN
										
									
								
								Base/res/cursors/i-beam.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 280 B | 
							
								
								
									
										
											BIN
										
									
								
								Base/res/cursors/resize-diagonal-bltr.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 463 B | 
							
								
								
									
										
											BIN
										
									
								
								Base/res/cursors/resize-diagonal-tlbr.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 456 B | 
							
								
								
									
										
											BIN
										
									
								
								Base/res/cursors/resize-horizontal.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 7.3 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Base/res/cursors/resize-vertical.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 7.3 KiB | 
|  | @ -21,12 +21,13 @@ WINDOWSERVER_OBJS = \ | ||||||
|     WSClientConnection.o \
 |     WSClientConnection.o \
 | ||||||
|     WSWindowSwitcher.o \
 |     WSWindowSwitcher.o \
 | ||||||
|     WSClipboard.o \
 |     WSClipboard.o \
 | ||||||
|  |     WSCursor.o \
 | ||||||
|     main.o |     main.o | ||||||
| 
 | 
 | ||||||
| APP = WindowServer | APP = WindowServer | ||||||
| OBJS = $(SHAREDGRAPHICS_OBJS) $(WINDOWSERVER_OBJS) | 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 | WARNING_FLAGS = -Wextra -Wall -Wundef -Wcast-qual -Wwrite-strings -Wimplicit-fallthrough | ||||||
| FLAVOR_FLAGS = -fno-exceptions -fno-rtti | FLAVOR_FLAGS = -fno-exceptions -fno-rtti | ||||||
| OPTIMIZATION_FLAGS = -Os | OPTIMIZATION_FLAGS = -Os | ||||||
|  |  | ||||||
							
								
								
									
										21
									
								
								Servers/WindowServer/WSCursor.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -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
									
								
								Servers/WindowServer/WSCursor.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -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; | ||||||
|  | }; | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
| #include <time.h> | #include <time.h> | ||||||
| #include <SharedGraphics/StylePainter.h> | #include <SharedGraphics/StylePainter.h> | ||||||
| #include <SharedGraphics/PNGLoader.h> | #include <SharedGraphics/PNGLoader.h> | ||||||
|  | #include "WSCursor.h" | ||||||
| 
 | 
 | ||||||
| #ifdef KERNEL | #ifdef KERNEL | ||||||
| #include <Kernel/ProcFS.h> | #include <Kernel/ProcFS.h> | ||||||
|  | @ -199,8 +200,13 @@ WSWindowManager::WSWindowManager() | ||||||
|     m_highlight_window_border_color2 = Color::from_rgb(0xfabbbb); |     m_highlight_window_border_color2 = Color::from_rgb(0xfabbbb); | ||||||
|     m_highlight_window_title_color = Color::White; |     m_highlight_window_title_color = Color::White; | ||||||
| 
 | 
 | ||||||
|     m_cursor_bitmap_inner = CharacterBitmap::create_from_ascii(cursor_bitmap_inner_ascii, 12, 17); |     m_arrow_cursor = WSCursor::create(*GraphicsBitmap::load_from_file("/res/cursors/arrow.png"), { 2, 2 }); | ||||||
|     m_cursor_bitmap_outer = CharacterBitmap::create_from_ascii(cursor_bitmap_outer_ascii, 12, 17); |     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_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 }); | ||||||
|  | @ -880,9 +886,8 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& event_ | ||||||
| void WSWindowManager::compose() | void WSWindowManager::compose() | ||||||
| { | { | ||||||
|     auto dirty_rects = move(m_dirty_rects); |     auto dirty_rects = move(m_dirty_rects); | ||||||
|     auto cursor_location = m_screen.cursor_location(); |  | ||||||
|     dirty_rects.add(m_last_cursor_rect); |     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 | #ifdef DEBUG_COUNTERS | ||||||
|     dbgprintf("[WM] compose #%u (%u rects)\n", ++m_compose_count, dirty_rects.rects().size()); |     dbgprintf("[WM] compose #%u (%u rects)\n", ++m_compose_count, dirty_rects.rects().size()); | ||||||
| #endif | #endif | ||||||
|  | @ -988,11 +993,14 @@ void WSWindowManager::compose() | ||||||
|         flush(r); |         flush(r); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Rect WSWindowManager::current_cursor_rect() const | ||||||
|  | { | ||||||
|  |     return { m_screen.cursor_location().translated(-active_cursor().hotspot()), active_cursor().size() }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void WSWindowManager::invalidate_cursor() | void WSWindowManager::invalidate_cursor() | ||||||
| { | { | ||||||
|     auto cursor_location = m_screen.cursor_location(); |     invalidate(current_cursor_rect()); | ||||||
|     Rect cursor_rect { cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() }; |  | ||||||
|     invalidate(cursor_rect); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Rect WSWindowManager::menubar_rect() const | Rect WSWindowManager::menubar_rect() const | ||||||
|  | @ -1073,14 +1081,12 @@ void WSWindowManager::draw_window_switcher() | ||||||
| 
 | 
 | ||||||
| void WSWindowManager::draw_cursor() | void WSWindowManager::draw_cursor() | ||||||
| { | { | ||||||
|     auto cursor_location = m_screen.cursor_location(); |     Rect cursor_rect = current_cursor_rect(); | ||||||
|     Rect cursor_rect { cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() }; |  | ||||||
|     Color inner_color = Color::White; |     Color inner_color = Color::White; | ||||||
|     Color outer_color = Color::Black; |     Color outer_color = Color::Black; | ||||||
|     if (m_screen.mouse_button_state() & (unsigned)MouseButton::Left) |     if (m_screen.mouse_button_state() & (unsigned)MouseButton::Left) | ||||||
|         swap(inner_color, outer_color); |         swap(inner_color, outer_color); | ||||||
|     m_back_painter->draw_bitmap(cursor_location, *m_cursor_bitmap_inner, inner_color); |     m_back_painter->blit(cursor_rect.location(), active_cursor().bitmap(), active_cursor().rect()); | ||||||
|     m_back_painter->draw_bitmap(cursor_location, *m_cursor_bitmap_outer, outer_color); |  | ||||||
|     m_last_cursor_rect = cursor_rect; |     m_last_cursor_rect = cursor_rect; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ | ||||||
| #include <WindowServer/WSWindowSwitcher.h> | #include <WindowServer/WSWindowSwitcher.h> | ||||||
| #include <WindowServer/WSWindowType.h> | #include <WindowServer/WSWindowType.h> | ||||||
| #include <WindowServer/WSWindow.h> | #include <WindowServer/WSWindow.h> | ||||||
|  | #include <WindowServer/WSCursor.h> | ||||||
| #include <AK/CircularQueue.h> | #include <AK/CircularQueue.h> | ||||||
| 
 | 
 | ||||||
| class WSAPIClientRequest; | class WSAPIClientRequest; | ||||||
|  | @ -23,7 +24,6 @@ class WSClientWantsToPaintMessage; | ||||||
| class WSWindow; | class WSWindow; | ||||||
| class WSClientConnection; | class WSClientConnection; | ||||||
| class WSWindowSwitcher; | class WSWindowSwitcher; | ||||||
| class CharacterBitmap; |  | ||||||
| class GraphicsBitmap; | class GraphicsBitmap; | ||||||
| 
 | 
 | ||||||
| enum class ResizeDirection { None, Left, UpLeft, Up, UpRight, Right, DownRight, Down, DownLeft }; | enum class ResizeDirection { None, Left, UpLeft, Up, UpRight, Right, DownRight, Down, DownLeft }; | ||||||
|  | @ -84,6 +84,9 @@ public: | ||||||
|     bool set_wallpaper(const String& path); |     bool set_wallpaper(const String& path); | ||||||
|     String wallpaper_path() const { return m_wallpaper_path; } |     String wallpaper_path() const { return m_wallpaper_path; } | ||||||
| 
 | 
 | ||||||
|  |     const WSCursor& active_cursor() const { return *m_arrow_cursor; } | ||||||
|  |     Rect current_cursor_rect() const; | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     void process_mouse_event(WSMouseEvent&, WSWindow*& event_window); |     void process_mouse_event(WSMouseEvent&, WSWindow*& event_window); | ||||||
|     bool process_ongoing_window_resize(WSMouseEvent&, WSWindow*& event_window); |     bool process_ongoing_window_resize(WSMouseEvent&, WSWindow*& event_window); | ||||||
|  | @ -154,8 +157,13 @@ private: | ||||||
| 
 | 
 | ||||||
|     bool m_pending_compose_event { false }; |     bool m_pending_compose_event { false }; | ||||||
| 
 | 
 | ||||||
|     RetainPtr<CharacterBitmap> m_cursor_bitmap_inner; |     RetainPtr<WSCursor> m_arrow_cursor; | ||||||
|     RetainPtr<CharacterBitmap> m_cursor_bitmap_outer; |     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_back_painter; | ||||||
|     OwnPtr<Painter> m_front_painter; |     OwnPtr<Painter> m_front_painter; | ||||||
|  |  | ||||||
|  | @ -28,6 +28,13 @@ public: | ||||||
|         move_by(delta.x(), delta.y()); |         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 translated(int dx, int dy) const | ||||||
|     { |     { | ||||||
|         Point point = *this; |         Point point = *this; | ||||||
|  |  | ||||||
 Andreas Kling
						Andreas Kling