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_FOX 0 26 #define PLAT_CURSES 0 27 #define PLAT_TK 0 28 #define PLAT_MORPHOS 0 29 30 #if defined(FOX) 31 #undef PLAT_FOX 32 #define PLAT_FOX 1 33 34 #elif defined(MORPHOS) 35 #undef PLAT_MORPHOS 36 #define PLAT_MORPHOS 1 37 38 #elif defined(__WX__) 39 #undef PLAT_WX 40 #define PLAT_WX 1 41 42 #elif defined(CURSES) 43 #undef PLAT_CURSES 44 #define PLAT_CURSES 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 #ifdef SCI_NAMESPACE 80 namespace Scintilla { 81 #endif 82 83 #if PLAT_MORPHOS 84 #include <intuition/classusr.h> 85 #endif 86 87 typedef float XYPOSITION; 88 typedef double XYACCUMULATOR; 89 inline int RoundXYPosition(XYPOSITION xyPos) { 90 return int(xyPos + 0.5); 91 } 92 93 // Underlying the implementation of the platform classes are platform specific types. 94 // Sometimes these need to be passed around by client code so they are defined here 95 96 typedef void *FontID; 97 typedef void *SurfaceID; 98 typedef void *WindowID; 99 typedef void *MenuID; 100 typedef void *TickerID; 101 typedef void *Function; 102 typedef void *IdlerID; 103 104 /** 105 * A geometric point class. 106 * Point is similar to the Win32 POINT and GTK+ GdkPoint types. 107 */ 108 class Point { 109 public: 110 XYPOSITION x; 111 XYPOSITION y; 112 113 explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) : x(x_), y(y_) { 114 } 115 116 static Point FromInts(int x_, int y_) { 117 return Point(static_cast<XYPOSITION>(x_), static_cast<XYPOSITION>(y_)); 118 } 119 120 // Other automatically defined methods (assignment, copy constructor, destructor) are fine 121 122 static Point FromLong(long lpoint); 123 }; 124 125 /** 126 * A geometric rectangle class. 127 * PRectangle is similar to the Win32 RECT. 128 * PRectangles contain their top and left sides, but not their right and bottom sides. 129 */ 130 class PRectangle { 131 public: 132 XYPOSITION left; 133 XYPOSITION top; 134 XYPOSITION right; 135 XYPOSITION bottom; 136 137 explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) : 138 left(left_), top(top_), right(right_), bottom(bottom_) { 139 } 140 141 static PRectangle FromInts(int left_, int top_, int right_, int bottom_) { 142 return PRectangle(static_cast<XYPOSITION>(left_), static_cast<XYPOSITION>(top_), 143 static_cast<XYPOSITION>(right_), static_cast<XYPOSITION>(bottom_)); 144 } 145 146 // Other automatically defined methods (assignment, copy constructor, destructor) are fine 147 148 bool operator==(PRectangle &rc) const { 149 return (rc.left == left) && (rc.right == right) && 150 (rc.top == top) && (rc.bottom == bottom); 151 } 152 bool Contains(Point pt) const { 153 return (pt.x >= left) && (pt.x <= right) && 154 (pt.y >= top) && (pt.y <= bottom); 155 } 156 bool ContainsWholePixel(Point pt) const { 157 // Does the rectangle contain all of the pixel to left/below the point 158 return (pt.x >= left) && ((pt.x+1) <= right) && 159 (pt.y >= top) && ((pt.y+1) <= bottom); 160 } 161 bool Contains(PRectangle rc) const { 162 return (rc.left >= left) && (rc.right <= right) && 163 (rc.top >= top) && (rc.bottom <= bottom); 164 } 165 bool Intersects(PRectangle other) const { 166 return (right > other.left) && (left < other.right) && 167 (bottom > other.top) && (top < other.bottom); 168 } 169 void Move(XYPOSITION xDelta, XYPOSITION yDelta) { 170 left += xDelta; 171 top += yDelta; 172 right += xDelta; 173 bottom += yDelta; 174 } 175 XYPOSITION Width() const { return right - left; } 176 XYPOSITION Height() const { return bottom - top; } 177 bool Empty() const { 178 return (Height() <= 0) || (Width() <= 0); 179 } 180 }; 181 182 /** 183 * Holds a desired RGB colour. 184 */ 185 class ColourDesired { 186 long co; 187 public: 188 ColourDesired(long lcol=0) { 189 co = lcol; 190 } 191 192 ColourDesired(unsigned int red, unsigned int green, unsigned int blue) { 193 Set(red, green, blue); 194 } 195 196 bool operator==(const ColourDesired &other) const { 197 return co == other.co; 198 } 199 200 void Set(long lcol) { 201 co = lcol; 202 } 203 204 void Set(unsigned int red, unsigned int green, unsigned int blue) { 205 #if PLAT_MORPHOS 206 co = (red << 16) | (green << 8) | blue; 207 #else 208 co = red | (green << 8) | (blue << 16); 209 #endif 210 } 211 212 static inline unsigned int ValueOfHex(const char ch) { 213 if (ch >= '0' && ch <= '9') 214 return ch - '0'; 215 else if (ch >= 'A' && ch <= 'F') 216 return ch - 'A' + 10; 217 else if (ch >= 'a' && ch <= 'f') 218 return ch - 'a' + 10; 219 else 220 return 0; 221 } 222 223 void Set(const char *val) { 224 if (*val == '#') { 225 val++; 226 } 227 unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]); 228 unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]); 229 unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]); 230 Set(r, g, b); 231 } 232 233 long AsLong() const { 234 return co; 235 } 236 237 unsigned int GetRed() const { 238 #if PLAT_MORPHOS 239 return (co >> 16) & 0xff; 240 #else 241 return co & 0xff; 242 #endif 243 } 244 245 unsigned int GetGreen() const { 246 #if PLAT_MORPHOS 247 return co & 0xff; 248 #else 249 return (co >> 8) & 0xff; 250 #endif 251 } 252 253 unsigned int GetBlue() const { 254 return (co >> 16) & 0xff; 255 } 256 }; 257 258 /** 259 * Font management. 260 */ 261 262 struct FontParameters { 263 const char *faceName; 264 float size; 265 int weight; 266 bool italic; 267 int extraFontFlag; 268 int technology; 269 int characterSet; 270 271 FontParameters( 272 const char *faceName_, 273 float size_=10, 274 int weight_=400, 275 bool italic_=false, 276 int extraFontFlag_=0, 277 int technology_=0, 278 int characterSet_=0) : 279 280 faceName(faceName_), 281 size(size_), 282 weight(weight_), 283 italic(italic_), 284 extraFontFlag(extraFontFlag_), 285 technology(technology_), 286 characterSet(characterSet_) 287 { 288 } 289 290 }; 291 292 class Font { 293 protected: 294 FontID fid; 295 // Private so Font objects can not be copied 296 Font(const Font &); 297 Font &operator=(const Font &); 298 public: 299 Font(); 300 virtual ~Font(); 301 302 virtual void Create(const FontParameters &fp); 303 virtual void Release(); 304 #if PLAT_MORPHOS 305 virtual void Create_TTE(const FontParameters &fp); 306 virtual void Release_TTE(); 307 BOOL ttengine; 308 #endif 309 310 FontID GetID() { return fid; } 311 // Alias another font - caller guarantees not to Release 312 void SetID(FontID fid_) { fid = fid_; } 313 friend class Surface; 314 friend class SurfaceImpl; 315 }; 316 317 /** 318 * A surface abstracts a place to draw. 319 */ 320 class Surface { 321 private: 322 // Private so Surface objects can not be copied 323 Surface(const Surface &) {} 324 Surface &operator=(const Surface &) { return *this; } 325 public: 326 Surface() {} 327 virtual ~Surface() {} 328 static Surface *Allocate(int technology); 329 330 virtual void Init(WindowID wid)=0; 331 virtual void Init(SurfaceID sid, WindowID wid)=0; 332 virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; 333 334 virtual void Release()=0; 335 virtual bool Initialised()=0; 336 virtual void PenColour(ColourDesired fore)=0; 337 virtual int LogPixelsY()=0; 338 virtual int DeviceHeightFont(int points)=0; 339 virtual void MoveTo(int x_, int y_)=0; 340 virtual void LineTo(int x_, int y_)=0; 341 virtual void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back)=0; 342 virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back)=0; 343 virtual void FillRectangle(PRectangle rc, ColourDesired back)=0; 344 virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; 345 virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back)=0; 346 virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, 347 ColourDesired outline, int alphaOutline, int flags)=0; 348 virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0; 349 virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0; 350 virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; 351 352 virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0; 353 virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0; 354 virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore)=0; 355 virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions)=0; 356 virtual XYPOSITION WidthText(Font &font_, const char *s, int len)=0; 357 virtual XYPOSITION WidthChar(Font &font_, char ch)=0; 358 virtual XYPOSITION Ascent(Font &font_)=0; 359 virtual XYPOSITION Descent(Font &font_)=0; 360 virtual XYPOSITION InternalLeading(Font &font_)=0; 361 virtual XYPOSITION ExternalLeading(Font &font_)=0; 362 virtual XYPOSITION Height(Font &font_)=0; 363 virtual XYPOSITION AverageCharWidth(Font &font_)=0; 364 365 virtual void SetClip(PRectangle rc)=0; 366 virtual void FlushCachedState()=0; 367 368 virtual void SetUnicodeMode(bool unicodeMode_)=0; 369 virtual void SetDBCSMode(int codePage)=0; 370 }; 371 372 /** 373 * A simple callback action passing one piece of untyped user data. 374 */ 375 typedef void (*CallBackAction)(void*); 376 377 #if PLAT_MORPHOS 378 class Window; 379 typedef Window *WindowPtr; 380 381 #include <exec/lists.h> 382 383 struct WindowNode 384 { 385 struct MinNode node; 386 WindowPtr self; 387 }; 388 389 #endif 390 391 /** 392 * Class to hide the details of window manipulation. 393 * Does not own the window which will normally have a longer life than this object. 394 */ 395 class Window { 396 protected: 397 WindowID wid; 398 #if PLAT_MORPHOS 399 Object *muiObject; 400 Object *muiApplication; 401 402 WindowPtr parentWindow; 403 404 /* calltip support */ 405 bool bCalltip; 406 bool bCalltipAdded; 407 408 /* non-calltip window handling calltips */ 409 struct List lCalltips; 410 struct WindowNode Node; 411 412 /* calltip window */ 413 Object *callTipWindow; 414 #endif 415 public: 416 Window() : wid(0), cursorLast(cursorInvalid) { 417 #if PLAT_MORPHOS 418 muiObject = 0; bCalltip = false; callTipWindow = 0; muiApplication = 0; bCalltipAdded = false; parentWindow = NULL; 419 Initialize(); 420 Node.self = this; 421 #endif 422 } 423 Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) { 424 #if PLAT_MORPHOS 425 muiObject = 0; bCalltip = false; callTipWindow = 0; muiApplication = 0; bCalltipAdded = false; parentWindow = NULL; 426 Initialize(); 427 Node.self = this; 428 #endif 429 } 430 virtual ~Window(); 431 Window &operator=(WindowID wid_) { 432 wid = wid_; 433 return *this; 434 } 435 WindowID GetID() const { return wid; } 436 bool Created() const { return wid != 0; } 437 void Destroy(); 438 bool HasFocus(); 439 PRectangle GetPosition(); 440 void SetPosition(PRectangle rc); 441 void SetPositionRelative(PRectangle rc, Window relativeTo); 442 PRectangle GetClientPosition(); 443 void Show(bool show=true); 444 void InvalidateAll(); 445 void InvalidateRectangle(PRectangle rc); 446 virtual void SetFont(Font &font); 447 enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand }; 448 void SetCursor(Cursor curs); 449 void SetTitle(const char *s); 450 PRectangle GetMonitorRect(Point pt); 451 #if PLAT_MORPHOS 452 void Initialize(); 453 454 void SetMuiObject(Object *ref) { muiObject = ref; }; 455 Object *GetMuiObject(void) const { return muiObject; }; 456 457 struct WindowNode *GetNode(void) { return &Node; }; 458 459 /* calltip handling */ 460 void SetIsCalltipWindow(bool bIsCalltip) { bCalltip = bIsCalltip; }; 461 bool GetIsCalltipWindow(void) const { return bCalltip; }; 462 463 void SetCalltipWindowObject(Object *calltip) { callTipWindow = calltip; }; 464 Object *GetCalltipWindowObject(void) { return callTipWindow; }; 465 466 void SetParentWindow(WindowPtr parent) { parentWindow = parent; }; 467 468 /* appending calltips to non-calltip windows */ 469 void AddCalltip(Window *win); 470 void RemoveCalltip(Window *win); 471 472 /* these are called on both types, either doing the job or forwarding to objs on the list */ 473 void ParentSetup(void); 474 void ParentCleanup(void); 475 void ParentShow(void); 476 void ParentHide(void); 477 void ParentWindowArranged(void); 478 479 #endif 480 private: 481 Cursor cursorLast; 482 }; 483 484 /** 485 * Listbox management. 486 */ 487 488 class ListBox : public Window { 489 public: 490 ListBox(); 491 virtual ~ListBox(); 492 static ListBox *Allocate(); 493 494 virtual void SetFont(Font &font)=0; 495 virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, int technology_)=0; 496 virtual void SetAverageCharWidth(int width)=0; 497 virtual void SetVisibleRows(int rows)=0; 498 virtual int GetVisibleRows() const=0; 499 virtual PRectangle GetDesiredRect()=0; 500 virtual int CaretFromEdge()=0; 501 virtual void Clear()=0; 502 virtual void Append(char *s, int type = -1)=0; 503 virtual int Length()=0; 504 virtual void Select(int n)=0; 505 virtual int GetSelection()=0; 506 virtual int Find(const char *prefix)=0; 507 virtual void GetValue(int n, char *value, int len)=0; 508 virtual void RegisterImage(int type, const char *xpm_data)=0; 509 virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0; 510 virtual void ClearRegisteredImages()=0; 511 virtual void SetDoubleClickAction(CallBackAction, void *)=0; 512 virtual void SetList(const char* list, char separator, char typesep)=0; 513 }; 514 515 /** 516 * Menu management. 517 */ 518 class Menu { 519 MenuID mid; 520 public: 521 Menu(); 522 MenuID GetID() { return mid; } 523 void CreatePopUp(); 524 void Destroy(); 525 void Show(Point pt, Window &w); 526 }; 527 528 class ElapsedTime { 529 long bigBit; 530 long littleBit; 531 public: 532 ElapsedTime(); 533 double Duration(bool reset=false); 534 }; 535 536 /** 537 * Dynamic Library (DLL/SO/...) loading 538 */ 539 class DynamicLibrary { 540 public: 541 virtual ~DynamicLibrary() {} 542 543 /// @return Pointer to function "name", or NULL on failure. 544 virtual Function FindFunction(const char *name) = 0; 545 546 /// @return true if the library was loaded successfully. 547 virtual bool IsValid() = 0; 548 549 /// @return An instance of a DynamicLibrary subclass with "modulePath" loaded. 550 static DynamicLibrary *Load(const char *modulePath); 551 }; 552 553 #if defined(__clang__) 554 # if __has_feature(attribute_analyzer_noreturn) 555 # define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) 556 # else 557 # define CLANG_ANALYZER_NORETURN 558 # endif 559 #else 560 # define CLANG_ANALYZER_NORETURN 561 #endif 562 563 /** 564 * Platform class used to retrieve system wide parameters such as double click speed 565 * and chrome colour. Not a creatable object, more of a module with several functions. 566 */ 567 class Platform { 568 // Private so Platform objects can not be copied 569 Platform(const Platform &) {} 570 Platform &operator=(const Platform &) { return *this; } 571 public: 572 // Should be private because no new Platforms are ever created 573 // but gcc warns about this 574 Platform() {} 575 ~Platform() {} 576 static ColourDesired Chrome(); 577 static ColourDesired ChromeHighlight(); 578 static const char *DefaultFont(); 579 static int DefaultFontSize(); 580 static unsigned int DoubleClickTime(); 581 static bool MouseButtonBounce(); 582 static void DebugDisplay(const char *s); 583 static bool IsKeyDown(int key); 584 static long SendScintilla( 585 WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0); 586 static long SendScintillaPointer( 587 WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0); 588 static bool IsDBCSLeadByte(int codePage, char ch); 589 static int DBCSCharLength(int codePage, const char *s); 590 static int DBCSCharMaxLength(); 591 592 // These are utility functions not really tied to a platform 593 static int Minimum(int a, int b); 594 static int Maximum(int a, int b); 595 // Next three assume 16 bit shorts and 32 bit longs 596 static long LongFromTwoShorts(short a,short b) { 597 return (a) | ((b) << 16); 598 } 599 static short HighShortFromLong(long x) { 600 return static_cast<short>(x >> 16); 601 } 602 static short LowShortFromLong(long x) { 603 return static_cast<short>(x & 0xffff); 604 } 605 static void DebugPrintf(const char *format, ...); 606 static bool ShowAssertionPopUps(bool assertionPopUps_); 607 static void Assert(const char *c, const char *file, int line) CLANG_ANALYZER_NORETURN; 608 static int Clamp(int val, int minVal, int maxVal); 609 #ifdef PLAT_MORPHOS 610 static PRectangle PRecToARec(PRectangle rc, void *areaobj); 611 #endif 612 }; 613 614 #ifdef NDEBUG 615 #define PLATFORM_ASSERT(c) ((void)0) 616 #else 617 #ifdef SCI_NAMESPACE 618 #define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__)) 619 #else 620 #define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__)) 621 #endif 622 #endif 623 624 #ifdef SCI_NAMESPACE 625 } 626 #endif 627 628 #endif