xref: /MusicPlayer2/scintilla/include/Platform.h (revision 8af74909132ed5e696cb05b6689ae4baf14c1c96)
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 <[email protected]>
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_FOX 0
26 #define PLAT_CURSES 0
27 #define PLAT_TK 0
28 #define PLAT_HAIKU 0
29 
30 #if defined(FOX)
31 #undef PLAT_FOX
32 #define PLAT_FOX 1
33 
34 #elif defined(__WX__)
35 #undef PLAT_WX
36 #define PLAT_WX  1
37 
38 #elif defined(CURSES)
39 #undef PLAT_CURSES
40 #define PLAT_CURSES 1
41 
42 #elif defined(__HAIKU__)
43 #undef PLAT_HAIKU
44 #define PLAT_HAIKU 1
45 
46 #elif defined(SCINTILLA_QT)
47 #undef PLAT_QT
48 #define PLAT_QT 1
49 
50 #elif defined(TK)
51 #undef PLAT_TK
52 #define PLAT_TK 1
53 
54 #elif defined(GTK)
55 #undef PLAT_GTK
56 #define PLAT_GTK 1
57 
58 #if defined(__WIN32__) || defined(_MSC_VER)
59 #undef PLAT_GTK_WIN32
60 #define PLAT_GTK_WIN32 1
61 #endif
62 
63 #if defined(__APPLE__)
64 #undef PLAT_GTK_MACOSX
65 #define PLAT_GTK_MACOSX 1
66 #endif
67 
68 #elif defined(__APPLE__)
69 
70 #undef PLAT_MACOSX
71 #define PLAT_MACOSX 1
72 
73 #else
74 #undef PLAT_WIN
75 #define PLAT_WIN 1
76 
77 #endif
78 
79 namespace Scintilla {
80 
81 typedef float XYPOSITION;
82 typedef double XYACCUMULATOR;
83 
84 // Underlying the implementation of the platform classes are platform specific types.
85 // Sometimes these need to be passed around by client code so they are defined here
86 
87 typedef void *FontID;
88 typedef void *SurfaceID;
89 typedef void *WindowID;
90 typedef void *MenuID;
91 typedef void *TickerID;
92 typedef void *Function;
93 typedef void *IdlerID;
94 
95 /**
96  * A geometric point class.
97  * Point is similar to the Win32 POINT and GTK+ GdkPoint types.
98  */
99 class Point {
100 public:
101 	XYPOSITION x;
102 	XYPOSITION y;
103 
x(x_)104 	constexpr explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) noexcept : x(x_), y(y_) {
105 	}
106 
FromInts(int x_,int y_)107 	static constexpr Point FromInts(int x_, int y_) noexcept {
108 		return Point(static_cast<XYPOSITION>(x_), static_cast<XYPOSITION>(y_));
109 	}
110 
111 	constexpr bool operator!=(Point other) const noexcept {
112 		return (x != other.x) || (y != other.y);
113 	}
114 
115 	constexpr Point operator+(Point other) const noexcept {
116 		return Point(x + other.x, y + other.y);
117 	}
118 
119 	constexpr Point operator-(Point other) const noexcept {
120 		return Point(x - other.x, y - other.y);
121 	}
122 
123 	// Other automatically defined methods (assignment, copy constructor, destructor) are fine
124 };
125 
126 /**
127  * A geometric rectangle class.
128  * PRectangle is similar to Win32 RECT.
129  * PRectangles contain their top and left sides, but not their right and bottom sides.
130  */
131 class PRectangle {
132 public:
133 	XYPOSITION left;
134 	XYPOSITION top;
135 	XYPOSITION right;
136 	XYPOSITION bottom;
137 
138 	constexpr explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) noexcept :
left(left_)139 		left(left_), top(top_), right(right_), bottom(bottom_) {
140 	}
141 
FromInts(int left_,int top_,int right_,int bottom_)142 	static constexpr PRectangle FromInts(int left_, int top_, int right_, int bottom_) noexcept {
143 		return PRectangle(static_cast<XYPOSITION>(left_), static_cast<XYPOSITION>(top_),
144 			static_cast<XYPOSITION>(right_), static_cast<XYPOSITION>(bottom_));
145 	}
146 
147 	// Other automatically defined methods (assignment, copy constructor, destructor) are fine
148 
149 	constexpr bool operator==(const PRectangle &rc) const noexcept {
150 		return (rc.left == left) && (rc.right == right) &&
151 			(rc.top == top) && (rc.bottom == bottom);
152 	}
Contains(Point pt)153 	constexpr bool Contains(Point pt) const noexcept {
154 		return (pt.x >= left) && (pt.x <= right) &&
155 			(pt.y >= top) && (pt.y <= bottom);
156 	}
ContainsWholePixel(Point pt)157 	constexpr bool ContainsWholePixel(Point pt) const noexcept {
158 		// Does the rectangle contain all of the pixel to left/below the point
159 		return (pt.x >= left) && ((pt.x+1) <= right) &&
160 			(pt.y >= top) && ((pt.y+1) <= bottom);
161 	}
Contains(PRectangle rc)162 	constexpr bool Contains(PRectangle rc) const noexcept {
163 		return (rc.left >= left) && (rc.right <= right) &&
164 			(rc.top >= top) && (rc.bottom <= bottom);
165 	}
Intersects(PRectangle other)166 	constexpr bool Intersects(PRectangle other) const noexcept {
167 		return (right > other.left) && (left < other.right) &&
168 			(bottom > other.top) && (top < other.bottom);
169 	}
Move(XYPOSITION xDelta,XYPOSITION yDelta)170 	void Move(XYPOSITION xDelta, XYPOSITION yDelta) noexcept {
171 		left += xDelta;
172 		top += yDelta;
173 		right += xDelta;
174 		bottom += yDelta;
175 	}
Width()176 	constexpr XYPOSITION Width() const noexcept { return right - left; }
Height()177 	constexpr XYPOSITION Height() const noexcept { return bottom - top; }
Empty()178 	constexpr bool Empty() const noexcept {
179 		return (Height() <= 0) || (Width() <= 0);
180 	}
181 };
182 
183 /**
184  * Holds an RGB colour with 8 bits for each component.
185  */
186 constexpr const float componentMaximum = 255.0f;
187 class ColourDesired {
188 	int co;
189 public:
co(co_)190 	constexpr explicit ColourDesired(int co_=0) noexcept : co(co_) {
191 	}
192 
ColourDesired(unsigned int red,unsigned int green,unsigned int blue)193 	constexpr ColourDesired(unsigned int red, unsigned int green, unsigned int blue) noexcept :
194 		co(red | (green << 8) | (blue << 16)) {
195 	}
196 
197 	constexpr bool operator==(const ColourDesired &other) const noexcept {
198 		return co == other.co;
199 	}
200 
AsInteger()201 	constexpr int AsInteger() const noexcept {
202 		return co;
203 	}
204 
205 	// Red, green and blue values as bytes 0..255
GetRed()206 	constexpr unsigned char GetRed() const noexcept {
207 		return co & 0xff;
208 	}
GetGreen()209 	constexpr unsigned char GetGreen() const noexcept {
210 		return (co >> 8) & 0xff;
211 	}
GetBlue()212 	constexpr unsigned char GetBlue() const noexcept {
213 		return (co >> 16) & 0xff;
214 	}
215 
216 	// Red, green and blue values as float 0..1.0
GetRedComponent()217 	constexpr float GetRedComponent() const noexcept {
218 		return GetRed() / componentMaximum;
219 	}
GetGreenComponent()220 	constexpr float GetGreenComponent() const noexcept {
221 		return GetGreen() / componentMaximum;
222 	}
GetBlueComponent()223 	constexpr float GetBlueComponent() const noexcept {
224 		return GetBlue() / componentMaximum;
225 	}
226 };
227 
228 /**
229 * Holds an RGBA colour.
230 */
231 class ColourAlpha : public ColourDesired {
232 public:
ColourDesired(co_)233 	constexpr explicit ColourAlpha(int co_ = 0) noexcept : ColourDesired(co_) {
234 	}
235 
ColourAlpha(unsigned int red,unsigned int green,unsigned int blue)236 	constexpr ColourAlpha(unsigned int red, unsigned int green, unsigned int blue) noexcept :
237 		ColourDesired(red | (green << 8) | (blue << 16)) {
238 	}
239 
ColourAlpha(unsigned int red,unsigned int green,unsigned int blue,unsigned int alpha)240 	constexpr ColourAlpha(unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha) noexcept :
241 		ColourDesired(red | (green << 8) | (blue << 16) | (alpha << 24)) {
242 	}
243 
ColourAlpha(ColourDesired cd,unsigned int alpha)244 	constexpr ColourAlpha(ColourDesired cd, unsigned int alpha) noexcept :
245 		ColourDesired(cd.AsInteger() | (alpha << 24)) {
246 	}
247 
GetColour()248 	constexpr ColourDesired GetColour() const noexcept {
249 		return ColourDesired(AsInteger() & 0xffffff);
250 	}
251 
GetAlpha()252 	constexpr unsigned char GetAlpha() const noexcept {
253 		return (AsInteger() >> 24) & 0xff;
254 	}
255 
GetAlphaComponent()256 	constexpr float GetAlphaComponent() const noexcept {
257 		return GetAlpha() / componentMaximum;
258 	}
259 
MixedWith(ColourAlpha other)260 	constexpr ColourAlpha MixedWith(ColourAlpha other) const noexcept {
261 		const unsigned int red = (GetRed() + other.GetRed()) / 2;
262 		const unsigned int green = (GetGreen() + other.GetGreen()) / 2;
263 		const unsigned int blue = (GetBlue() + other.GetBlue()) / 2;
264 		const unsigned int alpha = (GetAlpha() + other.GetAlpha()) / 2;
265 		return ColourAlpha(red, green, blue, alpha);
266 	}
267 };
268 
269 /**
270 * Holds an element of a gradient with an RGBA colour and a relative position.
271 */
272 class ColourStop {
273 public:
274 	float position;
275 	ColourAlpha colour;
ColourStop(float position_,ColourAlpha colour_)276 	ColourStop(float position_, ColourAlpha colour_) noexcept :
277 		position(position_), colour(colour_) {
278 	}
279 };
280 
281 /**
282  * Font management.
283  */
284 
285 struct FontParameters {
286 	const char *faceName;
287 	float size;
288 	int weight;
289 	bool italic;
290 	int extraFontFlag;
291 	int technology;
292 	int characterSet;
293 
294 	FontParameters(
295 		const char *faceName_,
296 		float size_=10,
297 		int weight_=400,
298 		bool italic_=false,
299 		int extraFontFlag_=0,
300 		int technology_=0,
301 		int characterSet_=0) noexcept :
302 
faceNameFontParameters303 		faceName(faceName_),
304 		size(size_),
305 		weight(weight_),
306 		italic(italic_),
307 		extraFontFlag(extraFontFlag_),
308 		technology(technology_),
309 		characterSet(characterSet_)
310 	{
311 	}
312 
313 };
314 
315 class Font {
316 protected:
317 	FontID fid;
318 public:
319 	Font() noexcept;
320 	// Deleted so Font objects can not be copied
321 	Font(const Font &) = delete;
322 	Font(Font &&) = delete;
323 	Font &operator=(const Font &) = delete;
324 	Font &operator=(Font &&) = delete;
325 	virtual ~Font();
326 
327 	virtual void Create(const FontParameters &fp);
328 	virtual void Release();
329 
GetID()330 	FontID GetID() const noexcept { return fid; }
331 	// Alias another font - caller guarantees not to Release
SetID(FontID fid_)332 	void SetID(FontID fid_) noexcept { fid = fid_; }
333 	friend class Surface;
334 	friend class SurfaceImpl;
335 };
336 
337 class IScreenLine {
338 public:
339 	virtual std::string_view Text() const = 0;
340 	virtual size_t Length() const = 0;
341 	virtual size_t RepresentationCount() const = 0;
342 	virtual XYPOSITION Width() const = 0;
343 	virtual XYPOSITION Height() const = 0;
344 	virtual XYPOSITION TabWidth() const = 0;
345 	virtual XYPOSITION TabWidthMinimumPixels() const = 0;
346 	virtual const Font *FontOfPosition(size_t position) const = 0;
347 	virtual XYPOSITION RepresentationWidth(size_t position) const = 0;
348 	virtual XYPOSITION TabPositionAfter(XYPOSITION xPosition) const = 0;
349 };
350 
351 struct Interval {
352 	XYPOSITION left;
353 	XYPOSITION right;
354 };
355 
356 class IScreenLineLayout {
357 public:
358 	virtual ~IScreenLineLayout() = default;
359 	virtual size_t PositionFromX(XYPOSITION xDistance, bool charPosition) = 0;
360 	virtual XYPOSITION XFromPosition(size_t caretPosition) = 0;
361 	virtual std::vector<Interval> FindRangeIntervals(size_t start, size_t end) = 0;
362 };
363 
364 /**
365  * A surface abstracts a place to draw.
366  */
367 class Surface {
368 public:
369 	Surface() noexcept = default;
370 	Surface(const Surface &) = delete;
371 	Surface(Surface &&) = delete;
372 	Surface &operator=(const Surface &) = delete;
373 	Surface &operator=(Surface &&) = delete;
~Surface()374 	virtual ~Surface() {}
375 	static Surface *Allocate(int technology);
376 
377 	virtual void Init(WindowID wid)=0;
378 	virtual void Init(SurfaceID sid, WindowID wid)=0;
379 	virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0;
380 
381 	virtual void Release()=0;
382 	virtual bool Initialised()=0;
383 	virtual void PenColour(ColourDesired fore)=0;
384 	virtual int LogPixelsY()=0;
385 	virtual int DeviceHeightFont(int points)=0;
386 	virtual void MoveTo(int x_, int y_)=0;
387 	virtual void LineTo(int x_, int y_)=0;
388 	virtual void Polygon(Point *pts, size_t npts, ColourDesired fore, ColourDesired back)=0;
389 	virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
390 	virtual void FillRectangle(PRectangle rc, ColourDesired back)=0;
391 	virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0;
392 	virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
393 	virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill,
394 		ColourDesired outline, int alphaOutline, int flags)=0;
395 	enum class GradientOptions { leftToRight, topToBottom };
396 	virtual void GradientRectangle(PRectangle rc, const std::vector<ColourStop> &stops, GradientOptions options)=0;
397 	virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0;
398 	virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
399 	virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
400 
401 	virtual std::unique_ptr<IScreenLineLayout> Layout(const IScreenLine *screenLine) = 0;
402 
403 	virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) = 0;
404 	virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore, ColourDesired back) = 0;
405 	virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, std::string_view text, ColourDesired fore) = 0;
406 	virtual void MeasureWidths(Font &font_, std::string_view text, XYPOSITION *positions) = 0;
407 	virtual XYPOSITION WidthText(Font &font_, std::string_view text) = 0;
408 	virtual XYPOSITION Ascent(Font &font_)=0;
409 	virtual XYPOSITION Descent(Font &font_)=0;
410 	virtual XYPOSITION InternalLeading(Font &font_)=0;
411 	virtual XYPOSITION Height(Font &font_)=0;
412 	virtual XYPOSITION AverageCharWidth(Font &font_)=0;
413 
414 	virtual void SetClip(PRectangle rc)=0;
415 	virtual void FlushCachedState()=0;
416 
417 	virtual void SetUnicodeMode(bool unicodeMode_)=0;
418 	virtual void SetDBCSMode(int codePage)=0;
419 	virtual void SetBidiR2L(bool bidiR2L_)=0;
420 };
421 
422 /**
423  * Class to hide the details of window manipulation.
424  * Does not own the window which will normally have a longer life than this object.
425  */
426 class Window {
427 protected:
428 	WindowID wid;
429 public:
Window()430 	Window() noexcept : wid(nullptr), cursorLast(cursorInvalid) {
431 	}
432 	Window(const Window &source) = delete;
433 	Window(Window &&) = delete;
434 	Window &operator=(WindowID wid_) noexcept {
435 		wid = wid_;
436 		cursorLast = cursorInvalid;
437 		return *this;
438 	}
439 	Window &operator=(const Window &) = delete;
440 	Window &operator=(Window &&) = delete;
441 	virtual ~Window();
GetID()442 	WindowID GetID() const noexcept { return wid; }
Created()443 	bool Created() const noexcept { return wid != nullptr; }
444 	void Destroy();
445 	PRectangle GetPosition() const;
446 	void SetPosition(PRectangle rc);
447 	void SetPositionRelative(PRectangle rc, const Window *relativeTo);
448 	PRectangle GetClientPosition() const;
449 	void Show(bool show=true);
450 	void InvalidateAll();
451 	void InvalidateRectangle(PRectangle rc);
452 	virtual void SetFont(Font &font);
453 	enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand };
454 	void SetCursor(Cursor curs);
455 	PRectangle GetMonitorRect(Point pt);
456 private:
457 	Cursor cursorLast;
458 };
459 
460 /**
461  * Listbox management.
462  */
463 
464 // ScintillaBase implements IListBoxDelegate to receive ListBoxEvents from a ListBox
465 
466 struct ListBoxEvent {
467 	enum class EventType { selectionChange, doubleClick } event;
ListBoxEventListBoxEvent468 	ListBoxEvent(EventType event_) noexcept : event(event_) {
469 	}
470 };
471 
472 class IListBoxDelegate {
473 public:
474 	virtual void ListNotify(ListBoxEvent *plbe)=0;
475 };
476 
477 class ListBox : public Window {
478 public:
479 	ListBox() noexcept;
480 	~ListBox() override;
481 	static ListBox *Allocate();
482 
483 	void SetFont(Font &font) override =0;
484 	virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, int technology_)=0;
485 	virtual void SetAverageCharWidth(int width)=0;
486 	virtual void SetVisibleRows(int rows)=0;
487 	virtual int GetVisibleRows() const=0;
488 	virtual PRectangle GetDesiredRect()=0;
489 	virtual int CaretFromEdge()=0;
490 	virtual void Clear()=0;
491 	virtual void Append(char *s, int type = -1)=0;
492 	virtual int Length()=0;
493 	virtual void Select(int n)=0;
494 	virtual int GetSelection()=0;
495 	virtual int Find(const char *prefix)=0;
496 	virtual void GetValue(int n, char *value, int len)=0;
497 	virtual void RegisterImage(int type, const char *xpm_data)=0;
498 	virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0;
499 	virtual void ClearRegisteredImages()=0;
500 	virtual void SetDelegate(IListBoxDelegate *lbDelegate)=0;
501 	virtual void SetList(const char* list, char separator, char typesep)=0;
502 };
503 
504 /**
505  * Menu management.
506  */
507 class Menu {
508 	MenuID mid;
509 public:
510 	Menu() noexcept;
GetID()511 	MenuID GetID() const noexcept { return mid; }
512 	void CreatePopUp();
513 	void Destroy();
514 	void Show(Point pt, Window &w);
515 };
516 
517 /**
518  * Dynamic Library (DLL/SO/...) loading
519  */
520 class DynamicLibrary {
521 public:
522 	virtual ~DynamicLibrary() = default;
523 
524 	/// @return Pointer to function "name", or NULL on failure.
525 	virtual Function FindFunction(const char *name) = 0;
526 
527 	/// @return true if the library was loaded successfully.
528 	virtual bool IsValid() = 0;
529 
530 	/// @return An instance of a DynamicLibrary subclass with "modulePath" loaded.
531 	static DynamicLibrary *Load(const char *modulePath);
532 };
533 
534 #if defined(__clang__)
535 # if __has_feature(attribute_analyzer_noreturn)
536 #  define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
537 # else
538 #  define CLANG_ANALYZER_NORETURN
539 # endif
540 #else
541 # define CLANG_ANALYZER_NORETURN
542 #endif
543 
544 /**
545  * Platform class used to retrieve system wide parameters such as double click speed
546  * and chrome colour. Not a creatable object, more of a module with several functions.
547  */
548 class Platform {
549 public:
550 	Platform() = default;
551 	Platform(const Platform &) = delete;
552 	Platform(Platform &&) = delete;
553 	Platform &operator=(const Platform &) = delete;
554 	Platform &operator=(Platform &&) = delete;
555 	~Platform() = default;
556 	static ColourDesired Chrome();
557 	static ColourDesired ChromeHighlight();
558 	static const char *DefaultFont();
559 	static int DefaultFontSize();
560 	static unsigned int DoubleClickTime();
561 	static void DebugDisplay(const char *s);
LongFromTwoShorts(short a,short b)562 	static constexpr long LongFromTwoShorts(short a,short b) noexcept {
563 		return (a) | ((b) << 16);
564 	}
565 
566 	static void DebugPrintf(const char *format, ...);
567 	static bool ShowAssertionPopUps(bool assertionPopUps_);
568 	static void Assert(const char *c, const char *file, int line) CLANG_ANALYZER_NORETURN;
569 };
570 
571 #ifdef  NDEBUG
572 #define PLATFORM_ASSERT(c) ((void)0)
573 #else
574 #define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__))
575 #endif
576 
577 }
578 
579 #endif
580