Platform.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  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. #ifndef PLATFORM_H
  9. #define PLATFORM_H
  10. // PLAT_GTK = GTK+ on Linux or Win32
  11. // PLAT_GTK_WIN32 is defined additionally when running PLAT_GTK under Win32
  12. // PLAT_WIN = Win32 API on Win32 OS
  13. // PLAT_WX is wxWindows on any supported platform
  14. // PLAT_TK = Tcl/TK on Linux or Win32
  15. #define PLAT_GTK 0
  16. #define PLAT_GTK_WIN32 0
  17. #define PLAT_GTK_MACOSX 0
  18. #define PLAT_MACOSX 0
  19. #define PLAT_WIN 0
  20. #define PLAT_WX 0
  21. #define PLAT_QT 0
  22. #define PLAT_FOX 0
  23. #define PLAT_CURSES 0
  24. #define PLAT_TK 0
  25. #if defined(FOX)
  26. #undef PLAT_FOX
  27. #define PLAT_FOX 1
  28. #elif defined(__WX__)
  29. #undef PLAT_WX
  30. #define PLAT_WX 1
  31. #elif defined(CURSES)
  32. #undef PLAT_CURSES
  33. #define PLAT_CURSES 1
  34. #elif defined(SCINTILLA_QT)
  35. #undef PLAT_QT
  36. #define PLAT_QT 1
  37. #include <Qsci/qsciglobal.h>
  38. QT_BEGIN_NAMESPACE
  39. class QPainter;
  40. QT_END_NAMESPACE
  41. // This is needed to work around an HP-UX bug with Qt4.
  42. #include <qnamespace.h>
  43. #elif defined(TK)
  44. #undef PLAT_TK
  45. #define PLAT_TK 1
  46. #elif defined(GTK)
  47. #undef PLAT_GTK
  48. #define PLAT_GTK 1
  49. #if defined(__WIN32__) || defined(_MSC_VER)
  50. #undef PLAT_GTK_WIN32
  51. #define PLAT_GTK_WIN32 1
  52. #endif
  53. #if defined(__APPLE__)
  54. #undef PLAT_GTK_MACOSX
  55. #define PLAT_GTK_MACOSX 1
  56. #endif
  57. #elif defined(__APPLE__)
  58. #undef PLAT_MACOSX
  59. #define PLAT_MACOSX 1
  60. #else
  61. #undef PLAT_WIN
  62. #define PLAT_WIN 1
  63. #endif
  64. #ifdef SCI_NAMESPACE
  65. namespace Scintilla {
  66. #endif
  67. typedef float XYPOSITION;
  68. typedef double XYACCUMULATOR;
  69. inline int RoundXYPosition(XYPOSITION xyPos) {
  70. return int(xyPos + 0.5);
  71. }
  72. // Underlying the implementation of the platform classes are platform specific types.
  73. // Sometimes these need to be passed around by client code so they are defined here
  74. typedef void *FontID;
  75. typedef void *SurfaceID;
  76. typedef void *WindowID;
  77. typedef void *MenuID;
  78. typedef void *TickerID;
  79. typedef void *Function;
  80. typedef void *IdlerID;
  81. /**
  82. * A geometric point class.
  83. * Point is similar to the Win32 POINT and GTK+ GdkPoint types.
  84. */
  85. class Point {
  86. public:
  87. XYPOSITION x;
  88. XYPOSITION y;
  89. explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) : x(x_), y(y_) {
  90. }
  91. static Point FromInts(int x_, int y_) {
  92. return Point(static_cast<XYPOSITION>(x_), static_cast<XYPOSITION>(y_));
  93. }
  94. // Other automatically defined methods (assignment, copy constructor, destructor) are fine
  95. static Point FromLong(long lpoint);
  96. };
  97. /**
  98. * A geometric rectangle class.
  99. * PRectangle is similar to the Win32 RECT.
  100. * PRectangles contain their top and left sides, but not their right and bottom sides.
  101. */
  102. class PRectangle {
  103. public:
  104. XYPOSITION left;
  105. XYPOSITION top;
  106. XYPOSITION right;
  107. XYPOSITION bottom;
  108. explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) :
  109. left(left_), top(top_), right(right_), bottom(bottom_) {
  110. }
  111. static PRectangle FromInts(int left_, int top_, int right_, int bottom_) {
  112. return PRectangle(static_cast<XYPOSITION>(left_), static_cast<XYPOSITION>(top_),
  113. static_cast<XYPOSITION>(right_), static_cast<XYPOSITION>(bottom_));
  114. }
  115. // Other automatically defined methods (assignment, copy constructor, destructor) are fine
  116. bool operator==(PRectangle &rc) const {
  117. return (rc.left == left) && (rc.right == right) &&
  118. (rc.top == top) && (rc.bottom == bottom);
  119. }
  120. bool Contains(Point pt) const {
  121. return (pt.x >= left) && (pt.x <= right) &&
  122. (pt.y >= top) && (pt.y <= bottom);
  123. }
  124. bool ContainsWholePixel(Point pt) const {
  125. // Does the rectangle contain all of the pixel to left/below the point
  126. return (pt.x >= left) && ((pt.x+1) <= right) &&
  127. (pt.y >= top) && ((pt.y+1) <= bottom);
  128. }
  129. bool Contains(PRectangle rc) const {
  130. return (rc.left >= left) && (rc.right <= right) &&
  131. (rc.top >= top) && (rc.bottom <= bottom);
  132. }
  133. bool Intersects(PRectangle other) const {
  134. return (right > other.left) && (left < other.right) &&
  135. (bottom > other.top) && (top < other.bottom);
  136. }
  137. void Move(XYPOSITION xDelta, XYPOSITION yDelta) {
  138. left += xDelta;
  139. top += yDelta;
  140. right += xDelta;
  141. bottom += yDelta;
  142. }
  143. XYPOSITION Width() const { return right - left; }
  144. XYPOSITION Height() const { return bottom - top; }
  145. bool Empty() const {
  146. return (Height() <= 0) || (Width() <= 0);
  147. }
  148. };
  149. /**
  150. * Holds a desired RGB colour.
  151. */
  152. class ColourDesired {
  153. long co;
  154. public:
  155. ColourDesired(long lcol=0) {
  156. co = lcol;
  157. }
  158. ColourDesired(unsigned int red, unsigned int green, unsigned int blue) {
  159. Set(red, green, blue);
  160. }
  161. bool operator==(const ColourDesired &other) const {
  162. return co == other.co;
  163. }
  164. void Set(long lcol) {
  165. co = lcol;
  166. }
  167. void Set(unsigned int red, unsigned int green, unsigned int blue) {
  168. co = red | (green << 8) | (blue << 16);
  169. }
  170. static inline unsigned int ValueOfHex(const char ch) {
  171. if (ch >= '0' && ch <= '9')
  172. return ch - '0';
  173. else if (ch >= 'A' && ch <= 'F')
  174. return ch - 'A' + 10;
  175. else if (ch >= 'a' && ch <= 'f')
  176. return ch - 'a' + 10;
  177. else
  178. return 0;
  179. }
  180. void Set(const char *val) {
  181. if (*val == '#') {
  182. val++;
  183. }
  184. unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]);
  185. unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]);
  186. unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]);
  187. Set(r, g, b);
  188. }
  189. long AsLong() const {
  190. return co;
  191. }
  192. unsigned int GetRed() const {
  193. return co & 0xff;
  194. }
  195. unsigned int GetGreen() const {
  196. return (co >> 8) & 0xff;
  197. }
  198. unsigned int GetBlue() const {
  199. return (co >> 16) & 0xff;
  200. }
  201. };
  202. /**
  203. * Font management.
  204. */
  205. struct FontParameters {
  206. const char *faceName;
  207. float size;
  208. int weight;
  209. bool italic;
  210. int extraFontFlag;
  211. int technology;
  212. int characterSet;
  213. FontParameters(
  214. const char *faceName_,
  215. float size_=10,
  216. int weight_=400,
  217. bool italic_=false,
  218. int extraFontFlag_=0,
  219. int technology_=0,
  220. int characterSet_=0) :
  221. faceName(faceName_),
  222. size(size_),
  223. weight(weight_),
  224. italic(italic_),
  225. extraFontFlag(extraFontFlag_),
  226. technology(technology_),
  227. characterSet(characterSet_)
  228. {
  229. }
  230. };
  231. class Font {
  232. protected:
  233. FontID fid;
  234. // Private so Font objects can not be copied
  235. Font(const Font &);
  236. Font &operator=(const Font &);
  237. public:
  238. Font();
  239. virtual ~Font();
  240. virtual void Create(const FontParameters &fp);
  241. virtual void Release();
  242. FontID GetID() { return fid; }
  243. // Alias another font - caller guarantees not to Release
  244. void SetID(FontID fid_) { fid = fid_; }
  245. friend class Surface;
  246. friend class SurfaceImpl;
  247. };
  248. /**
  249. * A surface abstracts a place to draw.
  250. */
  251. #if defined(PLAT_QT)
  252. class XPM;
  253. #endif
  254. class Surface {
  255. private:
  256. // Private so Surface objects can not be copied
  257. Surface(const Surface &) {}
  258. Surface &operator=(const Surface &) { return *this; }
  259. public:
  260. Surface() {}
  261. virtual ~Surface() {}
  262. static Surface *Allocate(int technology);
  263. virtual void Init(WindowID wid)=0;
  264. virtual void Init(SurfaceID sid, WindowID wid)=0;
  265. virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0;
  266. virtual void Release()=0;
  267. virtual bool Initialised()=0;
  268. virtual void PenColour(ColourDesired fore)=0;
  269. virtual int LogPixelsY()=0;
  270. virtual int DeviceHeightFont(int points)=0;
  271. virtual void MoveTo(int x_, int y_)=0;
  272. virtual void LineTo(int x_, int y_)=0;
  273. virtual void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back)=0;
  274. virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
  275. virtual void FillRectangle(PRectangle rc, ColourDesired back)=0;
  276. virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0;
  277. virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
  278. virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill,
  279. ColourDesired outline, int alphaOutline, int flags)=0;
  280. virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0;
  281. virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
  282. virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
  283. virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0;
  284. virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0;
  285. virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore)=0;
  286. virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions)=0;
  287. virtual XYPOSITION WidthText(Font &font_, const char *s, int len)=0;
  288. virtual XYPOSITION WidthChar(Font &font_, char ch)=0;
  289. virtual XYPOSITION Ascent(Font &font_)=0;
  290. virtual XYPOSITION Descent(Font &font_)=0;
  291. virtual XYPOSITION InternalLeading(Font &font_)=0;
  292. virtual XYPOSITION ExternalLeading(Font &font_)=0;
  293. virtual XYPOSITION Height(Font &font_)=0;
  294. virtual XYPOSITION AverageCharWidth(Font &font_)=0;
  295. virtual void SetClip(PRectangle rc)=0;
  296. virtual void FlushCachedState()=0;
  297. virtual void SetUnicodeMode(bool unicodeMode_)=0;
  298. virtual void SetDBCSMode(int codePage)=0;
  299. #if defined(PLAT_QT)
  300. virtual void Init(QPainter *p)=0;
  301. virtual void DrawXPM(PRectangle rc, const XPM *xpm)=0;
  302. #endif
  303. };
  304. /**
  305. * A simple callback action passing one piece of untyped user data.
  306. */
  307. typedef void (*CallBackAction)(void*);
  308. /**
  309. * Class to hide the details of window manipulation.
  310. * Does not own the window which will normally have a longer life than this object.
  311. */
  312. class Window {
  313. protected:
  314. WindowID wid;
  315. public:
  316. Window() : wid(0), cursorLast(cursorInvalid) {
  317. }
  318. Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) {
  319. }
  320. virtual ~Window();
  321. Window &operator=(WindowID wid_) {
  322. wid = wid_;
  323. return *this;
  324. }
  325. WindowID GetID() const { return wid; }
  326. bool Created() const { return wid != 0; }
  327. void Destroy();
  328. bool HasFocus();
  329. PRectangle GetPosition();
  330. void SetPosition(PRectangle rc);
  331. void SetPositionRelative(PRectangle rc, Window relativeTo);
  332. PRectangle GetClientPosition();
  333. void Show(bool show=true);
  334. void InvalidateAll();
  335. void InvalidateRectangle(PRectangle rc);
  336. virtual void SetFont(Font &font);
  337. enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand };
  338. void SetCursor(Cursor curs);
  339. void SetTitle(const char *s);
  340. PRectangle GetMonitorRect(Point pt);
  341. private:
  342. Cursor cursorLast;
  343. };
  344. /**
  345. * Listbox management.
  346. */
  347. class ListBox : public Window {
  348. public:
  349. ListBox();
  350. virtual ~ListBox();
  351. static ListBox *Allocate();
  352. virtual void SetFont(Font &font)=0;
  353. virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, int technology_)=0;
  354. virtual void SetAverageCharWidth(int width)=0;
  355. virtual void SetVisibleRows(int rows)=0;
  356. virtual int GetVisibleRows() const=0;
  357. virtual PRectangle GetDesiredRect()=0;
  358. virtual int CaretFromEdge()=0;
  359. virtual void Clear()=0;
  360. virtual void Append(char *s, int type = -1)=0;
  361. virtual int Length()=0;
  362. virtual void Select(int n)=0;
  363. virtual int GetSelection()=0;
  364. virtual int Find(const char *prefix)=0;
  365. virtual void GetValue(int n, char *value, int len)=0;
  366. virtual void RegisterImage(int type, const char *xpm_data)=0;
  367. virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0;
  368. virtual void ClearRegisteredImages()=0;
  369. virtual void SetDoubleClickAction(CallBackAction, void *)=0;
  370. virtual void SetList(const char* list, char separator, char typesep)=0;
  371. };
  372. /**
  373. * Menu management.
  374. */
  375. class Menu {
  376. MenuID mid;
  377. public:
  378. Menu();
  379. MenuID GetID() { return mid; }
  380. void CreatePopUp();
  381. void Destroy();
  382. void Show(Point pt, Window &w);
  383. };
  384. class ElapsedTime {
  385. long bigBit;
  386. long littleBit;
  387. public:
  388. ElapsedTime();
  389. double Duration(bool reset=false);
  390. };
  391. /**
  392. * Dynamic Library (DLL/SO/...) loading
  393. */
  394. class DynamicLibrary {
  395. public:
  396. virtual ~DynamicLibrary() {}
  397. /// @return Pointer to function "name", or NULL on failure.
  398. virtual Function FindFunction(const char *name) = 0;
  399. /// @return true if the library was loaded successfully.
  400. virtual bool IsValid() = 0;
  401. /// @return An instance of a DynamicLibrary subclass with "modulePath" loaded.
  402. static DynamicLibrary *Load(const char *modulePath);
  403. };
  404. #if defined(__clang__)
  405. # if __has_feature(attribute_analyzer_noreturn)
  406. # define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
  407. # else
  408. # define CLANG_ANALYZER_NORETURN
  409. # endif
  410. #else
  411. # define CLANG_ANALYZER_NORETURN
  412. #endif
  413. /**
  414. * Platform class used to retrieve system wide parameters such as double click speed
  415. * and chrome colour. Not a creatable object, more of a module with several functions.
  416. */
  417. class Platform {
  418. // Private so Platform objects can not be copied
  419. Platform(const Platform &) {}
  420. Platform &operator=(const Platform &) { return *this; }
  421. public:
  422. // Should be private because no new Platforms are ever created
  423. // but gcc warns about this
  424. Platform() {}
  425. ~Platform() {}
  426. static ColourDesired Chrome();
  427. static ColourDesired ChromeHighlight();
  428. static const char *DefaultFont();
  429. static int DefaultFontSize();
  430. static unsigned int DoubleClickTime();
  431. static bool MouseButtonBounce();
  432. static void DebugDisplay(const char *s);
  433. static bool IsKeyDown(int key);
  434. static long SendScintilla(
  435. WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0);
  436. static long SendScintillaPointer(
  437. WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0);
  438. static bool IsDBCSLeadByte(int codePage, char ch);
  439. static int DBCSCharLength(int codePage, const char *s);
  440. static int DBCSCharMaxLength();
  441. // These are utility functions not really tied to a platform
  442. static int Minimum(int a, int b);
  443. static int Maximum(int a, int b);
  444. // Next three assume 16 bit shorts and 32 bit longs
  445. static long LongFromTwoShorts(short a,short b) {
  446. return (a) | ((b) << 16);
  447. }
  448. static short HighShortFromLong(long x) {
  449. return static_cast<short>(x >> 16);
  450. }
  451. static short LowShortFromLong(long x) {
  452. return static_cast<short>(x & 0xffff);
  453. }
  454. static void DebugPrintf(const char *format, ...);
  455. static bool ShowAssertionPopUps(bool assertionPopUps_);
  456. static void Assert(const char *c, const char *file, int line) CLANG_ANALYZER_NORETURN;
  457. static int Clamp(int val, int minVal, int maxVal);
  458. };
  459. #ifdef NDEBUG
  460. #define PLATFORM_ASSERT(c) ((void)0)
  461. #else
  462. #ifdef SCI_NAMESPACE
  463. #define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__))
  464. #else
  465. #define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__))
  466. #endif
  467. #endif
  468. #ifdef SCI_NAMESPACE
  469. }
  470. #endif
  471. #endif