| 1 | // Scintilla source code edit control |
| 2 | /** @file Platform.h |
| 3 | ** Interface to platform facilities. Also includes some basic utilities. |
| 4 | ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows. |
| 5 | **/ |
| 6 | // Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org> |
| 7 | // The License.txt file describes the conditions under which this software may be distributed. |
| 8 | |
| 9 | #ifndef PLATFORM_H |
| 10 | #define PLATFORM_H |
| 11 | |
| 12 | // PLAT_GTK = GTK+ on Linux or Win32 |
| 13 | // PLAT_GTK_WIN32 is defined additionally when running PLAT_GTK under Win32 |
| 14 | // PLAT_WIN = Win32 API on Win32 OS |
| 15 | // PLAT_WX is wxWindows on any supported platform |
| 16 | // PLAT_TK = Tcl/TK on Linux or Win32 |
| 17 | |
| 18 | #define PLAT_GTK 0 |
| 19 | #define PLAT_GTK_WIN32 0 |
| 20 | #define PLAT_GTK_MACOSX 0 |
| 21 | #define PLAT_MACOSX 0 |
| 22 | #define PLAT_WIN 0 |
| 23 | #define PLAT_WX 0 |
| 24 | #define PLAT_QT 0 |
| 25 | #define PLAT_QT_QML 0 |
| 26 | #define PLAT_FOX 0 |
| 27 | #define PLAT_CURSES 0 |
| 28 | #define PLAT_TK 0 |
| 29 | #define PLAT_HAIKU 0 |
| 30 | |
| 31 | #if defined(FOX) |
| 32 | #undef PLAT_FOX |
| 33 | #define PLAT_FOX 1 |
| 34 | |
| 35 | #elif defined(__WX__) |
| 36 | #undef PLAT_WX |
| 37 | #define PLAT_WX 1 |
| 38 | |
| 39 | #elif defined(CURSES) |
| 40 | #undef PLAT_CURSES |
| 41 | #define PLAT_CURSES 1 |
| 42 | |
| 43 | #elif defined(__HAIKU__) |
| 44 | #undef PLAT_HAIKU |
| 45 | #define PLAT_HAIKU 1 |
| 46 | |
| 47 | #elif defined(SCINTILLA_QT) |
| 48 | #undef PLAT_QT |
| 49 | #define PLAT_QT 1 |
| 50 | |
| 51 | #elif defined(SCINTILLA_QT_QML) |
| 52 | #undef PLAT_QT_QML |
| 53 | #define PLAT_QT_QML 1 |
| 54 | |
| 55 | #elif defined(TK) |
| 56 | #undef PLAT_TK |
| 57 | #define PLAT_TK 1 |
| 58 | |
| 59 | #elif defined(GTK) |
| 60 | #undef PLAT_GTK |
| 61 | #define PLAT_GTK 1 |
| 62 | |
| 63 | #if defined(__WIN32__) || defined(_MSC_VER) |
| 64 | #undef PLAT_GTK_WIN32 |
| 65 | #define PLAT_GTK_WIN32 1 |
| 66 | #endif |
| 67 | |
| 68 | #if defined(__APPLE__) |
| 69 | #undef PLAT_GTK_MACOSX |
| 70 | #define PLAT_GTK_MACOSX 1 |
| 71 | #endif |
| 72 | |
| 73 | #elif defined(__APPLE__) |
| 74 | |
| 75 | #undef PLAT_MACOSX |
| 76 | #define PLAT_MACOSX 1 |
| 77 | |
| 78 | #else |
| 79 | #undef PLAT_WIN |
| 80 | #define PLAT_WIN 1 |
| 81 | |
| 82 | #endif |
| 83 | |
| 84 | namespace Scintilla::Internal { |
| 85 | |
| 86 | // Underlying the implementation of the platform classes are platform specific types. |
| 87 | // Sometimes these need to be passed around by client code so they are defined here |
| 88 | |
| 89 | typedef void *SurfaceID; |
| 90 | typedef void *WindowID; |
| 91 | typedef void *; |
| 92 | typedef void *TickerID; |
| 93 | typedef void *Function; |
| 94 | typedef void *IdlerID; |
| 95 | |
| 96 | /** |
| 97 | * Font management. |
| 98 | */ |
| 99 | |
| 100 | constexpr const char *localeNameDefault = "en-us" ; |
| 101 | |
| 102 | struct FontParameters { |
| 103 | const char *faceName; |
| 104 | XYPOSITION size; |
| 105 | Scintilla::FontWeight weight; |
| 106 | bool italic; |
| 107 | Scintilla::FontQuality ; |
| 108 | Scintilla::Technology technology; |
| 109 | Scintilla::CharacterSet characterSet; |
| 110 | const char *localeName; |
| 111 | |
| 112 | constexpr FontParameters( |
| 113 | const char *faceName_, |
| 114 | XYPOSITION size_=10, |
| 115 | Scintilla::FontWeight weight_= Scintilla::FontWeight::Normal, |
| 116 | bool italic_=false, |
| 117 | Scintilla::FontQuality = Scintilla::FontQuality::QualityDefault, |
| 118 | Scintilla::Technology technology_= Scintilla::Technology::Default, |
| 119 | Scintilla::CharacterSet characterSet_= Scintilla::CharacterSet::Ansi, |
| 120 | const char *localeName_=localeNameDefault) noexcept : |
| 121 | |
| 122 | faceName(faceName_), |
| 123 | size(size_), |
| 124 | weight(weight_), |
| 125 | italic(italic_), |
| 126 | extraFontFlag(extraFontFlag_), |
| 127 | technology(technology_), |
| 128 | characterSet(characterSet_), |
| 129 | localeName(localeName_) |
| 130 | { |
| 131 | } |
| 132 | |
| 133 | }; |
| 134 | |
| 135 | class Font { |
| 136 | public: |
| 137 | Font() noexcept = default; |
| 138 | // Deleted so Font objects can not be copied |
| 139 | Font(const Font &) = delete; |
| 140 | Font(Font &&) = delete; |
| 141 | Font &operator=(const Font &) = delete; |
| 142 | Font &operator=(Font &&) = delete; |
| 143 | virtual ~Font() noexcept = default; |
| 144 | |
| 145 | static std::shared_ptr<Font> Allocate(const FontParameters &fp); |
| 146 | }; |
| 147 | |
| 148 | class IScreenLine { |
| 149 | public: |
| 150 | virtual std::string_view Text() const = 0; |
| 151 | virtual size_t Length() const = 0; |
| 152 | virtual size_t RepresentationCount() const = 0; |
| 153 | virtual XYPOSITION Width() const = 0; |
| 154 | virtual XYPOSITION Height() const = 0; |
| 155 | virtual XYPOSITION TabWidth() const = 0; |
| 156 | virtual XYPOSITION TabWidthMinimumPixels() const = 0; |
| 157 | virtual const Font *FontOfPosition(size_t position) const = 0; |
| 158 | virtual XYPOSITION RepresentationWidth(size_t position) const = 0; |
| 159 | virtual XYPOSITION TabPositionAfter(XYPOSITION xPosition) const = 0; |
| 160 | }; |
| 161 | |
| 162 | class IScreenLineLayout { |
| 163 | public: |
| 164 | virtual ~IScreenLineLayout() noexcept = default; |
| 165 | virtual size_t PositionFromX(XYPOSITION xDistance, bool charPosition) = 0; |
| 166 | virtual XYPOSITION XFromPosition(size_t caretPosition) = 0; |
| 167 | virtual std::vector<Interval> FindRangeIntervals(size_t start, size_t end) = 0; |
| 168 | }; |
| 169 | |
| 170 | /** |
| 171 | * Parameters for surfaces. |
| 172 | */ |
| 173 | struct SurfaceMode { |
| 174 | int codePage = 0; |
| 175 | bool bidiR2L = false; |
| 176 | SurfaceMode() = default; |
| 177 | explicit SurfaceMode(int codePage_, bool bidiR2L_) noexcept : codePage(codePage_), bidiR2L(bidiR2L_) { |
| 178 | } |
| 179 | }; |
| 180 | |
| 181 | /** |
| 182 | * A surface abstracts a place to draw. |
| 183 | */ |
| 184 | class Surface { |
| 185 | public: |
| 186 | Surface() noexcept = default; |
| 187 | Surface(const Surface &) = delete; |
| 188 | Surface(Surface &&) = delete; |
| 189 | Surface &operator=(const Surface &) = delete; |
| 190 | Surface &operator=(Surface &&) = delete; |
| 191 | virtual ~Surface() noexcept = default; |
| 192 | static std::unique_ptr<Surface> Allocate(Scintilla::Technology technology); |
| 193 | |
| 194 | virtual void Init(WindowID wid)=0; |
| 195 | virtual void Init(SurfaceID sid, WindowID wid)=0; |
| 196 | virtual std::unique_ptr<Surface> AllocatePixMap(int width, int height)=0; |
| 197 | |
| 198 | virtual void SetMode(SurfaceMode mode)=0; |
| 199 | |
| 200 | enum class Ends { |
| 201 | semiCircles = 0x0, |
| 202 | leftFlat = 0x1, |
| 203 | leftAngle = 0x2, |
| 204 | rightFlat = 0x10, |
| 205 | rightAngle = 0x20, |
| 206 | }; |
| 207 | |
| 208 | virtual void Release() noexcept=0; |
| 209 | virtual int SupportsFeature(Scintilla::Supports feature) noexcept=0; |
| 210 | virtual bool Initialised()=0; |
| 211 | virtual int LogPixelsY()=0; |
| 212 | virtual int PixelDivisions()=0; |
| 213 | virtual int DeviceHeightFont(int points)=0; |
| 214 | virtual void LineDraw(Point start, Point end, Stroke stroke)=0; |
| 215 | virtual void PolyLine(const Point *pts, size_t npts, Stroke stroke)=0; |
| 216 | virtual void Polygon(const Point *pts, size_t npts, FillStroke fillStroke)=0; |
| 217 | virtual void RectangleDraw(PRectangle rc, FillStroke fillStroke)=0; |
| 218 | virtual void RectangleFrame(PRectangle rc, Stroke stroke)=0; |
| 219 | virtual void FillRectangle(PRectangle rc, Fill fill)=0; |
| 220 | virtual void FillRectangleAligned(PRectangle rc, Fill fill)=0; |
| 221 | virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; |
| 222 | virtual void RoundedRectangle(PRectangle rc, FillStroke fillStroke)=0; |
| 223 | virtual void AlphaRectangle(PRectangle rc, XYPOSITION cornerSize, FillStroke fillStroke)=0; |
| 224 | enum class GradientOptions { leftToRight, topToBottom }; |
| 225 | virtual void GradientRectangle(PRectangle rc, const std::vector<ColourStop> &stops, GradientOptions options)=0; |
| 226 | virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0; |
| 227 | virtual void Ellipse(PRectangle rc, FillStroke fillStroke)=0; |
| 228 | virtual void Stadium(PRectangle rc, FillStroke fillStroke, Ends ends)=0; |
| 229 | virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; |
| 230 | |
| 231 | virtual std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) = 0; |
| 232 | |
| 233 | virtual void DrawTextNoClip(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) = 0; |
| 234 | virtual void DrawTextClipped(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) = 0; |
| 235 | virtual void DrawTextTransparent(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore) = 0; |
| 236 | virtual void MeasureWidths(const Font *font_, std::string_view text, XYPOSITION *positions) = 0; |
| 237 | virtual XYPOSITION WidthText(const Font *font_, std::string_view text) = 0; |
| 238 | |
| 239 | virtual void DrawTextNoClipUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) = 0; |
| 240 | virtual void DrawTextClippedUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore, ColourRGBA back) = 0; |
| 241 | virtual void DrawTextTransparentUTF8(PRectangle rc, const Font *font_, XYPOSITION ybase, std::string_view text, ColourRGBA fore) = 0; |
| 242 | virtual void MeasureWidthsUTF8(const Font *font_, std::string_view text, XYPOSITION *positions) = 0; |
| 243 | virtual XYPOSITION WidthTextUTF8(const Font *font_, std::string_view text) = 0; |
| 244 | |
| 245 | virtual XYPOSITION Ascent(const Font *font_)=0; |
| 246 | virtual XYPOSITION Descent(const Font *font_)=0; |
| 247 | virtual XYPOSITION InternalLeading(const Font *font_)=0; |
| 248 | virtual XYPOSITION Height(const Font *font_)=0; |
| 249 | virtual XYPOSITION AverageCharWidth(const Font *font_)=0; |
| 250 | |
| 251 | virtual void SetClip(PRectangle rc)=0; |
| 252 | virtual void PopClip()=0; |
| 253 | virtual void FlushCachedState()=0; |
| 254 | virtual void FlushDrawing()=0; |
| 255 | }; |
| 256 | |
| 257 | /** |
| 258 | * Class to hide the details of window manipulation. |
| 259 | * Does not own the window which will normally have a longer life than this object. |
| 260 | */ |
| 261 | class Window { |
| 262 | protected: |
| 263 | WindowID wid; |
| 264 | public: |
| 265 | Window() noexcept : wid(nullptr), cursorLast(Cursor::invalid) { |
| 266 | } |
| 267 | Window(const Window &source) = delete; |
| 268 | Window(Window &&) = delete; |
| 269 | Window &operator=(WindowID wid_) noexcept { |
| 270 | wid = wid_; |
| 271 | cursorLast = Cursor::invalid; |
| 272 | return *this; |
| 273 | } |
| 274 | Window &operator=(const Window &) = delete; |
| 275 | Window &operator=(Window &&) = delete; |
| 276 | virtual ~Window() noexcept; |
| 277 | WindowID GetID() const noexcept { return wid; } |
| 278 | bool Created() const noexcept { return wid != nullptr; } |
| 279 | void Destroy() noexcept; |
| 280 | PRectangle GetPosition() const; |
| 281 | void SetPosition(PRectangle rc); |
| 282 | void SetPositionRelative(PRectangle rc, const Window *relativeTo); |
| 283 | PRectangle GetClientPosition() const; |
| 284 | void Show(bool show=true); |
| 285 | void InvalidateAll(); |
| 286 | void InvalidateRectangle(PRectangle rc); |
| 287 | enum class Cursor { invalid, text, arrow, up, wait, horizontal, vertical, reverseArrow, hand }; |
| 288 | void SetCursor(Cursor curs); |
| 289 | PRectangle GetMonitorRect(Point pt); |
| 290 | private: |
| 291 | Cursor cursorLast; |
| 292 | }; |
| 293 | |
| 294 | /** |
| 295 | * Listbox management. |
| 296 | */ |
| 297 | |
| 298 | // ScintillaBase implements IListBoxDelegate to receive ListBoxEvents from a ListBox |
| 299 | |
| 300 | struct ListBoxEvent { |
| 301 | enum class EventType { selectionChange, doubleClick } event; |
| 302 | ListBoxEvent(EventType event_) noexcept : event(event_) { |
| 303 | } |
| 304 | }; |
| 305 | |
| 306 | class IListBoxDelegate { |
| 307 | public: |
| 308 | virtual void ListNotify(ListBoxEvent *plbe)=0; |
| 309 | }; |
| 310 | |
| 311 | struct ListOptions { |
| 312 | std::optional<ColourRGBA> fore; |
| 313 | std::optional<ColourRGBA> back; |
| 314 | std::optional<ColourRGBA> foreSelected; |
| 315 | std::optional<ColourRGBA> backSelected; |
| 316 | AutoCompleteOption options=AutoCompleteOption::Normal; |
| 317 | }; |
| 318 | |
| 319 | class ListBox : public Window { |
| 320 | public: |
| 321 | ListBox() noexcept; |
| 322 | virtual ~ListBox() noexcept override; |
| 323 | static std::unique_ptr<ListBox> Allocate(); |
| 324 | |
| 325 | virtual void SetFont(const Font *font)=0; |
| 326 | virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, Scintilla::Technology technology_)=0; |
| 327 | virtual void SetAverageCharWidth(int width)=0; |
| 328 | virtual void SetVisibleRows(int rows)=0; |
| 329 | virtual int GetVisibleRows() const=0; |
| 330 | virtual PRectangle GetDesiredRect()=0; |
| 331 | virtual int CaretFromEdge()=0; |
| 332 | virtual void Clear() noexcept=0; |
| 333 | virtual void Append(char *s, int type = -1)=0; |
| 334 | virtual int Length()=0; |
| 335 | virtual void Select(int n)=0; |
| 336 | virtual int GetSelection()=0; |
| 337 | virtual int Find(const char *prefix)=0; |
| 338 | virtual std::string GetValue(int n)=0; |
| 339 | virtual void RegisterImage(int type, const char *xpm_data)=0; |
| 340 | virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0; |
| 341 | virtual void ClearRegisteredImages()=0; |
| 342 | virtual void SetDelegate(IListBoxDelegate *lbDelegate)=0; |
| 343 | virtual void SetList(const char* list, char separator, char typesep)=0; |
| 344 | virtual void SetOptions(ListOptions options_)=0; |
| 345 | }; |
| 346 | |
| 347 | /** |
| 348 | * Menu management. |
| 349 | */ |
| 350 | class { |
| 351 | MenuID ; |
| 352 | public: |
| 353 | () noexcept; |
| 354 | MenuID () const noexcept { return mid; } |
| 355 | void (); |
| 356 | void () noexcept; |
| 357 | void (Point pt, const Window &w); |
| 358 | }; |
| 359 | |
| 360 | /** |
| 361 | * Platform namespace used to retrieve system wide parameters such as double click speed |
| 362 | * and chrome colour. |
| 363 | */ |
| 364 | namespace Platform { |
| 365 | |
| 366 | ColourRGBA Chrome(); |
| 367 | ColourRGBA ChromeHighlight(); |
| 368 | const char *DefaultFont(); |
| 369 | int DefaultFontSize(); |
| 370 | unsigned int DoubleClickTime(); |
| 371 | constexpr long LongFromTwoShorts(short a,short b) noexcept { |
| 372 | return (a) | ((b) << 16); |
| 373 | } |
| 374 | |
| 375 | } |
| 376 | |
| 377 | } |
| 378 | |
| 379 | #endif |
| 380 | |