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 17 #define PLAT_GTK 0 18 #define PLAT_GTK_WIN32 0 19 #define PLAT_GTK_MACOSX 0 20 #define PLAT_MACOSX 0 21 #define PLAT_WIN 0 22 #define PLAT_WX 0 23 #define PLAT_FOX 0 24 25 #if defined(FOX) 26 #undef PLAT_FOX 27 #define PLAT_FOX 1 28 29 #elif defined(__WX__) 30 #undef PLAT_WX 31 #define PLAT_WX 1 32 33 #elif defined(GTK) 34 #undef PLAT_GTK 35 #define PLAT_GTK 1 36 37 #if defined(__WIN32__) || defined(_MSC_VER) 38 #undef PLAT_GTK_WIN32 39 #define PLAT_GTK_WIN32 1 40 #endif 41 42 #if defined(__APPLE__) 43 #undef PLAT_GTK_MACOSX 44 #define PLAT_GTK_MACOSX 1 45 #endif 46 47 #elif defined(__APPLE__) 48 49 #undef PLAT_MACOSX 50 #define PLAT_MACOSX 1 51 52 #else 53 #undef PLAT_WIN 54 #define PLAT_WIN 1 55 56 #endif 57 58 #ifdef SCI_NAMESPACE 59 namespace Scintilla { 60 #endif 61 62 // Underlying the implementation of the platform classes are platform specific types. 63 // Sometimes these need to be passed around by client code so they are defined here 64 65 #if PLAT_FOX 66 67 namespace FX { 68 69 class FXFont; 70 class FXDrawable; 71 class FXWindow; 72 class FXMenuPane; 73 class FXList; 74 class FXChore; 75 # ifndef WIN32 76 class FXTimer; 77 # else 78 struct FXTimer; 79 # endif // WIN32 80 81 }; 82 using namespace FX; 83 84 typedef FXFont * FontID; 85 typedef void * SurfaceID; 86 typedef FXWindow * WindowID; 87 typedef FXMenuPane * MenuID; 88 typedef FXTimer * TickerID; 89 typedef FXChore * IdlerID; 90 #else 91 typedef void *FontID; 92 typedef void *SurfaceID; 93 typedef void *WindowID; 94 typedef void *MenuID; 95 typedef void *TickerID; 96 typedef void *IdlerID; 97 #endif 98 typedef void *Function; 99 100 /** 101 * A geometric point class. 102 * Point is exactly the same as the Win32 POINT and GTK+ GdkPoint so can be used interchangeably. 103 */ 104 class Point { 105 public: 106 int x; 107 int y; 108 x(x_)109 explicit Point(int x_=0, int y_=0) : x(x_), y(y_) { 110 } 111 112 // Other automatically defined methods (assignment, copy constructor, destructor) are fine 113 114 static Point FromLong(long lpoint); 115 }; 116 117 /** 118 * A geometric rectangle class. 119 * PRectangle is exactly the same as the Win32 RECT so can be used interchangeably. 120 * PRectangles contain their top and left sides, but not their right and bottom sides. 121 */ 122 class PRectangle { 123 public: 124 int left; 125 int top; 126 int right; 127 int bottom; 128 129 PRectangle(int left_=0, int top_=0, int right_=0, int bottom_ = 0) : left(left_)130 left(left_), top(top_), right(right_), bottom(bottom_) { 131 } 132 133 // Other automatically defined methods (assignment, copy constructor, destructor) are fine 134 135 bool operator==(PRectangle &rc) { 136 return (rc.left == left) && (rc.right == right) && 137 (rc.top == top) && (rc.bottom == bottom); 138 } Contains(Point pt)139 bool Contains(Point pt) { 140 return (pt.x >= left) && (pt.x <= right) && 141 (pt.y >= top) && (pt.y <= bottom); 142 } Contains(PRectangle rc)143 bool Contains(PRectangle rc) { 144 return (rc.left >= left) && (rc.right <= right) && 145 (rc.top >= top) && (rc.bottom <= bottom); 146 } Intersects(PRectangle other)147 bool Intersects(PRectangle other) { 148 return (right > other.left) && (left < other.right) && 149 (bottom > other.top) && (top < other.bottom); 150 } Move(int xDelta,int yDelta)151 void Move(int xDelta, int yDelta) { 152 left += xDelta; 153 top += yDelta; 154 right += xDelta; 155 bottom += yDelta; 156 } Width()157 int Width() { return right - left; } Height()158 int Height() { return bottom - top; } Empty()159 bool Empty() { 160 return (Height() <= 0) || (Width() <= 0); 161 } 162 }; 163 164 /** 165 * In some circumstances, including Win32 in paletted mode and GTK+, each colour 166 * must be allocated before use. The desired colours are held in the ColourDesired class, 167 * and after allocation the allocation entry is stored in the ColourAllocated class. In other 168 * circumstances, such as Win32 in true colour mode, the allocation process just copies 169 * the RGB values from the desired to the allocated class. 170 * As each desired colour requires allocation before it can be used, the ColourPair class 171 * holds both a ColourDesired and a ColourAllocated 172 * The Palette class is responsible for managing the palette of colours which contains a 173 * list of ColourPair objects and performs the allocation. 174 */ 175 176 /** 177 * Holds a desired RGB colour. 178 */ 179 class ColourDesired { 180 long co; 181 public: 182 ColourDesired(long lcol=0) { 183 co = lcol; 184 } 185 ColourDesired(unsigned int red,unsigned int green,unsigned int blue)186 ColourDesired(unsigned int red, unsigned int green, unsigned int blue) { 187 Set(red, green, blue); 188 } 189 190 bool operator==(const ColourDesired &other) const { 191 return co == other.co; 192 } 193 Set(long lcol)194 void Set(long lcol) { 195 co = lcol; 196 } 197 Set(unsigned int red,unsigned int green,unsigned int blue)198 void Set(unsigned int red, unsigned int green, unsigned int blue) { 199 co = red | (green << 8) | (blue << 16); 200 } 201 ValueOfHex(const char ch)202 static inline unsigned int ValueOfHex(const char ch) { 203 if (ch >= '0' && ch <= '9') 204 return ch - '0'; 205 else if (ch >= 'A' && ch <= 'F') 206 return ch - 'A' + 10; 207 else if (ch >= 'a' && ch <= 'f') 208 return ch - 'a' + 10; 209 else 210 return 0; 211 } 212 Set(const char * val)213 void Set(const char *val) { 214 if (*val == '#') { 215 val++; 216 } 217 unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]); 218 unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]); 219 unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]); 220 Set(r, g, b); 221 } 222 AsLong()223 long AsLong() const { 224 return co; 225 } 226 GetRed()227 unsigned int GetRed() { 228 return co & 0xff; 229 } 230 GetGreen()231 unsigned int GetGreen() { 232 return (co >> 8) & 0xff; 233 } 234 GetBlue()235 unsigned int GetBlue() { 236 return (co >> 16) & 0xff; 237 } 238 }; 239 240 /** 241 * Holds an allocated RGB colour which may be an approximation to the desired colour. 242 */ 243 class ColourAllocated { 244 long coAllocated; 245 246 public: 247 248 ColourAllocated(long lcol=0) { 249 coAllocated = lcol; 250 } 251 Set(long lcol)252 void Set(long lcol) { 253 coAllocated = lcol; 254 } 255 AsLong()256 long AsLong() const { 257 return coAllocated; 258 } 259 }; 260 261 /** 262 * Colour pairs hold a desired colour and an allocated colour. 263 */ 264 struct ColourPair { 265 ColourDesired desired; 266 ColourAllocated allocated; 267 268 ColourPair(ColourDesired desired_=ColourDesired(0,0,0)) { 269 desired = desired_; 270 allocated.Set(desired.AsLong()); 271 } CopyColourPair272 void Copy() { 273 allocated.Set(desired.AsLong()); 274 } 275 }; 276 277 class Window; // Forward declaration for Palette 278 279 /** 280 * Colour palette management. 281 */ 282 class Palette { 283 int used; 284 int size; 285 ColourPair *entries; 286 #if PLAT_GTK 287 void *allocatedPalette; // GdkColor * 288 int allocatedLen; 289 #elif PLAT_FOX 290 void * visual; 291 #endif 292 // Private so Palette objects can not be copied 293 Palette(const Palette &); 294 Palette &operator=(const Palette &); 295 public: 296 #if PLAT_WIN 297 void *hpal; 298 #endif 299 bool allowRealization; 300 301 Palette(); 302 ~Palette(); 303 304 void Release(); 305 306 /** 307 * This method either adds a colour to the list of wanted colours (want==true) 308 * or retrieves the allocated colour back to the ColourPair. 309 * This is one method to make it easier to keep the code for wanting and retrieving in sync. 310 */ 311 void WantFind(ColourPair &cp, bool want); 312 313 void Allocate(Window &w); 314 }; 315 316 /** 317 * Font management. 318 */ 319 class Font { 320 protected: 321 FontID fid; 322 #if PLAT_WX 323 int ascent; 324 #endif 325 // Private so Font objects can not be copied 326 Font(const Font &); 327 Font &operator=(const Font &); 328 public: 329 Font(); 330 virtual ~Font(); 331 332 virtual void Create(const char *faceName, int characterSet, int size, 333 bool bold, bool italic, int extraFontFlag=0); 334 virtual void Release(); 335 GetID()336 FontID GetID() { return fid; } 337 // Alias another font - caller guarantees not to Release SetID(FontID fid_)338 void SetID(FontID fid_) { fid = fid_; } 339 #if PLAT_WX SetAscent(int ascent_)340 void SetAscent(int ascent_) { ascent = ascent_; } 341 #endif 342 friend class Surface; 343 friend class SurfaceImpl; 344 }; 345 346 /** 347 * A surface abstracts a place to draw. 348 */ 349 class Surface { 350 private: 351 // Private so Surface objects can not be copied Surface(const Surface &)352 Surface(const Surface &) {} 353 Surface &operator=(const Surface &) { return *this; } 354 public: Surface()355 Surface() {} ~Surface()356 virtual ~Surface() {} 357 static Surface *Allocate(); 358 359 virtual void Init(WindowID wid)=0; 360 virtual void Init(SurfaceID sid, WindowID wid)=0; 361 virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; 362 363 virtual void Release()=0; 364 virtual bool Initialised()=0; 365 virtual void PenColour(ColourAllocated fore)=0; 366 virtual int LogPixelsY()=0; 367 virtual int DeviceHeightFont(int points)=0; 368 virtual void MoveTo(int x_, int y_)=0; 369 virtual void LineTo(int x_, int y_)=0; 370 virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back)=0; 371 virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; 372 virtual void FillRectangle(PRectangle rc, ColourAllocated back)=0; 373 virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; 374 virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; 375 virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, 376 ColourAllocated outline, int alphaOutline, int flags)=0; 377 virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0; 378 virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; 379 virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; 380 381 virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; 382 virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; 383 virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore)=0; 384 virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0; 385 virtual int WidthText(Font &font_, const char *s, int len)=0; 386 virtual int WidthChar(Font &font_, char ch)=0; 387 virtual int Ascent(Font &font_)=0; 388 virtual int Descent(Font &font_)=0; 389 virtual int InternalLeading(Font &font_)=0; 390 virtual int ExternalLeading(Font &font_)=0; 391 virtual int Height(Font &font_)=0; 392 virtual int AverageCharWidth(Font &font_)=0; 393 394 virtual int SetPalette(Palette *pal, bool inBackGround)=0; 395 virtual void SetClip(PRectangle rc)=0; 396 virtual void FlushCachedState()=0; 397 398 virtual void SetUnicodeMode(bool unicodeMode_)=0; 399 virtual void SetDBCSMode(int codePage)=0; 400 }; 401 402 /** 403 * A simple callback action passing one piece of untyped user data. 404 */ 405 typedef void (*CallBackAction)(void*); 406 407 /** 408 * Class to hide the details of window manipulation. 409 * Does not own the window which will normally have a longer life than this object. 410 */ 411 class Window { 412 protected: 413 WindowID wid; 414 #if PLAT_MACOSX 415 void *windowRef; 416 void *control; 417 #endif 418 public: Window()419 Window() : wid(0), cursorLast(cursorInvalid) { 420 #if PLAT_MACOSX 421 windowRef = 0; 422 control = 0; 423 #endif 424 } Window(const Window & source)425 Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) { 426 #if PLAT_MACOSX 427 windowRef = 0; 428 control = 0; 429 #endif 430 } 431 virtual ~Window(); 432 Window &operator=(WindowID wid_) { 433 wid = wid_; 434 return *this; 435 } GetID()436 WindowID GetID() const { return wid; } Created()437 bool Created() const { return wid != 0; } 438 void Destroy(); 439 bool HasFocus(); 440 PRectangle GetPosition(); 441 void SetPosition(PRectangle rc); 442 void SetPositionRelative(PRectangle rc, Window relativeTo); 443 PRectangle GetClientPosition(); 444 #if PLAT_FOX 445 virtual 446 #endif 447 void Show(bool show=true); 448 void InvalidateAll(); 449 void InvalidateRectangle(PRectangle rc); 450 virtual void SetFont(Font &font); 451 enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand }; 452 void SetCursor(Cursor curs); 453 void SetTitle(const char *s); 454 PRectangle GetMonitorRect(Point pt); 455 #if PLAT_MACOSX SetWindow(void * ref)456 void SetWindow(void *ref) { windowRef = ref; } SetControl(void * _control)457 void SetControl(void *_control) { control = _control; } 458 #endif 459 private: 460 Cursor cursorLast; 461 }; 462 463 /** 464 * Listbox management. 465 */ 466 class ListBox : public Window { 467 public: 468 ListBox(); 469 virtual ~ListBox(); 470 static ListBox *Allocate(); 471 472 virtual void SetFont(Font &font)=0; 473 virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_)=0; 474 virtual void SetAverageCharWidth(int width)=0; 475 virtual void SetVisibleRows(int rows)=0; 476 virtual int GetVisibleRows() const=0; 477 virtual PRectangle GetDesiredRect()=0; 478 virtual int CaretFromEdge()=0; 479 virtual void Clear()=0; 480 virtual void Append(char *s, int type = -1)=0; 481 virtual int Length()=0; 482 virtual void Select(int n)=0; 483 virtual int GetSelection()=0; 484 virtual int Find(const char *prefix)=0; 485 virtual void GetValue(int n, char *value, int len)=0; 486 virtual void RegisterImage(int type, const char *xpm_data)=0; 487 virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0; 488 virtual void ClearRegisteredImages()=0; 489 virtual void SetDoubleClickAction(CallBackAction, void *)=0; 490 virtual void SetList(const char* list, char separator, char typesep)=0; 491 }; 492 493 /** 494 * Menu management. 495 */ 496 class Menu { 497 MenuID mid; 498 public: 499 Menu(); GetID()500 MenuID GetID() { return mid; } 501 void CreatePopUp(); 502 void Destroy(); 503 void Show(Point pt, Window &w); 504 }; 505 506 class ElapsedTime { 507 long bigBit; 508 long littleBit; 509 public: 510 ElapsedTime(); 511 double Duration(bool reset=false); 512 }; 513 514 /** 515 * Dynamic Library (DLL/SO/...) loading 516 */ 517 class DynamicLibrary { 518 public: ~DynamicLibrary()519 virtual ~DynamicLibrary() {} 520 521 /// @return Pointer to function "name", or NULL on failure. 522 virtual Function FindFunction(const char *name) = 0; 523 524 /// @return true if the library was loaded successfully. 525 virtual bool IsValid() = 0; 526 527 /// @return An instance of a DynamicLibrary subclass with "modulePath" loaded. 528 static DynamicLibrary *Load(const char *modulePath); 529 }; 530 531 /** 532 * Platform class used to retrieve system wide parameters such as double click speed 533 * and chrome colour. Not a creatable object, more of a module with several functions. 534 */ 535 class Platform { 536 // Private so Platform objects can not be copied Platform(const Platform &)537 Platform(const Platform &) {} 538 Platform &operator=(const Platform &) { return *this; } 539 public: 540 // Should be private because no new Platforms are ever created 541 // but gcc warns about this Platform()542 Platform() {} ~Platform()543 ~Platform() {} 544 static ColourDesired Chrome(); 545 static ColourDesired ChromeHighlight(); 546 static const char *DefaultFont(); 547 static int DefaultFontSize(); 548 static unsigned int DoubleClickTime(); 549 static bool MouseButtonBounce(); 550 static void DebugDisplay(const char *s); 551 static bool IsKeyDown(int key); 552 static long SendScintilla( 553 WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0); 554 static long SendScintillaPointer( 555 WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0); 556 static bool IsDBCSLeadByte(int codePage, char ch); 557 static int DBCSCharLength(int codePage, const char *s); 558 static int DBCSCharMaxLength(); 559 560 // These are utility functions not really tied to a platform 561 static int Minimum(int a, int b); 562 static int Maximum(int a, int b); 563 // Next three assume 16 bit shorts and 32 bit longs LongFromTwoShorts(short a,short b)564 static long LongFromTwoShorts(short a,short b) { 565 return (a) | ((b) << 16); 566 } HighShortFromLong(long x)567 static short HighShortFromLong(long x) { 568 return static_cast<short>(x >> 16); 569 } LowShortFromLong(long x)570 static short LowShortFromLong(long x) { 571 return static_cast<short>(x & 0xffff); 572 } 573 static void DebugPrintf(const char *format, ...); 574 static bool ShowAssertionPopUps(bool assertionPopUps_); 575 static void Assert(const char *c, const char *file, int line); 576 static int Clamp(int val, int minVal, int maxVal); 577 }; 578 579 #ifdef NDEBUG 580 #define PLATFORM_ASSERT(c) ((void)0) 581 #else 582 #ifdef SCI_NAMESPACE 583 #define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__)) 584 #else 585 #define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__)) 586 #endif 587 #endif 588 589 #ifdef SCI_NAMESPACE 590 } 591 #endif 592 593 // Shut up annoying Visual C++ warnings: 594 #ifdef _MSC_VER 595 #pragma warning(disable: 4244 4309 4514 4710) 596 #endif 597 598 #endif 599