aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorscaraveo <unknown>2007-06-01 00:57:26 +0000
committerscaraveo <unknown>2007-06-01 00:57:26 +0000
commit710f716e96f6e9ee9eb410b343b78b3c4d95bc46 (patch)
tree55e5547869daa67b6a639c89825058baf75545c7
parentcac98b923422b91839f7c285a9b78ea282cd6f0a (diff)
downloadscintilla-mirror-710f716e96f6e9ee9eb410b343b78b3c4d95bc46.tar.gz
integrate OS X support for scintilla. a big patch with a little commit message :)
- now uses namespaces (optionally for non-os x) to avoid conflicts with OS X libraries - several fixes in the OS X layer since the branch was commited in 2005 - used in Komodo since 2005, so pretty stable
-rw-r--r--include/KeyWords.h8
-rw-r--r--include/Platform.h41
-rw-r--r--include/PropSet.h7
-rw-r--r--include/SString.h9
-rw-r--r--include/Scintilla.h8
-rw-r--r--include/WindowAccessor.h8
-rw-r--r--macosx/PlatMacOSX.cxx1922
-rw-r--r--macosx/PlatMacOSX.h101
-rw-r--r--macosx/QuartzTextLayout.h130
-rw-r--r--macosx/QuartzTextStyle.h105
-rw-r--r--macosx/QuartzTextStyleAttribute.h146
-rw-r--r--macosx/SciTest/English.lproj/InfoPlist.stringsbin0 -> 256 bytes
-rw-r--r--macosx/SciTest/Info.plist24
-rw-r--r--macosx/SciTest/SciTest.xcode/project.pbxproj287
-rw-r--r--macosx/SciTest/SciTest_Prefix.pch5
-rw-r--r--macosx/SciTest/main.cpp225
-rw-r--r--macosx/SciTest/version.plist16
-rw-r--r--macosx/ScintillaCallTip.cxx117
-rw-r--r--macosx/ScintillaCallTip.h64
-rw-r--r--macosx/ScintillaListBox.cxx103
-rw-r--r--macosx/ScintillaListBox.h63
-rw-r--r--macosx/ScintillaMacOSX.cxx2118
-rw-r--r--macosx/ScintillaMacOSX.h192
-rw-r--r--macosx/TCarbonEvent.cxx519
-rw-r--r--macosx/TCarbonEvent.h230
-rw-r--r--macosx/TRect.h496
-rw-r--r--macosx/TView.cxx1462
-rw-r--r--macosx/TView.h286
-rw-r--r--macosx/deps.mak315
-rw-r--r--macosx/makefile95
-rw-r--r--src/AutoComplete.cxx4
-rw-r--r--src/AutoComplete.h8
-rw-r--r--src/CallTip.cxx15
-rw-r--r--src/CallTip.h8
-rw-r--r--src/CellBuffer.cxx4
-rw-r--r--src/CellBuffer.h8
-rw-r--r--src/ContractionState.cxx4
-rw-r--r--src/ContractionState.h8
-rw-r--r--src/Decoration.cxx4
-rw-r--r--src/Decoration.h8
-rw-r--r--src/Document.cxx4
-rw-r--r--src/Document.h8
-rw-r--r--src/DocumentAccessor.cxx4
-rw-r--r--src/DocumentAccessor.h8
-rw-r--r--src/Editor.cxx20
-rw-r--r--src/Editor.h8
-rw-r--r--src/ExternalLexer.cxx4
-rw-r--r--src/ExternalLexer.h8
-rw-r--r--src/Indicator.cxx4
-rw-r--r--src/Indicator.h8
-rw-r--r--src/KeyMap.cxx4
-rw-r--r--src/KeyMap.h8
-rw-r--r--src/KeyWords.cxx4
-rw-r--r--src/LexAPDL.cxx3
-rw-r--r--src/LexAU3.cxx4
-rw-r--r--src/LexAVE.cxx3
-rw-r--r--src/LexAda.cxx4
-rw-r--r--src/LexAsm.cxx3
-rw-r--r--src/LexAsn1.cxx4
-rw-r--r--src/LexBaan.cxx4
-rw-r--r--src/LexBash.cxx4
-rw-r--r--src/LexBasic.cxx4
-rw-r--r--src/LexBullant.cxx3
-rw-r--r--src/LexCLW.cxx4
-rw-r--r--src/LexCPP.cxx4
-rw-r--r--src/LexCSS.cxx4
-rw-r--r--src/LexCaml.cxx4
-rw-r--r--src/LexCmake.cxx3
-rw-r--r--src/LexConf.cxx4
-rw-r--r--src/LexCrontab.cxx4
-rw-r--r--src/LexCsound.cxx3
-rw-r--r--src/LexD.cxx4
-rw-r--r--src/LexEScript.cxx3
-rw-r--r--src/LexEiffel.cxx4
-rw-r--r--src/LexErlang.cxx4
-rw-r--r--src/LexFlagship.cxx4
-rw-r--r--src/LexForth.cxx4
-rw-r--r--src/LexFortran.cxx5
-rw-r--r--src/LexGAP.cxx3
-rw-r--r--src/LexGen.py31
-rw-r--r--src/LexGui4Cli.cxx4
-rw-r--r--src/LexHTML.cxx4
-rw-r--r--src/LexHaskell.cxx4
-rw-r--r--src/LexInno.cxx4
-rw-r--r--src/LexKix.cxx4
-rw-r--r--src/LexLisp.cxx4
-rw-r--r--src/LexLout.cxx4
-rw-r--r--src/LexLua.cxx4
-rw-r--r--src/LexMMIXAL.cxx3
-rw-r--r--src/LexMPT.cxx4
-rw-r--r--src/LexMSSQL.cxx4
-rw-r--r--src/LexMatlab.cxx3
-rw-r--r--src/LexMetapost.cxx4
-rw-r--r--src/LexNsis.cxx4
-rw-r--r--src/LexOpal.cxx4
-rw-r--r--src/LexOthers.cxx4
-rw-r--r--src/LexPB.cxx4
-rw-r--r--src/LexPOV.cxx4
-rw-r--r--src/LexPS.cxx4
-rw-r--r--src/LexPascal.cxx4
-rw-r--r--src/LexPerl.cxx4
-rw-r--r--src/LexPython.cxx4
-rw-r--r--src/LexRebol.cxx3
-rw-r--r--src/LexSQL.cxx4
-rw-r--r--src/LexScriptol.cxx4
-rw-r--r--src/LexSmalltalk.cxx4
-rw-r--r--src/LexSpecman.cxx3
-rw-r--r--src/LexSpice.cxx4
-rw-r--r--src/LexTADS3.cxx4
-rw-r--r--src/LexTCL.cxx4
-rw-r--r--src/LexTeX.cxx4
-rw-r--r--src/LexVB.cxx4
-rw-r--r--src/LexVHDL.cxx4
-rw-r--r--src/LexVerilog.cxx4
-rw-r--r--src/LexYAML.cxx4
-rw-r--r--src/LineMarker.cxx4
-rw-r--r--src/LineMarker.h8
-rw-r--r--src/PropSet.cxx4
-rw-r--r--src/RESearch.cxx4
-rw-r--r--src/RESearch.h8
-rw-r--r--src/RunStyles.cxx4
-rw-r--r--src/RunStyles.h8
-rw-r--r--src/SVector.h8
-rw-r--r--src/ScintillaBase.cxx4
-rw-r--r--src/ScintillaBase.h8
-rw-r--r--src/Style.cxx4
-rw-r--r--src/Style.h8
-rw-r--r--src/StyleContext.cxx4
-rw-r--r--src/StyleContext.h8
-rw-r--r--src/ViewStyle.cxx4
-rw-r--r--src/ViewStyle.h8
-rw-r--r--src/WindowAccessor.cxx4
-rw-r--r--src/XPM.cxx4
-rw-r--r--src/XPM.h8
134 files changed, 9625 insertions, 16 deletions
diff --git a/include/KeyWords.h b/include/KeyWords.h
index 059ac0da0..6abae5945 100644
--- a/include/KeyWords.h
+++ b/include/KeyWords.h
@@ -5,6 +5,10 @@
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler);
@@ -51,6 +55,10 @@ public:
static const LexerModule *Find(const char *languageName);
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
/**
* Check if a character is a space.
* This is ASCII specific but is safe with chars >= 0x80.
diff --git a/include/Platform.h b/include/Platform.h
index 60d7896ac..39e2b6eaf 100644
--- a/include/Platform.h
+++ b/include/Platform.h
@@ -16,6 +16,7 @@
#define PLAT_GTK 0
#define PLAT_GTK_WIN32 0
+#define PLAT_MACOSX 0
#define PLAT_WIN 0
#define PLAT_WX 0
#define PLAT_FOX 0
@@ -37,12 +38,19 @@
#define PLAT_GTK_WIN32 1
#endif
+#elif defined(MACOSX)
+#undef PLAT_MACOSX
+#define PLAT_MACOSX 1
+
#else
#undef PLAT_WIN
#define PLAT_WIN 1
#endif
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
// Underlying the implementation of the platform classes are platform specific types.
// Sometimes these need to be passed around by client code so they are defined here
@@ -360,9 +368,23 @@ typedef void (*CallBackAction)(void*);
class Window {
protected:
WindowID id;
+#ifdef PLAT_MACOSX
+ void *windowRef;
+ void *control;
+#endif
public:
- Window() : id(0), cursorLast(cursorInvalid) {}
- Window(const Window &source) : id(source.id), cursorLast(cursorInvalid) {}
+ Window() : id(0), cursorLast(cursorInvalid) {
+#ifdef PLAT_MACOSX
+ windowRef = 0;
+ control = 0;
+#endif
+ }
+ Window(const Window &source) : id(source.id), cursorLast(cursorInvalid) {
+#ifdef PLAT_MACOSX
+ windowRef = 0;
+ control = 0;
+#endif
+ }
virtual ~Window();
Window &operator=(WindowID id_) {
id = id_;
@@ -383,6 +405,10 @@ public:
enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand };
void SetCursor(Cursor curs);
void SetTitle(const char *s);
+#ifdef PLAT_MACOSX
+ void SetWindow(void *ref) { windowRef = ref; };
+ void SetControl(void *_control) { control = _control; };
+#endif
private:
Cursor cursorLast;
};
@@ -474,6 +500,9 @@ public:
static int DefaultFontSize();
static unsigned int DoubleClickTime();
static bool MouseButtonBounce();
+#ifdef __APPLE__
+ static bool WaitMouseMoved(Point pt);
+#endif
static void DebugDisplay(const char *s);
static bool IsKeyDown(int key);
static long SendScintilla(
@@ -506,8 +535,16 @@ public:
#ifdef NDEBUG
#define PLATFORM_ASSERT(c) ((void)0)
#else
+#ifdef SCI_NAMESPACE
+#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__))
+#else
#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__))
#endif
+#endif
+
+#ifdef SCI_NAMESPACE
+}
+#endif
// Shut up annoying Visual C++ warnings:
#ifdef _MSC_VER
diff --git a/include/PropSet.h b/include/PropSet.h
index e38de7dc4..e9d028c44 100644
--- a/include/PropSet.h
+++ b/include/PropSet.h
@@ -13,6 +13,10 @@ bool EqualCaseInsensitive(const char *a, const char *b);
bool isprefix(const char *target, const char *prefix);
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
struct Property {
unsigned int hash;
char *key;
@@ -104,6 +108,9 @@ inline bool IsAlphabetic(unsigned int ch) {
return ((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'));
}
+#ifdef SCI_NAMESPACE
+}
+#endif
#ifdef _MSC_VER
// Visual C++ doesn't like the private copy idiom for disabling
diff --git a/include/SString.h b/include/SString.h
index 38a206ccf..b770afebe 100644
--- a/include/SString.h
+++ b/include/SString.h
@@ -8,11 +8,16 @@
#ifndef SSTRING_H
#define SSTRING_H
+
// These functions are implemented because each platform calls them something different.
int CompareCaseInsensitive(const char *a, const char *b);
int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
bool EqualCaseInsensitive(const char *a, const char *b);
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
// Define another string class.
// While it would be 'better' to use std::string, that doubles the executable size.
// An SString may contain embedded nul characters.
@@ -277,4 +282,8 @@ inline char *StringDup(
return SContainer::StringAllocate(s, len);
}
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/include/Scintilla.h b/include/Scintilla.h
index ab5f05d76..9e67b44de 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -744,6 +744,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
// CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs.
// So older code that treats Scintilla as a RichEdit will work.
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
struct CharacterRange {
long cpMin;
long cpMax;
@@ -805,6 +809,10 @@ struct SCNotification {
int y; // SCN_DWELLSTART, SCN_DWELLEND
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
// Deprecation section listing all API features that are deprecated and will
// will be removed completely in a future version.
// To enable these features define INCLUDE_DEPRECATED_FEATURES
diff --git a/include/WindowAccessor.h b/include/WindowAccessor.h
index a55c2c459..e107a0659 100644
--- a/include/WindowAccessor.h
+++ b/include/WindowAccessor.h
@@ -6,6 +6,10 @@
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class WindowAccessor : public Accessor {
@@ -56,3 +60,7 @@ public:
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
void IndicatorFill(int start, int end, int indicator, int value);
};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
diff --git a/macosx/PlatMacOSX.cxx b/macosx/PlatMacOSX.cxx
new file mode 100644
index 000000000..149b99ceb
--- /dev/null
+++ b/macosx/PlatMacOSX.cxx
@@ -0,0 +1,1922 @@
+// Scintilla source code edit control
+// PlatMacOSX.cxx - implementation of platform facilities on MacOS X/Carbon
+// Based on work by Evan Jones (c) 2002 <ejones@uwaterloo.ca>
+// Based on PlatGTK.cxx Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <cstring>
+#include <cstdio>
+#include <cstdlib>
+
+#include <assert.h>
+
+#include <sys/time.h>
+
+#include <Carbon/Carbon.h>
+#include "QuartzTextLayout.h"
+#include "TCarbonEvent.h"
+
+#include "Platform.h"
+#include "Scintilla.h"
+#include "PlatMacOSX.h"
+#include "XPM.h"
+
+using namespace Scintilla;
+
+#include "ScintillaWidget.h"
+
+
+extern sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+
+inline CGRect PRectangleToCGRect( PRectangle& rc ) {
+ return CGRectMake( rc.left, rc.top, rc.Width(), rc.Height() );
+}
+
+inline PRectangle CGRectToPRectangle( const CGRect& rect ) {
+ PRectangle rc;
+ rc.left = (int)( rect.origin.x + 0.5 );
+ rc.top = (int)( rect.origin.y + 0.5 );
+ rc.right = (int)( rect.origin.x + rect.size.width + 0.5 );
+ rc.bottom = (int)( rect.origin.y + rect.size.height + 0.5 );
+ return rc;
+}
+
+Scintilla::Point Scintilla::Point::FromLong(long lpoint) {
+ return Scintilla::Point(
+ Platform::LowShortFromLong(lpoint),
+ Platform::HighShortFromLong(lpoint));
+}
+
+// The Palette is just ignored on Mac OS X. OS X runs "Millions" or "Thousands" of colours.
+Scintilla::Palette::Palette() {
+}
+
+Scintilla::Palette::~Palette() {
+}
+
+void Scintilla::Palette::Release() {
+}
+
+// Do nothing if it "wants" a colour. Copy the colour from desired to allocated if it is "finding" a colour.
+void Scintilla::Palette::WantFind(ColourPair &cp, bool want) {
+ if (want) {
+ } else {
+ cp.allocated.Set(cp.desired.AsLong());
+ }
+}
+
+void Scintilla::Palette::Allocate(Window &/*w*/) {
+ // OS X always runs in thousands or millions of colours
+}
+
+Font::Font() : id(0) {}
+
+Font::~Font() { Release(); }
+
+
+void Font::Create(const char *faceName, int /*characterSet*/,
+ int size, bool bold, bool italic, bool /*extraFontFlag*/) {
+ // TODO: How should I handle the characterSet request?
+ Release();
+
+ id = new QuartzTextStyle();
+
+ // Find the font
+ QuartzFont font( faceName, strlen( faceName ) );
+
+ // We set Font, Size, Bold, Italic
+ QuartzTextSize textSize( size );
+ QuartzTextBold isBold( bold );
+ QuartzTextItalic isItalic( italic );
+
+ // Actually set the attributes
+ QuartzTextStyleAttribute* attributes[] = { &font, &textSize, &isBold, &isItalic };
+ reinterpret_cast<QuartzTextStyle*>( id )->setAttributes( attributes, sizeof( attributes ) / sizeof( *attributes ) );
+
+ //ATSStyleRenderingOptions rendering = kATSStyleNoAntiAliasing;
+ //reinterpret_cast<QuartzTextStyle*>( id )->setAttribute( kATSUStyleRenderingOptionsTag, sizeof( rendering ), &rendering );
+
+ // TODO: Why do I have to manually set this?
+ reinterpret_cast<QuartzTextStyle*>( id )->setFontFeature( kLigaturesType, kCommonLigaturesOffSelector );
+}
+
+void Font::Release() {
+ if (id)
+ delete reinterpret_cast<QuartzTextStyle*>( id );
+
+ id = 0;
+}
+
+SurfaceImpl::SurfaceImpl() {
+ bitmapData = NULL; // Release will try and delete bitmapData if != NULL
+#ifdef SUPPORT_PORT
+ port = NULL;
+#endif
+ gc = NULL;
+ Release();
+}
+
+SurfaceImpl::~SurfaceImpl() {
+ Release();
+}
+
+void SurfaceImpl::Release() {
+ if ( bitmapData != NULL )
+ {
+ delete[] bitmapData;
+ // We only "own" the graphics context if we are a bitmap context
+ if ( gc != NULL ) CGContextRelease( gc );
+ }
+#ifdef SUPPORT_PORT
+ if ( port != NULL && gc != NULL) {
+ QDEndCGContext(port, &gc);
+ }
+#endif
+ bitmapData = NULL;
+ gc = NULL;
+
+ bitmapWidth = 0;
+ bitmapHeight = 0;
+ x = 0;
+ y = 0;
+ //inited = false;
+}
+
+bool SurfaceImpl::Initialised() {
+ // We are initalised if the graphics context is not null
+ return gc != NULL;// || port != NULL;
+}
+
+void SurfaceImpl::Init(WindowID /*wid*/) {
+ // To be able to draw, the surface must get a CGContext handle. We save the graphics port,
+ // then aquire/release the context on an as-need basis (see above).
+ // XXX Docs on QDBeginCGContext are light, a better way to do this would be good.
+ // AFAIK we should not hold onto a context retrieved this way, thus the need for
+ // aquire/release of the context.
+
+ Release();
+#ifdef SUPPORT_PORT
+ // Note, this seems to be unecessary, I have not seen any functionality loss by
+ // doing nothing in this method.
+
+ WindowRef window = GetControlOwner(reinterpret_cast<HIViewRef>(wid));
+ port = GetWindowPort(window);
+ QDBeginCGContext(port, &gc);
+#endif
+}
+
+void SurfaceImpl::Init(SurfaceID sid, WindowID /*wid*/) {
+ Release();
+ gc = reinterpret_cast<CGContextRef>( sid );
+ CGContextSetLineWidth( gc, 1.0 );
+}
+
+void SurfaceImpl::InitPixMap(int width, int height, Surface* /*surface_*/, WindowID /*wid*/) {
+ Release();
+ // Create a new bitmap context, along with the RAM for the bitmap itself
+ bitmapWidth = width;
+ bitmapHeight = height;
+
+ const int bitmapBytesPerRow = (width * BYTES_PER_PIXEL);
+ const int bitmapByteCount = (bitmapBytesPerRow * height);
+
+ // create an RGB color space
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ assert( colorSpace != NULL );
+
+ // create the bitmap
+ bitmapData = new uint8_t[ bitmapByteCount ];
+ assert( bitmapData != NULL );
+ if( bitmapData != NULL )
+ {
+ // create the context
+ gc = CGBitmapContextCreate( bitmapData,
+ width,
+ height,
+ BITS_PER_COMPONENT,
+ bitmapBytesPerRow,
+ colorSpace,
+ kCGImageAlphaPremultipliedLast);
+
+ if( gc == NULL )
+ {
+ // the context couldn't be created for some reason,
+ // and we have no use for the bitmap without the context
+ delete[] bitmapData;
+ bitmapData = NULL;
+ }
+ }
+
+ // the context retains the color space, so we can release it
+ CGColorSpaceRelease( colorSpace );
+
+ assert( gc != NULL && bitmapData != NULL );
+
+ // "Erase" to white
+ CGContextClearRect( gc, CGRectMake( 0, 0, width, height ) );
+ CGContextSetRGBFillColor( gc, 1.0, 1.0, 1.0, 1.0 );
+ CGContextFillRect( gc, CGRectMake( 0, 0, width, height ) );
+}
+
+void SurfaceImpl::PenColour(ColourAllocated fore) {
+ if (gc) {
+ ColourDesired colour( fore.AsLong() );
+
+ // Set the Stroke color to match
+ CGContextSetRGBStrokeColor( gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, 1.0 );
+ }
+}
+
+void SurfaceImpl::FillColour(const ColourAllocated& back) {
+ if (gc) {
+ ColourDesired colour( back.AsLong() );
+
+ // Set the Fill color to match
+ CGContextSetRGBFillColor( gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, 1.0 );
+ }
+}
+
+CGImageRef SurfaceImpl::GetImage() {
+ // For now, assume that GetImage can only be called on PixMap surfaces
+ if ( bitmapData == NULL ) return NULL;
+
+ CGContextFlush( gc );
+
+ // create an RGB color space
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ assert( colorSpace != NULL );
+
+ const int bitmapBytesPerRow = ((int) bitmapWidth * BYTES_PER_PIXEL);
+ const int bitmapByteCount = (bitmapBytesPerRow * (int) bitmapHeight);
+
+ // Create a data provider
+ CGDataProviderRef dataProvider = CGDataProviderCreateWithData( NULL, bitmapData, bitmapByteCount, NULL );
+ assert( dataProvider != NULL );
+
+ // create the CGImage
+ CGImageRef image = CGImageCreate( bitmapWidth,
+ bitmapHeight,
+ BITS_PER_COMPONENT,
+ BITS_PER_PIXEL,
+ bitmapBytesPerRow,
+ colorSpace,
+ kCGImageAlphaPremultipliedLast,
+ dataProvider,
+ NULL,
+ 0,
+ kCGRenderingIntentDefault );
+ assert( image != NULL );
+
+ // the image retains the color space, so we can release it
+ CGColorSpaceRelease( colorSpace );
+ colorSpace = NULL;
+
+ // Done with the data provider
+ CGDataProviderRelease( dataProvider );
+ dataProvider = NULL;
+
+ return image;
+}
+
+int SurfaceImpl::LogPixelsY() {
+ return 72;
+}
+
+int SurfaceImpl::DeviceHeightFont(int points) {
+ int logPix = LogPixelsY();
+ return (points * logPix + logPix / 2) / 72;
+}
+
+void SurfaceImpl::MoveTo(int x_, int y_) {
+ x = x_;
+ y = y_;
+}
+
+void SurfaceImpl::LineTo(int x_, int y_) {
+ CGContextBeginPath( gc );
+ // Because Quartz is based on floating point, lines are drawn with half their colour
+ // on each side of the line. Integer coordinates specify the INTERSECTION of the pixel
+ // divison lines. If you specify exact pixel values, you get a line that
+ // is twice as thick but half as intense. To get pixel aligned rendering,
+ // we render the "middle" of the pixels by adding 0.5 to the coordinates.
+ CGContextMoveToPoint( gc, x + 0.5, y + 0.5 );
+ CGContextAddLineToPoint( gc, x_ + 0.5, y_ + 0.5 );
+ CGContextStrokePath( gc );
+ x = x_;
+ y = y_;
+}
+
+void SurfaceImpl::Polygon(Scintilla::Point *pts, int npts, ColourAllocated fore,
+ ColourAllocated back) {
+ // Allocate memory for the array of points
+ CGPoint *points = new CGPoint[ npts ];
+
+ for (int i = 0;i < npts;i++) {
+ // Quartz floating point issues: plot the MIDDLE of the pixels
+ points[i].x = pts[i].x + 0.5;
+ points[i].y = pts[i].y + 0.5;
+ }
+
+ CGContextBeginPath( gc );
+
+ // Set colours
+ FillColour(back);
+ PenColour(fore);
+
+ // Draw the polygon
+ CGContextAddLines( gc, points, npts );
+ // TODO: Should the path be automatically closed, or is that the caller's responsability?
+ // Explicitly close the path, so it is closed for stroking AND filling (implicit close = filling only)
+ CGContextClosePath( gc );
+ CGContextDrawPath( gc, kCGPathFillStroke );
+
+ // Deallocate memory
+ delete points;
+ points = NULL;
+}
+
+void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
+ if ( gc ) {
+ CGContextBeginPath( gc );
+ FillColour(back);
+ PenColour(fore);
+
+ // Quartz integer -> float point conversion fun (see comment in SurfaceImpl::LineTo)
+ // We subtract 1 from the Width() and Height() so that all our drawing is within the area defined
+ // by the PRectangle. Otherwise, we draw one pixel too far to the right and bottom.
+ // TODO: Create some version of PRectangleToCGRect to do this conversion for us?
+ CGContextAddRect( gc, CGRectMake( rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1 ) );
+ CGContextDrawPath( gc, kCGPathFillStroke );
+ }
+}
+
+void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
+ if ( gc ) {
+ //CGContextBeginPath( gc );
+ FillColour(back);
+
+ CGRect rect = PRectangleToCGRect( rc );
+
+ CGContextFillRect( gc, rect );
+ //CGContextDrawPath( gc, kCGPathFill );
+ }
+}
+
+void drawImageRefCallback( CGImageRef pattern, CGContextRef gc )
+{
+ CGContextDrawImage( gc, CGRectMake( 0, 0, CGImageGetWidth( pattern ), CGImageGetHeight( pattern ) ), pattern );
+}
+
+void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
+ SurfaceImpl& patternSurface = static_cast<SurfaceImpl &>(surfacePattern);
+
+ // For now, assume that copy can only be called on PixMap surfaces
+ // Shows up black
+ CGImageRef image = patternSurface.GetImage();
+ if ( image == NULL )
+ {
+ FillRectangle(rc, ColourAllocated(0));
+ return;
+ }
+
+ assert( image != NULL );
+
+ const CGPatternCallbacks drawImageCallbacks = { 0, reinterpret_cast<CGPatternDrawPatternCallback>( drawImageRefCallback ), NULL };
+
+ CGPatternRef pattern = CGPatternCreate( image,
+ CGRectMake( 0, 0, patternSurface.bitmapWidth, patternSurface.bitmapHeight ),
+ CGAffineTransformIdentity,
+ patternSurface.bitmapWidth,
+ patternSurface.bitmapHeight,
+ kCGPatternTilingNoDistortion,
+ true,
+ &drawImageCallbacks
+ );
+ assert( pattern != NULL );
+
+ // Create a pattern color space
+ CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern( NULL );
+ assert( colorSpace != NULL );
+
+ CGContextSaveGState( gc );
+ CGContextSetFillColorSpace( gc, colorSpace );
+
+ // Unlike the documentation, you MUST pass in a "components" parameter:
+ // For coloured patterns it is the alpha value.
+ const float alpha = 1.0;
+ CGContextSetFillPattern( gc, pattern, &alpha );
+ CGContextFillRect( gc, PRectangleToCGRect( rc ) );
+
+ CGContextRestoreGState( gc );
+
+ // Free the color space, the pattern and image
+ CGColorSpaceRelease( colorSpace );
+ colorSpace = NULL;
+ CGPatternRelease( pattern );
+ pattern = NULL;
+ CGImageRelease( image );
+ image = NULL;
+}
+
+void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
+ // TODO: Look at the Win32 API to determine what this is supposed to do:
+ // ::RoundRect(hdc, rc.left + 1, rc.top, rc.right - 1, rc.bottom, 8, 8 );
+
+ // Create a rectangle with semicircles at the corners
+ const int MAX_RADIUS = 4;
+ int radius = Platform::Minimum( MAX_RADIUS, rc.Height()/2 );
+ radius = Platform::Minimum( radius, rc.Width()/2 );
+
+ // Points go clockwise, starting from just below the top left
+ // Corners are kept together, so we can easily create arcs to connect them
+ CGPoint corners[4][3] =
+ {
+ {
+ { rc.left, rc.top + radius },
+ { rc.left, rc.top },
+ { rc.left + radius, rc.top },
+ },
+ {
+ { rc.right - radius - 1, rc.top },
+ { rc.right - 1, rc.top },
+ { rc.right - 1, rc.top + radius },
+ },
+ {
+ { rc.right - 1, rc.bottom - radius - 1 },
+ { rc.right - 1, rc.bottom - 1 },
+ { rc.right - radius - 1, rc.bottom - 1 },
+ },
+ {
+ { rc.left + radius, rc.bottom - 1 },
+ { rc.left, rc.bottom - 1 },
+ { rc.left, rc.bottom - radius - 1 },
+ },
+ };
+
+ // Align the points in the middle of the pixels
+ // TODO: Should I include these +0.5 in the array creation code above?
+ for( int i = 0; i < 4*3; ++ i )
+ {
+ CGPoint* c = (CGPoint*) corners;
+ c[i].x += 0.5;
+ c[i].y += 0.5;
+ }
+
+ PenColour( fore );
+ FillColour( back );
+
+ // Move to the last point to begin the path
+ CGContextBeginPath( gc );
+ CGContextMoveToPoint( gc, corners[3][2].x, corners[3][2].y );
+
+ for ( int i = 0; i < 4; ++ i )
+ {
+ CGContextAddLineToPoint( gc, corners[i][0].x, corners[i][0].y );
+ CGContextAddArcToPoint( gc, corners[i][1].x, corners[i][1].y, corners[i][2].x, corners[i][2].y, radius );
+ }
+
+ // Close the path to enclose it for stroking and for filling, then draw it
+ CGContextClosePath( gc );
+ CGContextDrawPath( gc, kCGPathFillStroke );
+}
+
+void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
+ ColourAllocated outline, int alphaOutline, int flags) {
+ // XXX TODO
+ if ( gc ) {
+ CGContextBeginPath( gc );
+ //FillColour(fill);
+ PenColour(outline);
+
+ // Quartz integer -> float point conversion fun (see comment in SurfaceImpl::LineTo)
+ // We subtract 1 from the Width() and Height() so that all our drawing is within the area defined
+ // by the PRectangle. Otherwise, we draw one pixel too far to the right and bottom.
+ // TODO: Create some version of PRectangleToCGRect to do this conversion for us?
+ CGContextAddRect( gc, CGRectMake( rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1 ) );
+ CGContextDrawPath( gc, kCGPathFill );
+ }
+}
+
+void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
+ // Drawing an ellipse with bezier curves. Code modified from:
+ // http://www.codeguru.com/gdi/ellipse.shtml
+ // MAGICAL CONSTANT to map ellipse to beziers 2/3*(sqrt(2)-1)
+ const double EToBConst = 0.2761423749154;
+
+ CGSize offset = CGSizeMake((int)(rc.Width() * EToBConst), (int)(rc.Height() * EToBConst));
+ CGPoint centre = CGPointMake((rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2);
+
+ // The control point array
+ CGPoint cCtlPt[13];
+
+ // Assign values to all the control points
+ cCtlPt[0].x =
+ cCtlPt[1].x =
+ cCtlPt[11].x =
+ cCtlPt[12].x = rc.left + 0.5;
+ cCtlPt[5].x =
+ cCtlPt[6].x =
+ cCtlPt[7].x = rc.right - 0.5;
+ cCtlPt[2].x =
+ cCtlPt[10].x = centre.x - offset.width + 0.5;
+ cCtlPt[4].x =
+ cCtlPt[8].x = centre.x + offset.width + 0.5;
+ cCtlPt[3].x =
+ cCtlPt[9].x = centre.x + 0.5;
+
+ cCtlPt[2].y =
+ cCtlPt[3].y =
+ cCtlPt[4].y = rc.top + 0.5;
+ cCtlPt[8].y =
+ cCtlPt[9].y =
+ cCtlPt[10].y = rc.bottom - 0.5;
+ cCtlPt[7].y =
+ cCtlPt[11].y = centre.y + offset.height + 0.5;
+ cCtlPt[1].y =
+ cCtlPt[5].y = centre.y - offset.height + 0.5;
+ cCtlPt[0].y =
+ cCtlPt[12].y =
+ cCtlPt[6].y = centre.y + 0.5;
+
+ FillColour(back);
+ PenColour(fore);
+
+ CGContextBeginPath( gc );
+ CGContextMoveToPoint( gc, cCtlPt[0].x, cCtlPt[0].y );
+
+ for ( int i = 1; i < 13; i += 3 )
+ {
+ CGContextAddCurveToPoint( gc, cCtlPt[i].x, cCtlPt[i].y, cCtlPt[i+1].x, cCtlPt[i+1].y, cCtlPt[i+2].x, cCtlPt[i+2].y );
+ }
+
+ // Close the path to enclose it for stroking and for filling, then draw it
+ CGContextClosePath( gc );
+ CGContextDrawPath( gc, kCGPathFillStroke );
+}
+
+void SurfaceImpl::CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect)
+{
+ SurfaceImpl& source = static_cast<SurfaceImpl &>(surfaceSource);
+ CGImageRef image = source.GetImage();
+
+ CGRect src = PRectangleToCGRect(srcRect);
+ CGRect dst = PRectangleToCGRect(dstRect);
+
+ /* source from QuickDrawToQuartz2D.pdf on developer.apple.com */
+ float w = (float) CGImageGetWidth(image);
+ float h = (float) CGImageGetHeight(image);
+ CGRect drawRect = CGRectMake (0, 0, w, h);
+ if (!CGRectEqualToRect (src, dst))
+ {
+ float sx = CGRectGetWidth(dst) / CGRectGetWidth(src);
+ float sy = CGRectGetHeight(dst) / CGRectGetHeight(src);
+ float dx = CGRectGetMinX(dst) - (CGRectGetMinX(src) * sx);
+ float dy = CGRectGetMinY(dst) - (CGRectGetMinY(src) * sy);
+ drawRect = CGRectMake (dx, dy, w*sx, h*sy);
+ }
+ CGContextSaveGState (gc);
+ CGContextClipToRect (gc, dst);
+ CGContextDrawImage (gc, drawRect, image);
+ CGContextRestoreGState (gc);
+}
+
+void SurfaceImpl::Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource) {
+ // Maybe we have to make the Surface two contexts:
+ // a bitmap context which we do all the drawing on, and then a "real" context
+ // which we copy the output to when we call "Synchronize". Ugh! Gross and slow!
+
+ // For now, assume that copy can only be called on PixMap surfaces
+ SurfaceImpl& source = static_cast<SurfaceImpl &>(surfaceSource);
+
+ // Get the CGImageRef
+ CGImageRef image = source.GetImage();
+ // If we could not get an image reference, fill the rectangle black
+ if ( image == NULL )
+ {
+ FillRectangle( rc, ColourAllocated( 0 ) );
+ return;
+ }
+
+ assert( image != NULL );
+
+ // Now draw the image on the surface
+
+ // Some fancy clipping work is required here: draw only inside of rc
+ CGContextSaveGState( gc );
+ CGContextClipToRect( gc, PRectangleToCGRect( rc ) );
+
+ //Platform::DebugPrintf(stderr, "Copy: CGContextDrawImage: (%d, %d) - (%d X %d)\n", rc.left - from.x, rc.top - from.y, source.bitmapWidth, source.bitmapHeight );
+ CGContextDrawImage( gc, CGRectMake( rc.left - from.x, rc.top - from.y, source.bitmapWidth, source.bitmapHeight ), image );
+
+ // Undo the clipping fun
+ CGContextRestoreGState( gc );
+
+ // Done with the image
+ CGImageRelease( image );
+ image = NULL;
+}
+
+QuartzTextLayout* SurfaceImpl::GetTextLayout( Font &font_, const char *s, int len )
+{
+ // create the text layout
+ QuartzTextLayout* textLayout = new QuartzTextLayout( gc );
+ OSStatus err = textLayout->setText( reinterpret_cast<const UInt8*>( s ), len, ( unicodeMode ? kCFStringEncodingUTF8 : kCFStringEncodingASCII ) );
+ if (err != noErr) {
+ fprintf(stderr, "SurfaceImpl::GetTextLayout error calling textLayout->setText %d %s\n", err, unicodeMode?"Invalid UTF8":"Unknown error");
+ if (unicodeMode)
+ err = textLayout->setText( reinterpret_cast<const UInt8*>( s ), len, kCFStringEncodingASCII );
+ if (err != noErr)
+ return NULL;
+ }
+
+ textLayout->setStyle( *reinterpret_cast<QuartzTextStyle*>( font_.GetID() ) );
+
+ // TODO: If I could modify Scintilla to use ATSUHighlightText, this would not be required.
+ // However, using this setting makes Scintilla's rendering match TextEdit's (except for the antialiasing rules)
+ ATSLineLayoutOptions rendering = kATSLineUseDeviceMetrics;
+ textLayout->setControl( kATSULineLayoutOptionsTag, sizeof( rendering ), &rendering );
+
+ return textLayout;
+}
+
+void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len,
+ ColourAllocated fore, ColourAllocated back) {
+
+ FillRectangle(rc, back);
+ DrawTextTransparent( rc, font_, ybase, s, len, fore );
+}
+
+void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len,
+ ColourAllocated fore, ColourAllocated back) {
+
+ CGContextSaveGState( gc );
+ CGContextClipToRect( gc, PRectangleToCGRect( rc ) );
+ DrawTextNoClip( rc, font_, ybase, s, len, fore, back );
+ CGContextRestoreGState( gc );
+}
+
+void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore) {
+ PLATFORM_ASSERT( gc != NULL );
+ QuartzTextLayout* textLayout = GetTextLayout( font_, s, len );
+ if (!textLayout) return;
+ // The Quartz RGB fill color influences the ATSUI color
+ FillColour(fore);
+
+ // Draw the text, with the Y axis flipped
+ textLayout->draw( rc.left, ybase, true );
+
+ // Get rid of the layout object
+ delete textLayout;
+ textLayout = NULL;
+}
+
+void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) {
+ // sample at http://developer.apple.com/samplecode/ATSUICurveAccessDemo/listing1.html
+ // sample includes use of ATSUGetGlyphInfo which would be better for older
+ // OSX systems. We should expand to using that on older systems as well.
+ QuartzTextLayout* textLayout = GetTextLayout( font_, s, len );
+ if (!textLayout) return;
+
+ // Get the UNICODE character length
+ UniCharCount unicodeLength, unicodePosition;
+ OSStatus err;
+ err = ATSUGetTextLocation( textLayout->getLayout(), NULL, NULL, NULL, &unicodeLength, NULL );
+ assert( err == noErr );
+
+ ATSLayoutRecord *layoutRecords;
+ ItemCount numRecords;
+ // Get the arrays of glyph information
+ verify_noerr( ATSUDirectGetLayoutDataArrayPtrFromTextLayout(
+ textLayout->getLayout(), 0,
+ kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
+ (void **)&layoutRecords, &numRecords) );
+
+ int i, count;
+ long position;
+ unsigned char uch;
+ unsigned char mask;
+ FontID fontid = font_.GetID();
+
+ for ( unicodePosition = 0, i = 0; i < len && unicodePosition < numRecords; unicodePosition ++ ) {
+ if (fontid) {
+
+ // note: an extra layoutRecord is provided (eg. numRecords will be one
+ // more than unicodeLength). Each record contains the left x
+ // coordinate, but we need the right x coordinate, so we skip
+ // the first layoutRecord, thus unicodePosition+1.
+ position = Fix2Long( layoutRecords[unicodePosition+1].realPos );
+ uch = s[i];
+ positions[i++] = position;
+
+ // If we are using unicode (UTF8), map the Unicode position back to the UTF8 characters,
+ // as 1 unicode character can map to multiple UTF8 characters.
+ // See: http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF
+ // Or: http://www.cl.cam.ac.uk/~mgk25/unicode.html
+ if ( unicodeMode ) {
+ mask = 0xc0;
+ count = 1;
+ // Add one additonal byte for each extra high order one in the byte
+ while ( uch >= mask && count < 8 ) {
+ assert( i < len );
+ positions[i++] = position;
+ count ++;
+ mask = mask >> 1 | 0x80; // add an additional one in the highest order position
+ }
+ assert( count <= 8 );
+ }
+ } else {
+ positions[i++] = (i == 0) ? 1 : positions[i-1] + 1;
+ }
+ }
+ verify_noerr( ATSUDirectReleaseLayoutDataArrayPtr(NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void **)&layoutRecords) );
+ // Get rid of the layout object
+ delete textLayout;
+ textLayout = NULL;
+}
+
+int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
+ if (font_.GetID())
+ {
+ QuartzTextLayout* textLayout = GetTextLayout( font_, s, len );
+ if (!textLayout) return 0;
+
+ // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout?
+ unsigned long actualNumberOfBounds = 0;
+ ATSTrapezoid glyphBounds;
+
+ // We get a single bound, since the text should only require one. If it requires more, there is an issue
+ if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 )
+ {
+ Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthText" );
+ // Get rid of the layout object
+ delete textLayout;
+ textLayout = NULL;
+ return 0;
+ }
+
+ //Platform::DebugPrintf( "WidthText: \"%*s\" = %ld\n", len, s, Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ) );
+
+ // Get rid of the layout object
+ delete textLayout;
+ textLayout = NULL;
+ return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x );
+ }
+ return 1;
+}
+
+int SurfaceImpl::WidthChar(Font &font_, char ch) {
+ char str[2] = { ch, '\0' };
+ if (font_.GetID())
+ {
+ QuartzTextLayout* textLayout = GetTextLayout( font_, str, 1 );
+ if (!textLayout) return 0;
+
+ // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout?
+ unsigned long actualNumberOfBounds = 0;
+ ATSTrapezoid glyphBounds;
+
+ // We get a single bound, since the text should only require one. If it requires more, there is an issue
+ if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 )
+ {
+ Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthChar" );
+ // Get rid of the layout object
+ delete textLayout;
+ textLayout = NULL;
+ return 0;
+ }
+
+ // Get rid of the layout object
+ delete textLayout;
+ textLayout = NULL;
+ return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x );
+ }
+ else
+ return 1;
+}
+
+// Three possible strategies for determining ascent and descent of font:
+// 1) Call ATSUGetGlyphBounds with string containing all letters, numbers and punctuation.
+// 2) Use the ascent and descent fields of the font.
+// 3) Call ATSUGetGlyphBounds with string as 1 but also including accented capitals.
+// Smallest values given by 1 and largest by 3 with 2 in between.
+// Techniques 1 and 2 sometimes chop off extreme portions of ascenders and
+// descenders but are mostly OK except for accented characters which are
+// rarely used in code.
+
+// This string contains a good range of characters to test for size.
+const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890"
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+int SurfaceImpl::Ascent(Font &font_) {
+ if (!font_.GetID())
+ return 1;
+
+ ATSUTextMeasurement ascent = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getAttribute<ATSUTextMeasurement>( kATSUAscentTag );
+ return Fix2Long( ascent );
+}
+
+int SurfaceImpl::Descent(Font &font_) {
+ if (!font_.GetID())
+ return 1;
+
+ ATSUTextMeasurement descent = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getAttribute<ATSUTextMeasurement>( kATSUDescentTag );
+ return Fix2Long( descent );
+}
+
+int SurfaceImpl::InternalLeading(Font &) {
+ // TODO: How do we get EM_Size?
+ // internal leading = ascent - descent - EM_size
+ return 0;
+}
+
+int SurfaceImpl::ExternalLeading(Font &font_) {
+ if (!font_.GetID())
+ return 1;
+
+ ATSUTextMeasurement lineGap = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getAttribute<ATSUTextMeasurement>( kATSULeadingTag );
+ return Fix2Long( lineGap );
+}
+
+int SurfaceImpl::Height(Font &font_) {
+ return Ascent(font_) + Descent(font_);
+}
+
+int SurfaceImpl::AverageCharWidth(Font &font_) {
+
+ if (!font_.GetID())
+ return 1;
+
+ const int sizeStringLength = (sizeof( sizeString ) / sizeof( sizeString[0] ) - 1);
+ int width = WidthText( font_, sizeString, sizeStringLength );
+
+ return (int) ((width / (float) sizeStringLength) + 0.5);
+
+ /*
+ ATSUStyle textStyle = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getATSUStyle();
+ ATSUFontID fontID;
+
+ ByteCount actualSize = 0;
+ if ( ATSUGetAttribute( textStyle, kATSUFontTag, sizeof( fontID ), &fontID, &actualSize ) != noErr )
+ {
+Platform::DebugDisplay( "ATSUGetAttribute failed" );
+ return 1;
+ }
+
+ ATSFontMetrics metrics;
+ memset( &metrics, 0, sizeof( metrics ) );
+ if ( ATSFontGetHorizontalMetrics( fontID, kATSOptionFlagsDefault, &metrics ) != noErr )
+ {
+ Platform::DebugDisplay( "ATSFontGetHorizontalMetrics failed in AverageCharWidth" );
+ return 1;
+ }
+
+ printf( "%f %f %f\n", metrics.avgAdvanceWidth * 32, metrics.ascent * 32, metrics.descent * 32 );
+
+ return (int) (metrics.avgAdvanceWidth + 0.5);*/
+}
+
+int SurfaceImpl::SetPalette(Scintilla::Palette *, bool) {
+ // Mac OS X is always true colour (I think) so this doesn't matter
+ return 0;
+}
+
+void SurfaceImpl::SetClip(PRectangle rc) {
+ CGContextClipToRect( gc, PRectangleToCGRect( rc ) );
+}
+
+void SurfaceImpl::FlushCachedState() {
+ CGContextSynchronize( gc );
+}
+
+void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) {
+ unicodeMode = unicodeMode_;
+}
+
+void SurfaceImpl::SetDBCSMode(int codePage) {
+ // TODO: Implement this
+}
+
+Surface *Surface::Allocate() {
+ return new SurfaceImpl( );
+}
+
+Window::~Window() {}
+
+void Window::Destroy() {
+ if (windowRef) {
+ DisposeWindow(reinterpret_cast<WindowRef>( windowRef ));
+ }
+ id = 0;
+}
+
+bool Window::HasFocus() {
+ // TODO: Test this
+ return HIViewSubtreeContainsFocus( reinterpret_cast<HIViewRef>( id ) );
+}
+
+PRectangle Window::GetPosition() {
+ // Before any size allocated pretend its 1000 wide so not scrolled
+ PRectangle rc(0, 0, 1000, 1000);
+
+ // The frame rectangle gives the position of this view inside the parent view
+ if (id) {
+ HIRect controlFrame;
+ HIViewGetFrame( reinterpret_cast<HIViewRef>( id ), &controlFrame );
+ rc = CGRectToPRectangle( controlFrame );
+ }
+
+ return rc;
+}
+
+void Window::SetPosition(PRectangle rc) {
+ // Moves this view inside the parent view
+ if ( id )
+ {
+ // Set the frame on the view, the function handles the rest
+ CGRect r = PRectangleToCGRect( rc );
+ HIViewSetFrame( reinterpret_cast<HIViewRef>( id ), &r );
+ }
+}
+
+void Window::SetPositionRelative(PRectangle rc, Window window) {
+ // used to actually move child windows (ie. listbox/calltip) so we have to move
+ // the window, not the hiview
+ if (windowRef) {
+ // we go through some contortions here to get an accurate location for our
+ // child windows. This is necessary due to the multiple ways an embedding
+ // app may be setup. See SciTest/main.c (GOOD && BAD) for test case.
+ WindowRef relativeWindow = GetControlOwner(reinterpret_cast<HIViewRef>( window.GetID() ));
+ WindowRef thisWindow = reinterpret_cast<WindowRef>( windowRef );
+
+ Rect portBounds;
+ ::GetWindowBounds(relativeWindow, kWindowStructureRgn, &portBounds);
+ //fprintf(stderr, "portBounds %d %d %d %d\n", portBounds.left, portBounds.top, portBounds.right, portBounds.bottom);
+ PRectangle hbounds = window.GetPosition();
+ //fprintf(stderr, "hbounds %d %d %d %d\n", hbounds.left, hbounds.top, hbounds.right, hbounds.bottom);
+ HIViewRef parent = HIViewGetSuperview(reinterpret_cast<HIViewRef>( window.GetID() ));
+ Rect pbounds;
+ GetControlBounds(parent, &pbounds);
+ //fprintf(stderr, "pbounds %d %d %d %d\n", pbounds.left, pbounds.top, pbounds.right, pbounds.bottom);
+
+ PRectangle bounds;
+ bounds.top = portBounds.top + pbounds.top + hbounds.top + rc.top;
+ bounds.bottom = bounds.top + rc.Height();
+ bounds.left = portBounds.left + pbounds.left + hbounds.left + rc.left;
+ bounds.right = bounds.left + rc.Width();
+ //fprintf(stderr, "bounds %d %d %d %d\n", bounds.left, bounds.top, bounds.right, bounds.bottom);
+
+ MoveWindow(thisWindow, bounds.left, bounds.top, false);
+ SizeWindow(thisWindow, bounds.Width(), bounds.Height(), true);
+
+ SetPosition(PRectangle(0,0,rc.Width(),rc.Height()));
+ } else {
+ SetPosition(rc);
+ }
+}
+
+PRectangle Window::GetClientPosition() {
+ // This means, in MacOS X terms, get the "frame bounds". Call GetPosition, just like on Win32.
+ return GetPosition();
+}
+
+void Window::Show(bool show) {
+ if ( id ) {
+ HIViewSetVisible( reinterpret_cast<HIViewRef>( id ), show );
+ }
+ // this is necessary for calltip/listbox
+ if (windowRef) {
+ WindowRef thisWindow = reinterpret_cast<WindowRef>( windowRef );
+ if (show) {
+ ShowWindow( thisWindow );
+ DrawControls( thisWindow );
+ } else
+ HideWindow( thisWindow );
+ }
+}
+
+void Window::InvalidateAll() {
+ if ( id ) {
+ OSStatus err;
+ err = HIViewSetNeedsDisplay( reinterpret_cast<HIViewRef>( id ), true );
+ assert( err == noErr );
+ }
+}
+
+void Window::InvalidateRectangle(PRectangle rc) {
+ if (id) {
+ // Create a rectangular region
+ RgnHandle region = NewRgn();
+ assert( region != NULL );
+ SetRectRgn( region, rc.left, rc.top, rc.right, rc.bottom );
+
+ // Make that region invalid
+ OSStatus err;
+ err = HIViewSetNeedsDisplayInRegion( reinterpret_cast<HIViewRef>( id ), region, true );
+ assert( err == noErr );
+ DisposeRgn( region );
+ }
+}
+
+void Window::SetFont(Font &) {
+ // TODO: Do I need to implement this? MSDN: specifies the font that a control is to use when drawing text.
+}
+
+void Window::SetCursor(Cursor curs) {
+ if (id) {
+ // TODO: This isn't really implemented correctly. I should be using
+ // mouse tracking rectangles to only set the mouse cursor when it is over the control
+ ThemeCursor cursor;
+
+ switch ( curs ) {
+ case cursorText:
+ cursor = kThemeIBeamCursor;
+ break;
+ case cursorArrow:
+ cursor = kThemeArrowCursor;
+ break;
+ case cursorWait:
+ cursor = kThemeWatchCursor;
+ break;
+ case cursorHoriz:
+ cursor = kThemeResizeLeftRightCursor;
+ break;
+ case cursorVert:
+ case cursorReverseArrow:
+ case cursorUp:
+ default:
+ cursor = kThemeArrowCursor;
+ break;
+ }
+
+ SetThemeCursor( cursor );
+ }
+}
+
+void Window::SetTitle(const char *s) {
+ WindowRef window = GetControlOwner(reinterpret_cast<HIViewRef>( id ));
+ CFStringRef title = CFStringCreateWithCString(kCFAllocatorDefault, s, kCFStringEncodingMacRoman);
+ SetWindowTitleWithCFString(window, title);
+ CFRelease(title);
+}
+
+ListBox::ListBox() {}
+
+ListBox::~ListBox() {}
+
+static const OSType scintillaListBoxType = 'sclb';
+
+enum {
+ kItemsPerContainer = 1,
+ kIconColumn = 'icon',
+ kTextColumn = 'text'
+};
+static SInt32 kScrollBarWidth = 0;
+
+class LineData {
+ int *types;
+ CFStringRef *strings;
+ int len;
+ int maximum;
+public:
+ LineData() :types(0), strings(0), len(0), maximum(0) {}
+ ~LineData() {
+ Clear();
+ }
+ void Clear() {
+ delete []types;
+ types = 0;
+ for (int i=0; i<maximum; i++) {
+ if (strings[i]) CFRelease(strings[i]);
+ }
+ delete []strings;
+ strings = 0;
+ len = 0;
+ maximum = 0;
+ }
+ void Add(int index, int type, CFStringRef str ) {
+ if (index >= maximum) {
+ if (index >= len) {
+ int lenNew = (index+1) * 2;
+ int *typesNew = new int[lenNew];
+ CFStringRef *stringsNew = new CFStringRef[lenNew];
+ for (int i=0; i<maximum; i++) {
+ typesNew[i] = types[i];
+ stringsNew[i] = strings[i];
+ }
+ delete []types;
+ delete []strings;
+ types = typesNew;
+ strings = stringsNew;
+ len = lenNew;
+ }
+ while (maximum < index) {
+ types[maximum] = 0;
+ strings[maximum] = 0;
+ maximum++;
+ }
+ }
+ types[index] = type;
+ strings[index] = str;
+ if (index == maximum) {
+ maximum++;
+ }
+ }
+ int GetType(int index) {
+ if (index < maximum) {
+ return types[index];
+ } else {
+ return 0;
+ }
+ }
+ CFStringRef GetString(int index) {
+ if (index < maximum) {
+ return strings[index];
+ } else {
+ return 0;
+ }
+ }
+};
+
+class ListBoxImpl : public ListBox {
+private:
+ ControlRef lb;
+ XPMSet xset;
+ int lineHeight;
+ bool unicodeMode;
+ int desiredVisibleRows;
+ unsigned int maxItemCharacters;
+ unsigned int aveCharWidth;
+ Font font;
+ int maxWidth;
+
+ void InstallDataBrowserCustomCallbacks();
+ void ConfigureDataBrowser();
+
+ static pascal OSStatus WindowEventHandler(EventHandlerCallRef inCallRef,
+ EventRef inEvent,
+ void *inUserData );
+ EventHandlerRef eventHandler;
+
+protected:
+ WindowRef windowRef;
+
+public:
+ LineData ld;
+ CallBackAction doubleClickAction;
+ void *doubleClickActionData;
+
+ ListBoxImpl() : lb(NULL), lineHeight(10), unicodeMode(false),
+ desiredVisibleRows(5), maxItemCharacters(0), aveCharWidth(8),
+ doubleClickAction(NULL), doubleClickActionData(NULL)
+ {
+ if (kScrollBarWidth == 0)
+ GetThemeMetric(kThemeMetricScrollBarWidth, &kScrollBarWidth);
+ }
+
+ ~ListBoxImpl() {};
+ void SetFont(Font &font);
+ void Create(Window &parent, int ctrlID, Scintilla::Point pt, int lineHeight_, bool unicodeMode_);
+ void SetAverageCharWidth(int width);
+ void SetVisibleRows(int rows);
+ int GetVisibleRows() const;
+ PRectangle GetDesiredRect();
+ int CaretFromEdge();
+ void Clear();
+ void Append(char *s, int type = -1);
+ int Length();
+ void Select(int n);
+ int GetSelection();
+ int Find(const char *prefix);
+ void GetValue(int n, char *value, int len);
+ void Sort();
+ void RegisterImage(int type, const char *xpm_data);
+ void ClearRegisteredImages();
+ void SetDoubleClickAction(CallBackAction action, void *data) {
+ doubleClickAction = action;
+ doubleClickActionData = data;
+ }
+
+ int IconWidth();
+ void ShowHideScrollbar();
+#ifdef DB_TABLE_ROW_HEIGHT
+ void SetRowHeight(DataBrowserItemID itemID);
+#endif
+
+ void DrawRow(DataBrowserItemID item,
+ DataBrowserPropertyID property,
+ DataBrowserItemState itemState,
+ const Rect *theRect);
+
+ void SetList(const char* list, char separator, char typesep);
+};
+
+ListBox *ListBox::Allocate() {
+ ListBoxImpl *lb = new ListBoxImpl();
+ return lb;
+}
+
+void ListBoxImpl::Create(Window &/*parent*/, int /*ctrlID*/, Scintilla::Point /*pt*/,
+ int lineHeight_, bool unicodeMode_) {
+ lineHeight = lineHeight_;
+ unicodeMode = unicodeMode_;
+ maxWidth = 1000;
+
+ WindowClass windowClass = kHelpWindowClass;
+ WindowAttributes attributes = kWindowNoAttributes;
+ Rect contentBounds;
+ WindowRef outWindow;
+
+ contentBounds.top = contentBounds.left = 0;
+ contentBounds.right = 100;
+ contentBounds.bottom = lineHeight * desiredVisibleRows;
+
+ CreateNewWindow(windowClass, attributes, &contentBounds, &outWindow);
+
+ InstallStandardEventHandler(GetWindowEventTarget(outWindow));
+
+ ControlRef root;
+ CreateRootControl(outWindow, &root);
+
+ CreateDataBrowserControl(outWindow, &contentBounds, kDataBrowserListView, &lb);
+
+#ifdef DB_TABLE_ROW_HEIGHT
+ // XXX does not seem to have any effect
+ SetDataBrowserTableViewRowHeight(lb, lineHeight);
+#endif
+
+ // get rid of the frame, forces databrowser to the full size
+ // of the window
+ Boolean frameAndFocus = false;
+ SetControlData(lb, kControlNoPart, kControlDataBrowserIncludesFrameAndFocusTag,
+ sizeof(frameAndFocus), &frameAndFocus);
+
+ ListBoxImpl* lbThis = this;
+ SetControlProperty( lb, scintillaListBoxType, 0, sizeof( this ), &lbThis );
+
+ ConfigureDataBrowser();
+ InstallDataBrowserCustomCallbacks();
+
+ // install event handlers
+ static const EventTypeSpec kWindowEvents[] =
+ {
+ { kEventClassMouse, kEventMouseDown },
+ { kEventClassMouse, kEventMouseMoved },
+ };
+
+ eventHandler = NULL;
+ InstallWindowEventHandler( outWindow, WindowEventHandler,
+ GetEventTypeCount( kWindowEvents ),
+ kWindowEvents, this, &eventHandler );
+
+ id = lb;
+ SetControlVisibility(lb, true, true);
+ SetControl(lb);
+ SetWindow(outWindow);
+}
+
+pascal OSStatus ListBoxImpl::WindowEventHandler(
+ EventHandlerCallRef inCallRef,
+ EventRef inEvent,
+ void* inUserData )
+{
+
+ switch (GetEventClass(inEvent)) {
+ case kEventClassMouse:
+ switch (GetEventKind(inEvent))
+ {
+ case kEventMouseMoved:
+ {
+ SetThemeCursor( kThemeArrowCursor );
+ break;
+ }
+ case kEventMouseDown:
+ {
+ // we cannot handle the double click from the databrowser notify callback as
+ // calling doubleClickAction causes the listbox to be destroyed. It is
+ // safe to do it from this event handler since the destroy event will be queued
+ // until we're done here.
+ TCarbonEvent event( inEvent );
+ EventMouseButton inMouseButton;
+ event.GetParameter<EventMouseButton>( kEventParamMouseButton, typeMouseButton, &inMouseButton );
+
+ UInt32 inClickCount;
+ event.GetParameter( kEventParamClickCount, &inClickCount );
+ if (inMouseButton == kEventMouseButtonPrimary && inClickCount == 2) {
+ // handle our single mouse click now
+ ListBoxImpl* listbox = reinterpret_cast<ListBoxImpl*>( inUserData );
+ const WindowRef window = GetControlOwner(listbox->lb);
+ const HIViewRef rootView = HIViewGetRoot( window );
+ HIViewRef targetView = NULL;
+ HIViewGetViewForMouseEvent( rootView, inEvent, &targetView );
+ if ( targetView == listbox->lb )
+ {
+ if (listbox->doubleClickAction != NULL) {
+ listbox->doubleClickAction(listbox->doubleClickActionData);
+ }
+ }
+ }
+ }
+ }
+ }
+ return eventNotHandledErr;
+}
+
+#ifdef DB_TABLE_ROW_HEIGHT
+void ListBoxImpl::SetRowHeight(DataBrowserItemID itemID)
+{
+ // XXX does not seem to have any effect
+ SetDataBrowserTableViewItemRowHeight(lb, itemID, lineHeight);
+}
+#endif
+
+void ListBoxImpl::DrawRow(DataBrowserItemID item,
+ DataBrowserPropertyID property,
+ DataBrowserItemState itemState,
+ const Rect *theRect)
+{
+ Rect row = *theRect;
+ row.left = 0;
+
+ ColourPair fore;
+
+ if (itemState == kDataBrowserItemIsSelected) {
+ long systemVersion;
+ Gestalt( gestaltSystemVersion, &systemVersion );
+ // Panther DB starts using kThemeBrushSecondaryHighlightColor for inactive browser hilighting
+ if ( (systemVersion >= 0x00001030) && (IsControlActive( lb ) == false) )
+ SetThemePen( kThemeBrushSecondaryHighlightColor, 32, true );
+ else
+ //SetThemePen( kThemeBrushPrimaryHighlightColor, 32, true );
+ SetThemePen( kThemeBrushAlternatePrimaryHighlightColor, 32, true );
+
+ PaintRect(&row);
+ fore = ColourDesired(0xff,0xff,0xff);
+ }
+
+ int widthPix = xset.GetWidth() + 2;
+ int pixId = ld.GetType(item - 1);
+ XPM *pxpm = xset.Get(pixId);
+
+ char s[255];
+ GetValue(item - 1, s, 255);
+
+ Surface *surfaceItem = Surface::Allocate();
+ if (surfaceItem) {
+ CGContextRef cgContext;
+ GrafPtr port;
+ Rect bounds;
+
+ GetControlBounds(lb, &bounds);
+ GetPort( &port );
+ QDBeginCGContext( port, &cgContext );
+
+ CGContextSaveGState( cgContext );
+ CGContextTranslateCTM(cgContext, 0, bounds.bottom - bounds.top);
+ CGContextScaleCTM(cgContext, 1.0, -1.0);
+
+ surfaceItem->Init(cgContext, NULL);
+
+ int left = row.left;
+ if (pxpm) {
+ PRectangle rc(left + 1, row.top,
+ left + 1 + widthPix, row.bottom);
+ pxpm->Draw(surfaceItem, rc);
+ }
+
+ // draw the text
+ PRectangle trc(left + 2 + widthPix, row.top, row.right, row.bottom);
+ int ascent = surfaceItem->Ascent(font) - surfaceItem->InternalLeading(font);
+ int ytext = trc.top + ascent + 1;
+ trc.bottom = ytext + surfaceItem->Descent(font) + 1;
+ surfaceItem->DrawTextTransparent( trc, font, ytext, s, strlen(s), fore.allocated );
+
+ CGContextRestoreGState( cgContext );
+ QDEndCGContext( port, &cgContext );
+ delete surfaceItem;
+ }
+}
+
+
+pascal void ListBoxDrawItemCallback(ControlRef browser, DataBrowserItemID item,
+ DataBrowserPropertyID property,
+ DataBrowserItemState itemState,
+ const Rect *theRect, SInt16 gdDepth,
+ Boolean colorDevice)
+{
+ if (property != kIconColumn) return;
+ ListBoxImpl* lbThis = NULL;
+ OSStatus err;
+ err = GetControlProperty( browser, scintillaListBoxType, 0, sizeof( lbThis ), NULL, &lbThis );
+ // adjust our rect
+ lbThis->DrawRow(item, property, itemState, theRect);
+
+}
+
+void ListBoxImpl::ConfigureDataBrowser()
+{
+ DataBrowserViewStyle viewStyle;
+ DataBrowserSelectionFlags selectionFlags;
+ ::GetDataBrowserViewStyle(lb, &viewStyle);
+
+ ::SetDataBrowserHasScrollBars(lb, false, true);
+ ::SetDataBrowserListViewHeaderBtnHeight(lb, 0);
+ ::GetDataBrowserSelectionFlags(lb, &selectionFlags);
+ ::SetDataBrowserSelectionFlags(lb, selectionFlags |= kDataBrowserSelectOnlyOne);
+ // if you change the hilite style, also change the style in ListBoxDrawItemCallback
+ ::SetDataBrowserTableViewHiliteStyle(lb, kDataBrowserTableViewFillHilite);
+
+ Rect insetRect;
+ ::GetDataBrowserScrollBarInset(lb, &insetRect);
+
+ insetRect.right = kScrollBarWidth - 1;
+ ::SetDataBrowserScrollBarInset(lb, &insetRect);
+
+ switch (viewStyle)
+ {
+ case kDataBrowserListView:
+ {
+ DataBrowserListViewColumnDesc iconCol;
+ iconCol.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
+ iconCol.headerBtnDesc.minimumWidth = 0;
+ iconCol.headerBtnDesc.maximumWidth = maxWidth;
+ iconCol.headerBtnDesc.titleOffset = 0;
+ iconCol.headerBtnDesc.titleString = NULL;
+ iconCol.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing;
+
+ iconCol.headerBtnDesc.btnFontStyle.flags = kControlUseJustMask;
+ iconCol.headerBtnDesc.btnFontStyle.just = teFlushLeft;
+
+ iconCol.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
+
+ iconCol.propertyDesc.propertyID = kIconColumn;
+ iconCol.propertyDesc.propertyType = kDataBrowserCustomType;
+ iconCol.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn;
+
+ ::AddDataBrowserListViewColumn(lb, &iconCol, kDataBrowserListViewAppendColumn);
+ } break;
+
+ }
+}
+
+void ListBoxImpl::InstallDataBrowserCustomCallbacks()
+{
+ DataBrowserCustomCallbacks callbacks;
+
+ callbacks.version = kDataBrowserLatestCustomCallbacks;
+ verify_noerr(InitDataBrowserCustomCallbacks(&callbacks));
+ callbacks.u.v1.drawItemCallback = NewDataBrowserDrawItemUPP(ListBoxDrawItemCallback);
+ callbacks.u.v1.hitTestCallback = NULL;//NewDataBrowserHitTestUPP(ListBoxHitTestCallback);
+ callbacks.u.v1.trackingCallback = NULL;//NewDataBrowserTrackingUPP(ListBoxTrackingCallback);
+ callbacks.u.v1.editTextCallback = NULL;
+ callbacks.u.v1.dragRegionCallback = NULL;
+ callbacks.u.v1.acceptDragCallback = NULL;
+ callbacks.u.v1.receiveDragCallback = NULL;
+
+ SetDataBrowserCustomCallbacks(lb, &callbacks);
+}
+
+void ListBoxImpl::SetFont(Font &font_) {
+ // Having to do this conversion is LAME
+ QuartzTextStyle *ts = reinterpret_cast<QuartzTextStyle*>( font_.GetID() );
+ ControlFontStyleRec style;
+ ATSUAttributeValuePtr value;
+ ATSUFontID fontID;
+ style.flags = kControlUseFontMask | kControlUseSizeMask | kControlAddToMetaFontMask;
+ ts->getAttribute( kATSUFontTag, sizeof(fontID), &fontID, NULL );
+ ATSUFontIDtoFOND(fontID, &style.font, NULL);
+ ts->getAttribute( kATSUSizeTag, sizeof(Fixed), &value, NULL );
+ style.size = ((SInt16)FixRound((SInt32)value));
+ SetControlFontStyle(lb, &style);
+
+#ifdef DB_TABLE_ROW_HEIGHT
+ // XXX this doesn't *stick*
+ ATSUTextMeasurement ascent = ts->getAttribute<ATSUTextMeasurement>( kATSUAscentTag );
+ ATSUTextMeasurement descent = ts->getAttribute<ATSUTextMeasurement>( kATSUDescentTag );
+ lineHeight = Fix2Long( ascent ) + Fix2Long( descent );
+ SetDataBrowserTableViewRowHeight(lb, lineHeight + lineLeading);
+#endif
+
+ // !@&^#%$ we cant copy Font, but we need one for our custom drawing
+ Str255 fontName;
+ if (FMGetFontFamilyName(style.font, fontName) != kFMInvalidFontFamilyErr) {
+ // make sure we conver to a proper C string first.
+ char cFontName[255];
+ CopyPascalStringToC(fontName, cFontName);
+ font.Create((const char *)cFontName, 0, style.size, false, false);
+ }
+}
+
+void ListBoxImpl::SetAverageCharWidth(int width) {
+ aveCharWidth = width;
+}
+
+void ListBoxImpl::SetVisibleRows(int rows) {
+ desiredVisibleRows = rows;
+}
+
+int ListBoxImpl::GetVisibleRows() const {
+ // XXX Windows & GTK do this, but it seems incorrect to me. Other logic
+ // to do with visible rows is essentially the same across platforms.
+ return desiredVisibleRows;
+ /*
+ // This would be more correct
+ int rows = Length();
+ if ((rows == 0) || (rows > desiredVisibleRows))
+ rows = desiredVisibleRows;
+ return rows;
+ */
+}
+
+PRectangle ListBoxImpl::GetDesiredRect() {
+ PRectangle rcDesired = GetPosition();
+
+ // XXX because setting the line height on the table doesnt
+ // *stick*, we'll have to suffer and just use whatever
+ // the table desides is the correct height.
+ UInt16 itemHeight;// = lineHeight;
+ GetDataBrowserTableViewRowHeight(lb, &itemHeight);
+
+ int rows = Length();
+ if ((rows == 0) || (rows > desiredVisibleRows))
+ rows = desiredVisibleRows;
+
+ rcDesired.bottom = itemHeight * rows;
+ int width = maxItemCharacters;
+ if (width < 12)
+ width = 12;
+ // XXX use the quartz text stuff to figure out the correct string width
+ rcDesired.right = rcDesired.left + width * (aveCharWidth+aveCharWidth/4);
+ if (rcDesired.right > maxWidth) {
+ rcDesired.right = maxWidth;
+ }
+ if (Length() > rows)
+ rcDesired.right += kScrollBarWidth;
+ rcDesired.right += IconWidth();
+ return rcDesired;
+}
+
+void ListBoxImpl::ShowHideScrollbar() {
+ int rows = Length();
+ if (rows > desiredVisibleRows) {
+ ::SetDataBrowserHasScrollBars(lb, false, true);
+ } else {
+ ::SetDataBrowserHasScrollBars(lb, false, false);
+ }
+}
+
+int ListBoxImpl::IconWidth() {
+ return xset.GetWidth() + 2;
+}
+
+int ListBoxImpl::CaretFromEdge() {
+ return 0;
+}
+
+void ListBoxImpl::Clear() {
+ // passing NULL to "items" arg 4 clears the list
+ maxItemCharacters = 0;
+ ld.Clear();
+ AddDataBrowserItems (lb, kDataBrowserNoItem, 0, NULL, kDataBrowserItemNoProperty);
+}
+
+void ListBoxImpl::Append(char *s, int type) {
+ int count = Length();
+ CFStringRef r = CFStringCreateWithCString(NULL, s, kTextEncodingMacRoman);
+ ld.Add(count, type, r);
+
+ DataBrowserItemID items[1];
+ items[0] = count + 1;
+ AddDataBrowserItems (lb, kDataBrowserNoItem, 1, items, kDataBrowserItemNoProperty);
+ ShowHideScrollbar();
+
+ size_t len = strlen(s);
+ if (maxItemCharacters < len)
+ maxItemCharacters = len;
+
+}
+
+void ListBoxImpl::SetList(const char* list, char separator, char typesep) {
+ // XXX copied from PlatGTK, should be in base class
+ Clear();
+ int count = strlen(list) + 1;
+ char *words = new char[count];
+ if (words) {
+ memcpy(words, list, count);
+ char *startword = words;
+ char *numword = NULL;
+ int i = 0;
+ for (; words[i]; i++) {
+ if (words[i] == separator) {
+ words[i] = '\0';
+ if (numword)
+ *numword = '\0';
+ Append(startword, numword?atoi(numword + 1):-1);
+ startword = words + i + 1;
+ numword = NULL;
+ } else if (words[i] == typesep) {
+ numword = words + i;
+ }
+ }
+ if (startword) {
+ if (numword)
+ *numword = '\0';
+ Append(startword, numword?atoi(numword + 1):-1);
+ }
+ delete []words;
+ }
+}
+
+int ListBoxImpl::Length() {
+ UInt32 numItems = 0;
+ GetDataBrowserItemCount(lb, kDataBrowserNoItem, false, kDataBrowserItemAnyState, &numItems);
+ return (int)numItems;
+}
+
+void ListBoxImpl::Select(int n) {
+ DataBrowserItemID items[1];
+ items[0] = n + 1;
+ SetDataBrowserSelectedItems(lb, 1, items, kDataBrowserItemsAssign);
+ RevealDataBrowserItem(lb, items[0], kIconColumn, kDataBrowserRevealOnly);
+ // force update on selection
+ Draw1Control(lb);
+}
+
+int ListBoxImpl::GetSelection() {
+ Handle selectedItems = NewHandle(0);
+ GetDataBrowserItems(lb, kDataBrowserNoItem, true, kDataBrowserItemIsSelected, selectedItems);
+ UInt32 numSelectedItems = GetHandleSize(selectedItems)/sizeof(DataBrowserItemID);
+ if (numSelectedItems == 0) {
+ return -1;
+ }
+ HLock( selectedItems );
+ DataBrowserItemID *individualItem = (DataBrowserItemID*)( *selectedItems );
+ DataBrowserItemID selected[numSelectedItems];
+ selected[0] = *individualItem;
+ HUnlock( selectedItems );
+ return selected[0] - 1;
+}
+
+int ListBoxImpl::Find(const char *prefix) {
+ int count = Length();
+ char s[255];
+ for (int i = 0; i < count; i++) {
+ GetValue(i, s, 255);
+ if (s[0] != NULL && (0 == strncmp(prefix, s, strlen(prefix)))) {
+ return i;
+ }
+ }
+ return - 1;
+}
+
+void ListBoxImpl::GetValue(int n, char *value, int len) {
+ CFStringRef textString = ld.GetString(n);
+ if (textString == NULL) {
+ value[0] = '\0';
+ return;
+ }
+ CFIndex numUniChars = CFStringGetLength( textString );
+
+ // XXX how do we know the encoding of the listbox?
+ CFStringEncoding encoding = kCFStringEncodingUTF8; //( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII);
+ CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1;
+ char* text = new char[maximumByteLength];
+ CFIndex usedBufferLength = 0;
+ CFStringGetBytes( textString, CFRangeMake( 0, numUniChars ), encoding,
+ '?', false, reinterpret_cast<UInt8*>( text ),
+ maximumByteLength, &usedBufferLength );
+ text[usedBufferLength] = '\0'; // null terminate the ASCII/UTF8 string
+
+ if (text && len > 0) {
+ strncpy(value, text, len);
+ value[len - 1] = '\0';
+ } else {
+ value[0] = '\0';
+ }
+ delete text;
+}
+
+void ListBoxImpl::Sort() {
+ // TODO: Implement this
+ fprintf(stderr, "ListBox::Sort\n");
+}
+
+void ListBoxImpl::RegisterImage(int type, const char *xpm_data) {
+ xset.Add(type, xpm_data);
+}
+
+void ListBoxImpl::ClearRegisteredImages() {
+ xset.Clear();
+}
+
+Menu::Menu() : id(0) { }
+
+void Menu::CreatePopUp() {
+ // TODO: Could I just feed a constant menu ID parameter, or does
+ // it really need to be unique?
+ static int nextMenuID = 1;
+ Destroy();
+ OSStatus err;
+ err = CreateNewMenu( nextMenuID++, 0, reinterpret_cast<MenuRef*>( &id ) );
+ assert( noErr == err && id != NULL );
+}
+
+void Menu::Destroy() {
+ if ( id != NULL )
+ {
+ ReleaseMenu( reinterpret_cast<MenuRef>( id ) );
+ id = NULL;
+ }
+}
+
+void Menu::Show(Point pt, Window &) {
+ UInt32 userSelection = 0;
+ SInt16 menuId = 0;
+ MenuItemIndex menuItem = 0;
+ ::Point globalPoint;
+ globalPoint.h = pt.x;
+ globalPoint.v = pt.y;
+ OSStatus err;
+ err = ContextualMenuSelect( reinterpret_cast<MenuRef>( id ), globalPoint,
+ false, kCMHelpItemRemoveHelp, NULL,
+ NULL, &userSelection,
+ &menuId,
+ &menuItem
+ );
+ // The system should always handle the command for us, so we should get userCanceledErr
+ assert( /*noErr == err ||*/ userCanceledErr == err );
+}
+
+// TODO: Consider if I should be using GetCurrentEventTime instead of gettimeoday
+ElapsedTime::ElapsedTime() {
+ struct timeval curTime;
+ int retVal;
+ retVal = gettimeofday( &curTime, NULL );
+ assert( retVal == 0 );
+
+ bigBit = curTime.tv_sec;
+ littleBit = curTime.tv_usec;
+}
+
+double ElapsedTime::Duration(bool reset) {
+ struct timeval curTime;
+ int retVal;
+ retVal = gettimeofday( &curTime, NULL );
+ assert( retVal == 0 );
+ long endBigBit = curTime.tv_sec;
+ long endLittleBit = curTime.tv_usec;
+ double result = 1000000.0 * (endBigBit - bigBit);
+ result += endLittleBit - littleBit;
+ result /= 1000000.0;
+ if (reset) {
+ bigBit = endBigBit;
+ littleBit = endLittleBit;
+ }
+ return result;
+}
+
+ColourDesired Platform::Chrome() {
+ RGBColor c;
+ GetThemeBrushAsColor(kThemeBrushButtonActiveDarkShadow , 24, true, &c);
+ return ColourDesired(c.red>>8, c.green>>8, c.blue>>8);
+}
+
+ColourDesired Platform::ChromeHighlight() {
+ RGBColor c;
+ GetThemeBrushAsColor(kThemeBrushButtonInactiveLightShadow , 24, true, &c);
+ return ColourDesired(c.red>>8, c.green>>8, c.blue>>8);
+}
+
+static Str255 PlatformDefaultFontName;
+const char *Platform::DefaultFont() {
+ long id = HighShortFromLong(GetScriptVariable(smCurrentScript, smScriptAppFondSize));
+ FMGetFontFamilyName(id, PlatformDefaultFontName);
+ return (const char *)PlatformDefaultFontName;
+}
+
+int Platform::DefaultFontSize() {
+ return LowShortFromLong(GetScriptVariable(smCurrentScript, smScriptAppFondSize));
+}
+
+unsigned int Platform::DoubleClickTime() {
+ // Convert from ticks to milliseconds. I think it would be better to use the events to tell us
+ // when we have a double and triple click, but what do I know?
+ return static_cast<unsigned int>( TicksToEventTime( GetDblTime() ) / kEventDurationMillisecond );
+}
+
+bool Platform::MouseButtonBounce() {
+ return false;
+}
+
+bool Platform::WaitMouseMoved(Scintilla::Point pt) {
+ ::Point mpt;
+ mpt.v = pt.x;
+ mpt.h = pt.y;
+ return ::WaitMouseMoved(mpt);
+}
+
+bool Platform::IsKeyDown(int keyCode) {
+ return false;
+ // TODO: Map Scintilla/Windows key codes to Mac OS X key codes
+ // TODO: Do I need this?
+ /*
+ // Inspired by code at: http://www.sover.net/~jams/Morgan/docs/GameInputMethods.txt
+
+ // Get the keys
+ KeyMap keys;
+ GetKeys( keys );
+
+ // Calculate the key map index
+ long keyMapIndex = keys[keyCode/8];
+ // Calculate the individual bit to check
+ short bitToCheck = keyCode % 8;
+ // Check the status of the key
+ return ( keyMapIndex >> bitToCheck ) & 0x01;
+ */
+}
+
+long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) {
+ return scintilla_send_message( w, msg, wParam, lParam );
+}
+
+bool Platform::IsDBCSLeadByte(int /*codePage*/, char /*ch*/) {
+ // TODO: Implement this
+ return false;
+}
+
+int Platform::DBCSCharLength(int /*codePage*/, const char* /*s*/) {
+ // TODO: Implement this
+ return 1;
+}
+
+int Platform::DBCSCharMaxLength() {
+ // TODO: Implement this
+ //return CFStringGetMaximumSizeForEncoding( 1, CFStringEncoding encoding );
+ return 2;
+}
+
+// These are utility functions not really tied to a platform
+int Platform::Minimum(int a, int b) {
+ if (a < b)
+ return a;
+ else
+ return b;
+}
+
+int Platform::Maximum(int a, int b) {
+ if (a > b)
+ return a;
+ else
+ return b;
+}
+
+//#define TRACE
+#ifdef TRACE
+
+void Platform::DebugDisplay(const char *s) {
+ fprintf( stderr, s );
+}
+
+void Platform::DebugPrintf(const char *format, ...) {
+ const int BUF_SIZE = 2000;
+ char buffer[BUF_SIZE];
+
+ va_list pArguments;
+ va_start(pArguments, format);
+ vsnprintf(buffer, BUF_SIZE, format, pArguments);
+ va_end(pArguments);
+ Platform::DebugDisplay(buffer);
+}
+
+#else
+
+void Platform::DebugDisplay(const char *) {}
+
+void Platform::DebugPrintf(const char *, ...) {}
+
+#endif
+
+// Not supported for GTK+
+static bool assertionPopUps = true;
+
+bool Platform::ShowAssertionPopUps(bool assertionPopUps_) {
+ bool ret = assertionPopUps;
+ assertionPopUps = assertionPopUps_;
+ return ret;
+}
+
+void Platform::Assert(const char *c, const char *file, int line) {
+ char buffer[2000];
+ sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line);
+ strcat(buffer, "\r\n");
+ Platform::DebugDisplay(buffer);
+ abort();
+}
+
+int Platform::Clamp(int val, int minVal, int maxVal) {
+ assert( minVal <= maxVal );
+ if (val > maxVal)
+ val = maxVal;
+ if (val < minVal)
+ val = minVal;
+ return val;
+}
diff --git a/macosx/PlatMacOSX.h b/macosx/PlatMacOSX.h
new file mode 100644
index 000000000..168ba74ee
--- /dev/null
+++ b/macosx/PlatMacOSX.h
@@ -0,0 +1,101 @@
+#ifndef PLATMACOSX_H
+#define PLATMACOSX_H
+
+#include <cstring>
+#include <cstdio>
+#include <cstdlib>
+
+#include <assert.h>
+
+#include <sys/time.h>
+
+#include <Carbon/Carbon.h>
+#include "QuartzTextLayout.h"
+
+#include "Platform.h"
+#include "Scintilla.h"
+
+namespace Scintilla {
+
+class SurfaceImpl : public Surface {
+private:
+ bool unicodeMode;
+ float x;
+ float y;
+
+#ifdef SUPPORT_PORT
+ CGrafPtr port;
+#endif
+ CGContextRef gc;
+
+
+ /** If the surface is a bitmap context, contains a reference to the bitmap data. */
+ uint8_t* bitmapData;
+ /** If the surface is a bitmap context, stores the dimensions of the bitmap. */
+ int bitmapWidth;
+ int bitmapHeight;
+
+ /** Set the CGContext's fill colour to the specified allocated colour. */
+ void FillColour( const ColourAllocated& back );
+
+
+ // 24-bit RGB+A bitmap data constants
+ static const int BITS_PER_COMPONENT = 8;
+ static const int BITS_PER_PIXEL = BITS_PER_COMPONENT * 4;
+ static const int BYTES_PER_PIXEL = BITS_PER_PIXEL / 8;
+public:
+ SurfaceImpl();
+ ~SurfaceImpl();
+
+ void Init(WindowID wid);
+ void Init(SurfaceID sid, WindowID wid);
+ void InitPixMap(int width, int height, Surface *surface_, WindowID wid);
+ CGContextRef GetContext() { return gc; }
+
+ void Release();
+ bool Initialised();
+ void PenColour(ColourAllocated fore);
+
+ /** Returns a CGImageRef that represents the surface. Returns NULL if this is not possible. */
+ CGImageRef GetImage();
+ void CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect);
+
+ int LogPixelsY();
+ int DeviceHeightFont(int points);
+ void MoveTo(int x_, int y_);
+ void LineTo(int x_, int y_);
+ void Polygon(Scintilla::Point *pts, int npts, ColourAllocated fore, ColourAllocated back);
+ void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+ void FillRectangle(PRectangle rc, ColourAllocated back);
+ void FillRectangle(PRectangle rc, Surface &surfacePattern);
+ void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+ void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
+ ColourAllocated outline, int alphaOutline, int flags);
+ void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+ void Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource);
+
+ QuartzTextLayout* GetTextLayout( Font &font_, const char *s, int len );
+ void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
+ void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back);
+ void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore);
+ void MeasureWidths(Font &font_, const char *s, int len, int *positions);
+ int WidthText(Font &font_, const char *s, int len);
+ int WidthChar(Font &font_, char ch);
+ int Ascent(Font &font_);
+ int Descent(Font &font_);
+ int InternalLeading(Font &font_);
+ int ExternalLeading(Font &font_);
+ int Height(Font &font_);
+ int AverageCharWidth(Font &font_);
+
+ int SetPalette(Scintilla::Palette *pal, bool inBackGround);
+ void SetClip(PRectangle rc);
+ void FlushCachedState();
+
+ void SetUnicodeMode(bool unicodeMode_);
+ void SetDBCSMode(int codePage);
+};
+
+}
+
+#endif
diff --git a/macosx/QuartzTextLayout.h b/macosx/QuartzTextLayout.h
new file mode 100644
index 000000000..1461a078f
--- /dev/null
+++ b/macosx/QuartzTextLayout.h
@@ -0,0 +1,130 @@
+/*
+ * QuartzTextLayout.h
+ * wtf
+ *
+ * Created by Evan Jones on Wed Oct 02 2002.
+ * Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#ifndef _QUARTZ_TEXT_LAYOUT_H
+#define _QUARTZ_TEXT_LAYOUT_H
+
+#include <Carbon/Carbon.h>
+
+#include "QuartzTextStyle.h"
+
+class QuartzTextLayout
+{
+public:
+ /** Create a text layout for drawing on the specified context. */
+ QuartzTextLayout( CGContextRef context ) : layout( NULL ), unicode_string( NULL ), unicode_length( 0 )
+ {
+ gc = context;
+
+ OSStatus err;
+ err = ATSUCreateTextLayout( &layout );
+ assert( err == noErr && layout != NULL );
+
+ setControl( kATSUCGContextTag, sizeof( gc ), &gc );
+
+ /*ATSUAttributeTag tag = kATSULineLayoutOptionsTag;
+ ByteCount size = sizeof( ATSLineLayoutOptions );
+ ATSLineLayoutOptions rendering = kATSLineHasNoOpticalAlignment; // kATSLineUseDeviceMetrics; | kATSLineFractDisable | kATSLineUseQDRendering
+ ATSUAttributeValuePtr valuePtr = &rendering;
+ err = ATSUSetLayoutControls( layout, 1, &tag, &size, &valuePtr );
+ assert( err == noErr );*/
+ }
+
+ ~QuartzTextLayout()
+ {
+ assert( layout != NULL );
+ ATSUDisposeTextLayout( layout );
+ layout = NULL;
+
+ if ( unicode_string != NULL )
+ {
+ delete[] unicode_string;
+ unicode_string = NULL;
+ unicode_length = 0;
+ }
+ }
+
+ /** Assign a string to the text layout object. */
+ // TODO: Create a UTF8 version
+ // TODO: Optimise the ASCII version by not copying so much
+ OSStatus setText( const UInt8* buffer, size_t byteLength, CFStringEncoding encoding )
+ {
+ assert( buffer != NULL && byteLength > 0 );
+
+ CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, encoding, false );
+ if (!str)
+ return -1;
+
+ unicode_length = CFStringGetLength( str );
+ unicode_string = new UniChar[ unicode_length ];
+ CFStringGetCharacters( str, CFRangeMake( 0, unicode_length ), unicode_string );
+
+ CFRelease( str );
+ str = NULL;
+
+ OSStatus err;
+ err = ATSUSetTextPointerLocation( layout, unicode_string, kATSUFromTextBeginning, kATSUToTextEnd, unicode_length );
+ if( err != noErr ) return err;
+
+ // Turn on the default font fallbacks
+ return ATSUSetTransientFontMatching( layout, true );
+ }
+
+ /** Apply the specified text style on the entire range of text. */
+ void setStyle( const QuartzTextStyle& style )
+ {
+ OSStatus err;
+ err = ATSUSetRunStyle( layout, style.getATSUStyle(), kATSUFromTextBeginning, kATSUToTextEnd );
+ assert( err == noErr );
+ }
+
+ /** Draw the text layout into the current CGContext at the specified position, flipping the CGContext's Y axis if required.
+ * @param x The x axis position to draw the baseline in the current CGContext.
+ * @param y The y axis position to draw the baseline in the current CGContext.
+ * @param flipTextYAxis If true, the CGContext's Y axis will be flipped before drawing the text, and restored afterwards. Use this when drawing in an HIView's CGContext, where the origin is the top left corner. */
+ void draw( float x, float y, bool flipTextYAxis = false )
+ {
+ if ( flipTextYAxis )
+ {
+ CGContextSaveGState( gc );
+ CGContextScaleCTM( gc, 1.0, -1.0 );
+ y = -y;
+ }
+
+ OSStatus err;
+ err = ATSUDrawText( layout, kATSUFromTextBeginning, kATSUToTextEnd, X2Fix( x ), X2Fix( y ) );
+ assert( err == noErr );
+
+ if ( flipTextYAxis ) CGContextRestoreGState( gc );
+ }
+
+ /** Sets a single text layout control on the ATSUTextLayout object.
+ * @param tag The control to set.
+ * @param size The size of the parameter pointed to by value.
+ * @param value A pointer to the new value for the control.
+ */
+ void setControl( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value )
+ {
+ OSStatus err;
+ err = ATSUSetLayoutControls( layout, 1, &tag, &size, &value );
+ assert( noErr == err );
+ }
+
+ ATSUTextLayout getLayout() {
+ return layout;
+ }
+
+private:
+ ATSUTextLayout layout;
+ UniChar* unicode_string;
+ int unicode_length;
+ CGContextRef gc;
+};
+
+#endif
diff --git a/macosx/QuartzTextStyle.h b/macosx/QuartzTextStyle.h
new file mode 100644
index 000000000..d3a5db5dc
--- /dev/null
+++ b/macosx/QuartzTextStyle.h
@@ -0,0 +1,105 @@
+/*
+ * QuartzTextStyle.h
+ * wtf
+ *
+ * Created by Evan Jones on Wed Oct 02 2002.
+ * Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include <Carbon/Carbon.h>
+
+#ifndef _QUARTZ_TEXT_STYLE_H
+#define _QUARTZ_TEXT_STYLE_H
+
+#include "QuartzTextStyleAttribute.h"
+
+class QuartzTextStyle
+{
+public:
+ QuartzTextStyle()
+ {
+ OSStatus err;
+ err = ATSUCreateStyle( &style );
+ assert( err == noErr );
+ }
+
+ ~QuartzTextStyle()
+ {
+ assert( style != NULL );
+ ATSUDisposeStyle( style );
+ style = NULL;
+ }
+
+ void setAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value )
+ {
+ OSStatus err;
+ err = ATSUSetAttributes( style, 1, &tag, &size, &value );
+ assert( err == noErr );
+ }
+
+ void setAttribute( QuartzTextStyleAttribute& attribute )
+ {
+ setAttribute( attribute.getTag(), attribute.getSize(), attribute.getValuePtr() );
+ }
+
+ void getAttribute( ATSUAttributeTag tag, ByteCount size, ATSUAttributeValuePtr value, ByteCount* actualSize )
+ {
+ OSStatus err; err = ATSUGetAttribute( style, tag, size, value, actualSize );
+ assert( err == noErr );
+ }
+
+ template <class T>
+ T getAttribute( ATSUAttributeTag tag )
+ {
+ T value;
+ ByteCount actualSize;
+ OSStatus err;
+ err = ATSUGetAttribute( style, tag, sizeof( T ), &value, &actualSize );
+ assert( (err == noErr || err == kATSUNotSetErr) && actualSize == sizeof( T ) );
+ return value;
+ }
+
+ // TODO: Is calling this actually faster than calling setAttribute multiple times?
+ void setAttributes( QuartzTextStyleAttribute* attributes[], int number )
+ {
+ // Create the parallel arrays and initialize them properly
+ ATSUAttributeTag* tags = new ATSUAttributeTag[ number ];
+ ByteCount* sizes = new ByteCount[ number ];
+ ATSUAttributeValuePtr* values = new ATSUAttributeValuePtr[ number ];
+
+ for ( int i = 0; i < number; ++ i )
+ {
+ tags[i] = attributes[i]->getTag();
+ sizes[i] = attributes[i]->getSize();
+ values[i] = attributes[i]->getValuePtr();
+ }
+
+ OSStatus err;
+ err = ATSUSetAttributes( style, number, tags, sizes, values );
+ //assert( err == noErr );
+
+ // Free the arrays that were allocated
+ delete[] tags;
+ delete[] sizes;
+ delete[] values;
+ }
+
+ void setFontFeature( ATSUFontFeatureType featureType, ATSUFontFeatureSelector selector )
+ {
+ OSStatus err;
+ err = ATSUSetFontFeatures( style, 1, &featureType, &selector );
+ assert( err == noErr );
+ }
+
+ const ATSUStyle& getATSUStyle() const
+ {
+ return style;
+ }
+
+private:
+ ATSUStyle style;
+};
+
+#endif
+
diff --git a/macosx/QuartzTextStyleAttribute.h b/macosx/QuartzTextStyleAttribute.h
new file mode 100644
index 000000000..490ef7d02
--- /dev/null
+++ b/macosx/QuartzTextStyleAttribute.h
@@ -0,0 +1,146 @@
+/*
+ * QuartzTextStyleAttribute.h
+ * wtf
+ *
+ * Created by Evan Jones on Wed Oct 02 2002.
+ * Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+
+#include <Carbon/Carbon.h>
+
+#ifndef _QUARTZ_TEXT_STYLE_ATTRIBUTE_H
+#define _QUARTZ_TEXT_STYLE_ATTRIBUTE_H
+
+class QuartzTextStyleAttribute
+{
+public:
+ virtual ByteCount getSize() const = 0;
+ virtual ATSUAttributeValuePtr getValuePtr() = 0;
+ virtual ATSUAttributeTag getTag() const = 0;
+};
+
+class QuartzTextSize : public QuartzTextStyleAttribute
+{
+public:
+ QuartzTextSize( float points )
+ {
+ size = X2Fix( points );
+ }
+
+ ByteCount getSize() const
+ {
+ return sizeof( size );
+ }
+
+ ATSUAttributeValuePtr getValuePtr()
+ {
+ return &size;
+ }
+
+ ATSUAttributeTag getTag() const
+ {
+ return kATSUSizeTag;
+ }
+
+private:
+ Fixed size;
+};
+
+class QuartzTextStyleAttributeBoolean : public QuartzTextStyleAttribute
+{
+public:
+ QuartzTextStyleAttributeBoolean( bool newVal ) : value( newVal ) {}
+
+ ByteCount getSize() const
+ {
+ return sizeof( value );
+ }
+ ATSUAttributeValuePtr getValuePtr()
+ {
+ return &value;
+ }
+
+ virtual ATSUAttributeTag getTag() const = 0;
+
+private:
+ Boolean value;
+};
+
+class QuartzTextBold : public QuartzTextStyleAttributeBoolean
+{
+public:
+ QuartzTextBold( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {}
+ ATSUAttributeTag getTag() const
+ {
+ return kATSUQDBoldfaceTag;
+ }
+};
+
+class QuartzTextItalic : public QuartzTextStyleAttributeBoolean
+{
+public:
+ QuartzTextItalic( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {}
+ ATSUAttributeTag getTag() const
+ {
+ return kATSUQDItalicTag;
+ }
+};
+
+class QuartzTextUnderline : public QuartzTextStyleAttributeBoolean
+{
+public:
+ QuartzTextUnderline( bool newVal ) : QuartzTextStyleAttributeBoolean( newVal ) {}
+ ATSUAttributeTag getTag() const {
+ return kATSUQDUnderlineTag;
+ }
+};
+
+class QuartzFont : public QuartzTextStyleAttribute
+{
+public:
+ /** Create a font style from a name. */
+ QuartzFont( const char* name, int length )
+ {
+ assert( name != NULL && length > 0 && name[length] == '\0' );
+ /*CFStringRef fontName = CFStringCreateWithCString( NULL, name, kCFStringEncodingMacRoman );
+
+ ATSFontRef fontRef = ATSFontFindFromName( fontName, kATSOptionFlagsDefault );
+ assert( fontRef != NULL );
+ fontid = fontRef;
+
+ CFRelease( fontName );*/
+
+ OSStatus err;
+ err = ATSUFindFontFromName( const_cast<char*>( name ), length, kFontFullName, (unsigned) kFontNoPlatform, kFontRomanScript, (unsigned) kFontNoLanguage, &fontid );
+ //assert( err == noErr && fontid != kATSUInvalidFontID );
+ }
+
+ ByteCount getSize() const
+ {
+ return sizeof( fontid );
+ }
+
+ ATSUAttributeValuePtr getValuePtr()
+ {
+ return &fontid;
+ }
+
+ ATSUAttributeTag getTag() const
+ {
+ return kATSUFontTag;
+ }
+
+ ATSUFontID getFontID() const
+ {
+ return fontid;
+ }
+
+private:
+ ATSUFontID fontid;
+};
+
+
+#endif
+
diff --git a/macosx/SciTest/English.lproj/InfoPlist.strings b/macosx/SciTest/English.lproj/InfoPlist.strings
new file mode 100644
index 000000000..4dcb4fe03
--- /dev/null
+++ b/macosx/SciTest/English.lproj/InfoPlist.strings
Binary files differ
diff --git a/macosx/SciTest/Info.plist b/macosx/SciTest/Info.plist
new file mode 100644
index 000000000..7163dff62
--- /dev/null
+++ b/macosx/SciTest/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>SciTest</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.myCarbonApp</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+</dict>
+</plist>
diff --git a/macosx/SciTest/SciTest.xcode/project.pbxproj b/macosx/SciTest/SciTest.xcode/project.pbxproj
new file mode 100644
index 000000000..9ef8fd9bb
--- /dev/null
+++ b/macosx/SciTest/SciTest.xcode/project.pbxproj
@@ -0,0 +1,287 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 3002B123087DCEC600CEAF79 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3002B122087DCEC600CEAF79 /* main.cpp */; };
+ 30973FF8086B7F4F0088809C /* libscintilla.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 30973FF7086B7F4F0088809C /* libscintilla.a */; };
+ 8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; };
+ 8D0C4E8E0486CD37000505A6 /* main.nib in Resources */ = {isa = PBXBuildFile; fileRef = 02345980000FD03B11CA0E72 /* main.nib */; };
+ 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 0867D6ABFE840B52C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 1870340FFE93FCAF11CA0CD7 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/main.nib; sourceTree = "<group>"; };
+ 20286C33FDCF999611CA2CEA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
+ 3002B122087DCEC600CEAF79 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+ 30973FF7086B7F4F0088809C /* libscintilla.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libscintilla.a; path = ../../bin/libscintilla.a; sourceTree = SOURCE_ROOT; };
+ 32DBCF6D0370B57F00C91783 /* SciTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SciTest_Prefix.pch; sourceTree = "<group>"; };
+ 4A9504C8FFE6A3BC11CA0CBA /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
+ 4A9504CAFFE6A41611CA0CBA /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
+ 8D0C4E960486CD37000505A6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+ 8D0C4E970486CD37000505A6 /* SciTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SciTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D0C4E910486CD37000505A6 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */,
+ 30973FF8086B7F4F0088809C /* libscintilla.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 195DF8CFFE9D517E11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D0C4E970486CD37000505A6 /* SciTest.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 20286C29FDCF999611CA2CEA /* SciTest */ = {
+ isa = PBXGroup;
+ children = (
+ 20286C2AFDCF999611CA2CEA /* Sources */,
+ 20286C2CFDCF999611CA2CEA /* Resources */,
+ 20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */,
+ 195DF8CFFE9D517E11CA2CBB /* Products */,
+ );
+ name = SciTest;
+ sourceTree = "<group>";
+ };
+ 20286C2AFDCF999611CA2CEA /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 3002B122087DCEC600CEAF79 /* main.cpp */,
+ 32DBCF6D0370B57F00C91783 /* SciTest_Prefix.pch */,
+ );
+ name = Sources;
+ sourceTree = "<group>";
+ };
+ 20286C2CFDCF999611CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 8D0C4E960486CD37000505A6 /* Info.plist */,
+ 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */,
+ 02345980000FD03B11CA0E72 /* main.nib */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 30973FF7086B7F4F0088809C /* libscintilla.a */,
+ 20286C33FDCF999611CA2CEA /* Carbon.framework */,
+ 4A9504CAFFE6A41611CA0CBA /* CoreServices.framework */,
+ 4A9504C8FFE6A3BC11CA0CBA /* ApplicationServices.framework */,
+ );
+ name = "External Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D0C4E890486CD37000505A6 /* SciTest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 304E977D0C0519E500702100 /* Build configuration list for PBXNativeTarget "SciTest" */;
+ buildPhases = (
+ 8D0C4E8C0486CD37000505A6 /* Resources */,
+ 8D0C4E8F0486CD37000505A6 /* Sources */,
+ 8D0C4E910486CD37000505A6 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SciTest;
+ productInstallPath = "$(HOME)/Applications";
+ productName = SciTest;
+ productReference = 8D0C4E970486CD37000505A6 /* SciTest.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 20286C28FDCF999611CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 304E97810C0519E500702100 /* Build configuration list for PBXProject "SciTest" */;
+ hasScannedForEncodings = 1;
+ mainGroup = 20286C29FDCF999611CA2CEA /* SciTest */;
+ projectDirPath = "";
+ targets = (
+ 8D0C4E890486CD37000505A6 /* SciTest */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D0C4E8C0486CD37000505A6 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */,
+ 8D0C4E8E0486CD37000505A6 /* main.nib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D0C4E8F0486CD37000505A6 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3002B123087DCEC600CEAF79 /* main.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 02345980000FD03B11CA0E72 /* main.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 1870340FFE93FCAF11CA0CD7 /* English */,
+ );
+ name = main.nib;
+ sourceTree = "<group>";
+ };
+ 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 0867D6ABFE840B52C02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 304E977E0C0519E500702100 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = SciTest_Prefix.pch;
+ HEADER_SEARCH_PATHS = (
+ ..,
+ ../../include,
+ ../../src,
+ );
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ LIBRARY_SEARCH_PATHS = ../../bin;
+ OTHER_CFLAGS = (
+ "-DSCI_NAMESPACE=1",
+ "-DSCI_NAMESPACE",
+ "-DMACOSX",
+ "-DSCI_LEXER",
+ );
+ OTHER_CPLUSPLUSFLAGS = (
+ "-DSCI_NAMESPACE=1",
+ "-DSCI_NAMESPACE",
+ "-DMACOSX",
+ "-DSCI_LEXER",
+ );
+ PRODUCT_NAME = SciTest;
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ 304E977F0C0519E500702100 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = SciTest_Prefix.pch;
+ HEADER_SEARCH_PATHS = (
+ ..,
+ ../../include,
+ ../../src,
+ );
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ LIBRARY_SEARCH_PATHS = "";
+ PRODUCT_NAME = SciTest;
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ 304E97800C0519E500702100 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = SciTest_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ LIBRARY_SEARCH_PATHS = "";
+ PRODUCT_NAME = SciTest;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Default;
+ };
+ 304E97820C0519E500702100 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Development;
+ };
+ 304E97830C0519E500702100 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Deployment;
+ };
+ 304E97840C0519E500702100 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Default;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 304E977D0C0519E500702100 /* Build configuration list for PBXNativeTarget "SciTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 304E977E0C0519E500702100 /* Development */,
+ 304E977F0C0519E500702100 /* Deployment */,
+ 304E97800C0519E500702100 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ 304E97810C0519E500702100 /* Build configuration list for PBXProject "SciTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 304E97820C0519E500702100 /* Development */,
+ 304E97830C0519E500702100 /* Deployment */,
+ 304E97840C0519E500702100 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 20286C28FDCF999611CA2CEA /* Project object */;
+}
diff --git a/macosx/SciTest/SciTest_Prefix.pch b/macosx/SciTest/SciTest_Prefix.pch
new file mode 100644
index 000000000..552cf97fc
--- /dev/null
+++ b/macosx/SciTest/SciTest_Prefix.pch
@@ -0,0 +1,5 @@
+//
+// Prefix header for all source files of the 'SciTest' target in the 'SciTest' project.
+//
+
+#include <Carbon/Carbon.h>
diff --git a/macosx/SciTest/main.cpp b/macosx/SciTest/main.cpp
new file mode 100644
index 000000000..374038005
--- /dev/null
+++ b/macosx/SciTest/main.cpp
@@ -0,0 +1,225 @@
+//
+// main.c
+// SciTest
+//
+// Copyright (c) 2005-2006 ActiveState Software Inc.
+// All rights reserved.
+//
+// Created by Shane Caraveo on 3/20/05.
+//
+
+#include <Carbon/Carbon.h>
+#include "TView.h"
+#include "TCarbonEvent.h"
+#include "ScintillaMacOSX.h"
+
+extern "C" HIViewRef scintilla_new(void);
+
+const HILayoutInfo kBindToParentLayout = {
+ kHILayoutInfoVersionZero,
+ { { NULL, kHILayoutBindTop }, { NULL, kHILayoutBindLeft }, { NULL, kHILayoutBindBottom }, { NULL, kHILayoutBindRight } },
+ { { NULL, kHILayoutScaleAbsolute, 0 }, { NULL, kHILayoutScaleAbsolute, 0 } },
+ { { NULL, kHILayoutPositionTop, 0 }, { NULL, kHILayoutPositionLeft, 0 } }
+};
+
+using namespace Scintilla;
+
+/* XPM */
+static char *ac_class[] = {
+/* columns rows colors chars-per-pixel */
+"18 12 24 1",
+" c black",
+". c #403030",
+"X c #473636",
+"o c #4E3C3C",
+"O c #474141",
+"+ c #5F4C4C",
+"@ c #756362",
+"# c #98342C",
+"$ c #A0392F",
+"% c #B24235",
+"& c #B2443C",
+"* c #B34E3E",
+"= c #B54E44",
+"- c #B65146",
+"; c #B7584F",
+": c #B8554C",
+"> c #B75A50",
+", c #B95852",
+"< c #B96259",
+"1 c #B89B9B",
+"2 c #BCA0A0",
+"3 c #C1A5A5",
+"4 c gray100",
+"5 c None",
+/* pixels */
+"555555555555555555",
+"55553$$$$$$$#@5555",
+"55552;%&&==;=o5555",
+"55551>&&*=;:=.5555",
+"55551>&*=;::=.5555",
+"55551>*==:::-X5555",
+"55551>==:::,;.5555",
+"55551<==:;,<>.5555",
+"55551<;;;;<<;.5555",
+"55551;-==;;;;X5555",
+"55555+XX..X..O5555",
+"555555555555555555"
+};
+
+pascal OSStatus WindowEventHandler(EventHandlerCallRef inCallRef,
+ EventRef inEvent,
+ void* inUserData )
+{
+ HIViewRef sciView = *reinterpret_cast<HIViewRef*>( inUserData );
+ WindowRef window = GetControlOwner(sciView);
+ ScintillaMacOSX* scintilla;
+ GetControlProperty( sciView, scintillaMacOSType, 0, sizeof( scintilla ), NULL, &scintilla );
+ TCarbonEvent event( inEvent );
+
+ // If the window is not active, let the standard window handler execute.
+ if ( ! IsWindowActive( window ) ) return eventNotHandledErr;
+
+ const HIViewRef rootView = HIViewGetRoot( window );
+ assert( rootView != NULL );
+
+ if ( event.GetKind() == kEventMouseDown )
+ {
+ UInt32 inKeyModifiers;
+ event.GetParameter( kEventParamKeyModifiers, &inKeyModifiers );
+
+ EventMouseButton inMouseButton;
+ event.GetParameter<EventMouseButton>( kEventParamMouseButton, typeMouseButton, &inMouseButton );
+ if (inMouseButton == kEventMouseButtonTertiary) {
+ if (inKeyModifiers & optionKey) {
+ const char *test = "\001This is a test calltip This is a test calltip This is a test calltip";
+ scintilla->WndProc( SCI_CALLTIPSHOW, 0, (long int)test );
+ } else {
+ char *list = "test_1?0 test_2 test_3 test_4 test_5 test_6 test_7 test_8 test_9 test_10 test_11 test_12";
+ scintilla->WndProc( SCI_AUTOCSHOW, 0, (long int)list );
+ }
+ return noErr;
+ }
+ }
+
+ return eventNotHandledErr;
+}
+
+int main(int argc, char* argv[])
+{
+ IBNibRef nibRef;
+ WindowRef window;
+
+ OSStatus err;
+
+ // Create a Nib reference passing the name of the nib file (without the .nib extension)
+ // CreateNibReference only searches into the application bundle.
+ err = CreateNibReference(CFSTR("main"), &nibRef);
+ require_noerr( err, CantGetNibRef );
+
+ // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
+ // object. This name is set in InterfaceBuilder when the nib is created.
+ err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
+ require_noerr( err, CantSetMenuBar );
+
+ // Then create a window. "MainWindow" is the name of the window object. This name is set in
+ // InterfaceBuilder when the nib is created.
+ err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window);
+ require_noerr( err, CantCreateWindow );
+
+ // We don't need the nib reference anymore.
+ DisposeNibReference(nibRef);
+
+
+ HIRect boundsRect;
+ // GOOD and BAD methods off embedding into a window. This is used
+ // to test Window::SetPositionRelative under different situations.
+#define GOOD
+#ifdef GOOD
+#ifdef USE_CONTROL
+ ControlRef root;
+ GetRootControl(window, &root);
+#else
+ HIViewRef root;
+ HIViewFindByID(HIViewGetRoot(window),
+ kHIViewWindowContentID,
+ &root);
+#endif
+ HIViewGetBounds(root, &boundsRect);
+
+#else // BAD like mozilla
+ HIViewRef root;
+ root = HIViewGetRoot(window);
+
+ Rect cBounds, sBounds;
+ GetWindowBounds(window, kWindowContentRgn, &cBounds);
+ GetWindowBounds(window, kWindowStructureRgn, &sBounds);
+ boundsRect.origin.x = cBounds.left - sBounds.left;
+ boundsRect.origin.y = cBounds.top - sBounds.top;
+ boundsRect.size.width = cBounds.right - cBounds.left;
+ boundsRect.size.height = cBounds.bottom - cBounds.top;
+#endif
+
+ // get a scintilla control, and add it to it's parent container
+ HIViewRef sciView;
+ sciView = scintilla_new();
+ HIViewAddSubview(root, sciView);
+
+ // some scintilla init
+ ScintillaMacOSX* scintilla;
+ GetControlProperty( sciView, scintillaMacOSType, 0, sizeof( scintilla ), NULL, &scintilla );
+
+ scintilla->WndProc( SCI_SETLEXER, SCLEX_CPP, 0);
+ scintilla->WndProc( SCI_SETSTYLEBITS, 5, 0);
+ /*
+ these fail compilation on osx now
+ scintilla->WndProc( SCI_SETPROPERTY, "fold", (long int)"1");
+ scintilla->WndProc( SCI_SETPROPERTY, "fold.compact", (long int)"0");
+ scintilla->WndProc( SCI_SETPROPERTY, "fold.comment", (long int)"1");
+ scintilla->WndProc( SCI_SETPROPERTY, "fold.preprocessor", (long int)"1");
+ */
+
+ scintilla->WndProc( SCI_REGISTERIMAGE, 0, (long int)ac_class);
+
+ scintilla->WndProc( SCI_SETMARGINTYPEN, 0, (long int)SC_MARGIN_NUMBER);
+ scintilla->WndProc( SCI_SETMARGINWIDTHN, 0, (long int)30);
+ scintilla->WndProc( SCI_SETMARGINTYPEN, 1, (long int)SC_MARGIN_SYMBOL);
+ scintilla->WndProc( SCI_SETMARGINMASKN, 1, (long int)SC_MASK_FOLDERS);
+ scintilla->WndProc( SCI_SETMARGINWIDTHN, 1, (long int)20);
+ scintilla->WndProc( SCI_SETMARGINTYPEN, 2, (long int)SC_MARGIN_SYMBOL);
+ scintilla->WndProc( SCI_SETMARGINWIDTHN, 2, (long int)16);
+ //scintilla->WndProc( SCI_SETWRAPMODE, SC_WRAP_WORD, 0);
+ //scintilla->WndProc( SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_END | SC_WRAPVISUALFLAG_START, 0);
+
+ // set the size of scintilla to the size of the container
+ HIViewSetFrame( sciView, &boundsRect );
+
+ // bind the size of scintilla to the size of it's container window
+ HIViewSetLayoutInfo(sciView, &kBindToParentLayout);
+
+ // setup some event handling
+ static const EventTypeSpec kWindowMouseEvents[] =
+ {
+ { kEventClassMouse, kEventMouseDown },
+ };
+
+ InstallEventHandler( GetWindowEventTarget( window ), WindowEventHandler,
+ GetEventTypeCount( kWindowMouseEvents ), kWindowMouseEvents, &sciView, NULL );
+
+ // show scintilla
+ ShowControl(sciView);
+
+ SetAutomaticControlDragTrackingEnabledForWindow(window, true);
+
+ // The window was created hidden so show it.
+ ShowWindow( window );
+
+ // Call the event loop
+ RunApplicationEventLoop();
+
+CantCreateWindow:
+CantSetMenuBar:
+CantGetNibRef:
+ return err;
+}
+
diff --git a/macosx/SciTest/version.plist b/macosx/SciTest/version.plist
new file mode 100644
index 000000000..df8c3dc7d
--- /dev/null
+++ b/macosx/SciTest/version.plist
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>BuildVersion</key>
+ <string>92</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>ProductBuildVersion</key>
+ <string>7K571</string>
+ <key>ProjectName</key>
+ <string>NibPBTemplates</string>
+ <key>SourceVersion</key>
+ <string>1200000</string>
+</dict>
+</plist>
diff --git a/macosx/ScintillaCallTip.cxx b/macosx/ScintillaCallTip.cxx
new file mode 100644
index 000000000..6799b435a
--- /dev/null
+++ b/macosx/ScintillaCallTip.cxx
@@ -0,0 +1,117 @@
+
+#include "ScintillaMacOSX.h"
+#include "ScintillaCallTip.h"
+#include "CallTip.h"
+
+using namespace Scintilla;
+
+const CFStringRef ScintillaCallTip::kScintillaCallTipClassID = CFSTR( "org.scintilla.calltip" );
+const ControlKind ScintillaCallTip::kScintillaCallTipKind = { 'ejon', 'Scct' };
+
+ScintillaCallTip::ScintillaCallTip( void* windowid ) :
+ TView( reinterpret_cast<HIViewRef>( windowid ) )
+{
+ ActivateInterface( kMouse );
+ // debugPrint = true;
+}
+
+void ScintillaCallTip::Draw(
+ RgnHandle /*inLimitRgn*/,
+ CGContextRef inContext )
+{
+ // Get a reference to the Scintilla C++ object
+ CallTip* ctip = NULL;
+ OSStatus err;
+ err = GetControlProperty( GetViewRef(), scintillaCallTipType, 0, sizeof( ctip ), NULL, &ctip );
+ assert(err == noErr);
+ if (ctip == NULL) return;
+
+ Rect contentBounds;
+ GetControlBounds(GetViewRef(), &contentBounds);
+
+ HIRect controlFrame;
+ HIViewGetFrame( GetViewRef(), &controlFrame );
+
+ // what is the global pos?
+ Surface *surfaceWindow = Surface::Allocate();
+ if (surfaceWindow) {
+ surfaceWindow->Init(inContext, GetViewRef());
+ ctip->PaintCT(surfaceWindow);
+ surfaceWindow->Release();
+ delete surfaceWindow;
+ }
+
+}
+
+ControlPartCode ScintillaCallTip::HitTest( const HIPoint& where )
+{
+ if ( CGRectContainsPoint( Bounds(), where ) )
+ return 1;
+ else
+ return kControlNoPart;
+}
+
+OSStatus ScintillaCallTip::MouseDown(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ )
+{
+ if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr;
+ CallTip* ctip = NULL;
+ ScintillaMacOSX *sciThis = NULL;
+ OSStatus err = GetControlProperty( GetViewRef(), scintillaCallTipType, 0, sizeof( ctip ), NULL, &ctip );
+ err = GetControlProperty( GetViewRef(), scintillaMacOSType, 0, sizeof( sciThis ), NULL, &sciThis );
+ ctip->MouseClick( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ));
+ sciThis->CallTipClick();
+ return noErr;
+}
+
+OSStatus ScintillaCallTip::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ )
+{
+ if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr;
+ return noErr;
+}
+
+OSStatus ScintillaCallTip::MouseDragged( HIPoint& location, UInt32 /*modifiers*/, EventMouseButton /*button*/, UInt32 /*clickCount*/ )
+{
+ SetThemeCursor( kThemeArrowCursor );
+ return noErr;
+}
+
+HIViewRef ScintillaCallTip::Create()
+{
+ // Register the HIView, if needed
+ static bool registered = false;
+
+ if ( not registered )
+ {
+ TView::RegisterSubclass( kScintillaCallTipClassID, Construct );
+ registered = true;
+ }
+
+ OSStatus err = noErr;
+ EventRef event = CreateInitializationEvent();
+ assert( event != NULL );
+
+ HIViewRef control = NULL;
+ err = HIObjectCreate( kScintillaCallTipClassID, event, reinterpret_cast<HIObjectRef*>( &control ) );
+ ReleaseEvent( event );
+ if ( err == noErr ) {
+ Platform::DebugPrintf("ScintillaCallTip::Create control %08X\n",control);
+ return control;
+ }
+ return NULL;
+}
+
+OSStatus ScintillaCallTip::Construct( HIViewRef inControl, TView** outView )
+{
+ *outView = new ScintillaCallTip( inControl );
+ Platform::DebugPrintf("ScintillaCallTip::Construct scintilla %08X\n",*outView);
+ if ( *outView != NULL )
+ return noErr;
+ else
+ return memFullErr;
+}
+
+extern "C" {
+HIViewRef scintilla_calltip_new() {
+ return ScintillaCallTip::Create();
+}
+}
diff --git a/macosx/ScintillaCallTip.h b/macosx/ScintillaCallTip.h
new file mode 100644
index 000000000..525804942
--- /dev/null
+++ b/macosx/ScintillaCallTip.h
@@ -0,0 +1,64 @@
+/*
+ * ScintillaMacOSX.h
+ * tutorial
+ *
+ * Created by Evan Jones on Sun Sep 01 2002.
+ * Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+ *
+ */
+#ifndef SCINTILLA_CALLTIP_H
+#define SCINTILLA_CALLTIP_H
+
+#include "TView.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "Platform.h"
+#include "Scintilla.h"
+
+static const OSType scintillaCallTipType = 'Scct';
+
+namespace Scintilla {
+
+class ScintillaCallTip : public TView
+{
+public:
+ // Private so ScintillaCallTip objects can not be copied
+ ScintillaCallTip(const ScintillaCallTip &) : TView( NULL ) {}
+ ScintillaCallTip &operator=(const ScintillaCallTip &) { return * this; }
+ ~ScintillaCallTip() {};
+
+public:
+ /** This is the class ID that we've assigned to Scintilla. */
+ static const CFStringRef kScintillaCallTipClassID;
+ static const ControlKind kScintillaCallTipKind;
+
+ ScintillaCallTip( void* windowid );
+
+ /** Returns the HIView object kind, needed to subclass TView. */
+ virtual ControlKind GetKind() { return kScintillaCallTipKind; }
+
+private:
+
+ virtual ControlPartCode HitTest( const HIPoint& where );
+ virtual void Draw( RgnHandle rgn, CGContextRef gc );
+ virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+ virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+ virtual OSStatus MouseDragged( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+
+public:
+ static HIViewRef Create();
+private:
+ static OSStatus Construct( HIViewRef inControl, TView** outView );
+
+};
+
+
+}
+
+
+#endif
diff --git a/macosx/ScintillaListBox.cxx b/macosx/ScintillaListBox.cxx
new file mode 100644
index 000000000..90c72d857
--- /dev/null
+++ b/macosx/ScintillaListBox.cxx
@@ -0,0 +1,103 @@
+
+#include "ScintillaMacOSX.h"
+#include "ScintillaListBox.h"
+
+using namespace Scintilla;
+
+const CFStringRef ScintillaListBox::kScintillaListBoxClassID = CFSTR( "org.scintilla.listbox" );
+const ControlKind ScintillaListBox::kScintillaListBoxKind = { 'ejon', 'Sclb' };
+
+ScintillaListBox::ScintillaListBox( void* windowid ) :
+ TView( reinterpret_cast<HIViewRef>( windowid ) )
+{
+ ActivateInterface( kMouse );
+ // debugPrint = true;
+}
+
+void ScintillaListBox::Draw(
+ RgnHandle /*inLimitRgn*/,
+ CGContextRef inContext )
+{
+ Rect contentBounds;
+ GetControlBounds(GetViewRef(), &contentBounds);
+
+ HIRect controlFrame;
+ HIViewGetFrame( GetViewRef(), &controlFrame );
+
+ // what is the global pos?
+ Surface *surfaceWindow = Surface::Allocate();
+ if (surfaceWindow) {
+ surfaceWindow->Init(inContext, GetViewRef());
+ ctip->PaintCT(surfaceWindow);
+ surfaceWindow->Release();
+ delete surfaceWindow;
+ }
+
+}
+
+ControlPartCode ScintillaListBox::HitTest( const HIPoint& where )
+{
+ if ( CGRectContainsPoint( Bounds(), where ) )
+ return 1;
+ else
+ return kControlNoPart;
+}
+
+OSStatus ScintillaListBox::MouseDown(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ )
+{
+ if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr;
+ ListBox* ctip = NULL;
+ ScintillaMacOSX *sciThis = NULL;
+ OSStatus err = GetControlProperty( GetViewRef(), scintillaListBoxType, 0, sizeof( ctip ), NULL, &ctip );
+ err = GetControlProperty( GetViewRef(), scintillaMacOSType, 0, sizeof( sciThis ), NULL, &sciThis );
+ ctip->MouseClick( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ));
+ sciThis->ListBoxClick();
+ return noErr;
+}
+
+OSStatus ScintillaListBox::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton button, UInt32 /*inClickCount*/ )
+{
+ if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr;
+ return noErr;
+}
+
+HIViewRef ScintillaListBox::Create()
+{
+ // Register the HIView, if needed
+ static bool registered = false;
+
+ if ( not registered )
+ {
+ TView::RegisterSubclass( kScintillaListBoxClassID, Construct );
+ registered = true;
+ }
+
+ OSStatus err = noErr;
+ EventRef event = CreateInitializationEvent();
+ assert( event != NULL );
+
+ HIViewRef control = NULL;
+ err = HIObjectCreate( kScintillaListBoxClassID, event, reinterpret_cast<HIObjectRef*>( &control ) );
+ ReleaseEvent( event );
+ if ( err == noErr ) {
+ Platform::DebugPrintf("ScintillaListBox::Create control %08X\n",control);
+ return control;
+ }
+ return NULL;
+}
+
+OSStatus ScintillaListBox::Construct( HIViewRef inControl, TView** outView )
+{
+ *outView = new ScintillaListBox( inControl );
+ Platform::DebugPrintf("ScintillaListBox::Construct scintilla %08X\n",*outView);
+ if ( *outView != NULL )
+ return noErr;
+ else
+ return memFullErr;
+}
+
+extern "C" {
+HIViewRef scintilla_listbox_new() {
+ return ScintillaListBox::Create();
+}
+}
diff --git a/macosx/ScintillaListBox.h b/macosx/ScintillaListBox.h
new file mode 100644
index 000000000..e26d354eb
--- /dev/null
+++ b/macosx/ScintillaListBox.h
@@ -0,0 +1,63 @@
+/*
+ * ScintillaMacOSX.h
+ * tutorial
+ *
+ * Created by Evan Jones on Sun Sep 01 2002.
+ * Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+ *
+ */
+#ifndef SCINTILLA_LISTBOX_H
+#define SCINTILLA_LISTBOX_H
+
+#include "TView.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "Platform.h"
+#include "Scintilla.h"
+
+static const OSType scintillaListBoxType = 'sclb';
+
+namespace Scintilla {
+
+class ScintillaListBox : public TView
+{
+public:
+ // Private so ScintillaListBox objects can not be copied
+ ScintillaListBox(const ScintillaListBox &) : TView( NULL ) {}
+ ScintillaListBox &operator=(const ScintillaListBox &) { return * this; }
+ ~ScintillaListBox() {};
+
+public:
+ /** This is the class ID that we've assigned to Scintilla. */
+ static const CFStringRef kScintillaListBoxClassID;
+ static const ControlKind kScintillaListBoxKind;
+
+ ScintillaListBox( void* windowid );
+
+ /** Returns the HIView object kind, needed to subclass TView. */
+ virtual ControlKind GetKind() { return kScintillaListBoxKind; }
+
+private:
+
+ virtual ControlPartCode HitTest( const HIPoint& where );
+ virtual void Draw( RgnHandle rgn, CGContextRef gc );
+ virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+ virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+
+public:
+ static HIViewRef Create();
+private:
+ static OSStatus Construct( HIViewRef inControl, TView** outView );
+
+};
+
+
+}
+
+
+#endif
diff --git a/macosx/ScintillaMacOSX.cxx b/macosx/ScintillaMacOSX.cxx
new file mode 100644
index 000000000..9ac746f4b
--- /dev/null
+++ b/macosx/ScintillaMacOSX.cxx
@@ -0,0 +1,2118 @@
+// Scintilla source code edit control
+// ScintillaMacOSX.cxx - Mac OS X subclass of ScintillaBase
+// Copyright 2003 by Evan Jones <ejones@uwaterloo.ca>
+// Based on ScintillaGTK.cxx Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+
+#include "ScintillaMacOSX.h"
+#include "UniConversion.h"
+
+using namespace Scintilla;
+
+const CFStringRef ScintillaMacOSX::kScintillaClassID = CFSTR( "org.scintilla.scintilla" );
+const ControlKind ScintillaMacOSX::kScintillaKind = { 'ejon', 'Scin' };
+
+extern "C" HIViewRef scintilla_calltip_new(void);
+
+#ifndef WM_UNICHAR
+#define WM_UNICHAR 0x0109
+#endif
+
+// required for paste/dragdrop, see comment in paste function below
+static int BOMlen(unsigned char *cstr) {
+ switch(cstr[0]) {
+ case 0xEF: // BOM_UTF8
+ if (cstr[1] == 0xBB && cstr[2] == 0xBF) {
+ return 3;
+ }
+ break;
+ case 0xFE:
+ if (cstr[1] == 0xFF) {
+ if (cstr[2] == 0x00 && cstr[3] == 0x00) {
+ return 4;
+ }
+ return 2;
+ }
+ break;
+ case 0xFF:
+ if (cstr[1] == 0xFE) {
+ if (cstr[2] == 0x00 && cstr[3] == 0x00) {
+ return 4;
+ }
+ return 2;
+ }
+ break;
+ case 0x00:
+ if (cstr[1] == 0x00) {
+ if (cstr[2] == 0xFE && cstr[3] == 0xFF) {
+ return 4;
+ }
+ if (cstr[2] == 0xFF && cstr[3] == 0xFE) {
+ return 4;
+ }
+ return 2;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+ScintillaMacOSX::ScintillaMacOSX( void* windowid ) :
+ TView( reinterpret_cast<HIViewRef>( windowid ) )
+{
+ wMain = windowid;
+ OSStatus err;
+ err = GetThemeMetric( kThemeMetricScrollBarWidth, &scrollBarFixedSize );
+ assert( err == noErr );
+
+ mouseTrackingRef = NULL;
+ mouseTrackingID.signature = scintillaMacOSType;
+ mouseTrackingID.id = (SInt32)this;
+ capturedMouse = false;
+
+ // Enable keyboard events and mouse events
+#if !defined(CONTAINER_HANDLES_EVENTS)
+ ActivateInterface( kKeyboardFocus );
+ ActivateInterface( kMouse );
+ ActivateInterface( kDragAndDrop );
+#endif
+ ActivateInterface( kMouseTracking );
+
+ Initialise();
+
+ // Create some bounds rectangle which will just get reset to the correct rectangle later
+ Rect tempScrollRect;
+ tempScrollRect.top = -1;
+ tempScrollRect.left = 400;
+ tempScrollRect.bottom = 300;
+ tempScrollRect.right = 450;
+
+ // Create the scroll bar with fake values that will get set correctly later
+ err = CreateScrollBarControl( this->GetOwner(), &tempScrollRect, 0, 0, 100, 100, true, LiveScrollHandler, &vScrollBar );
+ assert( vScrollBar != NULL && err == noErr );
+ err = CreateScrollBarControl( this->GetOwner(), &tempScrollRect, 0, 0, 100, 100, true, LiveScrollHandler, &hScrollBar );
+ assert( hScrollBar != NULL && err == noErr );
+
+ // Set a property on the scrollbars to store a pointer to the Scintilla object
+ ScintillaMacOSX* objectPtr = this;
+ err = SetControlProperty( vScrollBar, scintillaMacOSType, 0, sizeof( this ), &objectPtr );
+ assert( err == noErr );
+ err = SetControlProperty( hScrollBar, scintillaMacOSType, 0, sizeof( this ), &objectPtr );
+ assert( err == noErr );
+
+ // set this into our parent control so we can be retrieved easily at a later time
+ // (see scintilla_send below)
+ err = SetControlProperty( reinterpret_cast<HIViewRef>( windowid ), scintillaMacOSType, 0, sizeof( this ), &objectPtr );
+ assert( err == noErr );
+
+ // Tell Scintilla not to buffer: Quartz buffers drawing for us
+ // TODO: Can we disable this option on Mac OS X?
+ WndProc( SCI_SETBUFFEREDDRAW, 0, 0 );
+ // Turn on UniCode mode
+ WndProc( SCI_SETCODEPAGE, SC_CP_UTF8, 0 );
+
+ const EventTypeSpec commandEventInfo[] = {
+ { kEventClassCommand, kEventProcessCommand },
+ { kEventClassCommand, kEventCommandUpdateStatus },
+ };
+
+ err = InstallEventHandler( GetControlEventTarget( reinterpret_cast<HIViewRef>( windowid ) ),
+ CommandEventHandler,
+ GetEventTypeCount( commandEventInfo ),
+ commandEventInfo,
+ this, NULL);
+ assert( err == noErr );
+}
+
+ScintillaMacOSX::~ScintillaMacOSX() {
+ // If the window is closed and the timer is not removed,
+ // A segment violation will occur when it attempts to fire the timer next.
+ if ( mouseTrackingRef != NULL ) {
+ ReleaseMouseTrackingRegion(mouseTrackingRef);
+ }
+ mouseTrackingRef = NULL;
+ SetTicking(false);
+}
+
+void ScintillaMacOSX::Initialise() {
+ // TODO: Do anything here? Maybe this stuff should be here instead of the constructor?
+}
+
+void ScintillaMacOSX::Finalise() {
+ SetTicking(false);
+ ScintillaBase::Finalise();
+}
+
+// --------------------------------------------------------------------------------------------------------------
+//
+// IsDropInFinderTrash - Returns true if the given dropLocation AEDesc is a descriptor of the Finder's Trash.
+//
+#pragma segment Drag
+
+Boolean IsDropInFinderTrash(AEDesc *dropLocation)
+{
+ OSErr result;
+ AEDesc dropSpec;
+ FSSpec *theSpec;
+ CInfoPBRec thePB;
+ short trashVRefNum;
+ long trashDirID;
+
+ // Coerce the dropLocation descriptor into an FSSpec. If there's no dropLocation or
+ // it can't be coerced into an FSSpec, then it couldn't have been the Trash.
+
+ if ((dropLocation->descriptorType != typeNull) &&
+ (AECoerceDesc(dropLocation, typeFSS, &dropSpec) == noErr))
+ {
+ unsigned char flags = HGetState((Handle)dropSpec.dataHandle);
+
+ HLock((Handle)dropSpec.dataHandle);
+ theSpec = (FSSpec *) *dropSpec.dataHandle;
+
+ // Get the directory ID of the given dropLocation object.
+
+ thePB.dirInfo.ioCompletion = 0L;
+ thePB.dirInfo.ioNamePtr = (StringPtr) &theSpec->name;
+ thePB.dirInfo.ioVRefNum = theSpec->vRefNum;
+ thePB.dirInfo.ioFDirIndex = 0;
+ thePB.dirInfo.ioDrDirID = theSpec->parID;
+
+ result = PBGetCatInfoSync(&thePB);
+
+ HSetState((Handle)dropSpec.dataHandle, flags);
+ AEDisposeDesc(&dropSpec);
+
+ if (result != noErr)
+ return false;
+
+ // If the result is not a directory, it must not be the Trash.
+
+ if (!(thePB.dirInfo.ioFlAttrib & (1 << 4)))
+ return false;
+
+ // Get information about the Trash folder.
+
+ FindFolder(theSpec->vRefNum, kTrashFolderType, kCreateFolder, &trashVRefNum, &trashDirID);
+
+ // If the directory ID of the dropLocation object is the same as the directory ID
+ // returned by FindFolder, then the drop must have occurred into the Trash.
+
+ if (thePB.dirInfo.ioDrDirID == trashDirID)
+ return true;
+ }
+
+ return false;
+
+} // IsDropInFinderTrash
+
+HIPoint ScintillaMacOSX::GetLocalPoint(::Point pt)
+{
+ // get the mouse position so we can offset it
+ Rect bounds;
+ GetWindowBounds( GetOwner(), kWindowStructureRgn, &bounds );
+
+ PRectangle hbounds = wMain.GetPosition();
+ HIViewRef parent = HIViewGetSuperview(GetViewRef());
+ Rect pbounds;
+ GetControlBounds(parent, &pbounds);
+
+ bounds.left += pbounds.left + hbounds.left;
+ bounds.top += pbounds.top + hbounds.top;
+
+ HIPoint offset = { pt.h - bounds.left, pt.v - bounds.top };
+ return offset;
+}
+
+void ScintillaMacOSX::StartDrag() {
+#define DRAG_DROP_PASTEBOARD
+ if (currentPos == anchor) return;
+
+ SelectionText selectedText;
+ CopySelectionRange(&selectedText);
+
+ // some of this taken from copytoclipboard
+ if (selectedText.len == 0)
+ return;
+
+ CFStringEncoding encoding = ( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII);
+
+ // Create a CFString from the ASCII/UTF8 data, convert it to UTF16
+ CFStringRef string = CFStringCreateWithBytes( NULL, reinterpret_cast<UInt8*>( selectedText.s ), selectedText.len - 1, encoding, false );
+ assert( string != NULL );
+
+#ifndef DRAG_DROP_PASTEBOARD
+ CFIndex numUniChars = CFStringGetLength( string );
+ UniChar* buffer = new UniChar[ numUniChars ];
+ CFStringGetCharacters( string, CFRangeMake( 0, numUniChars ), buffer );
+
+ // Create an c string byte buffer
+ CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1;
+ char* cstring = new char[maximumByteLength];
+ CFIndex usedBufferLength = 0;
+ CFIndex numCharsConverted;
+ numCharsConverted = CFStringGetBytes( string, CFRangeMake( 0, numUniChars ), encoding,
+ '?', false, reinterpret_cast<UInt8*>( cstring ),
+ maximumByteLength, &usedBufferLength );
+ cstring[usedBufferLength] = '\0'; // null terminate the ASCII/UTF8 string
+ assert( numCharsConverted == numUniChars );
+#endif
+
+ // calculate the bounds of the selection
+ PRectangle client = GetTextRectangle();
+ int selStart = Platform::Minimum(anchor, currentPos);
+ int selEnd = Platform::Maximum(anchor, currentPos);
+ int startLine = pdoc->LineFromPosition(selStart);
+ int endLine = pdoc->LineFromPosition(selEnd);
+ Point pt;
+ int startPos, endPos, ep;
+ Rect rcSel;
+ rcSel.top = rcSel.bottom = rcSel.right = rcSel.left = -1;
+ for (int l = startLine; l <= endLine; l++) {
+ startPos = WndProc(SCI_GETLINESELSTARTPOSITION, l, 0);
+ endPos = WndProc(SCI_GETLINESELENDPOSITION, l, 0);
+ if (endPos == startPos) continue;
+ // step back a position if we're counting the newline
+ ep = WndProc(SCI_GETLINEENDPOSITION, l, 0);
+ if (endPos > ep) endPos = ep;
+
+ pt = LocationFromPosition(startPos); // top left of line selection
+ if (pt.x < rcSel.left || rcSel.left < 0) rcSel.left = pt.x;
+ if (pt.y < rcSel.top || rcSel.top < 0) rcSel.top = pt.y;
+
+ pt = LocationFromPosition(endPos); // top right of line selection
+ pt.y += vs.lineHeight; // get to the bottom of the line
+ if (pt.x > rcSel.right || rcSel.right < 0) {
+ if (pt.x > client.right)
+ rcSel.right = client.right;
+ else
+ rcSel.right = pt.x;
+ }
+ if (pt.y > rcSel.bottom || rcSel.bottom < 0) {
+ if (pt.y > client.bottom)
+ rcSel.bottom = client.bottom;
+ else
+ rcSel.bottom = pt.y;
+ }
+ }
+
+ // must convert to global coordinates for drag regions, but also save the
+ // image rectangle for further calculations and copy operations
+ PRectangle imageRect = PRectangle(rcSel.left, rcSel.top, rcSel.right, rcSel.bottom);
+ QDLocalToGlobalRect(GetWindowPort(GetOwner()), &rcSel);
+
+ // get the mouse position so we can offset it
+ HIPoint offset = GetLocalPoint(mouseDownEvent.where);
+ offset.y = (imageRect.top * 1.0) - offset.y;
+ offset.x = (imageRect.left * 1.0) - offset.x;
+
+ // to get a bitmap of the text we're dragging, we just use Paint on a
+ // pixmap surface.
+ SurfaceImpl *sw = new SurfaceImpl();
+ SurfaceImpl *pixmap = NULL;
+
+ if (sw) {
+ pixmap = new SurfaceImpl();
+ if (pixmap) {
+ client = GetClientRectangle();
+ paintState = painting;
+ sw->InitPixMap( client.Width(), client.Height(), NULL, NULL );
+
+ Paint(sw, imageRect);
+ paintState = notPainting;
+
+ pixmap->InitPixMap( imageRect.Width(), imageRect.Height(), NULL, NULL );
+
+ CGContextRef gc = pixmap->GetContext();
+
+ // to make Paint() work on a bitmap, we have to flip our coordinates
+ // and translate the origin
+ //fprintf(stderr, "translate to %d\n", client.Height() );
+ CGContextTranslateCTM(gc, 0, imageRect.Height());
+ CGContextScaleCTM(gc, 1.0, -1.0);
+
+ pixmap->CopyImageRectangle( *sw, imageRect, PRectangle( 0, 0, imageRect.Width(), imageRect.Height() ));
+ // XXX TODO: overwrite any part of the image that is not part of the
+ // selection to make it transparent. right now we just use
+ // the full rectangle which may include non-selected text.
+ }
+ sw->Release();
+ delete sw;
+ }
+
+ // now we initiate the drag session
+
+ RgnHandle dragRegion = NewRgn();
+ RgnHandle tempRegion;
+ DragRef inDrag;
+ DragAttributes attributes;
+ AEDesc dropLocation;
+ SInt16 mouseDownModifiers, mouseUpModifiers;
+ bool copyText;
+ CGImageRef image = NULL;
+
+ RectRgn(dragRegion, &rcSel);
+
+#ifdef DRAG_DROP_PASTEBOARD
+ PasteboardRef theClipboard;
+ PasteboardCreate( kPasteboardClipboard, &theClipboard );
+ PasteboardClear( theClipboard );
+
+ CFDataRef data = NULL;
+ data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingMacRoman, 0 );
+ PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1,
+ CFSTR("com.apple.traditional-mac-plain-text"),
+ data, 0 );
+ CFRelease(data);
+ data = CFStringCreateExternalRepresentation ( kCFAllocatorDefault, string, kCFStringEncodingUnicode, 0 );
+ PasteboardPutItemFlavor( theClipboard, (PasteboardItemID)1,
+ CFSTR("public.utf16-plain-text"),
+ data, 0 );
+ CFRelease(data);
+ NewDragWithPasteboard( theClipboard, &inDrag);
+#else
+ NewDrag(&inDrag);
+ AddDragItemFlavor(inDrag, 1, 'utxt', buffer, sizeof( UniChar ) * numUniChars, 0);
+ AddDragItemFlavor(inDrag, 1, 'txt', cstring, sizeof( char ) * usedBufferLength, 0);
+#endif
+
+ // Set the item's bounding rectangle in global coordinates.
+ SetDragItemBounds(inDrag, 1, &rcSel);
+
+ // Prepare the drag region.
+ tempRegion = NewRgn();
+ CopyRgn(dragRegion, tempRegion);
+ InsetRgn(tempRegion, 1, 1);
+ DiffRgn(dragRegion, tempRegion, dragRegion);
+ DisposeRgn(tempRegion);
+
+ // if we have a pixmap, lets use that
+ if (pixmap) {
+ image = pixmap->GetImage();
+ SetDragImageWithCGImage (inDrag, image, &offset, kDragStandardTranslucency);
+ }
+
+ // Drag the text. TrackDrag will return userCanceledErr if the drop whooshed back for any reason.
+ inDragSession = true;
+ OSErr error = TrackDrag(inDrag, &mouseDownEvent, dragRegion);
+ inDragSession = false;
+
+ // Check to see if the drop occurred in the Finder's Trash. If the drop occurred
+ // in the Finder's Trash and a copy operation wasn't specified, delete the
+ // source selection. Note that we can continute to get the attributes, drop location
+ // modifiers, etc. of the drag until we dispose of it using DisposeDrag.
+ if (error == noErr) {
+ GetDragAttributes(inDrag, &attributes);
+ if (!(attributes & kDragInsideSenderApplication))
+ {
+ GetDropLocation(inDrag, &dropLocation);
+
+ GetDragModifiers(inDrag, 0L, &mouseDownModifiers, &mouseUpModifiers);
+ copyText = (mouseDownModifiers | mouseUpModifiers) & optionKey;
+
+ if ((!copyText) && (IsDropInFinderTrash(&dropLocation)))
+ {
+ // delete the selected text from the buffer
+ ClearSelection();
+ }
+
+ AEDisposeDesc(&dropLocation);
+ }
+ }
+
+ // Dispose of this drag, 'cause we're done.
+ DisposeDrag(inDrag);
+ DisposeRgn(dragRegion);
+ CFRelease( string );
+
+ if (pixmap) {
+ CGImageRelease(image);
+ pixmap->Release();
+ delete pixmap;
+ }
+
+ // Done with the UniChar* buffer
+#ifdef DRAG_DROP_PASTEBOARD
+ CFRelease( theClipboard );
+#else
+ delete[] buffer;
+ buffer = NULL;
+ delete[] cstring;
+ cstring = NULL;
+#endif
+}
+
+void ScintillaMacOSX::SetDragCursor(DragRef inDrag)
+{
+ DragAttributes attributes;
+ SInt16 modifiers = 0;
+ ThemeCursor cursor = kThemeCopyArrowCursor;
+ GetDragAttributes( inDrag, &attributes );
+
+ if ( attributes & kDragInsideSenderWindow ) {
+ GetDragModifiers(inDrag, &modifiers, NULL, NULL);
+ switch (modifiers & ~btnState) // Filter out btnState (on for drop)
+ {
+ case optionKey:
+ // it's a copy, leave it as a copy arrow
+ break;
+
+ case cmdKey:
+ case cmdKey | optionKey:
+ default:
+ // what to do with these? rectangular drag?
+ cursor = kThemeArrowCursor;
+ break;
+ }
+ }
+ SetThemeCursor(cursor);
+}
+
+bool ScintillaMacOSX::DragEnter(DragRef inDrag )
+{
+ if (!DragWithin(inDrag))
+ return false;
+
+ DragAttributes attributes;
+ GetDragAttributes( inDrag, &attributes );
+
+ // only show the drag hilight if the drag has left the sender window per HI spec
+ if( attributes & kDragHasLeftSenderWindow )
+ {
+ HIRect textFrame;
+ RgnHandle hiliteRgn = NewRgn();
+
+ // get the text view's frame ...
+ HIViewGetFrame( GetViewRef(), &textFrame );
+
+ // ... and convert it into a region for ShowDragHilite
+ HIShapeRef textShape = HIShapeCreateWithRect( &textFrame );
+ HIShapeGetAsQDRgn( textShape, hiliteRgn );
+ CFRelease( textShape );
+
+ // add the drag hilight to the inside of the text view
+ ShowDragHilite( inDrag, hiliteRgn, true );
+
+ DisposeRgn( hiliteRgn );
+ }
+ SetDragCursor(inDrag);
+ return true;
+}
+
+Scintilla::Point ScintillaMacOSX::GetDragPoint(DragRef inDrag)
+{
+ ::Point mouse, globalMouse;
+ GetDragMouse(inDrag, &mouse, &globalMouse);
+ QDGlobalToLocalPoint(GetWindowPort(GetOwner()), &globalMouse);
+ HIPoint hiPoint = {globalMouse.h, globalMouse.v};
+ return Point(static_cast<int>(hiPoint.x), static_cast<int>(hiPoint.y));
+}
+
+
+void ScintillaMacOSX::DragScroll()
+{
+#define RESET_SCROLL_TIMER(lines) \
+ scrollSpeed = (lines); \
+ scrollTicks = 2000;
+
+ if (posDrag == invalidPosition) {
+ RESET_SCROLL_TIMER(1);
+ return;
+ }
+ Point dragMouse = LocationFromPosition(posDrag);
+ int line = pdoc->LineFromPosition(posDrag);
+ int currentVisibleLine = cs.DisplayFromDoc(line);
+ int lastVisibleLine = Platform::Minimum(topLine + LinesOnScreen() - 1, pdoc->LinesTotal() - 1);
+
+ if (currentVisibleLine <= topLine && topLine > 0) {
+ ScrollTo( topLine - scrollSpeed );
+ } else if (currentVisibleLine >= lastVisibleLine) {
+ ScrollTo( topLine + scrollSpeed );
+ } else {
+ RESET_SCROLL_TIMER(1);
+ return;
+ }
+ if (scrollSpeed == 1) {
+ scrollTicks -= timer.tickSize;
+ if (scrollTicks <= 0) {
+ RESET_SCROLL_TIMER(5);
+ }
+ }
+
+ SetDragPosition(PositionFromLocation(dragMouse));
+
+#undef RESET_SCROLL_TIMER
+}
+
+bool ScintillaMacOSX::DragWithin(DragRef inDrag )
+{
+ PasteboardRef pasteBoard;
+ OSStatus status = GetDragData(inDrag, pasteBoard, NULL);
+ if (status != noErr) {
+ return false;
+ }
+
+ ::Point mouse, globalMouse;
+ GetDragMouse(inDrag, &mouse, &globalMouse);
+ QDGlobalToLocalPoint(GetWindowPort(GetOwner()), &globalMouse);
+ HIPoint globalHit = {globalMouse.h, globalMouse.v};
+ // HIPoint localHit = {mouse.h, mouse.v};
+
+ if (!CGRectContainsPoint( Bounds(), globalHit )) {
+ return false;
+ }
+
+ SetDragPosition(PositionFromLocation(Point(static_cast<int>(globalHit.x),static_cast<int>(globalHit.y))));
+ SetDragCursor(inDrag);
+
+ return true;
+}
+
+bool ScintillaMacOSX::DragLeave(DragRef inDrag )
+{
+ HideDragHilite( inDrag );
+ SetDragPosition(invalidPosition);
+ WndProc(SCI_SETCURSOR, Window::cursorArrow, 0);
+ return true;
+}
+
+OSStatus ScintillaMacOSX::GetDragData(DragRef inDrag, PasteboardRef &pasteBoard, CFStringRef *textString)
+{
+ // TODO: add support for special flavors: flavorTypeHFS and flavorTypePromiseHFS so we
+ // can handle files being dropped on the editor
+ OSStatus status;
+ status = GetDragPasteboard(inDrag, &pasteBoard);
+ if (status != noErr) {
+ return dragNotAcceptedErr;
+ }
+
+ // how many items in the pasteboard?
+ ItemCount i, itemCount;
+ status = PasteboardGetItemCount(pasteBoard, &itemCount);
+ if (status != noErr) {
+ return dragNotAcceptedErr;
+ }
+
+ // as long as we didn't get our text, let's loop on the items. We stop as soon as we get it
+ CFArrayRef flavorTypeArray = NULL;
+ bool haveMatch = false;
+ for (i = 1; i <= itemCount; i++)
+ {
+ PasteboardItemID itemID;
+ CFIndex j, flavorCount = 0;
+
+ status = PasteboardGetItemIdentifier(pasteBoard, i, &itemID);
+ if (status != noErr) {
+ return dragNotAcceptedErr;
+ }
+
+ // how many flavors in this item?
+ status = PasteboardCopyItemFlavors(pasteBoard, itemID, &flavorTypeArray);
+ if (status != noErr) {
+ return dragNotAcceptedErr;
+ }
+
+ if (flavorTypeArray != NULL)
+ flavorCount = CFArrayGetCount(flavorTypeArray);
+
+ // as long as we didn't get our text, let's loop on the flavors. We stop as soon as we get it
+ for(j = 0; j < flavorCount; j++)
+ {
+ CFDataRef flavorData;
+ CFStringRef flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, j);
+ if (flavorType != NULL) {
+ if (UTTypeConformsTo(flavorType, CFSTR("public.utf16-plain-text"))) // this is 'utxt'
+ {
+ // if we got a flavor match, and we have no textString, we just want
+ // to know that we can accept this drag data, so jump out now
+ if (textString == NULL) {
+ haveMatch = true;
+ goto DragDataRetrieved;
+ }
+ if (PasteboardCopyItemFlavorData(pasteBoard, itemID, flavorType, &flavorData) == noErr)
+ {
+ CFIndex flavorDataSize = CFDataGetLength(flavorData);
+
+ // getting the text
+ *textString = CFStringCreateWithCharacters(NULL,
+ (UniChar *)CFDataGetBytePtr(flavorData),
+ flavorDataSize >> 1);
+ CFRelease(flavorData);
+ goto DragDataRetrieved;
+ }
+ }
+ }
+ }
+ }
+DragDataRetrieved:
+ if (flavorTypeArray != NULL) CFRelease(flavorTypeArray);
+ if (haveMatch || textString != NULL && *textString != NULL)
+ return noErr;
+ return dragNotAcceptedErr;
+}
+
+OSStatus ScintillaMacOSX::DragReceive(DragRef inDrag )
+{
+ OSStatus status;
+ PasteboardRef pasteBoard;
+ CFStringRef textString = NULL;
+ status = GetDragData(inDrag, pasteBoard, &textString);
+ if (status != noErr) {
+ return dragNotAcceptedErr;
+ }
+
+ // getting the length of the text and setting the value
+ if (textString == NULL) {
+ return noErr;
+ }
+
+ // XXX the following is identical (ALMOST) to code in Paste
+
+ // Allocate a buffer, plus the null byte
+ CFIndex numUniChars = CFStringGetLength( textString );
+ CFStringEncoding encoding = ( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII);
+ CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1;
+ char* cstring = new char[maximumByteLength];
+ CFIndex usedBufferLength = 0;
+ CFIndex numCharsConverted;
+ numCharsConverted = CFStringGetBytes( textString, CFRangeMake( 0, numUniChars ), encoding,
+ '?', false, reinterpret_cast<UInt8*>( cstring ),
+ maximumByteLength, &usedBufferLength );
+ cstring[usedBufferLength] = '\0'; // null terminate the ASCII/UTF8 string
+ assert( numCharsConverted == numUniChars );
+
+ // Default allocator releases both the CFString and the UniChar buffer (text)
+ CFRelease( textString );
+ textString = NULL;
+
+ // determine whether a BOM is in the string. Apps like Emacs prepends a BOM
+ // to the string, CFStrinGetBytes reflects that (though it may change in the conversion)
+ // so we need to remove it before pasting into our buffer. TextWrangler has no
+ // problem dealing with BOM when pasting into it.
+ int bomLen = BOMlen((unsigned char *)cstring);
+
+ // convert line endings to the document line ending
+ int droppedLen = 0;
+ char *droppedText = Document::TransformLineEnds(&droppedLen,
+ cstring + bomLen,
+ usedBufferLength - bomLen,
+ pdoc->eolMode);
+
+ pdoc->BeginUndoAction();
+
+ // figure out if this is a move or a paste
+ DragAttributes attributes;
+ SInt16 modifiers = 0;
+ GetDragAttributes( inDrag, &attributes );
+
+ int position = PositionFromLocation(GetDragPoint(inDrag));
+ int selStart = Platform::Minimum(anchor, currentPos);
+ int selEnd = Platform::Maximum(anchor, currentPos);
+ if ( attributes & kDragInsideSenderWindow ) {
+ if (position >= selStart && position <= selEnd) {
+ // droping on top of what we dragged, we should ignore this
+ goto endDrag;
+ }
+ GetDragModifiers(inDrag, NULL, NULL, &modifiers);
+ switch (modifiers & ~btnState) // Filter out btnState (on for drop)
+ {
+ case optionKey:
+ // default is copy text
+ break;
+
+ case cmdKey:
+ case cmdKey | optionKey:
+ default:
+ // what to do with these? rectangular drag?
+ position = selStart;
+ ClearSelection();
+ break;
+ }
+ } else {
+ if (position >= selStart && position <= selEnd) {
+ // droping on top of a selection from another app or control, clear it
+ position = selStart;
+ ClearSelection();
+ }
+ }
+
+ // lets put the text in our document now
+ if ( pdoc->InsertString( position, droppedText, droppedLen ) )
+ {
+ SetEmptySelection( currentPos + droppedLen );
+ }
+
+endDrag:
+ delete[] droppedText;
+ delete[] cstring;
+ cstring = NULL;
+
+ pdoc->EndUndoAction();
+ NotifyChange();
+
+ // dragleave IS called, but for some reason (probably to do with inDrag)
+ // the hide hilite does not happen unless we do it here
+ HideDragHilite( inDrag );
+
+ return noErr;
+}
+
+/** The simulated message loop. */
+sptr_t ScintillaMacOSX::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
+ switch (iMessage) {
+ case SCI_GETDIRECTFUNCTION:
+ Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Returning DirectFunction address.\n" );
+ return reinterpret_cast<sptr_t>( DirectFunction );
+
+ case SCI_GETDIRECTPOINTER:
+ Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Returning Direct pointer address.\n" );
+ return reinterpret_cast<sptr_t>( this );
+
+ case SCI_GRABFOCUS:
+ Platform::DebugDisplay( "ScintillaMacOSX::WndProc: Got an unhandled message. Ignoring it.\n" );
+ break;
+ case WM_UNICHAR:
+ if (IsUnicodeMode()) {
+ char utfval[4];
+ wchar_t wcs[2] = {wParam, 0};
+ unsigned int len = UTF8Length(wcs, 1);
+ UTF8FromUTF16(wcs, 1, utfval, len);
+ AddCharUTF(utfval, len);
+ return 1;
+ } else {
+ return 0;
+ }
+
+ default:
+ unsigned int r = ScintillaBase::WndProc(iMessage, wParam, lParam);
+
+ return r;
+ }
+ return 0l;
+}
+
+sptr_t ScintillaMacOSX::DefWndProc(unsigned int, uptr_t, sptr_t) {
+ return 0;
+}
+
+void ScintillaMacOSX::SetTicking(bool on) {
+ if (timer.ticking != on) {
+ timer.ticking = on;
+ if (timer.ticking) {
+ // Scintilla ticks = milliseconds
+ EventLoopTimerRef timerRef = NULL;
+ InstallTimer( timer.tickSize * kEventDurationMillisecond, &timerRef );
+ assert( timerRef != NULL );
+ timer.tickerID = reinterpret_cast<TickerID>( timerRef );
+ } else if ( timer.tickerID != NULL ) {
+ RemoveEventLoopTimer( reinterpret_cast<EventLoopTimerRef>( timer.tickerID ) );
+ }
+ }
+ timer.ticksToWait = caret.period;
+}
+
+bool ScintillaMacOSX::SetIdle(bool on) {
+ if (on) {
+ // Start idler, if it's not running.
+ if (idler.state == false) {
+ idler.state = true;
+ EventLoopTimerRef idlTimer;
+ InstallEventLoopIdleTimer(GetCurrentEventLoop(),
+ timer.tickSize * kEventDurationMillisecond,
+ 75 * kEventDurationMillisecond,
+ IdleTimerEventHandler, this, &idlTimer);
+ idler.idlerID = reinterpret_cast<IdlerID>( idlTimer );
+ }
+ } else {
+ // Stop idler, if it's running
+ if (idler.state == true) {
+ idler.state = false;
+ if (idler.idlerID != NULL)
+ RemoveEventLoopTimer( reinterpret_cast<EventLoopTimerRef>( idler.idlerID ) );
+ }
+ }
+ return true;
+}
+
+pascal void ScintillaMacOSX::IdleTimerEventHandler( EventLoopTimerRef inTimer,
+ EventLoopIdleTimerMessage inState,
+ void *scintilla )
+{
+ ScintillaMacOSX *sciThis = reinterpret_cast<ScintillaMacOSX*>( scintilla );
+ bool ret = sciThis->Idle();
+ if (ret == false) {
+ sciThis->SetIdle(false);
+ }
+}
+
+void ScintillaMacOSX::SetMouseCapture(bool on) {
+ capturedMouse = on;
+ if (mouseDownCaptures) {
+ if (capturedMouse) {
+ WndProc(SCI_SETCURSOR, Window::cursorArrow, 0);
+ } else {
+ // reset to normal, buttonmove will change for other area's in the editor
+ WndProc(SCI_SETCURSOR, (long int)SC_CURSORNORMAL, 0);
+ }
+ }
+}
+
+bool ScintillaMacOSX::HaveMouseCapture() {
+ return capturedMouse;
+}
+
+// The default GetClientRectangle calls GetClientPosition on wMain.
+// We override it to return "view local" co-ordinates so we can draw properly
+// plus we need to remove the space occupied by the scroll bars
+PRectangle ScintillaMacOSX::GetClientRectangle() {
+ PRectangle rc = wMain.GetClientPosition();
+ if (verticalScrollBarVisible)
+ rc.right -= scrollBarFixedSize + 1;
+ if (horizontalScrollBarVisible && (wrapState == eWrapNone))
+ rc.bottom -= scrollBarFixedSize + 1;
+ // Move to origin
+ rc.right -= rc.left;
+ rc.bottom -= rc.top;
+ rc.left = 0;
+ rc.top = 0;
+ return rc;
+}
+
+// Synchronously paint a rectangle of the window.
+void ScintillaMacOSX::SyncPaint(void* gc, PRectangle rc) {
+ paintState = painting;
+ rcPaint = rc;
+ PRectangle rcText = GetTextRectangle();
+ paintingAllText = rcPaint.Contains(rcText);
+ //Platform::DebugPrintf("ScintillaMacOSX::SyncPaint %0d,%0d %0d,%0d\n",
+ // rcPaint.left, rcPaint.top, rcPaint.right, rcPaint.bottom);
+ Surface *sw = Surface::Allocate();
+ if (sw) {
+ sw->Init( gc, wMain.GetID() );
+ Paint(sw, rc);
+ if (paintState == paintAbandoned) {
+ // XXX a bit of a hack to avoid excesive flashing when typing.
+ paintState = painting;
+ paintingAllText = true;
+ Paint(sw, rc);
+ // TODO: There is a chance that this causes an infinite drawing loop...
+ wMain.InvalidateAll();
+ }
+ sw->Release();
+ delete sw;
+ }
+ paintState = notPainting;
+}
+
+void ScintillaMacOSX::ScrollText(int /*linesToMove*/) {
+ // This function will invalidate the correct regions of the view,
+ // So shortly after this happens, draw will be called.
+ // But I'm not quite sure how this works ...
+ // I have a feeling that it is only supposed to work in conjunction with an HIScrollView.
+ // TODO: Cook up my own bitblt scroll: Grab the bits on screen, blit them shifted, invalidate the remaining stuff
+ //CGRect r = CGRectMake( 0, 0, rc.Width(), rc.Height() );
+ //HIViewScrollRect( reinterpret_cast<HIViewRef>( wMain.GetID() ), NULL, 0, vs.lineHeight * linesToMove );
+ wMain.InvalidateAll();
+}
+
+void ScintillaMacOSX::SetVerticalScrollPos() {
+ SetControl32BitValue( vScrollBar, topLine );
+}
+
+void ScintillaMacOSX::SetHorizontalScrollPos() {
+ SetControl32BitValue( hScrollBar, xOffset );
+}
+
+bool ScintillaMacOSX::ModifyScrollBars(int nMax, int nPage) {
+ Platform::DebugPrintf( "nMax: %d nPage: %d hScroll (%d -> %d) page: %d\n", nMax, nPage, 0, scrollWidth, GetTextRectangle().Width() );
+ // Minimum value = 0
+ // TODO: This is probably not needed, since we set this when the scroll bars are created
+ SetControl32BitMinimum( vScrollBar, 0 );
+ SetControl32BitMinimum( hScrollBar, 0 );
+
+ // Maximum vertical value = nMax + 1 - nPage (lines available to scroll)
+ SetControl32BitMaximum( vScrollBar, Platform::Maximum( nMax + 1 - nPage, 0 ) );
+ // Maximum horizontal value = scrollWidth - GetTextRectangle().Width() (pixels available to scroll)
+ SetControl32BitMaximum( hScrollBar, Platform::Maximum( scrollWidth - GetTextRectangle().Width(), 0 ) );
+
+ // Vertical page size = nPage
+ SetControlViewSize( vScrollBar, nPage );
+ // Horizontal page size = TextRectangle().Width()
+ SetControlViewSize( hScrollBar, GetTextRectangle().Width() );
+
+ // TODO: Verify what this return value is for
+ // The scroll bar components will handle if they need to be rerendered or not
+ return false;
+}
+
+void ScintillaMacOSX::ReconfigureScrollBars() {
+ PRectangle rc = wMain.GetClientPosition();
+ Resize(rc.Width(), rc.Height());
+}
+
+void ScintillaMacOSX::Resize(int width, int height) {
+ // Get the horizontal/vertical size of the scroll bars
+ GetThemeMetric( kThemeMetricScrollBarWidth, &scrollBarFixedSize );
+
+ bool showSBHorizontal = horizontalScrollBarVisible && (wrapState == eWrapNone);
+ HIRect scrollRect;
+ if (verticalScrollBarVisible) {
+ scrollRect.origin.x = width - scrollBarFixedSize;
+ scrollRect.origin.y = 0;
+ scrollRect.size.width = scrollBarFixedSize;
+ if (showSBHorizontal) {
+ scrollRect.size.height = Platform::Maximum(1, height - scrollBarFixedSize);
+ } else {
+ scrollRect.size.height = height;
+ }
+
+ HIViewSetFrame( vScrollBar, &scrollRect );
+ if (HIViewGetSuperview(vScrollBar) == NULL) {
+ HIViewSetDrawingEnabled( vScrollBar, true );
+ HIViewSetVisible(vScrollBar, true);
+ HIViewAddSubview(GetViewRef(), vScrollBar );
+ Draw1Control(vScrollBar);
+ }
+ } else if (HIViewGetSuperview(vScrollBar) != NULL) {
+ HIViewSetDrawingEnabled( vScrollBar, false );
+ HIViewRemoveFromSuperview(vScrollBar);
+ }
+
+ if (showSBHorizontal) {
+ scrollRect.origin.x = 0;
+ // Always draw the scrollbar to avoid the "potiential" horizontal scroll bar and to avoid the resize box.
+ // This should be "good enough". Best would be to avoid the resize box.
+ // Even better would be to embed Scintilla inside an HIScrollView, which would handle this for us.
+ scrollRect.origin.y = height - scrollBarFixedSize;
+ if (verticalScrollBarVisible) {
+ scrollRect.size.width = Platform::Maximum( 1, width - scrollBarFixedSize );
+ } else {
+ scrollRect.size.width = width;
+ }
+ scrollRect.size.height = scrollBarFixedSize;
+
+ HIViewSetFrame( hScrollBar, &scrollRect );
+ if (HIViewGetSuperview(hScrollBar) == NULL) {
+ HIViewSetDrawingEnabled( hScrollBar, true );
+ HIViewAddSubview( GetViewRef(), hScrollBar );
+ Draw1Control(hScrollBar);
+ }
+ } else if (HIViewGetSuperview(hScrollBar) != NULL) {
+ HIViewSetDrawingEnabled( hScrollBar, false );
+ HIViewRemoveFromSuperview(hScrollBar);
+ }
+
+ ChangeSize();
+}
+
+void ScintillaMacOSX::NotifyChange() {
+ // TODO: How should this be implemented on OS X? Should it be?
+}
+
+pascal void ScintillaMacOSX::LiveScrollHandler( HIViewRef control, SInt16 part )
+{
+ SInt16 currentValue = GetControl32BitValue( control );
+ SInt16 min = GetControl32BitMinimum( control );
+ SInt16 max = GetControl32BitMaximum( control );
+ SInt16 page = GetControlViewSize( control );
+
+ // Get a reference to the Scintilla C++ object
+ ScintillaMacOSX* scintilla = NULL;
+ OSStatus err;
+ err = GetControlProperty( control, scintillaMacOSType, 0, sizeof( scintilla ), NULL, &scintilla );
+ assert( err == noErr && scintilla != NULL );
+
+ int singleScroll = 0;
+ if ( control == scintilla->vScrollBar )
+ {
+ // Vertical single scroll = one line
+ // TODO: Is there a Scintilla preference for this somewhere?
+ singleScroll = 1;
+ } else {
+ assert( control == scintilla->hScrollBar );
+ // Horizontal single scroll = 20 pixels (hardcoded from ScintillaWin)
+ // TODO: Is there a Scintilla preference for this somewhere?
+ singleScroll = 20;
+ }
+
+ // Determine the new value
+ int newValue = 0;
+ switch ( part )
+ {
+ case kControlUpButtonPart:
+ newValue = Platform::Maximum( currentValue - singleScroll, min );
+ break;
+
+ case kControlDownButtonPart:
+ // the the user scrolls to the right, allow more scroll space
+ if ( control == scintilla->hScrollBar && currentValue >= max) {
+ // change the max value
+ scintilla->scrollWidth += singleScroll;
+ SetControl32BitMaximum( control,
+ Platform::Maximum( scintilla->scrollWidth - scintilla->GetTextRectangle().Width(), 0 ) );
+ max = GetControl32BitMaximum( control );
+ scintilla->SetScrollBars();
+ }
+ newValue = Platform::Minimum( currentValue + singleScroll, max );
+ break;
+
+ case kControlPageUpPart:
+ newValue = Platform::Maximum( currentValue - page, min );
+ break;
+
+ case kControlPageDownPart:
+ newValue = Platform::Minimum( currentValue + page, max );
+ break;
+
+ case kControlIndicatorPart:
+ newValue = currentValue;
+ break;
+
+ default:
+ assert( false );
+ return;
+ }
+
+ // Set the new value
+ if ( control == scintilla->vScrollBar )
+ {
+ scintilla->ScrollTo( newValue );
+ } else {
+ assert( control == scintilla->hScrollBar );
+ scintilla->HorizontalScrollTo( newValue );
+ }
+}
+
+bool ScintillaMacOSX::ScrollBarHit(HIPoint location) {
+ // is this on our scrollbars? If so, track them
+ HIViewRef view;
+ // view is null if on editor, otherwise on scrollbar
+ HIViewGetSubviewHit(reinterpret_cast<ControlRef>(wMain.GetID()),
+ &location, true, &view);
+ if (view) {
+ HIViewPartCode part;
+
+ // make the point local to a scrollbar
+ PRectangle client = GetClientRectangle();
+ if (view == vScrollBar) {
+ location.x -= client.Width();
+ } else if (view == hScrollBar) {
+ location.y -= client.Height();
+ } else {
+ fprintf(stderr, "got a subview hit, but not a scrollbar???\n");
+ return false;
+ }
+
+ HIViewGetPartHit(view, &location, &part);
+
+ switch (part)
+ {
+ case kControlUpButtonPart:
+ case kControlDownButtonPart:
+ case kControlPageUpPart:
+ case kControlPageDownPart:
+ case kControlIndicatorPart:
+ ::Point p;
+ p.h = location.x;
+ p.v = location.y;
+ // We are assuming Appearance 1.1 or later, so we
+ // have the "live scroll" variant of the scrollbar,
+ // which lets you pass the action proc to TrackControl
+ // for the thumb (this was illegal in previous
+ // versions of the defproc).
+ isTracking = true;
+ ::TrackControl(view, p, ScintillaMacOSX::LiveScrollHandler);
+ ::HiliteControl(view, 0);
+ isTracking = false;
+ // The mouseup was eaten by TrackControl, however if we
+ // do not get a mouseup in the scintilla xbl widget,
+ // many bad focus issues happen. Simply post a mouseup
+ // and this firey pit becomes a bit cooler.
+ PostEvent(mouseUp, 0);
+ break;
+ default:
+ fprintf(stderr, "PlatformScrollBarHit part %d\n", part);
+ }
+ return true;
+ }
+ return false;
+}
+
+
+void ScintillaMacOSX::NotifyFocus(bool /*focus*/) {
+ // TODO: How should this be implemented on OS X? Should it be?
+}
+
+typedef void (*SciNotifyFunc)(sptr_t *, long);
+void ScintillaMacOSX::NotifyParent(SCNotification scn) {
+ OSStatus err;
+ sptr_t *ptr = NULL;
+ SciNotifyFunc fn = NULL;
+
+ // XXX do this at some other point, or otherwise cache the results
+ err = GetControlProperty(GetViewRef(),
+ scintillaNotifyObject, 0,
+ sizeof( sptr_t * ), NULL, &ptr );
+ if (err != noErr) return;
+ err = GetControlProperty(GetViewRef(),
+ scintillaNotifyFN, 0,
+ sizeof( SciNotifyFunc ), NULL, &fn );
+ if (err != noErr || !fn) return;
+
+ scn.nmhdr.hwndFrom = GetViewRef();
+ scn.nmhdr.idFrom = (unsigned int)wMain.GetID();
+ fn(ptr, (long int)&scn);
+}
+
+void ScintillaMacOSX::NotifyKey(int key, int modifiers) {
+ SCNotification scn;
+ scn.nmhdr.code = SCN_KEY;
+ scn.ch = key;
+ scn.modifiers = modifiers;
+
+ NotifyParent(scn);
+}
+
+void ScintillaMacOSX::NotifyURIDropped(const char *list) {
+ SCNotification scn;
+ scn.nmhdr.code = SCN_URIDROPPED;
+ scn.text = list;
+
+ NotifyParent(scn);
+}
+
+int ScintillaMacOSX::KeyDefault(int key, int modifiers) {
+ if (!(modifiers & SCI_CTRL) && !(modifiers & SCI_ALT) && (key < 256)) {
+ AddChar(key);
+ return 1;
+ } else {
+ // Pass up to container in case it is an accelerator
+ NotifyKey(key, modifiers);
+ return 0;
+ }
+ //Platform::DebugPrintf("SK-key: %d %x %x\n",key, modifiers);
+}
+
+template <class T, class U>
+struct StupidMap
+{
+public:
+ T key;
+ U value;
+};
+
+template <class T, class U>
+inline static U StupidMapFindFunction( const StupidMap<T, U>* elements, size_t length, const T& desiredKey )
+{
+ for ( size_t i = 0; i < length; ++ i )
+ {
+ if ( elements[i].key == desiredKey )
+ {
+ return elements[i].value;
+ }
+ }
+
+ return NULL;
+}
+
+// NOTE: If this macro is used on a StupidMap that isn't defined by StupidMap x[] = ...
+// The size calculation will fail!
+#define StupidMapFind( x, y ) StupidMapFindFunction( x, sizeof(x)/sizeof(*x), y )
+
+pascal OSStatus ScintillaMacOSX::CommandEventHandler( EventHandlerCallRef /*inCallRef*/, EventRef event, void* data )
+{
+ // TODO: Verify automatically that each constant only appears once?
+ const StupidMap<UInt32, void (ScintillaMacOSX::*)()> processCommands[] = {
+ { kHICommandCopy, &ScintillaMacOSX::Copy },
+ { kHICommandPaste, &ScintillaMacOSX::Paste },
+ { kHICommandCut, &ScintillaMacOSX::Cut },
+ { kHICommandUndo, &ScintillaMacOSX::Undo },
+ { kHICommandRedo, &ScintillaMacOSX::Redo },
+ { kHICommandClear, &ScintillaMacOSX::ClearSelection },
+ { kHICommandSelectAll, &ScintillaMacOSX::SelectAll },
+ };
+ const StupidMap<UInt32, bool (ScintillaMacOSX::*)()> canProcessCommands[] = {
+ { kHICommandCopy, &ScintillaMacOSX::HasSelection },
+ { kHICommandPaste, &ScintillaMacOSX::CanPaste },
+ { kHICommandCut, &ScintillaMacOSX::HasSelection },
+ { kHICommandUndo, &ScintillaMacOSX::CanUndo },
+ { kHICommandRedo, &ScintillaMacOSX::CanRedo },
+ { kHICommandClear, &ScintillaMacOSX::HasSelection },
+ { kHICommandSelectAll, &ScintillaMacOSX::AlwaysTrue },
+ };
+
+ HICommand command;
+ OSStatus result = GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof( command ), NULL, &command );
+ assert( result == noErr );
+
+ UInt32 kind = GetEventKind( event );
+ Platform::DebugPrintf("ScintillaMacOSX::CommandEventHandler kind %d\n", kind);
+
+ ScintillaMacOSX* scintilla = reinterpret_cast<ScintillaMacOSX*>( data );
+ assert( scintilla != NULL );
+
+ if ( kind == kEventProcessCommand )
+ {
+ // Find the method pointer that matches this command
+ void (ScintillaMacOSX::*methodPtr)() = StupidMapFind( processCommands, command.commandID );
+
+ if ( methodPtr != NULL )
+ {
+ // Call the method if we found it, and tell the caller that we handled this event
+ (scintilla->*methodPtr)();
+ result = noErr;
+ } else {
+ // tell the caller that we did not handle the event
+ result = eventNotHandledErr;
+ }
+ }
+ // The default Mac OS X text editor does not handle these events to enable/disable menu items
+ // Why not? I think it should, so Scintilla does.
+ else if ( kind == kEventCommandUpdateStatus && ( command.attributes & kHICommandFromMenu ) )
+ {
+ // Find the method pointer that matches this command
+ bool (ScintillaMacOSX::*methodPtr)() = StupidMapFind( canProcessCommands, command.commandID );
+
+ if ( methodPtr != NULL ) {
+ // Call the method if we found it: enabling/disabling menu items
+ if ( (scintilla->*methodPtr)() ) {
+ EnableMenuItem( command.menu.menuRef, command.menu.menuItemIndex );
+ } else {
+ DisableMenuItem( command.menu.menuRef, command.menu.menuItemIndex );
+ }
+ result = noErr;
+ } else {
+ // tell the caller that we did not handle the event
+ result = eventNotHandledErr;
+ }
+ } else {
+ // Unhandled event: We should never get here
+ assert( false );
+ result = eventNotHandledErr;
+ }
+
+ return result;
+}
+
+bool ScintillaMacOSX::HasSelection()
+{
+ return ( SelectionEnd() - SelectionStart() > 0 );
+}
+
+bool ScintillaMacOSX::CanUndo()
+{
+ return pdoc->CanUndo();
+}
+
+bool ScintillaMacOSX::CanRedo()
+{
+ return pdoc->CanRedo();
+}
+
+bool ScintillaMacOSX::AlwaysTrue()
+{
+ return true;
+}
+
+void ScintillaMacOSX::CopyToClipboard(const SelectionText &selectedText) {
+ if (selectedText.len == 0)
+ return;
+
+ CFStringEncoding encoding = ( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII);
+
+ // Create a CFString from the ASCII/UTF8 data, convert it to UTF16
+ CFStringRef string = CFStringCreateWithBytes( NULL, reinterpret_cast<UInt8*>( selectedText.s ), selectedText.len - 1, encoding, false );
+ assert( string != NULL );
+
+ CFIndex numUniChars = CFStringGetLength( string );
+ UniChar* buffer = new UniChar[ numUniChars ];
+ CFStringGetCharacters( string, CFRangeMake( 0, numUniChars ), buffer );
+
+ // Done with the CFString
+ CFRelease( string );
+ string = NULL;
+
+ OSStatus err;
+ err = ClearCurrentScrap();
+ assert( err == noErr );
+
+ ScrapRef scrap = NULL;
+ err = GetCurrentScrap( &scrap );
+ assert( err == noErr && scrap != NULL );
+
+ err = PutScrapFlavor( scrap, kScrapFlavorTypeUnicode, 0, sizeof( UniChar ) * numUniChars, buffer );
+ assert( err == noErr );
+ err = PutScrapFlavor( scrap, kScrapFlavorTypeText, 0, sizeof( char ) * selectedText.len, reinterpret_cast<UInt8*>( selectedText.s ) );
+ assert( err == noErr );
+
+ // Done with the UniChar* buffer
+ delete[] buffer;
+ buffer = NULL;
+}
+
+void ScintillaMacOSX::Copy()
+{
+ if (currentPos != anchor) {
+ SelectionText selectedText;
+ CopySelectionRange(&selectedText);
+ CopyToClipboard(selectedText);
+ }
+}
+
+bool ScintillaMacOSX::CanPaste()
+{
+ ScrapRef scrap = NULL;
+ OSStatus err;
+ err = GetCurrentScrap( &scrap );
+ assert( err == noErr && scrap != NULL );
+
+ ScrapFlavorFlags flavorFlags;
+ return GetScrapFlavorFlags ( scrap, kScrapFlavorTypeUnicode, &flavorFlags ) == noErr ||
+ GetScrapFlavorFlags ( scrap, kScrapFlavorTypeText, &flavorFlags ) == noErr;
+}
+
+void ScintillaMacOSX::Paste()
+{
+ Paste(false);
+}
+
+// XXX there is no system flag (I can find) to tell us that a paste is rectangular, so
+// applications must implement an additional command (eg. option-V like BBEdit)
+// in order to provide rectangular paste
+void ScintillaMacOSX::Paste(bool isRectangular)
+{
+ // Make sure that we CAN paste
+ if ( ! CanPaste() ) return;
+
+ // Get the clipboard reference
+ ScrapRef scrap = NULL;
+ OSStatus err;
+ err = GetCurrentScrap( &scrap );
+ assert( err == noErr && scrap != NULL );
+
+ ScrapFlavorFlags flavorFlags;
+ Size bytes = 0;
+ CFStringRef string = NULL;
+ if (GetScrapFlavorFlags ( scrap, kScrapFlavorTypeUnicode, &flavorFlags ) == noErr)
+ {
+ // No error, we have unicode data in a Scrap. Find out how many bytes of data it is.
+ err = GetScrapFlavorSize( scrap, kScrapFlavorTypeUnicode, &bytes );
+ assert( err == noErr && bytes != 0 );
+ Size numUniChars = bytes / sizeof( UniChar );
+
+ // Allocate a buffer for the text using Core Foundation
+ UniChar* buffer = reinterpret_cast<UniChar*>( CFAllocatorAllocate( NULL, bytes, 0 ) );
+ assert( buffer != NULL );
+
+ // Get a copy of the text
+ Size nextBytes = bytes;
+ err = GetScrapFlavorData( scrap, kScrapFlavorTypeUnicode, &nextBytes, buffer );
+ assert( err == noErr && nextBytes == bytes );
+
+ // Create a CFString which wraps and takes ownership of the buffer
+ string = CFStringCreateWithCharactersNoCopy( NULL, buffer, numUniChars, NULL );
+ assert( string != NULL );
+ buffer = NULL; // string now owns this buffer
+ } else if (GetScrapFlavorFlags ( scrap, kScrapFlavorTypeText, &flavorFlags ) == noErr) {
+ // No error, we have unicode data in a Scrap. Find out how many bytes of data it is.
+ err = GetScrapFlavorSize( scrap, kScrapFlavorTypeText, &bytes );
+ assert( err == noErr && bytes != 0 );
+
+ // Allocate a buffer for the text using Core Foundation
+ char* buffer = reinterpret_cast<char*>( CFAllocatorAllocate( NULL, bytes + 1, 0 ) );
+ assert( buffer != NULL );
+
+ // Get a copy of the text
+ Size nextBytes = bytes;
+ err = GetScrapFlavorData( scrap, kScrapFlavorTypeText, &nextBytes, buffer );
+ assert( err == noErr && nextBytes == bytes );
+ buffer[bytes]=0;
+ // Create a CFString which wraps and takes ownership of the buffer
+ string = CFStringCreateWithCStringNoCopy( NULL, buffer, kCFStringEncodingMacRoman, NULL );
+ assert( string != NULL );
+ buffer = NULL; // string now owns this buffer
+ } else {
+ // a flavor we do not understand
+ return;
+ }
+
+
+ // Allocate a buffer, plus the null byte
+ CFIndex numUniChars = CFStringGetLength( string );
+ CFStringEncoding encoding = ( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII);
+ CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1;
+ char* cstring = new char[maximumByteLength];
+ CFIndex usedBufferLength = 0;
+ CFIndex numCharsConverted;
+ numCharsConverted = CFStringGetBytes( string, CFRangeMake( 0, numUniChars ), encoding,
+ '?', false, reinterpret_cast<UInt8*>( cstring ),
+ maximumByteLength, &usedBufferLength );
+ cstring[usedBufferLength] = '\0'; // null terminate the ASCII/UTF8 string
+ assert( numCharsConverted == numUniChars );
+
+ // Default allocator releases both the CFString and the UniChar buffer (text)
+ CFRelease( string );
+ string = NULL;
+
+ // determine whether a BOM is in the string. Apps like Emacs prepends a BOM
+ // to the string, CFStrinGetBytes reflects that (though it may change in the conversion)
+ // so we need to remove it before pasting into our buffer. TextWrangler has no
+ // problem dealing with BOM when pasting into it.
+ int bomLen = BOMlen((unsigned char *)cstring);
+
+ // convert line endings to the document line ending
+ int newlen = 0;
+ char *pasted = Document::TransformLineEnds(&newlen,
+ cstring + bomLen,
+ usedBufferLength - bomLen,
+ pdoc->eolMode);
+
+ pdoc->BeginUndoAction();
+ ClearSelection();
+
+ if (isRectangular) {
+ int selStart = SelectionStart();
+ PasteRectangular(selStart, pasted, newlen);
+ } else
+ if ( pdoc->InsertString( currentPos, pasted, newlen ) ) {
+ SetEmptySelection( currentPos + newlen );
+ }
+
+ delete[] pasted;
+ delete[] cstring;
+ cstring = NULL;
+
+ pdoc->EndUndoAction();
+ NotifyChange();
+ Redraw();
+}
+
+void ScintillaMacOSX::CreateCallTipWindow(PRectangle rc) {
+ // create a calltip window
+ if (!ct.wCallTip.Created()) {
+ WindowClass windowClass = kHelpWindowClass;
+ WindowAttributes attributes = kWindowNoAttributes;
+ Rect contentBounds;
+ WindowRef outWindow;
+
+ // convert PRectangle to Rect
+ // this adjustment gets the calltip window placed in the correct location relative
+ // to our editor window
+ Rect bounds;
+ OSStatus err;
+ err = GetWindowBounds( this->GetOwner(), kWindowGlobalPortRgn, &bounds );
+ assert( err == noErr );
+ contentBounds.top = rc.top + bounds.top;
+ contentBounds.bottom = rc.bottom + bounds.top;
+ contentBounds.right = rc.right + bounds.left;
+ contentBounds.left = rc.left + bounds.left;
+
+ // create our calltip hiview
+ HIViewRef ctw = scintilla_calltip_new();
+ CallTip* objectPtr = &ct;
+ ScintillaMacOSX* sciThis = this;
+ SetControlProperty( ctw, scintillaMacOSType, 0, sizeof( this ), &sciThis );
+ SetControlProperty( ctw, scintillaCallTipType, 0, sizeof( objectPtr ), &objectPtr );
+
+ CreateNewWindow(windowClass, attributes, &contentBounds, &outWindow);
+ ControlRef root;
+ CreateRootControl(outWindow, &root);
+
+ HIViewRef hiroot = HIViewGetRoot (outWindow);
+ HIViewAddSubview(hiroot, ctw);
+
+ HIRect boundsRect;
+ HIViewGetFrame(hiroot, &boundsRect);
+ HIViewSetFrame( ctw, &boundsRect );
+
+ // bind the size of the calltip to the size of it's container window
+ HILayoutInfo layout = {
+ kHILayoutInfoVersionZero,
+ {
+ { NULL, kHILayoutBindTop, 0 },
+ { NULL, kHILayoutBindLeft, 0 },
+ { NULL, kHILayoutBindBottom, 0 },
+ { NULL, kHILayoutBindRight, 0 }
+ },
+ {
+ { NULL, kHILayoutScaleAbsolute, 0 },
+ { NULL, kHILayoutScaleAbsolute, 0 }
+
+ },
+ {
+ { NULL, kHILayoutPositionTop, 0 },
+ { NULL, kHILayoutPositionLeft, 0 }
+ }
+ };
+ HIViewSetLayoutInfo(ctw, &layout);
+
+ ct.wCallTip = root;
+ ct.wDraw = ctw;
+ ct.wCallTip.SetWindow(outWindow);
+ HIViewSetVisible(ctw,true);
+
+ }
+}
+
+void ScintillaMacOSX::CallTipClick()
+{
+ ScintillaBase::CallTipClick();
+}
+
+void ScintillaMacOSX::AddToPopUp( const char *label, int cmd, bool enabled )
+{
+ // Translate stuff into menu item attributes
+ MenuItemAttributes attributes = 0;
+ if ( label[0] == '\0' ) attributes |= kMenuItemAttrSeparator;
+ if ( ! enabled ) attributes |= kMenuItemAttrDisabled;
+
+ // Translate Scintilla commands into Mac OS commands
+ // TODO: If I create an AEDesc, OS X may insert these standard
+ // text editing commands into the menu for me
+ MenuCommand macCommand;
+ switch( cmd )
+ {
+ case idcmdUndo:
+ macCommand = kHICommandUndo;
+ break;
+ case idcmdRedo:
+ macCommand = kHICommandRedo;
+ break;
+ case idcmdCut:
+ macCommand = kHICommandCut;
+ break;
+ case idcmdCopy:
+ macCommand = kHICommandCopy;
+ break;
+ case idcmdPaste:
+ macCommand = kHICommandPaste;
+ break;
+ case idcmdDelete:
+ macCommand = kHICommandClear;
+ break;
+ case idcmdSelectAll:
+ macCommand = kHICommandSelectAll;
+ break;
+ case 0:
+ macCommand = 0;
+ break;
+ default:
+ assert( false );
+ return;
+ }
+
+ CFStringRef string = CFStringCreateWithCString( NULL, label, kTextEncodingMacRoman );
+ OSStatus err;
+ err = AppendMenuItemTextWithCFString( reinterpret_cast<MenuRef>( popup.GetID() ),
+ string, attributes, macCommand, NULL );
+ assert( err == noErr );
+
+ CFRelease( string );
+ string = NULL;
+}
+
+void ScintillaMacOSX::ClaimSelection() {
+ // Mac OS X does not have a primary selection
+}
+
+/** A wrapper function to permit external processes to directly deliver messages to our "message loop". */
+sptr_t ScintillaMacOSX::DirectFunction(
+ ScintillaMacOSX *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
+ return sciThis->WndProc(iMessage, wParam, lParam);
+}
+
+sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
+ HIViewRef control = reinterpret_cast<HIViewRef>(sci);
+ // Platform::DebugPrintf("scintilla_send_message %08X control %08X\n",sci,control);
+ // Get a reference to the Scintilla C++ object
+ ScintillaMacOSX* scintilla = NULL;
+ OSStatus err;
+ err = GetControlProperty( control, scintillaMacOSType, 0, sizeof( scintilla ), NULL, &scintilla );
+ assert( err == noErr && scintilla != NULL );
+ //Platform::DebugPrintf("scintilla_send_message scintilla %08X\n",scintilla);
+
+ return scintilla->WndProc(iMessage, wParam, lParam);
+}
+
+void ScintillaMacOSX::TimerFired( EventLoopTimerRef )
+{
+ Tick();
+ DragScroll();
+}
+
+OSStatus ScintillaMacOSX::BoundsChanged( UInt32 /*inOptions*/, const HIRect& inOriginalBounds, const HIRect& inCurrentBounds, RgnHandle /*inInvalRgn*/ )
+{
+ // If the width or height changed, modify the scroll bars and notify Scintilla
+ // This event is also delivered when the window moves, and we don't care about that
+ if ( inOriginalBounds.size.width != inCurrentBounds.size.width || inOriginalBounds.size.height != inCurrentBounds.size.height )
+ {
+ Resize( static_cast<int>( inCurrentBounds.size.width ), static_cast<int>( inCurrentBounds.size.height ) );
+ }
+ return noErr;
+}
+
+void ScintillaMacOSX::Draw( RgnHandle rgn, CGContextRef gc )
+{
+ Rect invalidRect;
+ GetRegionBounds( rgn, &invalidRect );
+
+ // NOTE: We get draw events that include the area covered by the scroll bar. No fear: Scintilla correctly ignores them
+ SyncPaint( gc, PRectangle( invalidRect.left, invalidRect.top, invalidRect.right, invalidRect.bottom ) );
+}
+
+ControlPartCode ScintillaMacOSX::HitTest( const HIPoint& where )
+{
+ if ( CGRectContainsPoint( Bounds(), where ) )
+ return 1;
+ else
+ return kControlNoPart;
+}
+
+OSStatus ScintillaMacOSX::SetFocusPart( ControlPartCode desiredFocus, RgnHandle /*invalidRgn*/, Boolean /*inFocusEverything*/, ControlPartCode* outActualFocus )
+{
+ assert( outActualFocus != NULL );
+
+ if ( desiredFocus == 0 ) {
+ // We are losing the focus
+ SetFocusState(false);
+ } else {
+ // We are getting the focus
+ SetFocusState(true);
+ }
+
+ *outActualFocus = desiredFocus;
+ return noErr;
+}
+
+// Map Mac Roman character codes to their equivalent Scintilla codes
+static inline int KeyTranslate( UniChar unicodeChar )
+{
+ switch ( unicodeChar )
+ {
+ case kDownArrowCharCode:
+ return SCK_DOWN;
+ case kUpArrowCharCode:
+ return SCK_UP;
+ case kLeftArrowCharCode:
+ return SCK_LEFT;
+ case kRightArrowCharCode:
+ return SCK_RIGHT;
+ case kHomeCharCode:
+ return SCK_HOME;
+ case kEndCharCode:
+ return SCK_END;
+ case kPageUpCharCode:
+ return SCK_PRIOR;
+ case kPageDownCharCode:
+ return SCK_NEXT;
+ case kDeleteCharCode:
+ return SCK_DELETE;
+ // TODO: Is there an insert key in the mac world? My insert key is the "help" key
+ case kHelpCharCode:
+ return SCK_INSERT;
+ case kEnterCharCode:
+ case kReturnCharCode:
+ return SCK_RETURN;
+ case kEscapeCharCode:
+ return SCK_ESCAPE;
+ case kBackspaceCharCode:
+ return SCK_BACK;
+ case '\t':
+ return SCK_TAB;
+ case '+':
+ return SCK_ADD;
+ case '-':
+ return SCK_SUBTRACT;
+ case '/':
+ return SCK_DIVIDE;
+ case kFunctionKeyCharCode:
+ return kFunctionKeyCharCode;
+ default:
+ return 0;
+ }
+}
+
+static inline UniChar GetCharacterWithoutModifiers( EventRef rawKeyboardEvent )
+{
+ UInt32 keyCode;
+ // Get the key code from the raw key event
+ GetEventParameter( rawKeyboardEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof( keyCode ), NULL, &keyCode );
+
+ // Get the current keyboard layout
+ // TODO: If this is a performance sink, we need to cache these values
+ SInt16 lastKeyLayoutID = GetScriptVariable( /*currentKeyScript*/ GetScriptManagerVariable(smKeyScript), smScriptKeys);
+ Handle uchrHandle = GetResource('uchr', lastKeyLayoutID);
+
+ // Translate the key press ignoring ctrl and option
+ UInt32 ignoredDeadKeys = 0;
+ UInt32 ignoredActualLength = 0;
+ UniChar unicodeKey = 0;
+ // (((modifiers & shiftKey) >> 8) & 0xFF)
+ OSStatus err;
+ err = UCKeyTranslate( reinterpret_cast<UCKeyboardLayout*>( *uchrHandle ), keyCode, kUCKeyActionDown,
+ /* modifierKeyState */ 0, LMGetKbdType(), kUCKeyTranslateNoDeadKeysMask, &ignoredDeadKeys,
+ /* buffer length */ 1,
+ /* actual length */ &ignoredActualLength,
+ /* string */ &unicodeKey );
+ assert( err == noErr );
+
+ return unicodeKey;
+}
+
+// Text input is very annoying:
+// If the control key is pressed, or if the key is a "special" key (eg. arrow keys, function keys, whatever)
+// we let Scintilla handle it. If scintilla does not handle it, we do nothing (eventNotHandledErr).
+// Otherwise, the event is just some text and we add it to the buffer
+OSStatus ScintillaMacOSX::TextInput( TCarbonEvent& event )
+{
+ // Obtain the number of bytes of text
+ UInt32 actualSize = 0;
+ OSStatus err;
+ err = event.GetParameterSize( kEventParamTextInputSendText, &actualSize );
+ assert( err == noErr );
+ assert( actualSize != 0 );
+
+ const int numUniChars = actualSize / sizeof( UniChar );
+
+ // Allocate a buffer for the text using Core Foundation
+ UniChar* text = reinterpret_cast<UniChar*>( CFAllocatorAllocate( CFAllocatorGetDefault(), actualSize, 0 ) );
+ assert( text != NULL );
+
+ // Get a copy of the text
+ err = event.GetParameter( kEventParamTextInputSendText, typeUnicodeText, actualSize, text );
+ assert( err == noErr );
+
+ // TODO: This is a gross hack to ignore function keys
+ // Surely we can do better?
+ if ( numUniChars == 1 && text[0] == kFunctionKeyCharCode ) return eventNotHandledErr;
+ int modifiers = GetCurrentEventKeyModifiers();
+ int scintillaKey = KeyTranslate( text[0] );
+
+ // Create a CFString which wraps and takes ownership of the "text" buffer
+ CFStringRef string = CFStringCreateWithCharactersNoCopy( NULL, text, numUniChars, NULL );
+ assert( string != NULL );
+ //delete text;
+ text = NULL;
+
+ // If we have a single unicode character that is special or
+ // to process a command. Try to do some translation.
+ if ( numUniChars == 1 && ( modifiers & controlKey || scintillaKey != 0 ) ) {
+ // If we have a modifier, we need to get the character without modifiers
+ if ( modifiers & controlKey ) {
+ EventRef rawKeyboardEvent = NULL;
+ event.GetParameter(
+ kEventParamTextInputSendKeyboardEvent,
+ typeEventRef,
+ sizeof( EventRef ),
+ &rawKeyboardEvent );
+ assert( rawKeyboardEvent != NULL );
+ scintillaKey = GetCharacterWithoutModifiers( rawKeyboardEvent );
+
+ // Make sure that we still handle special characters correctly
+ int temp = KeyTranslate( scintillaKey );
+ if ( temp != 0 ) scintillaKey = temp;
+
+ // TODO: This is a gross Unicode hack: ASCII chars have a value < 127
+ if ( scintillaKey <= 127 ) {
+ scintillaKey = toupper( (char) scintillaKey );
+ }
+ }
+
+ // Code taken from Editor::KeyDown
+ // It is copied here because we don't want to feed the key via
+ // KeyDefault if there is no special action
+ DwellEnd(false);
+ int scintillaModifiers = ( (modifiers & shiftKey) ? SCI_SHIFT : 0) | ( (modifiers & controlKey) ? SCI_CTRL : 0) |
+ ( (modifiers & optionKey) ? SCI_ALT : 0);
+ int msg = kmap.Find( scintillaKey, scintillaModifiers );
+ if (msg) {
+ // The keymap has a special event for this key: perform the operation
+ WndProc(msg, 0, 0);
+ err = noErr;
+ } else {
+ // We do not handle this event
+ err = eventNotHandledErr;
+ }
+ } else {
+ CFStringEncoding encoding = ( IsUnicodeMode() ? kCFStringEncodingUTF8 : kCFStringEncodingASCII);
+
+ // Allocate the buffer (don't forget the null!)
+ CFIndex maximumByteLength = CFStringGetMaximumSizeForEncoding( numUniChars, encoding ) + 1;
+ char* buffer = new char[maximumByteLength];
+
+ CFIndex usedBufferLength = 0;
+ CFIndex numCharsConverted;
+ numCharsConverted = CFStringGetBytes( string, CFRangeMake( 0, numUniChars ), encoding,
+ '?', false, reinterpret_cast<UInt8*>( buffer ),
+ maximumByteLength, &usedBufferLength );
+ assert( numCharsConverted == numUniChars );
+ buffer[usedBufferLength] = '\0'; // null terminate
+
+ // Add all the characters to the document
+ // NOTE: OS X doesn't specify that text input events provide only a single character
+ // if we get a single character, add it as a character
+ // otherwise, we insert the entire string
+ if ( numUniChars == 1 ) {
+ AddCharUTF( buffer, usedBufferLength );
+ } else {
+ // WARNING: This is an untested code path as with my US keyboard, I only enter a single character at a time
+ if (pdoc->InsertString(currentPos, buffer, usedBufferLength)) {
+ SetEmptySelection(currentPos + usedBufferLength);
+ }
+ }
+
+ // Free the buffer that was allocated
+ delete[] buffer;
+ buffer = NULL;
+ err = noErr;
+ }
+
+ // Default allocator releases both the CFString and the UniChar buffer (text)
+ CFRelease( string );
+ string = NULL;
+
+ return err;
+}
+
+UInt32 ScintillaMacOSX::GetBehaviors()
+{
+ return TView::GetBehaviors() | kControlGetsFocusOnClick | kControlSupportsEmbedding;
+}
+
+OSStatus ScintillaMacOSX::MouseEntered(HIPoint& location, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ )
+{
+ if (!HaveMouseCapture() && HIViewGetSuperview(GetViewRef()) != NULL) {
+ HIViewRef view;
+ HIViewGetSubviewHit(reinterpret_cast<ControlRef>(wMain.GetID()), &location, true, &view);
+ if (view) {
+ // the hit is on a subview (ie. scrollbars)
+ WndProc(SCI_SETCURSOR, Window::cursorArrow, 0);
+ } else {
+ // reset to normal, buttonmove will change for other area's in the editor
+ WndProc(SCI_SETCURSOR, (long int)SC_CURSORNORMAL, 0);
+ }
+ return noErr;
+ }
+ return eventNotHandledErr;
+}
+
+OSStatus ScintillaMacOSX::MouseExited(HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount )
+{
+ if (HIViewGetSuperview(GetViewRef()) != NULL) {
+ if (HaveMouseCapture()) {
+ ButtonUp( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ),
+ static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ),
+ (modifiers & controlKey) != 0 );
+ }
+ WndProc(SCI_SETCURSOR, Window::cursorArrow, 0);
+ return noErr;
+ }
+ return eventNotHandledErr;
+}
+
+
+OSStatus ScintillaMacOSX::MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount , TCarbonEvent& inEvent)
+{
+ ConvertEventRefToEventRecord( inEvent.GetEventRef(), &mouseDownEvent );
+ return MouseDown(location, modifiers, button, clickCount);
+}
+
+OSStatus ScintillaMacOSX::MouseDown( EventRecord *event )
+{
+ HIPoint pt = GetLocalPoint(event->where);
+ int button = kEventMouseButtonPrimary;
+ mouseDownEvent = *event;
+
+ if ( event->modifiers & controlKey )
+ button = kEventMouseButtonSecondary;
+ return MouseDown(pt, event->modifiers, button, 1);
+}
+
+OSStatus ScintillaMacOSX::MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 /*clickCount*/ )
+{
+ // We only deal with the first mouse button
+ if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr;
+ // TODO: Verify that Scintilla wants the time in milliseconds
+ if (!HaveMouseCapture() && HIViewGetSuperview(GetViewRef()) != NULL) {
+ if (ScrollBarHit(location)) return noErr;
+ }
+ ButtonDown( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ),
+ static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ),
+ (modifiers & shiftKey) != 0,
+ (modifiers & controlKey) != 0,
+ (modifiers & cmdKey) );
+#if !defined(CONTAINER_HANDLES_EVENTS)
+ OSStatus err;
+ err = SetKeyboardFocus( this->GetOwner(), this->GetViewRef(), 1 );
+ assert( err == noErr );
+ return noErr;
+#else
+ return eventNotHandledErr; // allow event to go to container
+#endif
+}
+
+OSStatus ScintillaMacOSX::MouseUp( EventRecord *event )
+{
+ HIPoint pt = GetLocalPoint(event->where);
+ int button = kEventMouseButtonPrimary;
+ if ( event->modifiers & controlKey )
+ button = kEventMouseButtonSecondary;
+ return MouseUp(pt, event->modifiers, button, 1);
+}
+
+OSStatus ScintillaMacOSX::MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 /*clickCount*/ )
+{
+ // We only deal with the first mouse button
+ if ( button != kEventMouseButtonPrimary ) return eventNotHandledErr;
+ ButtonUp( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ),
+ static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ),
+ (modifiers & controlKey) != 0 );
+
+#if !defined(CONTAINER_HANDLES_EVENTS)
+ return noErr;
+#else
+ return eventNotHandledErr; // allow event to go to container
+#endif
+}
+
+OSStatus ScintillaMacOSX::MouseDragged( EventRecord *event )
+{
+ HIPoint pt = GetLocalPoint(event->where);
+ int button = 0;
+ if ( event->modifiers & btnStateBit ) {
+ button = kEventMouseButtonPrimary;
+ if ( event->modifiers & controlKey )
+ button = kEventMouseButtonSecondary;
+ }
+ return MouseDragged(pt, event->modifiers, button, 1);
+}
+
+OSStatus ScintillaMacOSX::MouseDragged( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount )
+{
+#if !defined(CONTAINER_HANDLES_EVENTS)
+ ButtonMove( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ) );
+ return noErr;
+#else
+ if (HaveMouseCapture() && !inDragDrop) {
+ MouseTrackingResult mouseStatus = 0;
+ ::Point theQDPoint;
+ UInt32 outModifiers;
+ EventTimeout inTimeout=0.1;
+ while (mouseStatus != kMouseTrackingMouseReleased) {
+ ButtonMove( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ) );
+ TrackMouseLocationWithOptions((GrafPtr)-1,
+ kTrackMouseLocationOptionDontConsumeMouseUp,
+ inTimeout,
+ &theQDPoint,
+ &outModifiers,
+ &mouseStatus);
+ location = GetLocalPoint(theQDPoint);
+ }
+ ButtonUp( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ),
+ static_cast<int>( GetCurrentEventTime() / kEventDurationMillisecond ),
+ (modifiers & controlKey) != 0 );
+ } else {
+ if (!HaveMouseCapture() && HIViewGetSuperview(GetViewRef()) != NULL) {
+ HIViewRef view;
+ HIViewGetSubviewHit(reinterpret_cast<ControlRef>(wMain.GetID()), &location, true, &view);
+ if (view) {
+ // the hit is on a subview (ie. scrollbars)
+ WndProc(SCI_SETCURSOR, Window::cursorArrow, 0);
+ return eventNotHandledErr;
+ } else {
+ // reset to normal, buttonmove will change for other area's in the editor
+ WndProc(SCI_SETCURSOR, (long int)SC_CURSORNORMAL, 0);
+ }
+ }
+ ButtonMove( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ) );
+ }
+ return eventNotHandledErr; // allow event to go to container
+#endif
+}
+
+OSStatus ScintillaMacOSX::MouseWheelMoved( EventMouseWheelAxis axis, SInt32 delta, UInt32 modifiers )
+{
+ if ( axis != 1 ) return eventNotHandledErr;
+
+ if ( modifiers & controlKey ) {
+ // Zoom! We play with the font sizes in the styles.
+ // Number of steps/line is ignored, we just care if sizing up or down
+ if ( delta > 0 ) {
+ KeyCommand( SCI_ZOOMIN );
+ } else {
+ KeyCommand( SCI_ZOOMOUT );
+ }
+ } else {
+ // Decide if this should be optimized?
+ ScrollTo( topLine - delta );
+ }
+
+ return noErr;
+}
+
+OSStatus ScintillaMacOSX::ContextualMenuClick( HIPoint& location )
+{
+ // convert screen coords to window relative
+ Rect bounds;
+ OSStatus err;
+ err = GetWindowBounds( this->GetOwner(), kWindowContentRgn, &bounds );
+ assert( err == noErr );
+ location.x += bounds.left;
+ location.y += bounds.top;
+ ContextMenu( Scintilla::Point( static_cast<int>( location.x ), static_cast<int>( location.y ) ) );
+ return noErr;
+}
+
+OSStatus ScintillaMacOSX::ActiveStateChanged()
+{
+ // If the window is being deactivated, lose the focus and turn off the ticking
+ if ( ! this->IsActive() ) {
+ DropCaret();
+ //SetFocusState( false );
+ SetTicking( false );
+ } else {
+ ShowCaretAtCurrentPosition();
+ }
+ return noErr;
+}
+
+HIViewRef ScintillaMacOSX::Create()
+{
+ // Register the HIView, if needed
+ static bool registered = false;
+
+ if ( not registered ) {
+ TView::RegisterSubclass( kScintillaClassID, Construct );
+ registered = true;
+ }
+
+ OSStatus err = noErr;
+ EventRef event = CreateInitializationEvent();
+ assert( event != NULL );
+
+ HIViewRef control = NULL;
+ err = HIObjectCreate( kScintillaClassID, event, reinterpret_cast<HIObjectRef*>( &control ) );
+ ReleaseEvent( event );
+ if ( err == noErr ) {
+ Platform::DebugPrintf("ScintillaMacOSX::Create control %08X\n",control);
+ return control;
+ }
+ return NULL;
+}
+
+OSStatus ScintillaMacOSX::Construct( HIViewRef inControl, TView** outView )
+{
+ *outView = new ScintillaMacOSX( inControl );
+ Platform::DebugPrintf("ScintillaMacOSX::Construct scintilla %08X\n",*outView);
+ if ( *outView != NULL )
+ return noErr;
+ else
+ return memFullErr; // could be a lie
+}
+
+extern "C" {
+HIViewRef scintilla_new() {
+ return ScintillaMacOSX::Create();
+}
+}
diff --git a/macosx/ScintillaMacOSX.h b/macosx/ScintillaMacOSX.h
new file mode 100644
index 000000000..0f02042f5
--- /dev/null
+++ b/macosx/ScintillaMacOSX.h
@@ -0,0 +1,192 @@
+/*
+ * ScintillaMacOSX.h
+ * tutorial
+ *
+ * Created by Evan Jones on Sun Sep 01 2002.
+ * Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+ *
+ */
+#include "TView.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "Platform.h"
+#include "Scintilla.h"
+#include "PlatMacOSX.h"
+
+
+#include "ScintillaWidget.h"
+#ifdef SCI_LEXER
+#include "SciLexer.h"
+#include "PropSet.h"
+#include "Accessor.h"
+#include "KeyWords.h"
+#endif
+#include "ContractionState.h"
+#include "SVector.h"
+#include "SplitVector.h"
+#include "Partitioning.h"
+#include "RunStyles.h"
+#include "CellBuffer.h"
+#include "CallTip.h"
+#include "KeyMap.h"
+#include "Indicator.h"
+#include "XPM.h"
+#include "LineMarker.h"
+#include "Style.h"
+#include "AutoComplete.h"
+#include "ViewStyle.h"
+#include "CharClassify.h"
+#include "Decoration.h"
+#include "Document.h"
+#include "Editor.h"
+#include "SString.h"
+#include "ScintillaBase.h"
+#include "ScintillaCallTip.h"
+
+static const OSType scintillaMacOSType = 'Scin';
+static const OSType scintillaNotifyObject = 'Snob';
+static const OSType scintillaNotifyFN = 'Snfn';
+
+namespace Scintilla {
+
+class ScintillaMacOSX : public ScintillaBase, public TView
+{
+ public:
+ HIViewRef vScrollBar;
+ HIViewRef hScrollBar;
+ SInt32 scrollBarFixedSize;
+
+ bool capturedMouse;
+ bool inDragSession; // true if scintilla initiated the drag session
+ bool isTracking;
+
+ // Private so ScintillaMacOSX objects can not be copied
+ ScintillaMacOSX(const ScintillaMacOSX &) : ScintillaBase(), TView( NULL ) {}
+ ScintillaMacOSX &operator=(const ScintillaMacOSX &) { return * this; }
+
+public:
+ /** This is the class ID that we've assigned to Scintilla. */
+ static const CFStringRef kScintillaClassID;
+ static const ControlKind kScintillaKind;
+
+ ScintillaMacOSX( void* windowid );
+ virtual ~ScintillaMacOSX();
+ //~ static void ClassInit(GtkObjectClass* object_class, GtkWidgetClass *widget_class);
+
+ /** Returns the HIView object kind, needed to subclass TView. */
+ virtual ControlKind GetKind() { return kScintillaKind; }
+
+private:
+ virtual void Initialise();
+ virtual void Finalise();
+ virtual void StartDrag();
+ Scintilla::Point GetDragPoint(DragRef inDrag);
+ OSStatus GetDragData(DragRef inDrag, PasteboardRef &pasteBoard, CFStringRef *textString);
+ void SetDragCursor(DragRef inDrag);
+
+ // Drag and drop
+ virtual bool DragEnter(DragRef inDrag );
+ virtual bool DragWithin(DragRef inDrag );
+ virtual bool DragLeave(DragRef inDrag );
+ virtual OSStatus DragReceive(DragRef inDrag );
+ void DragScroll();
+ int scrollSpeed;
+ int scrollTicks;
+
+ EventRecord mouseDownEvent;
+ MouseTrackingRef mouseTrackingRef;
+ MouseTrackingRegionID mouseTrackingID;
+ HIPoint GetLocalPoint(::Point pt);
+
+ static pascal void IdleTimerEventHandler(EventLoopTimerRef inTimer,
+ EventLoopIdleTimerMessage inState,
+ void *scintilla );
+
+public: // Public for scintilla_send_message
+ virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+
+ void SyncPaint( void* gc, PRectangle rc);
+ //void FullPaint( void* gc );
+ virtual void Draw( RgnHandle rgn, CGContextRef gc );
+
+ virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+ virtual void SetTicking(bool on);
+ virtual bool SetIdle(bool on);
+ virtual void SetMouseCapture(bool on);
+ virtual bool HaveMouseCapture();
+ virtual PRectangle GetClientRectangle();
+
+ virtual void ScrollText(int linesToMove);
+ virtual void SetVerticalScrollPos();
+ virtual void SetHorizontalScrollPos();
+ virtual bool ModifyScrollBars(int nMax, int nPage);
+ virtual void ReconfigureScrollBars();
+ void Resize(int width, int height);
+ static pascal void LiveScrollHandler( ControlHandle control, SInt16 part );
+ bool ScrollBarHit(HIPoint location);
+
+ virtual void NotifyChange();
+ virtual void NotifyFocus(bool focus);
+ virtual void NotifyParent(SCNotification scn);
+ void NotifyKey(int key, int modifiers);
+ void NotifyURIDropped(const char *list);
+ virtual int KeyDefault(int key, int modifiers);
+ static pascal OSStatus CommandEventHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* data );
+
+ bool HasSelection();
+ bool CanUndo();
+ bool CanRedo();
+ bool AlwaysTrue();
+ virtual void CopyToClipboard(const SelectionText &selectedText);
+ virtual void Copy();
+ virtual bool CanPaste();
+ virtual void Paste();
+ virtual void Paste(bool rectangular);
+ virtual void CreateCallTipWindow(PRectangle rc);
+ virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true);
+ virtual void ClaimSelection();
+
+ static sptr_t DirectFunction(ScintillaMacOSX *sciThis,
+ unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+
+ /** Timer event handler. Simply turns around and calls Tick. */
+ virtual void TimerFired( EventLoopTimerRef );
+ virtual OSStatus BoundsChanged( UInt32 inOptions, const HIRect& inOriginalBounds, const HIRect& inCurrentBounds, RgnHandle inInvalRgn );
+ virtual ControlPartCode HitTest( const HIPoint& where );
+ virtual OSStatus SetFocusPart( ControlPartCode desiredFocus, RgnHandle, Boolean, ControlPartCode* outActualFocus );
+ virtual OSStatus TextInput( TCarbonEvent& event );
+
+ // Configure the features of this control
+ virtual UInt32 GetBehaviors();
+
+ virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount, TCarbonEvent& inEvent );
+ virtual OSStatus MouseDown( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+ virtual OSStatus MouseDown( EventRecord *rec );
+ virtual OSStatus MouseUp( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+ virtual OSStatus MouseUp( EventRecord *rec );
+ virtual OSStatus MouseDragged( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+ virtual OSStatus MouseDragged( EventRecord *rec );
+ virtual OSStatus MouseEntered( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+ virtual OSStatus MouseExited( HIPoint& location, UInt32 modifiers, EventMouseButton button, UInt32 clickCount );
+ virtual OSStatus MouseWheelMoved( EventMouseWheelAxis axis, SInt32 delta, UInt32 modifiers );
+ virtual OSStatus ContextualMenuClick( HIPoint& location );
+
+ virtual OSStatus ActiveStateChanged();
+
+ virtual void CallTipClick();
+
+
+public:
+ static HIViewRef Create();
+private:
+ static OSStatus Construct( HIViewRef inControl, TView** outView );
+
+};
+
+
+}
diff --git a/macosx/TCarbonEvent.cxx b/macosx/TCarbonEvent.cxx
new file mode 100644
index 000000000..eca31e569
--- /dev/null
+++ b/macosx/TCarbonEvent.cxx
@@ -0,0 +1,519 @@
+/*
+ File: TCarbonEvent.cp
+
+ Version: 1.0
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright © 2002 Apple Computer, Inc., All Rights Reserved
+*/
+
+#include "TCarbonEvent.h"
+
+//-----------------------------------------------------------------------------------
+// TCarbonEvent constructor
+//-----------------------------------------------------------------------------------
+//
+TCarbonEvent::TCarbonEvent(
+ UInt32 inClass,
+ UInt32 inKind )
+{
+ CreateEvent( NULL, inClass, inKind, GetCurrentEventTime(), 0, &fEvent );
+}
+
+//-----------------------------------------------------------------------------------
+// TCarbonEvent constructor
+//-----------------------------------------------------------------------------------
+//
+TCarbonEvent::TCarbonEvent(
+ EventRef inEvent )
+{
+ fEvent = inEvent;
+ RetainEvent( fEvent );
+}
+
+//-----------------------------------------------------------------------------------
+// TCarbonEvent destructor
+//-----------------------------------------------------------------------------------
+//
+TCarbonEvent::~TCarbonEvent()
+{
+ ReleaseEvent( fEvent );
+}
+
+//-----------------------------------------------------------------------------------
+// GetClass
+//-----------------------------------------------------------------------------------
+//
+UInt32 TCarbonEvent::GetClass() const
+{
+ return GetEventClass( fEvent );
+}
+
+//-----------------------------------------------------------------------------------
+// GetKind
+//-----------------------------------------------------------------------------------
+//
+UInt32 TCarbonEvent::GetKind() const
+{
+ return GetEventKind( fEvent );
+}
+
+//-----------------------------------------------------------------------------------
+// SetTime
+//-----------------------------------------------------------------------------------
+//
+void TCarbonEvent::SetTime(
+ EventTime inTime )
+{
+ SetEventTime( fEvent, inTime );
+}
+
+//-----------------------------------------------------------------------------------
+// GetTime
+//-----------------------------------------------------------------------------------
+//
+EventTime TCarbonEvent::GetTime() const
+{
+ return GetEventTime( fEvent );
+}
+
+//-----------------------------------------------------------------------------------
+// Retain
+//-----------------------------------------------------------------------------------
+//
+void TCarbonEvent::Retain()
+{
+ RetainEvent( fEvent );
+}
+
+//-----------------------------------------------------------------------------------
+// Release
+//-----------------------------------------------------------------------------------
+//
+void TCarbonEvent::Release()
+{
+ ReleaseEvent( fEvent );
+}
+
+//-----------------------------------------------------------------------------------
+// PostToQueue
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::PostToQueue(
+ EventQueueRef inQueue,
+ EventPriority inPriority )
+{
+ return PostEventToQueue( inQueue, fEvent, inPriority );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ EventParamType inType,
+ UInt32 inSize,
+ const void* inData )
+{
+ return SetEventParameter( fEvent, inName, inType, inSize, inData );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ EventParamType inType,
+ UInt32 inBufferSize,
+ void* outData )
+{
+ return GetEventParameter( fEvent, inName, inType, NULL, inBufferSize, NULL, outData );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameterType
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameterType(
+ EventParamName inName,
+ EventParamType* outType )
+{
+ return GetEventParameter( fEvent, inName, typeWildCard, outType, 0, NULL, NULL );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameterSize
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameterSize(
+ EventParamName inName,
+ UInt32* outSize )
+{
+ return GetEventParameter( fEvent, inName, typeWildCard, NULL, 0, outSize, NULL );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ Boolean inValue )
+{
+ return SetParameter<Boolean>( inName, typeBoolean, inValue );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ Boolean* outValue )
+{
+ return GetParameter<Boolean>( inName, typeBoolean, outValue );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ bool inValue )
+{
+ return SetParameter<Boolean>( inName, typeBoolean, (Boolean) inValue );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ bool* outValue )
+{
+ return GetParameter<Boolean>( inName, sizeof( Boolean ), (Boolean*) outValue );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ Point inPt )
+{
+ return SetParameter<Point>( inName, typeQDPoint, inPt );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ Point* outPt )
+{
+ return GetParameter<Point>( inName, typeQDPoint, outPt );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ const HIPoint& inPt )
+{
+ return SetParameter<HIPoint>( inName, typeHIPoint, inPt );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ HIPoint* outPt )
+{
+ return GetParameter<HIPoint>( inName, typeHIPoint, outPt );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ const Rect& inRect )
+{
+ return SetParameter<Rect>( inName, typeQDRectangle, inRect );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ Rect* outRect )
+{
+ return GetParameter<Rect>( inName, typeQDRectangle, outRect );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ const HIRect& inRect )
+{
+ return SetParameter<HIRect>( inName, typeHIRect, inRect );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ HIRect* outRect )
+{
+ return GetParameter<HIRect>( inName, typeHIRect, outRect );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ const HISize& inSize )
+{
+ return SetParameter<HISize>( inName, typeHISize, inSize );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ HISize* outSize )
+{
+ return GetParameter<HISize>( inName, typeHISize, outSize );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ RgnHandle inRegion )
+{
+ return SetParameter<RgnHandle>( inName, typeQDRgnHandle, inRegion );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ RgnHandle* outRegion )
+{
+ return GetParameter<RgnHandle>( inName, typeQDRgnHandle, outRegion );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ WindowRef inWindow )
+{
+ return SetParameter<WindowRef>( inName, typeWindowRef, inWindow );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ WindowRef* outWindow )
+{
+ return GetParameter<WindowRef>( inName, typeWindowRef, outWindow );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ ControlRef inControl )
+{
+ return SetParameter<ControlRef>( inName, typeControlRef, inControl );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ ControlRef* outControl )
+{
+ return GetParameter<ControlRef>( inName, typeControlRef, outControl );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ MenuRef inMenu )
+{
+ return SetParameter<MenuRef>( inName, typeMenuRef, inMenu );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ MenuRef* outMenu )
+{
+ return GetParameter<MenuRef>( inName, typeMenuRef, outMenu );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ DragRef inDrag )
+{
+ return SetParameter<DragRef>( inName, typeDragRef, inDrag );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ DragRef* outDrag )
+{
+ return GetParameter<DragRef>( inName, typeDragRef, outDrag );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ UInt32 inValue )
+{
+ return SetParameter<UInt32>( inName, typeUInt32, inValue );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ UInt32* outValue )
+{
+ return GetParameter<UInt32>( inName, typeUInt32, outValue );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ const HICommand& inValue )
+{
+ return SetParameter<HICommand>( inName, typeHICommand, inValue );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ HICommand* outValue )
+{
+ return GetParameter<HICommand>( inName, typeHICommand, outValue );
+}
+
+//-----------------------------------------------------------------------------------
+// SetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::SetParameter(
+ EventParamName inName,
+ const ControlPartCode& inValue )
+{
+ return SetParameter<ControlPartCode>( inName, typeControlPartCode, inValue );
+}
+
+//-----------------------------------------------------------------------------------
+// GetParameter
+//-----------------------------------------------------------------------------------
+//
+OSStatus TCarbonEvent::GetParameter(
+ EventParamName inName,
+ ControlPartCode* outValue )
+{
+ return GetParameter<ControlPartCode>( inName, typeControlPartCode, outValue );
+}
diff --git a/macosx/TCarbonEvent.h b/macosx/TCarbonEvent.h
new file mode 100644
index 000000000..d40da9795
--- /dev/null
+++ b/macosx/TCarbonEvent.h
@@ -0,0 +1,230 @@
+/*
+ File: TCarbonEvent.h
+
+ Version: 1.0
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright © 2002 Apple Computer, Inc., All Rights Reserved
+*/
+
+#ifndef TCarbonEvent_H_
+#define TCarbonEvent_H_
+
+#include <Carbon/Carbon.h>
+
+class TCarbonEvent
+{
+public:
+ // Construction/Destruction
+ TCarbonEvent(
+ UInt32 inClass,
+ UInt32 inKind );
+ TCarbonEvent(
+ EventRef inEvent );
+ virtual ~TCarbonEvent();
+
+ UInt32 GetClass() const;
+ UInt32 GetKind() const;
+
+ // Time
+ void SetTime(
+ EventTime inTime );
+ EventTime GetTime() const;
+
+ // Retention
+ void Retain();
+ void Release();
+
+ // Accessors
+ operator EventRef&()
+ { return fEvent; };
+ EventRef GetEventRef()
+ { return fEvent; }
+
+ // Posting
+ OSStatus PostToQueue(
+ EventQueueRef inQueue,
+ EventPriority inPriority = kEventPriorityStandard );
+
+ // Parameters
+ OSStatus SetParameter(
+ EventParamName inName,
+ EventParamType inType,
+ UInt32 inSize,
+ const void* inData );
+ OSStatus GetParameter(
+ EventParamName inName,
+ EventParamType inType,
+ UInt32 inBufferSize,
+ void* outData );
+
+ OSStatus GetParameterType(
+ EventParamName inName,
+ EventParamType* outType );
+ OSStatus GetParameterSize(
+ EventParamName inName,
+ UInt32* outSize );
+
+ // Simple parameters
+ OSStatus SetParameter(
+ EventParamName inName,
+ Boolean inValue );
+ OSStatus GetParameter(
+ EventParamName inName,
+ Boolean* outValue );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ bool inValue );
+ OSStatus GetParameter(
+ EventParamName inName,
+ bool* outValue );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ Point inPt );
+ OSStatus GetParameter(
+ EventParamName inName,
+ Point* outPt );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ const HIPoint& inPt );
+
+ OSStatus GetParameter(
+ EventParamName inName,
+ HIPoint* outPt );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ const Rect& inRect );
+ OSStatus GetParameter(
+ EventParamName inName,
+ Rect* outRect );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ const HIRect& inRect );
+ OSStatus GetParameter(
+ EventParamName inName,
+ HIRect* outRect );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ const HISize& inSize );
+ OSStatus GetParameter(
+ EventParamName inName,
+ HISize* outSize );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ RgnHandle inRegion );
+ OSStatus GetParameter(
+ EventParamName inName,
+ RgnHandle* outRegion );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ WindowRef inWindow );
+ OSStatus GetParameter(
+ EventParamName inName,
+ WindowRef* outWindow );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ ControlRef inControl );
+ OSStatus GetParameter(
+ EventParamName inName,
+ ControlRef* outControl );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ MenuRef inMenu );
+ OSStatus GetParameter(
+ EventParamName inName,
+ MenuRef* outMenu );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ DragRef inDrag );
+ OSStatus GetParameter(
+ EventParamName inName,
+ DragRef* outDrag );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ UInt32 inValue );
+ OSStatus GetParameter(
+ EventParamName inName,
+ UInt32* outValue );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ const HICommand& inValue );
+ OSStatus GetParameter(
+ EventParamName inName,
+ HICommand* outValue );
+
+ OSStatus SetParameter(
+ EventParamName inName,
+ const ControlPartCode& inValue );
+ OSStatus GetParameter(
+ EventParamName inName,
+ ControlPartCode* outValue );
+
+ // Template parameters
+ template <class T> OSStatus SetParameter(
+ EventParamName inName,
+ EventParamType inType,
+ const T& inValue )
+ {
+ return SetParameter( inName, inType, sizeof( T ), &inValue );
+ }
+
+ template <class T> OSStatus GetParameter(
+ EventParamName inName,
+ EventParamType inType,
+ T* outValue )
+ {
+ return GetParameter( inName, inType, sizeof( T ), outValue );
+ }
+
+private:
+ EventRef fEvent;
+};
+
+#endif // TCarbonEvent_H_
diff --git a/macosx/TRect.h b/macosx/TRect.h
new file mode 100644
index 000000000..5a4199300
--- /dev/null
+++ b/macosx/TRect.h
@@ -0,0 +1,496 @@
+/*
+ File: TRect.h
+
+ Version: 1.0
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright © 2002 Apple Computer, Inc., All Rights Reserved
+*/
+
+#ifndef TRect_H_
+#define TRect_H_
+
+#include <Carbon/Carbon.h>
+
+class TRect
+ : public HIRect
+{
+public:
+ // Construction/Destruction
+ TRect();
+ TRect(
+ const HIRect* inRect );
+ TRect(
+ const HIRect& inRect );
+ TRect(
+ const HIPoint& inOrigin,
+ const HISize& inSize );
+ TRect(
+ float inX,
+ float inY,
+ float inWidth,
+ float inHeight );
+ TRect(
+ const Rect& inRect );
+ ~TRect();
+
+ // Operators
+ operator HIRect*()
+ { return this; }
+ operator Rect() const;
+
+ // Accessors
+ float MinX() const
+ { return CGRectGetMinX( *this ); }
+ float MaxX() const
+ { return CGRectGetMaxX( *this ); }
+ float MinY() const
+ { return CGRectGetMinY( *this ); }
+ float MaxY() const
+ { return CGRectGetMaxY( *this ); }
+
+ float Width() const
+ { return CGRectGetWidth( *this ); }
+ float Height() const
+ { return CGRectGetHeight( *this ); }
+
+ const HIPoint& Origin() const
+ { return origin; }
+ const HISize& Size() const
+ { return size; }
+
+ float CenterX() const
+ { return CGRectGetMidX( *this ); }
+ float CenterY() const
+ { return CGRectGetMidY( *this ); }
+ HIPoint Center() const;
+
+ // Modifiers
+ const HIRect& Inset(
+ float inX,
+ float inY );
+ const HIRect& Outset(
+ float inX,
+ float inY );
+ const HIRect& MoveBy(
+ float inDx,
+ float inDy );
+ const HIRect& MoveTo(
+ float inX,
+ float inY );
+
+ const HIRect& Set(
+ const HIRect* inRect );
+ const HIRect& Set(
+ const HIRect& inRect );
+ const HIRect& Set(
+ float inX,
+ float inY,
+ float inWidth,
+ float inHeight );
+ const HIRect& Set(
+ const Rect* inRect );
+
+ const HIRect& SetAroundCenter(
+ float inCenterX,
+ float inCenterY,
+ float inWidth,
+ float inHeight );
+
+ const HIRect& SetWidth(
+ float inWidth );
+ const HIRect& SetHeight(
+ float inHeight );
+
+ const HIRect& SetOrigin(
+ const HIPoint& inOrigin );
+ const HIRect& SetOrigin(
+ float inX,
+ float inY );
+ const HIRect& SetSize(
+ const HISize& inSize );
+ const HIRect& SetSize(
+ float inWidth,
+ float inHeight );
+
+ // Tests
+ bool Contains(
+ const HIPoint& inPoint );
+ bool Contains(
+ const HIRect& inRect );
+ bool Contains(
+ const Point& inPoint );
+ bool Contains(
+ const Rect& inRect );
+};
+
+//-----------------------------------------------------------------------------------
+// TRect constructor
+//-----------------------------------------------------------------------------------
+//
+inline TRect::TRect()
+{
+}
+
+//-----------------------------------------------------------------------------------
+// TRect constructor
+//-----------------------------------------------------------------------------------
+//
+inline TRect::TRect(
+ const HIRect* inRect )
+{
+ *this = *inRect;
+}
+
+//-----------------------------------------------------------------------------------
+// TRect constructor
+//-----------------------------------------------------------------------------------
+//
+inline TRect::TRect(
+ const HIRect& inRect )
+{
+ origin = inRect.origin;
+ size = inRect.size;
+}
+
+//-----------------------------------------------------------------------------------
+// TRect constructor
+//-----------------------------------------------------------------------------------
+//
+inline TRect::TRect(
+ const HIPoint& inOrigin,
+ const HISize& inSize )
+{
+ origin = inOrigin;
+ size = inSize;
+}
+
+//-----------------------------------------------------------------------------------
+// TRect constructor
+//-----------------------------------------------------------------------------------
+//
+inline TRect::TRect(
+ float inX,
+ float inY,
+ float inWidth,
+ float inHeight )
+{
+ *this = CGRectMake( inX, inY, inWidth, inHeight );
+}
+
+//-----------------------------------------------------------------------------------
+// TRect destructor
+//-----------------------------------------------------------------------------------
+//
+inline TRect::~TRect()
+{
+}
+
+//-----------------------------------------------------------------------------------
+// TRect constructor
+//-----------------------------------------------------------------------------------
+//
+inline TRect::TRect(
+ const Rect& inRect )
+{
+ Set( &inRect );
+}
+
+//-----------------------------------------------------------------------------------
+// Rect operator
+//-----------------------------------------------------------------------------------
+// Converts the HIRect to a QD rect and returns it
+//
+inline TRect::operator Rect() const
+{
+ Rect qdRect;
+
+ qdRect.top = (SInt16) MinY();
+ qdRect.left = (SInt16) MinX();
+ qdRect.bottom = (SInt16) MaxY();
+ qdRect.right = (SInt16) MaxX();
+
+ return qdRect;
+}
+
+//-----------------------------------------------------------------------------------
+// Center
+//-----------------------------------------------------------------------------------
+//
+inline HIPoint TRect::Center() const
+{
+ return CGPointMake( CGRectGetMidX( *this ), CGRectGetMidY( *this ) );
+}
+
+//-----------------------------------------------------------------------------------
+// Inset
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::Inset(
+ float inX,
+ float inY )
+{
+ *this = CGRectInset( *this, inX, inY );
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// Outset
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::Outset(
+ float inX,
+ float inY )
+{
+ *this = CGRectInset( *this, -inX, -inY );
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// MoveBy
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::MoveBy(
+ float inDx,
+ float inDy )
+{
+ origin = CGPointMake( MinX() + inDx, MinY() + inDy );
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// MoveTo
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::MoveTo(
+ float inX,
+ float inY )
+{
+ origin = CGPointMake( inX, inY );
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// Set
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::Set(
+ const HIRect* inRect )
+{
+ *this = *inRect;
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// Set
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::Set(
+ const HIRect& inRect )
+{
+ *this = inRect;
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// Set
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::Set(
+ float inX,
+ float inY,
+ float inWidth,
+ float inHeight )
+{
+ *this = CGRectMake( inX, inY, inWidth, inHeight );
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// Set
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::Set(
+ const Rect* inRect )
+{
+ origin.x = inRect->left;
+ origin.y = inRect->top;
+ size.width = inRect->right - inRect->left;
+ size.height = inRect->bottom - inRect->top;
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// SetAroundCenter
+//-----------------------------------------------------------------------------------
+// Sets the rectangle by specifying dimensions around a center point
+//
+inline const HIRect& TRect::SetAroundCenter(
+ float inCenterX,
+ float inCenterY,
+ float inWidth,
+ float inHeight )
+{
+ *this = CGRectMake( inCenterX - inWidth/2, inCenterY - inHeight/2, inWidth, inHeight );
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// SetWidth
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::SetWidth(
+ float inWidth )
+{
+ size.width = inWidth;
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// SetHeight
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::SetHeight(
+ float inHeight )
+{
+ size.height = inHeight;
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// SetOrigin
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::SetOrigin(
+ const HIPoint& inOrigin )
+{
+ origin = inOrigin;
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// SetOrigin
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::SetOrigin(
+ float inX,
+ float inY )
+{
+ origin = CGPointMake( inX, inY );
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// SetSize
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::SetSize(
+ const HISize& inSize )
+{
+ size = inSize;
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// SetSize
+//-----------------------------------------------------------------------------------
+//
+inline const HIRect& TRect::SetSize(
+ float inWidth,
+ float inHeight )
+{
+ size = CGSizeMake( inWidth, inHeight );
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------------
+// Contains
+//-----------------------------------------------------------------------------------
+//
+inline bool TRect::Contains(
+ const HIPoint& inPoint )
+{
+ return CGRectContainsPoint( *this, inPoint );
+}
+
+//-----------------------------------------------------------------------------------
+// Contains
+//-----------------------------------------------------------------------------------
+//
+inline bool TRect::Contains(
+ const HIRect& inRect )
+{
+ return CGRectContainsRect( *this, inRect );
+}
+
+//-----------------------------------------------------------------------------------
+// Contains
+//-----------------------------------------------------------------------------------
+//
+inline bool TRect::Contains(
+ const Point& inPoint )
+{
+ return Contains( CGPointMake( inPoint.h, inPoint.v ) );
+}
+
+//-----------------------------------------------------------------------------------
+// Contains
+//-----------------------------------------------------------------------------------
+//
+inline bool TRect::Contains(
+ const Rect& inRect )
+{
+ return Contains( CGRectMake( inRect.left, inRect.top,
+ inRect.right - inRect.left, inRect.bottom - inRect.top ) );
+}
+
+#endif // TRect_H_
diff --git a/macosx/TView.cxx b/macosx/TView.cxx
new file mode 100644
index 000000000..9ed02b110
--- /dev/null
+++ b/macosx/TView.cxx
@@ -0,0 +1,1462 @@
+/*
+ File: TView.cp
+
+ Version: 1.0
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright © 2002 Apple Computer, Inc., All Rights Reserved
+*/
+
+/*
+ NOTE: This is NOWHERE near a completely exhaustive implementation of a view. There are
+ many more carbon events one could intercept and hook into this.
+*/
+
+#include "TView.h"
+
+//-----------------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------------
+//
+const EventTypeSpec kHIObjectEvents[] =
+{ { kEventClassHIObject, kEventHIObjectConstruct },
+ { kEventClassHIObject, kEventHIObjectInitialize },
+ { kEventClassHIObject, kEventHIObjectDestruct }
+};
+
+const EventTypeSpec kHIViewEvents[] =
+{ { kEventClassCommand, kEventCommandProcess },
+ { kEventClassCommand, kEventCommandUpdateStatus },
+
+ { kEventClassControl, kEventControlInitialize },
+ { kEventClassControl, kEventControlDraw },
+ { kEventClassControl, kEventControlHitTest },
+ { kEventClassControl, kEventControlGetPartRegion },
+ { kEventClassControl, kEventControlGetData },
+ { kEventClassControl, kEventControlSetData },
+ { kEventClassControl, kEventControlGetOptimalBounds },
+ { kEventClassControl, kEventControlBoundsChanged },
+ { kEventClassControl, kEventControlTrack },
+ { kEventClassControl, kEventControlGetSizeConstraints },
+ { kEventClassControl, kEventControlHit },
+
+ { kEventClassControl, kEventControlHiliteChanged },
+ { kEventClassControl, kEventControlActivate },
+ { kEventClassControl, kEventControlDeactivate },
+ { kEventClassControl, kEventControlValueFieldChanged },
+ { kEventClassControl, kEventControlTitleChanged },
+ { kEventClassControl, kEventControlEnabledStateChanged },
+};
+
+// This param name was accidentally left unexported for
+// the release of Jaguar.
+const EventParamName kEventParamControlLikesDrag = 'cldg';
+
+//-----------------------------------------------------------------------------------
+// TView constructor
+//-----------------------------------------------------------------------------------
+//
+TView::TView(
+ HIViewRef inControl )
+ : fViewRef( inControl )
+{
+ verify_noerr( InstallEventHandler( GetControlEventTarget( fViewRef ), ViewEventHandler,
+ GetEventTypeCount( kHIViewEvents ), kHIViewEvents, this, &fHandler ) );
+
+ mouseEventHandler = NULL;
+ fAutoInvalidateFlags = 0;
+ debugPrint = false;
+}
+
+//-----------------------------------------------------------------------------------
+// TView destructor
+//-----------------------------------------------------------------------------------
+//
+TView::~TView()
+{
+ // If we have installed our custom mouse events handler on the window,
+ // go forth and remove it. Note: -1 is used to indicate that no handler has
+ // been installed yet, but we want to once we get a window.
+ if ( mouseEventHandler != NULL && mouseEventHandler != reinterpret_cast<void*>( -1 ) )
+ {
+ OSStatus err;
+ err = RemoveEventHandler( mouseEventHandler );
+ assert( err == noErr );
+ }
+ mouseEventHandler = NULL;
+}
+
+//-----------------------------------------------------------------------------------
+// Initialize
+//-----------------------------------------------------------------------------------
+// Called during HIObject construction, this is your subclasses' chance to extract
+// any parameters it might have added to the initialization event passed into the
+// HIObjectCreate call.
+//
+OSStatus TView::Initialize( TCarbonEvent& /*inEvent*/ )
+{
+ return noErr;
+}
+
+//-----------------------------------------------------------------------------------
+// GetBehaviors
+//-----------------------------------------------------------------------------------
+// Returns our behaviors. Any subclass that overrides this should OR in its behaviors
+// into the inherited behaviors.
+//
+UInt32 TView::GetBehaviors()
+{
+ return kControlSupportsDataAccess | kControlSupportsGetRegion;
+}
+
+//-----------------------------------------------------------------------------------
+// Draw
+//-----------------------------------------------------------------------------------
+// Draw your view. You should draw based on VIEW coordinates, not frame coordinates.
+//
+void TView::Draw(
+ RgnHandle /*inLimitRgn*/,
+ CGContextRef /*inContext*/ )
+{
+}
+
+//-----------------------------------------------------------------------------------
+// HitTest
+//-----------------------------------------------------------------------------------
+// Asks your view to return what part of itself (if any) is hit by the point given
+// to it. The point is in VIEW coordinates, so you should get the view rect to do
+// bounds checking.
+//
+ControlPartCode TView::HitTest(
+ const HIPoint& /*inWhere*/ )
+{
+ return kControlNoPart;
+}
+
+//-----------------------------------------------------------------------------------
+// GetRegion
+//-----------------------------------------------------------------------------------
+// This is called when someone wants to know certain metrics regarding this view.
+// The base class does nothing. Subclasses should handle their own parts, such as
+// the content region by overriding this method. The structure region is, by default,
+// the view's bounds. If a subclass does not have a region for a given part, it
+// should always call the inherited method.
+//
+OSStatus TView::GetRegion(
+ ControlPartCode inPart,
+ RgnHandle outRgn )
+{
+#pragma unused( inPart, outRgn )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// PrintDebugInfo
+//-----------------------------------------------------------------------------------
+// This is called when asked to print debugging information.
+//
+void TView::PrintDebugInfo()
+{
+}
+
+//-----------------------------------------------------------------------------------
+// GetData
+//-----------------------------------------------------------------------------------
+// Gets some data from our view. Subclasses should override to handle their own
+// defined data tags. If a tag is not understood by the subclass, it should call the
+// inherited method. As a convienience, we map the request for ControlKind into our
+// GetKind method.
+//
+OSStatus TView::GetData(
+ OSType inTag,
+ ControlPartCode inPart,
+ Size inSize,
+ Size* outSize,
+ void* inPtr )
+{
+#pragma unused( inPart )
+
+ OSStatus err = noErr;
+
+ switch( inTag )
+ {
+ case kControlKindTag:
+ if ( inPtr )
+ {
+ if ( inSize != sizeof( ControlKind ) )
+ err = errDataSizeMismatch;
+ else
+ ( *(ControlKind *) inPtr ) = GetKind();
+ }
+ *outSize = sizeof( ControlKind );
+ break;
+
+ default:
+ err = eventNotHandledErr;
+ break;
+ }
+
+ return err;
+}
+
+//-----------------------------------------------------------------------------------
+// SetData
+//-----------------------------------------------------------------------------------
+// Sets some data on our control. Subclasses should override to handle their own
+// defined data tags. If a tag is not understood by the subclass, it should call the
+// inherited method.
+//
+OSStatus TView::SetData(
+ OSType inTag,
+ ControlPartCode inPart,
+ Size inSize,
+ const void* inPtr )
+{
+#pragma unused( inTag, inPart, inSize, inPtr )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// GetOptimalSize
+//-----------------------------------------------------------------------------------
+// Someone wants to know this view's optimal size and text baseline, probably to help
+// do some type of layout. The base class does nothing, but subclasses should
+// override and do something meaningful here.
+//
+OSStatus TView::GetOptimalSize(
+ HISize* outSize,
+ float* outBaseLine )
+{
+#pragma unused( outSize, outBaseLine )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// GetSizeConstraints
+//-----------------------------------------------------------------------------------
+// Someone wants to know this view's minimum and maximum sizes, probably to help
+// do some type of layout. The base class does nothing, but subclasses should
+// override and do something meaningful here.
+//
+OSStatus TView::GetSizeConstraints(
+ HISize* outMin,
+ HISize* outMax )
+{
+#pragma unused( outMin, outMax )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// BoundsChanged
+//-----------------------------------------------------------------------------------
+// The bounds of our view have changed. Subclasses can override here to make note
+// of it and flush caches, etc. The base class does nothing.
+//
+OSStatus TView::BoundsChanged(
+ UInt32 inOptions,
+ const HIRect& inOriginalBounds,
+ const HIRect& inCurrentBounds,
+ RgnHandle inInvalRgn )
+{
+#pragma unused( inOptions, inOriginalBounds, inCurrentBounds, inInvalRgn )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// ControlHit
+//-----------------------------------------------------------------------------------
+// The was hit. Subclasses can overide to care about what part was hit.
+//
+OSStatus TView::ControlHit(
+ ControlPartCode inPart,
+ UInt32 inModifiers )
+{
+#pragma unused( inPart, inModifiers )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// HiliteChanged
+//-----------------------------------------------------------------------------------
+// The hilite of our view has changed. Subclasses can override here to make note
+// of it and flush caches, etc. The base class does nothing.
+//
+OSStatus TView::HiliteChanged(
+ ControlPartCode inOriginalPart,
+ ControlPartCode inCurrentPart,
+ RgnHandle inInvalRgn )
+{
+#pragma unused( inOriginalPart, inCurrentPart, inInvalRgn )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// DragEnter
+//-----------------------------------------------------------------------------------
+// A drag has entered our bounds. The Drag and Drop interface also should have been
+// activated or else this method will NOT be called. If true is returned, this view
+// likes the drag and will receive drag within/leave/receive messages as appropriate.
+// If false is returned, it is assumed the drag is not valid for this view, and no
+// further drag activity will flow into this view unless the drag leaves and is
+// re-entered.
+//
+bool TView::DragEnter(
+ DragRef inDrag )
+{
+#pragma unused( inDrag )
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------------
+// DragWithin
+//-----------------------------------------------------------------------------------
+// A drag has moved within our bounds. In order for this method to be called, the
+// view must have signaled the drag as being desirable in the DragEnter method. The
+// Drag and Drop interface also should have been activated.
+//
+bool TView::DragWithin(
+ DragRef inDrag )
+{
+#pragma unused( inDrag )
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------------
+// DragLeave
+//-----------------------------------------------------------------------------------
+// A drag has left. Deal with it. Subclasses should override as necessary. The
+// Drag and Drop interface should be activated in order for this method to be valid.
+// The drag must have also been accepted in the DragEnter method, else this method
+// will NOT be called.
+//
+bool TView::DragLeave(
+ DragRef inDrag )
+{
+#pragma unused( inDrag )
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------------
+// DragReceive
+//-----------------------------------------------------------------------------------
+// Deal with receiving a drag. By default we return dragNotAcceptedErr. I'm not sure
+// if this is correct, or eventNotHandledErr. Time will tell...
+//
+OSStatus TView::DragReceive(
+ DragRef inDrag )
+{
+#pragma unused( inDrag )
+
+ return dragNotAcceptedErr;
+}
+
+//-----------------------------------------------------------------------------------
+// Track
+//-----------------------------------------------------------------------------------
+// Default tracking method. Subclasses should override as necessary. We do nothing
+// here in the base class, so we return eventNotHandledErr.
+//
+OSStatus TView::Track(
+ TCarbonEvent& inEvent,
+ ControlPartCode* outPart )
+{
+#pragma unused( inEvent, outPart )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// SetFocusPart
+//-----------------------------------------------------------------------------------
+// Handle focusing. Our base behavior is to punt.
+//
+OSStatus TView::SetFocusPart(
+ ControlPartCode inDesiredFocus,
+ RgnHandle inInvalidRgn,
+ Boolean inFocusEverything,
+ ControlPartCode* outActualFocus )
+{
+#pragma unused( inDesiredFocus, inInvalidRgn, inFocusEverything, outActualFocus )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// ProcessCommand
+//-----------------------------------------------------------------------------------
+// Process a command. Subclasses should override as necessary.
+//
+OSStatus TView::ProcessCommand(
+ const HICommand& inCommand )
+{
+#pragma unused( inCommand )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// UpdateCommandStatus
+//-----------------------------------------------------------------------------------
+// Update the status for a command. Subclasses should override as necessary.
+//
+OSStatus
+TView::UpdateCommandStatus(
+ const HICommand& inCommand )
+{
+#pragma unused( inCommand )
+
+ return eventNotHandledErr;
+}
+
+OSStatus TView::MouseDown(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ ,
+ TCarbonEvent& /*inEvent*/)
+{
+ return eventNotHandledErr;
+}
+
+OSStatus TView::MouseUp(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ )
+{
+ return eventNotHandledErr;
+}
+
+OSStatus TView::MouseDragged(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ )
+{
+ return eventNotHandledErr;
+}
+
+OSStatus TView::MouseEntered(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ )
+{
+ return eventNotHandledErr;
+}
+
+OSStatus TView::MouseExited(HIPoint& /*inMouseLocation*/, UInt32 /*inKeyModifiers*/, EventMouseButton /*inMouseButton*/, UInt32 /*inClickCount*/ )
+{
+ return eventNotHandledErr;
+}
+
+OSStatus TView::MouseWheelMoved( EventMouseWheelAxis /*inAxis*/, SInt32 /*inDelta*/, UInt32 /*inKeyModifiers*/ )
+{
+ return eventNotHandledErr;
+}
+
+OSStatus TView::ContextualMenuClick( HIPoint& /*inMouseLocation*/ )
+{
+ return eventNotHandledErr;
+}
+
+
+//-----------------------------------------------------------------------------------
+// ActivateInterface
+//-----------------------------------------------------------------------------------
+// This routine is used to allow a subclass to turn on a specific event or suite of
+// events, like Drag and Drop. This allows us to keep event traffic down if we are
+// not interested, but register for the events if we are.
+//
+OSStatus TView::ActivateInterface(
+ TView::Interface inInterface )
+{
+ OSStatus result = noErr;
+
+ switch( inInterface )
+ {
+ case kDragAndDrop:
+ {
+ static const EventTypeSpec kDragEvents[] =
+ {
+ { kEventClassControl, kEventControlDragEnter },
+ { kEventClassControl, kEventControlDragLeave },
+ { kEventClassControl, kEventControlDragWithin },
+ { kEventClassControl, kEventControlDragReceive }
+ };
+
+ result = AddEventTypesToHandler( fHandler, GetEventTypeCount( kDragEvents ),
+ kDragEvents );
+
+ SetControlDragTrackingEnabled( GetViewRef(), true);
+ }
+ break;
+
+ case kKeyboardFocus:
+ {
+ static const EventTypeSpec kKeyboardFocusEvents[] =
+ {
+ { kEventClassControl, kEventControlSetFocusPart },
+ { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
+ };
+
+ result = AddEventTypesToHandler( fHandler, GetEventTypeCount( kKeyboardFocusEvents ),
+ kKeyboardFocusEvents );
+ }
+ break;
+
+ case kMouse:
+ {
+ if ( mouseEventHandler == NULL )
+ {
+ // This case is quite different: Mouse events are delivered to the window, not the controls.
+ // mouse wheel events are the exception: They ARE delivered to the control
+ static const EventTypeSpec kControlMouseEvents[] =
+ {
+ { kEventClassMouse, kEventMouseWheelMoved },
+ { kEventClassControl, kEventControlContextualMenuClick },
+ // So we can reinstall our events when the window changes
+ { kEventClassControl, kEventControlOwningWindowChanged },
+ };
+
+ result = AddEventTypesToHandler( fHandler, GetEventTypeCount( kControlMouseEvents ),
+ kControlMouseEvents );
+ assert( result == noErr );
+ }
+
+ if ( this->GetOwner() != NULL )
+ {
+ // We use "-1" to indicate that we want to install an event handler once we get a window
+ if ( mouseEventHandler != NULL && mouseEventHandler != reinterpret_cast<void*>( -1 ) )
+ {
+ result = RemoveEventHandler( mouseEventHandler );
+ assert( result != NULL );
+ }
+ mouseEventHandler = NULL;
+
+ static const EventTypeSpec kWindowMouseEvents[] =
+ {
+ { kEventClassMouse, kEventMouseDown },
+ { kEventClassMouse, kEventMouseUp },
+ { kEventClassMouse, kEventMouseMoved },
+ { kEventClassMouse, kEventMouseDragged },
+ };
+
+ assert( mouseEventHandler == NULL );
+ result = InstallEventHandler( GetWindowEventTarget( this->GetOwner() ), WindowEventHandler,
+ GetEventTypeCount( kWindowMouseEvents ), kWindowMouseEvents,
+ this, &mouseEventHandler );
+ assert( result == noErr && mouseEventHandler != NULL );
+ }
+ // If we have no window yet. Set the mouseEventHandler to -1 so when we get one we
+ // will install the event handler
+ else
+ {
+ mouseEventHandler = reinterpret_cast<EventHandlerRef>( -1 );
+ }
+ }
+ break;
+ case kMouseTracking:
+ {
+ {
+ static const EventTypeSpec kControlMouseEvents[] =
+ {
+ { kEventClassMouse, kEventMouseEntered }, // only works if mousetracking is started
+ { kEventClassMouse, kEventMouseExited }, // only works if mousetracking is started
+ };
+
+ result = AddEventTypesToHandler( fHandler, GetEventTypeCount( kControlMouseEvents ),
+ kControlMouseEvents );
+ assert( result == noErr );
+ }
+ }
+
+ //default:
+ // assert( false );
+ }
+
+ return result;
+}
+
+OSStatus TView::InstallTimer( EventTimerInterval inFireDelay, EventLoopTimerRef* outTimer )
+{
+ return InstallEventLoopTimer( GetCurrentEventLoop(), inFireDelay, inFireDelay, TimerEventHandler, this, outTimer );
+}
+
+//-----------------------------------------------------------------------------------
+// RegisterSubclass
+//-----------------------------------------------------------------------------------
+// This routine should be called by subclasses so they can be created as HIObjects.
+//
+OSStatus TView::RegisterSubclass(
+ CFStringRef inID,
+ ConstructProc inProc )
+{
+ return HIObjectRegisterSubclass( inID, kHIViewClassID, 0, ObjectEventHandler,
+ GetEventTypeCount( kHIObjectEvents ), kHIObjectEvents, (void*) inProc, NULL );
+}
+
+//-----------------------------------------------------------------------------------
+// ObjectEventHandler
+//-----------------------------------------------------------------------------------
+// Our static event handler proc. We handle any HIObject based events directly in
+// here at present.
+//
+pascal OSStatus TView::ObjectEventHandler(
+ EventHandlerCallRef inCallRef,
+ EventRef inEvent,
+ void* inUserData )
+{
+ OSStatus result = eventNotHandledErr;
+ TView* view = (TView*) inUserData;
+ TCarbonEvent event( inEvent );
+
+ switch ( event.GetClass() )
+ {
+ case kEventClassHIObject:
+ switch ( event.GetKind() )
+ {
+ case kEventHIObjectConstruct:
+ {
+ ControlRef control; // ControlRefs are HIObjectRefs
+ TView* view;
+
+ result = event.GetParameter<HIObjectRef>( kEventParamHIObjectInstance,
+ typeHIObjectRef, (HIObjectRef*)&control );
+ require_noerr( result, ParameterMissing );
+
+ // on entry for our construct event, we're passed the
+ // creation proc we registered with for this class.
+ // we use it now to create the instance, and then we
+ // replace the instance parameter data with said instance
+ // as type void.
+
+ result = (*(ConstructProc)inUserData)( control, &view );
+ if ( result == noErr )
+ event.SetParameter<TViewPtr>( kEventParamHIObjectInstance,
+ typeVoidPtr, view );
+ }
+ break;
+
+ case kEventHIObjectInitialize:
+ result = CallNextEventHandler( inCallRef, inEvent );
+ if ( result == noErr )
+ result = view->Initialize( event );
+ break;
+
+ case kEventHIObjectDestruct:
+ delete view;
+ break;
+ }
+ break;
+ }
+
+ParameterMissing:
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------------
+// ViewEventHandler
+//-----------------------------------------------------------------------------------
+// Our static event handler proc. We handle all non-HIObject events here.
+//
+pascal OSStatus TView::ViewEventHandler(
+ EventHandlerCallRef inCallRef,
+ EventRef inEvent,
+ void* inUserData )
+{
+ OSStatus result;
+ TView* view = (TView*) inUserData;
+ TCarbonEvent event( inEvent );
+ if (view->debugPrint)
+ fprintf(stderr,"TView::ViewEventHandler\n");
+ result = view->HandleEvent( inCallRef, event );
+
+ return result;
+}
+
+
+pascal OSStatus TView::WindowEventHandler(
+ EventHandlerCallRef inCallRef,
+ EventRef inEvent,
+ void* inUserData )
+{
+ TView* view = reinterpret_cast<TView*>( inUserData );
+ TCarbonEvent event( inEvent );
+
+ const WindowRef window = view->GetOwner();
+ assert( window != NULL );
+
+ // If the window is not active, let the standard window handler execute.
+ if ( ! IsWindowActive( window ) ) return eventNotHandledErr;
+ if (view->debugPrint)
+ fprintf(stderr,"TView::WindowEventHandler\n");
+
+ const HIViewRef rootView = HIViewGetRoot( window );
+ assert( rootView != NULL );
+
+ // TODO: On OS X 10.3, test if this bug still exists
+ // This is a hack to work around a bug in the OS. See:
+ // http://lists.apple.com/archives/carbon-development/2002/Sep/29/keventmousemovedeventsno.004.txt
+ OSStatus err;
+ if ( event.GetKind() == kEventMouseMoved )
+ {
+ // We need to set some parameters correctly
+ event.SetParameter( kEventParamWindowRef, window );
+
+ HIPoint ptMouse;
+ event.GetParameter( kEventParamMouseLocation, &ptMouse );
+
+ // convert screen coords to window relative
+ Rect bounds;
+ err = GetWindowBounds( window, kWindowStructureRgn, &bounds );
+ assert( err == noErr );
+
+ ptMouse.x -= bounds.left;
+ ptMouse.y -= bounds.top;
+
+ event.SetParameter( kEventParamWindowMouseLocation, ptMouse );
+ }
+
+ HIViewRef targetView = NULL;
+ err = HIViewGetViewForMouseEvent( rootView, inEvent, &targetView );
+ assert( err == noErr && targetView != NULL );
+ if (view->debugPrint)
+ fprintf(stderr,"TView::WindowEventHandler root[%08X] viewRef[%08X] targetView[%08X]\n", rootView, view->GetViewRef(), targetView);
+ if ( targetView == view->GetViewRef() || event.GetKind() == kEventMouseDragged )
+ {
+ return view->HandleEvent( inCallRef, event );
+ }
+
+ return eventNotHandledErr;
+}
+
+pascal void TView::TimerEventHandler( EventLoopTimerRef inTimer, void* view )
+{
+ reinterpret_cast<TView*>( view )->TimerFired( inTimer );
+}
+
+//-----------------------------------------------------------------------------------
+// HandleEvent
+//-----------------------------------------------------------------------------------
+// Our object's virtual event handler method. I'm not sure if we need this these days.
+// We used to do various things with it, but those days are long gone...
+//
+OSStatus TView::HandleEvent(
+ EventHandlerCallRef inCallRef,
+ TCarbonEvent& inEvent )
+{
+#pragma unused( inCallRef )
+
+ OSStatus result = eventNotHandledErr;
+ HIPoint where;
+ OSType tag;
+ void * ptr;
+ Size size, outSize;
+ UInt32 features;
+ RgnHandle region = NULL;
+ ControlPartCode part;
+ RgnHandle invalRgn;
+
+ switch ( inEvent.GetClass() )
+ {
+ case kEventClassCommand:
+ {
+ HICommand command;
+
+ result = inEvent.GetParameter( kEventParamDirectObject, &command );
+ require_noerr( result, MissingParameter );
+
+ switch ( inEvent.GetKind() )
+ {
+ case kEventCommandProcess:
+ result = ProcessCommand( command );
+ break;
+
+ case kEventCommandUpdateStatus:
+ result = UpdateCommandStatus( command );
+ break;
+ }
+ }
+ break;
+
+ case kEventClassControl:
+ switch ( inEvent.GetKind() )
+ {
+ case kEventControlInitialize:
+ features = GetBehaviors();
+ inEvent.SetParameter( kEventParamControlFeatures, features );
+ result = noErr;
+ break;
+
+ case kEventControlDraw:
+ {
+ CGContextRef context = NULL;
+
+ inEvent.GetParameter( kEventParamRgnHandle, &region );
+ inEvent.GetParameter<CGContextRef>( kEventParamCGContextRef, typeCGContextRef, &context );
+
+ Draw( region, context );
+ result = noErr;
+ }
+ break;
+
+ case kEventControlHitTest:
+ inEvent.GetParameter<HIPoint>( kEventParamMouseLocation, typeHIPoint, &where );
+ part = HitTest( where );
+ inEvent.SetParameter<ControlPartCode>( kEventParamControlPart, typeControlPartCode, part );
+ result = noErr;
+ break;
+
+ case kEventControlGetPartRegion:
+ inEvent.GetParameter<ControlPartCode>( kEventParamControlPart, typeControlPartCode, &part );
+ inEvent.GetParameter( kEventParamControlRegion, &region );
+ result = GetRegion( part, region );
+ break;
+
+ case kEventControlGetData:
+ inEvent.GetParameter<ControlPartCode>( kEventParamControlPart, typeControlPartCode, &part );
+ inEvent.GetParameter<OSType>( kEventParamControlDataTag, typeEnumeration, &tag );
+ inEvent.GetParameter<Ptr>( kEventParamControlDataBuffer, typePtr, (Ptr*)&ptr );
+ inEvent.GetParameter<Size>( kEventParamControlDataBufferSize, typeLongInteger, &size );
+
+ result = GetData( tag, part, size, &outSize, ptr );
+
+ if ( result == noErr )
+ verify_noerr( inEvent.SetParameter<Size>( kEventParamControlDataBufferSize, typeLongInteger, outSize ) );
+ break;
+
+ case kEventControlSetData:
+ inEvent.GetParameter<ControlPartCode>( kEventParamControlPart, typeControlPartCode, &part );
+ inEvent.GetParameter<OSType>( kEventParamControlDataTag, typeEnumeration, &tag );
+ inEvent.GetParameter<Ptr>( kEventParamControlDataBuffer, typePtr, (Ptr*)&ptr );
+ inEvent.GetParameter<Size>( kEventParamControlDataBufferSize, typeLongInteger, &size );
+
+ result = SetData( tag, part, size, ptr );
+ break;
+
+ case kEventControlGetOptimalBounds:
+ {
+ HISize size;
+ float floatBaseLine;
+
+ result = GetOptimalSize( &size, &floatBaseLine );
+ if ( result == noErr )
+ {
+ Rect bounds;
+ SInt16 baseLine;
+
+ GetControlBounds( GetViewRef(), &bounds );
+
+ bounds.bottom = bounds.top + (SInt16)size.height;
+ bounds.right = bounds.left + (SInt16)size.width;
+ baseLine = (SInt16)floatBaseLine;
+
+ inEvent.SetParameter( kEventParamControlOptimalBounds, bounds );
+ inEvent.SetParameter<SInt16>( kEventParamControlOptimalBaselineOffset, typeShortInteger, baseLine );
+ }
+ }
+ break;
+
+ case kEventControlBoundsChanged:
+ {
+ HIRect prevRect, currRect;
+ UInt32 attrs;
+
+ inEvent.GetParameter( kEventParamAttributes, &attrs );
+ inEvent.GetParameter( kEventParamOriginalBounds, &prevRect );
+ inEvent.GetParameter( kEventParamCurrentBounds, &currRect );
+ inEvent.GetParameter( kEventParamControlInvalRgn, &invalRgn );
+
+ result = BoundsChanged( attrs, prevRect, currRect, invalRgn );
+
+ if ( mouseEventHandler != NULL )
+ {
+ ActivateInterface( kMouse );
+ }
+
+ }
+ break;
+
+ case kEventControlHit:
+ {
+ UInt32 modifiers;
+
+ inEvent.GetParameter<ControlPartCode>( kEventParamControlPart, typeControlPartCode, &part );
+ inEvent.GetParameter( kEventParamKeyModifiers, &modifiers );
+
+ result = ControlHit( part, modifiers );
+ }
+ break;
+
+ case kEventControlHiliteChanged:
+ {
+ ControlPartCode prevPart, currPart;
+
+ inEvent.GetParameter<ControlPartCode>( kEventParamControlPreviousPart, typeControlPartCode, &prevPart );
+ inEvent.GetParameter<ControlPartCode>( kEventParamControlCurrentPart, typeControlPartCode, &currPart );
+ inEvent.GetParameter( kEventParamControlInvalRgn, &invalRgn );
+
+ result = HiliteChanged( prevPart, currPart, invalRgn );
+
+ if ( GetAutoInvalidateFlags() & kAutoInvalidateOnHilite )
+ Invalidate();
+ }
+ break;
+
+ case kEventControlActivate:
+ result = ActiveStateChanged();
+
+ if ( GetAutoInvalidateFlags() & kAutoInvalidateOnActivate )
+ Invalidate();
+ break;
+
+ case kEventControlDeactivate:
+ result = ActiveStateChanged();
+
+ if ( GetAutoInvalidateFlags() & kAutoInvalidateOnActivate )
+ Invalidate();
+ break;
+
+ case kEventControlValueFieldChanged:
+ result = ValueChanged();
+
+ if ( GetAutoInvalidateFlags() & kAutoInvalidateOnValueChange )
+ Invalidate();
+ break;
+
+ case kEventControlTitleChanged:
+ result = TitleChanged();
+
+ if ( GetAutoInvalidateFlags() & kAutoInvalidateOnTitleChange )
+ Invalidate();
+ break;
+
+ case kEventControlEnabledStateChanged:
+ result = EnabledStateChanged();
+
+ if ( GetAutoInvalidateFlags() & kAutoInvalidateOnEnable )
+ Invalidate();
+ break;
+
+ case kEventControlDragEnter:
+ case kEventControlDragLeave:
+ case kEventControlDragWithin:
+ {
+ DragRef drag;
+ bool likesDrag;
+
+ inEvent.GetParameter( kEventParamDragRef, &drag );
+
+ switch ( inEvent.GetKind() )
+ {
+ case kEventControlDragEnter:
+ likesDrag = DragEnter( drag );
+ // Why only if likesDrag? What if it doesn't? No parameter?
+ if ( likesDrag )
+ result = inEvent.SetParameter( kEventParamControlLikesDrag, likesDrag );
+ break;
+
+ case kEventControlDragLeave:
+ DragLeave( drag );
+ result = noErr;
+ break;
+
+ case kEventControlDragWithin:
+ DragWithin( drag );
+ result = noErr;
+ break;
+ }
+ }
+ break;
+
+ case kEventControlDragReceive:
+ {
+ DragRef drag;
+
+ inEvent.GetParameter( kEventParamDragRef, &drag );
+
+ result = DragReceive( drag );
+ }
+ break;
+
+ case kEventControlTrack:
+ {
+ ControlPartCode part;
+
+ result = Track( inEvent, &part );
+ if ( result == noErr )
+ verify_noerr( inEvent.SetParameter<ControlPartCode>( kEventParamControlPart, typeControlPartCode, part ) );
+ }
+ break;
+
+ case kEventControlGetSizeConstraints:
+ {
+ HISize minSize, maxSize;
+
+ result = GetSizeConstraints( &minSize, &maxSize );
+
+ if ( result == noErr )
+ {
+ verify_noerr( inEvent.SetParameter( kEventParamMinimumSize, minSize ) );
+ verify_noerr( inEvent.SetParameter( kEventParamMaximumSize, maxSize ) );
+ }
+ }
+ break;
+
+ case kEventControlSetFocusPart:
+ {
+ ControlPartCode desiredFocus;
+ RgnHandle invalidRgn;
+ Boolean focusEverything;
+ ControlPartCode actualFocus;
+
+ result = inEvent.GetParameter<ControlPartCode>( kEventParamControlPart, typeControlPartCode, &desiredFocus );
+ require_noerr( result, MissingParameter );
+
+ inEvent.GetParameter( kEventParamControlInvalRgn, &invalidRgn );
+
+ focusEverything = false; // a good default in case the parameter doesn't exist
+
+ inEvent.GetParameter( kEventParamControlFocusEverything, &focusEverything );
+
+ result = SetFocusPart( desiredFocus, invalidRgn, focusEverything, &actualFocus );
+
+ if ( result == noErr )
+ verify_noerr( inEvent.SetParameter<ControlPartCode>( kEventParamControlPart, typeControlPartCode, actualFocus ) );
+ }
+ break;
+
+ case kEventControlOwningWindowChanged:
+ {
+ // If our owning window has changed, reactivate the mouse interface
+ if ( mouseEventHandler != NULL )
+ {
+ ActivateInterface( kMouse );
+ }
+ }
+ break;
+
+ case kEventControlContextualMenuClick:
+ {
+ HIPoint ptMouse;
+ inEvent.GetParameter( kEventParamMouseLocation, &ptMouse );
+ result = ContextualMenuClick( ptMouse );
+ }
+ break;
+
+ // some other kind of Control event
+ default:
+ assert( false );
+ break;
+ }
+ break;
+
+ case kEventClassTextInput:
+ result = TextInput( inEvent );
+ break;
+
+ case kEventClassMouse:
+ result = inEvent.GetParameter<HIPoint>( kEventParamWindowMouseLocation, typeHIPoint, &where );
+ HIViewConvertPoint( &where, NULL, fViewRef );
+ assert( result == noErr );
+
+ UInt32 inKeyModifiers;
+ result = inEvent.GetParameter( kEventParamKeyModifiers, &inKeyModifiers );
+ assert( result == noErr );
+
+ switch ( inEvent.GetKind() )
+ {
+ case kEventMouseWheelMoved:
+ {
+ EventMouseWheelAxis inAxis;
+ result = inEvent.GetParameter<EventMouseWheelAxis>( kEventParamMouseWheelAxis, typeMouseWheelAxis, &inAxis );
+ assert( noErr == result );
+
+ SInt32 inDelta;
+ result = inEvent.GetParameter<SInt32>( kEventParamMouseWheelDelta, typeSInt32, &inDelta );
+ assert( noErr == result );
+
+ result = MouseWheelMoved( inAxis, inDelta, inKeyModifiers );
+ }
+ break;
+
+
+ // some other kind of Mouse event: This is (in my opinion) an error
+ // TODO: There is also a MouseMoved event that we do not handle
+ default:
+ {
+ EventMouseButton inMouseButton;
+ result = inEvent.GetParameter<EventMouseButton>( kEventParamMouseButton, typeMouseButton, &inMouseButton );
+ assert( result == noErr );
+
+ UInt32 inClickCount;
+ result = inEvent.GetParameter( kEventParamClickCount, &inClickCount );
+ assert( result == noErr );
+
+ switch ( inEvent.GetKind() )
+ {
+ case kEventMouseDown:
+ result = MouseDown( where, inKeyModifiers, inMouseButton, inClickCount, inEvent );
+ break;
+ case kEventMouseUp:
+ result = MouseUp( where, inKeyModifiers, inMouseButton, inClickCount );
+ break;
+ case kEventMouseExited:
+ result = MouseExited( where, inKeyModifiers, inMouseButton, inClickCount );
+ break;
+ case kEventMouseEntered:
+ result = MouseEntered( where, inKeyModifiers, inMouseButton, inClickCount );
+ break;
+ case kEventMouseMoved:
+ case kEventMouseDragged:
+ result = MouseDragged( where, inKeyModifiers, inMouseButton, inClickCount );
+ break;
+ }
+ }
+ break;
+ }
+ break;
+
+ // some other event class
+ default:
+ assert( false );
+ break;
+ }
+
+MissingParameter:
+ return result;
+}
+
+//-----------------------------------------------------------------------------------
+// CreateInitializationEvent
+//-----------------------------------------------------------------------------------
+// Create a basic intialization event containing the parent control and bounds. At
+// present we set the bounds to empty and the parent to NULL. In theory, after creating
+// this event, any subclass could add its own parameter to receive in its
+// Initialize method.
+//
+EventRef TView::CreateInitializationEvent()
+{
+ OSStatus result = noErr;
+ EventRef event;
+
+ result = CreateEvent( NULL, kEventClassHIObject, kEventHIObjectInitialize,
+ GetCurrentEventTime(), 0, &event );
+ require_noerr_action( result, CantCreateEvent, event = NULL );
+
+CantCreateEvent:
+ return event;
+}
+
+//-----------------------------------------------------------------------------------
+// Frame
+//-----------------------------------------------------------------------------------
+//
+HIRect TView::Frame()
+{
+ HIRect frame;
+
+ HIViewGetFrame( GetViewRef(), &frame );
+
+ return frame;
+}
+
+//-----------------------------------------------------------------------------------
+// SetFrame
+//-----------------------------------------------------------------------------------
+//
+OSStatus TView::SetFrame(
+ const HIRect& inFrame )
+{
+ OSStatus err;
+
+ err = HIViewSetFrame( GetViewRef(), &inFrame );
+
+ return err;
+}
+
+//-----------------------------------------------------------------------------------
+// Bounds
+//-----------------------------------------------------------------------------------
+//
+HIRect TView::Bounds()
+{
+ HIRect bounds;
+
+ HIViewGetBounds( GetViewRef(), &bounds );
+
+ return bounds;
+}
+
+//-----------------------------------------------------------------------------------
+// Show
+//-----------------------------------------------------------------------------------
+//
+OSStatus TView::Show()
+{
+ return HIViewSetVisible( GetViewRef(), true );
+}
+
+//-----------------------------------------------------------------------------------
+// Hide
+//-----------------------------------------------------------------------------------
+//
+OSStatus TView::Hide()
+{
+ return HIViewSetVisible( GetViewRef(), false );
+}
+
+//-----------------------------------------------------------------------------------
+// GetEventTarget
+//-----------------------------------------------------------------------------------
+//
+EventTargetRef TView::GetEventTarget()
+{
+ return HIObjectGetEventTarget( (HIObjectRef) GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// AddSubView
+//-----------------------------------------------------------------------------------
+//
+OSStatus TView::AddSubView(
+ TView* inSubView )
+{
+ return HIViewAddSubview( GetViewRef(), inSubView->GetViewRef() );;
+}
+
+//-----------------------------------------------------------------------------------
+// RemoveFromSuperView
+//-----------------------------------------------------------------------------------
+//
+OSStatus TView::RemoveFromSuperView()
+{
+ return HIViewRemoveFromSuperview( GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// GetHilite
+//-----------------------------------------------------------------------------------
+//
+ControlPartCode TView::GetHilite()
+{
+ return GetControlHilite( GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// GetValue
+//-----------------------------------------------------------------------------------
+//
+SInt32 TView::GetValue()
+{
+ return GetControl32BitValue( GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// SetValue
+//-----------------------------------------------------------------------------------
+//
+void TView::SetValue(
+ SInt32 inValue )
+{
+ SetControl32BitValue( GetViewRef(), inValue );
+}
+
+//-----------------------------------------------------------------------------------
+// GetMinimum
+//-----------------------------------------------------------------------------------
+//
+SInt32 TView::GetMinimum()
+{
+ return GetControlMinimum( GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// SetMinimum
+//-----------------------------------------------------------------------------------
+//
+void TView::SetMinimum(
+ SInt32 inMinimum )
+{
+ SetControlMinimum( GetViewRef(), inMinimum );
+}
+
+//-----------------------------------------------------------------------------------
+// GetMaximum
+//-----------------------------------------------------------------------------------
+//
+SInt32 TView::GetMaximum()
+{
+ return GetControlMaximum( GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// SetMaximum
+//-----------------------------------------------------------------------------------
+//
+void TView::SetMaximum(
+ SInt32 inMaximum )
+{
+ SetControlMaximum( GetViewRef(), inMaximum );
+}
+
+//-----------------------------------------------------------------------------------
+// GetOwner
+//-----------------------------------------------------------------------------------
+//
+WindowRef TView::GetOwner()
+{
+ return GetControlOwner( GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// Hilite
+//-----------------------------------------------------------------------------------
+//
+void TView::Hilite(
+ ControlPartCode inPart)
+{
+ return HiliteControl( GetViewRef(), inPart );
+}
+
+//-----------------------------------------------------------------------------------
+// Invalidate
+//-----------------------------------------------------------------------------------
+//
+OSStatus TView::Invalidate()
+{
+ return HIViewSetNeedsDisplay( GetViewRef(), true );
+}
+
+void TView::TimerFired( EventLoopTimerRef inTimer )
+{
+#pragma unused( inTimer )
+}
+
+
+//-----------------------------------------------------------------------------------
+// IsVisible
+//-----------------------------------------------------------------------------------
+//
+Boolean TView::IsVisible()
+{
+ return IsControlVisible( GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// IsEnabled
+//-----------------------------------------------------------------------------------
+//
+Boolean TView::IsEnabled()
+{
+ return IsControlEnabled( GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// IsActive
+//-----------------------------------------------------------------------------------
+//
+Boolean TView::IsActive()
+{
+ return IsControlActive( GetViewRef() );
+}
+
+//-----------------------------------------------------------------------------------
+// ActiveStateChanged
+//-----------------------------------------------------------------------------------
+// Default activation method. Subclasses should override as necessary. We do nothing
+// here in the base class, so we return eventNotHandledErr.
+//
+OSStatus TView::ActiveStateChanged()
+{
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// ValueChanged
+//-----------------------------------------------------------------------------------
+// Default value changed method. Subclasses should override as necessary. We do
+// nothing here in the base class, so we return eventNotHandledErr.
+//
+OSStatus TView::ValueChanged()
+{
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// TitleChanged
+//-----------------------------------------------------------------------------------
+// Default title changed method. Subclasses should override as necessary. We
+// do nothing here in the base class, so we return eventNotHandledErr.
+//
+OSStatus TView::TitleChanged()
+{
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// EnabledStateChanged
+//-----------------------------------------------------------------------------------
+// Default enable method. Subclasses should override as necessary. We
+// do nothing here in the base class, so we return eventNotHandledErr.
+//
+OSStatus TView::EnabledStateChanged()
+{
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// TextInput
+//-----------------------------------------------------------------------------------
+// Default text (Unicode) input method. Subclasses should override as necessary. We
+// do nothing here in the base class, so we return eventNotHandledErr.
+//
+OSStatus TView::TextInput(
+ TCarbonEvent& inEvent )
+{
+#pragma unused( inEvent )
+
+ return eventNotHandledErr;
+}
+
+//-----------------------------------------------------------------------------------
+// ChangeAutoInvalidateFlags
+//-----------------------------------------------------------------------------------
+// Change behavior for auto-invalidating views on certain actions.
+//
+void TView::ChangeAutoInvalidateFlags(
+ OptionBits inSetThese,
+ OptionBits inClearThese )
+{
+ fAutoInvalidateFlags = ( ( fAutoInvalidateFlags | inSetThese ) & ( ~inClearThese ) );
+}
diff --git a/macosx/TView.h b/macosx/TView.h
new file mode 100644
index 000000000..97c8f7b55
--- /dev/null
+++ b/macosx/TView.h
@@ -0,0 +1,286 @@
+/*
+ File: TView.h
+
+ Version: 1.0
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright © 2002 Apple Computer, Inc., All Rights Reserved
+*/
+
+#ifndef TView_H_
+#define TView_H_
+
+#include <Carbon/Carbon.h>
+
+#include "TCarbonEvent.h"
+#include "TRect.h"
+
+#define PURE_VIRTUAL 0
+
+class TView
+{
+public:
+ // Bounds and Frame
+ OSStatus SetFrame(
+ const HIRect& inBounds );
+ HIRect Frame();
+ HIRect Bounds();
+
+ // Visibility
+ OSStatus Show();
+ OSStatus Hide();
+
+ EventTargetRef GetEventTarget();
+
+ OSStatus AddSubView(
+ TView* inSubView );
+ OSStatus RemoveFromSuperView();
+
+ // Accessors
+ HIViewRef GetViewRef() const
+ { return fViewRef; }
+ void Hilite(
+ ControlPartCode inPart );
+ ControlPartCode GetHilite();
+ WindowRef GetOwner();
+ SInt32 GetValue();
+ void SetValue(
+ SInt32 inValue );
+ SInt32 GetMinimum();
+ void SetMinimum(
+ SInt32 inMinimum );
+ SInt32 GetMaximum();
+ void SetMaximum(
+ SInt32 inMaximum );
+
+ // State
+ Boolean IsVisible();
+ Boolean IsEnabled();
+ Boolean IsActive();
+
+ OSStatus Invalidate(); // was SetNeedsDisplay()
+
+ // A "fake" event handler
+ virtual void TimerFired( EventLoopTimerRef inTimer );
+
+protected:
+ // Autoinvalidation
+ enum {
+ kAutoInvalidateOnActivate = (1 << 0),
+ kAutoInvalidateOnHilite = (1 << 1),
+ kAutoInvalidateOnEnable = (1 << 2),
+ kAutoInvalidateOnValueChange = (1 << 3),
+ kAutoInvalidateOnTitleChange = (1 << 4)
+ };
+ void ChangeAutoInvalidateFlags(
+ OptionBits inSetFlags,
+ OptionBits inClearFlags );
+ OptionBits GetAutoInvalidateFlags()
+ { return fAutoInvalidateFlags; }
+
+ // Types
+ typedef OSStatus (*ConstructProc)(
+ ControlRef inBaseControl,
+ TView** outView );
+
+ // Construction/Destruction
+ TView( HIViewRef inControl );
+ virtual ~TView();
+
+ virtual ControlKind GetKind() = PURE_VIRTUAL;
+ virtual UInt32 GetBehaviors();
+
+ // Handlers
+ virtual OSStatus ActiveStateChanged();
+ virtual OSStatus BoundsChanged(
+ UInt32 inOptions,
+ const HIRect& inOriginalBounds,
+ const HIRect& inCurrentBounds,
+ RgnHandle inInvalRgn );
+ virtual OSStatus ControlHit(
+ ControlPartCode inPart,
+ UInt32 inModifiers );
+ virtual OSStatus EnabledStateChanged();
+ virtual void Draw(
+ RgnHandle inLimitRgn,
+ CGContextRef inContext );
+ virtual OSStatus GetData(
+ OSType inTag,
+ ControlPartCode inPart,
+ Size inSize,
+ Size* outSize,
+ void* inPtr );
+ virtual OSStatus GetRegion(
+ ControlPartCode inPart,
+ RgnHandle outRgn );
+ virtual OSStatus HiliteChanged(
+ ControlPartCode inOriginalPart,
+ ControlPartCode inCurrentPart,
+ RgnHandle inInvalRgn );
+ virtual ControlPartCode HitTest(
+ const HIPoint& inWhere );
+ virtual OSStatus Initialize(
+ TCarbonEvent& inEvent );
+ virtual OSStatus SetData(
+ OSType inTag,
+ ControlPartCode inPart,
+ Size inSize,
+ const void* inPtr );
+ virtual OSStatus SetFocusPart(
+ ControlPartCode inDesiredFocus,
+ RgnHandle inNnvalidRgn,
+ Boolean inFocusEverything,
+ ControlPartCode* outActualFocus );
+ virtual OSStatus TextInput(
+ TCarbonEvent& inEvent );
+ virtual OSStatus TitleChanged();
+ virtual OSStatus Track(
+ TCarbonEvent& inEvent,
+ ControlPartCode* outPartHit );
+ virtual OSStatus ValueChanged();
+
+ // Sizing
+ virtual OSStatus GetSizeConstraints(
+ HISize* outMin,
+ HISize* outMax );
+ virtual OSStatus GetOptimalSize(
+ HISize* outSize,
+ float* outBaseLine );
+
+ // Accessors
+ WindowRef GetWindowRef()
+ { return GetControlOwner( GetViewRef() ); }
+
+
+ // Drag and drop
+ virtual bool DragEnter(
+ DragRef inDrag );
+ virtual bool DragWithin(
+ DragRef inDrag );
+ virtual bool DragLeave(
+ DragRef inDrag );
+ virtual OSStatus DragReceive(
+ DragRef inDrag );
+
+ // Command processing
+ virtual OSStatus ProcessCommand(
+ const HICommand& inCommand );
+ virtual OSStatus UpdateCommandStatus(
+ const HICommand& inCommand );
+
+ // Mouse events
+ virtual OSStatus MouseDown(
+ HIPoint& inMouseLocation,
+ UInt32 inKeyModifiers,
+ EventMouseButton inMouseButton,
+ UInt32 inClickCount,
+ TCarbonEvent& inEvent);
+ virtual OSStatus MouseUp(
+ HIPoint& inMouseLocation,
+ UInt32 inKeyModifiers,
+ EventMouseButton inMouseButton,
+ UInt32 inClickCount );
+ virtual OSStatus MouseDragged(
+ HIPoint& inMouseLocation,
+ UInt32 inKeyModifiers,
+ EventMouseButton inMouseButton,
+ UInt32 inClickCount );
+ virtual OSStatus MouseEntered(
+ HIPoint& inMouseLocation,
+ UInt32 inKeyModifiers,
+ EventMouseButton inMouseButton,
+ UInt32 inClickCount );
+ virtual OSStatus MouseExited(
+ HIPoint& inMouseLocation,
+ UInt32 inKeyModifiers,
+ EventMouseButton inMouseButton,
+ UInt32 inClickCount );
+ virtual OSStatus MouseWheelMoved( EventMouseWheelAxis inAxis, SInt32 inDelta, UInt32 inKeyModifiers );
+ virtual OSStatus ContextualMenuClick( HIPoint& inMouseLocation );
+
+ // Utility
+ static OSStatus RegisterSubclass(
+ CFStringRef inID,
+ ConstructProc inProc );
+ static EventRef CreateInitializationEvent();
+ enum Interface {
+ kDragAndDrop = 1,
+ kKeyboardFocus,
+ kMouse,
+ kMouseTracking
+ };
+ virtual OSStatus ActivateInterface(
+ Interface inInterface );
+
+ OSStatus InstallTimer(
+ EventTimerInterval inFireDelay,
+ EventLoopTimerRef* outTimer );
+
+ // Debugging
+ virtual void PrintDebugInfo();
+ Boolean debugPrint;
+private:
+ static pascal OSStatus ObjectEventHandler(
+ EventHandlerCallRef inCallRef,
+ EventRef inEvent,
+ void* inUserData );
+ static pascal OSStatus ViewEventHandler(
+ EventHandlerCallRef inCallRef,
+ EventRef inEvent,
+ void* inUserData );
+ static pascal OSStatus WindowEventHandler(
+ EventHandlerCallRef inCallRef,
+ EventRef inEvent,
+ void* inUserData );
+ static pascal void TimerEventHandler(
+ EventLoopTimerRef inTimer,
+ void* inUserData );
+ OSStatus HandleEvent(
+ EventHandlerCallRef inCallRef,
+ TCarbonEvent& inEvent );
+
+ HIViewRef fViewRef;
+ EventHandlerRef fHandler;
+
+ EventHandlerRef mouseEventHandler;
+ OptionBits fAutoInvalidateFlags;
+
+};
+
+typedef TView* TViewPtr;
+
+#endif // TView_H_
diff --git a/macosx/deps.mak b/macosx/deps.mak
new file mode 100644
index 000000000..5c65dcc1f
--- /dev/null
+++ b/macosx/deps.mak
@@ -0,0 +1,315 @@
+PlatMacOSX.o: PlatMacOSX.cxx QuartzTextLayout.h QuartzTextStyle.h \
+ QuartzTextStyleAttribute.h TCarbonEvent.h ../include/Platform.h \
+ ../include/Scintilla.h PlatMacOSX.h ../src/XPM.h \
+ ../include/ScintillaWidget.h
+ScintillaCallTip.o: ScintillaCallTip.cxx ScintillaMacOSX.h TView.h \
+ TCarbonEvent.h TRect.h ../include/Platform.h ../include/Scintilla.h \
+ PlatMacOSX.h QuartzTextLayout.h QuartzTextStyle.h \
+ QuartzTextStyleAttribute.h ../include/ScintillaWidget.h \
+ ../include/SciLexer.h ../include/PropSet.h ../include/SString.h \
+ ../include/Accessor.h ../include/KeyWords.h ../src/ContractionState.h \
+ ../src/SVector.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \
+ ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \
+ ../src/AutoComplete.h ../src/ViewStyle.h ../src/Document.h \
+ ../src/Editor.h ../src/ScintillaBase.h ScintillaCallTip.h
+ScintillaListBox.o: ScintillaListBox.cxx ScintillaMacOSX.h TView.h \
+ TCarbonEvent.h TRect.h ../include/Platform.h ../include/Scintilla.h \
+ PlatMacOSX.h QuartzTextLayout.h QuartzTextStyle.h \
+ QuartzTextStyleAttribute.h ../include/ScintillaWidget.h \
+ ../include/SciLexer.h ../include/PropSet.h ../include/SString.h \
+ ../include/Accessor.h ../include/KeyWords.h ../src/ContractionState.h \
+ ../src/SVector.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \
+ ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \
+ ../src/AutoComplete.h ../src/ViewStyle.h ../src/Document.h \
+ ../src/Editor.h ../src/ScintillaBase.h ScintillaCallTip.h \
+ ScintillaListBox.h
+ScintillaMacOSX.o: ScintillaMacOSX.cxx ScintillaMacOSX.h TView.h \
+ TCarbonEvent.h TRect.h ../include/Platform.h ../include/Scintilla.h \
+ PlatMacOSX.h QuartzTextLayout.h QuartzTextStyle.h \
+ QuartzTextStyleAttribute.h ../include/ScintillaWidget.h \
+ ../include/SciLexer.h ../include/PropSet.h ../include/SString.h \
+ ../include/Accessor.h ../include/KeyWords.h ../src/ContractionState.h \
+ ../src/SVector.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \
+ ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \
+ ../src/AutoComplete.h ../src/ViewStyle.h ../src/Document.h \
+ ../src/Editor.h ../src/ScintillaBase.h ScintillaCallTip.h \
+ ../src/UniConversion.h
+TCarbonEvent.o: TCarbonEvent.cxx TCarbonEvent.h
+TView.o: TView.cxx TView.h TCarbonEvent.h TRect.h
+AutoComplete.o: ../src/AutoComplete.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../src/AutoComplete.h
+CallTip.o: ../src/CallTip.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../src/CallTip.h
+CellBuffer.o: ../src/CellBuffer.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \
+ ../src/Partitioning.h ../src/CellBuffer.h
+CharClassify.o: ../src/CharClassify.cxx ../src/CharClassify.h
+ContractionState.o: ../src/ContractionState.cxx ../include/Platform.h \
+ ../src/ContractionState.h
+Decoration.o: ../src/Decoration.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \
+ ../src/RunStyles.h ../src/Decoration.h
+Document.o: ../src/Document.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \
+ ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \
+ ../src/CharClassify.h ../src/Decoration.h ../src/Document.h \
+ ../src/RESearch.h
+DocumentAccessor.o: ../src/DocumentAccessor.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../src/SVector.h \
+ ../include/Accessor.h ../src/DocumentAccessor.h ../src/SplitVector.h \
+ ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \
+ ../include/Scintilla.h ../src/CharClassify.h ../src/Decoration.h \
+ ../src/Document.h
+Editor.o: ../src/Editor.cxx ../include/Platform.h ../include/Scintilla.h \
+ ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \
+ ../src/Partitioning.h ../src/CellBuffer.h ../src/KeyMap.h \
+ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \
+ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \
+ ../src/Decoration.h ../src/Document.h ../src/Editor.h
+ExternalLexer.o: ../src/ExternalLexer.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../include/SciLexer.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/DocumentAccessor.h \
+ ../include/KeyWords.h ../src/ExternalLexer.h
+Indicator.o: ../src/Indicator.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../src/Indicator.h
+KeyMap.o: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintilla.h \
+ ../src/KeyMap.h
+KeyWords.o: ../src/KeyWords.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexAPDL.o: ../src/LexAPDL.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexAU3.o: ../src/LexAU3.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexAVE.o: ../src/LexAVE.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexAda.o: ../src/LexAda.cxx ../include/Platform.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/PropSet.h ../include/SString.h \
+ ../include/KeyWords.h ../include/SciLexer.h
+LexAsm.o: ../src/LexAsm.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexAsn1.o: ../src/LexAsn1.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexBaan.o: ../src/LexBaan.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexBash.o: ../src/LexBash.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../include/KeyWords.h \
+ ../include/Scintilla.h ../include/SciLexer.h
+LexBasic.o: ../src/LexBasic.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexBullant.o: ../src/LexBullant.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexCLW.o: ../src/LexCLW.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexCPP.o: ../src/LexCPP.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexCSS.o: ../src/LexCSS.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexCaml.o: ../src/LexCaml.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexCmake.o: ../src/LexCmake.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexConf.o: ../src/LexConf.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../include/KeyWords.h \
+ ../include/Scintilla.h ../include/SciLexer.h
+LexCrontab.o: ../src/LexCrontab.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexCsound.o: ../src/LexCsound.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexD.o: ../src/LexD.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexEScript.o: ../src/LexEScript.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexEiffel.o: ../src/LexEiffel.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexErlang.o: ../src/LexErlang.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexFlagship.o: ../src/LexFlagship.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexForth.o: ../src/LexForth.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexFortran.o: ../src/LexFortran.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexGAP.o: ../src/LexGAP.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexGui4Cli.o: ../src/LexGui4Cli.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexHTML.o: ../src/LexHTML.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexHaskell.o: ../src/LexHaskell.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexInno.o: ../src/LexInno.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexKix.o: ../src/LexKix.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexLisp.o: ../src/LexLisp.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../include/KeyWords.h \
+ ../include/Scintilla.h ../include/SciLexer.h ../src/StyleContext.h
+LexLout.o: ../src/LexLout.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexLua.o: ../src/LexLua.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexMMIXAL.o: ../src/LexMMIXAL.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexMPT.o: ../src/LexMPT.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../include/KeyWords.h \
+ ../include/Scintilla.h ../include/SciLexer.h
+LexMSSQL.o: ../src/LexMSSQL.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexMatlab.o: ../src/LexMatlab.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexMetapost.o: ../src/LexMetapost.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h \
+ ../src/StyleContext.h
+LexNsis.o: ../src/LexNsis.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../include/KeyWords.h \
+ ../include/Scintilla.h ../include/SciLexer.h
+LexOpal.o: ../src/LexOpal.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../include/KeyWords.h \
+ ../include/Scintilla.h ../include/SciLexer.h ../src/StyleContext.h
+LexOthers.o: ../src/LexOthers.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexPB.o: ../src/LexPB.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexPOV.o: ../src/LexPOV.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexPS.o: ../src/LexPS.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexPascal.o: ../src/LexPascal.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h \
+ ../src/StyleContext.h
+LexPerl.o: ../src/LexPerl.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../include/KeyWords.h \
+ ../include/Scintilla.h ../include/SciLexer.h
+LexPython.o: ../src/LexPython.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexRebol.o: ../src/LexRebol.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h \
+ ../src/StyleContext.h
+LexRuby.o: ../src/LexRuby.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../include/KeyWords.h \
+ ../include/Scintilla.h ../include/SciLexer.h
+LexSQL.o: ../src/LexSQL.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexScriptol.o: ../src/LexScriptol.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexSmalltalk.o: ../src/LexSmalltalk.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexSpecman.o: ../src/LexSpecman.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexSpice.o: ../src/LexSpice.cxx ../include/Platform.h \
+ ../include/Accessor.h ../src/StyleContext.h ../include/PropSet.h \
+ ../include/SString.h ../include/KeyWords.h ../include/SciLexer.h
+LexTADS3.o: ../src/LexTADS3.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexTCL.o: ../src/LexTCL.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexTeX.o: ../src/LexTeX.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../include/KeyWords.h \
+ ../include/Scintilla.h ../include/SciLexer.h ../src/StyleContext.h
+LexVB.o: ../src/LexVB.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexVHDL.o: ../src/LexVHDL.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LexVerilog.o: ../src/LexVerilog.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h ../include/KeyWords.h ../include/Scintilla.h \
+ ../include/SciLexer.h
+LexYAML.o: ../src/LexYAML.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h ../include/Accessor.h ../src/StyleContext.h \
+ ../include/KeyWords.h ../include/Scintilla.h ../include/SciLexer.h
+LineMarker.o: ../src/LineMarker.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../src/XPM.h ../src/LineMarker.h
+PropSet.o: ../src/PropSet.cxx ../include/Platform.h ../include/PropSet.h \
+ ../include/SString.h
+RESearch.o: ../src/RESearch.cxx ../src/CharClassify.h ../src/RESearch.h
+RunStyles.o: ../src/RunStyles.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \
+ ../src/RunStyles.h
+ScintillaBase.o: ../src/ScintillaBase.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../include/PropSet.h ../include/SString.h \
+ ../include/SciLexer.h ../include/Accessor.h ../src/DocumentAccessor.h \
+ ../include/KeyWords.h ../src/ContractionState.h ../src/SVector.h \
+ ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \
+ ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h \
+ ../src/XPM.h ../src/LineMarker.h ../src/Style.h ../src/ViewStyle.h \
+ ../src/AutoComplete.h ../src/CharClassify.h ../src/Decoration.h \
+ ../src/Document.h ../src/Editor.h ../src/ScintillaBase.h
+Style.o: ../src/Style.cxx ../include/Platform.h ../include/Scintilla.h \
+ ../src/Style.h
+StyleContext.o: ../src/StyleContext.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../src/StyleContext.h
+UniConversion.o: ../src/UniConversion.cxx ../src/UniConversion.h
+ViewStyle.o: ../src/ViewStyle.cxx ../include/Platform.h \
+ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \
+ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \
+ ../src/Style.h ../src/ViewStyle.h
+WindowAccessor.o: ../src/WindowAccessor.cxx ../include/Platform.h \
+ ../include/PropSet.h ../include/SString.h ../include/Accessor.h \
+ ../include/WindowAccessor.h ../include/Scintilla.h
+XPM.o: ../src/XPM.cxx ../include/Platform.h ../src/XPM.h
diff --git a/macosx/makefile b/macosx/makefile
new file mode 100644
index 000000000..0ddbb9ccc
--- /dev/null
+++ b/macosx/makefile
@@ -0,0 +1,95 @@
+# Make file for Scintilla on Mac OS X
+# Copyright 2002 by Evan Jones <ejones@uwaterloo.ca>
+# Based on the GTK makefile Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
+# The License.txt file describes the conditions under which this software may be distributed.
+# This makefile assumes that Apple's version of GCC 3.1 is used and changes will be needed to use other compilers.
+# GNU make does not like \r\n line endings so should be saved to CVS in binary form.
+
+.SUFFIXES: .cxx .c .o .h .a
+CC = c++
+CCOMP = gcc
+LIBTOOL = libtool
+
+GCC_MAJOR := $(shell $(CC) -v 2>&1 | \
+ grep version | cut -d' ' -f3 | cut -d'.' -f1)
+
+# We call it "libscintilla" so when you add it to a Project Builder project,
+# Project Builder will link it correctly.
+COMPLIB=../bin/libscintilla.a
+
+vpath %.h ../src ../include
+vpath %.cxx ../src
+
+INCLUDEDIRS=-I ../include -I ../src
+
+ifeq ($(GCC_MAJOR),3)
+# 10.4 will have GCC 4 or better, so this should only ever happen
+# on a 10.3 or older PPC box
+ARCHFLAGS=-arch ppc -faltivec -mcpu=7400 -mtune=7400 -mpowerpc -mpowerpc-gfxopt
+else
+ARCHFLAGS=-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386
+LDFLAGS=/usr/include/Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386
+endif
+
+OPTIONS=-Wall -Wno-missing-braces -Wno-char-subscripts -DSCI_NAMESPACE -DMACOSX -DSCI_LEXER
+
+#DEBUG = 1
+
+ifdef DEBUG
+DFLAGS=-DDEBUG -g
+else
+DFLAGS=-DNDEBUG -Os
+endif
+
+ifdef CONTAINER_HANDLES_EVENTS
+CONTAINER=-DCONTAINER_HANDLES_EVENTS=1
+endif
+
+.cxx.o:
+ $(CC) $(CXXFLAGS) $(OPTIONS) $(DFLAGS) $(CONTAINER) $(ARCHFLAGS) $(INCLUDEDIRS) -c $<
+.c.o:
+ $(CCOMP) $(CXXFLAGS) $(OPTIONS) $(DFLAGS) $(CONTAINER) $(ARCHFLAGS) $(INCLUDEDIRS) -w -c $<
+
+#++Autogenerated -- run src/LexGen.py to regenerate
+#**LEXOBJS=\\\n\(\*.o \)
+LEXOBJS=\
+LexAda.o LexAPDL.o LexAsm.o LexAsn1.o LexAU3.o LexAVE.o LexBaan.o LexBash.o \
+LexBasic.o LexBullant.o LexCaml.o LexCLW.o LexCmake.o LexConf.o LexCPP.o \
+LexCrontab.o LexCsound.o LexCSS.o LexD.o LexEiffel.o LexErlang.o LexEScript.o \
+LexFlagship.o LexForth.o LexFortran.o LexGAP.o LexGui4Cli.o LexHaskell.o \
+LexHTML.o LexInno.o LexKix.o LexLisp.o LexLout.o LexLua.o LexMatlab.o \
+LexMetapost.o LexMMIXAL.o LexMPT.o LexMSSQL.o LexNsis.o LexOpal.o LexOthers.o \
+LexPascal.o LexPB.o LexPerl.o LexPOV.o LexPS.o LexPython.o LexRebol.o \
+LexRuby.o LexScriptol.o LexSmalltalk.o LexSpecman.o LexSpice.o LexSQL.o \
+LexTADS3.o LexTCL.o LexTeX.o LexVB.o LexVerilog.o LexVHDL.o LexYAML.o
+#--Autogenerated -- end of automatically generated section
+
+# The LEXOBJS have to be treated specially as the functions in them are not called from external code
+
+all: $(COMPLIB) $(LEXOBJS)
+
+clean:
+ rm -f *.o $(COMPLIB)
+
+deps:
+ $(CC) -MM $(CXXFLAGS) *.cxx ../src/*.cxx >deps.mak
+
+$(COMPLIB): DocumentAccessor.o WindowAccessor.o KeyWords.o StyleContext.o \
+ CharClassify.o Decoration.o Document.o CallTip.o \
+ ScintillaBase.o ContractionState.o Editor.o ExternalLexer.o PropSet.o PlatMacOSX.o \
+ KeyMap.o LineMarker.o ScintillaMacOSX.o CellBuffer.o ViewStyle.o \
+ RESearch.o RunStyles.o Style.o Indicator.o AutoComplete.o UniConversion.o XPM.o \
+ TCarbonEvent.o TView.o ScintillaCallTip.o \
+ $(LEXOBJS)
+ $(LIBTOOL) -o $@ $^
+
+# Generate header files from Scintilla.iface
+../include/Scintilla_gen.h: ../include/HFacer.py ../include/Face.py ../include/Scintilla.iface
+ cd ../include && python HFacer.py
+../include/SciLexer_gen.h: ../include/HFacer.py ../include/Face.py ../include/Scintilla.iface
+ cd ../include && python HFacer.py
+../include/Scintilla.h: ../include/Scintilla_gen.h
+../include/SciLexer.h: ../include/SciLexer_gen.h
+
+# Automatically generate header dependencies with "make deps"
+include deps.mak
diff --git a/src/AutoComplete.cxx b/src/AutoComplete.cxx
index 753adca77..af6154ea1 100644
--- a/src/AutoComplete.cxx
+++ b/src/AutoComplete.cxx
@@ -14,6 +14,10 @@
#include "PropSet.h"
#include "AutoComplete.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
AutoComplete::AutoComplete() :
active(false),
separator(' '),
diff --git a/src/AutoComplete.h b/src/AutoComplete.h
index 10577ca38..b10cdce82 100644
--- a/src/AutoComplete.h
+++ b/src/AutoComplete.h
@@ -8,6 +8,10 @@
#ifndef AUTOCOMPLETE_H
#define AUTOCOMPLETE_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class AutoComplete {
@@ -67,4 +71,8 @@ public:
void Select(const char *word);
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/CallTip.cxx b/src/CallTip.cxx
index f4bc5f83c..9f5f88476 100644
--- a/src/CallTip.cxx
+++ b/src/CallTip.cxx
@@ -12,6 +12,11 @@
#include "Scintilla.h"
#include "CallTip.h"
+#include <stdio.h>
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static const int insetX = 5; // text inset in x from calltip border
static const int widthArrow = 14;
@@ -29,8 +34,14 @@ CallTip::CallTip() {
tabSize = 0;
useStyleCallTip = false; // for backwards compatibility
+#ifdef __APPLE__
+ // proper apple colours for the default
+ colourBG.desired = ColourDesired(0xff, 0xff, 0xc6);
+ colourUnSel.desired = ColourDesired(0, 0, 0);
+#else
colourBG.desired = ColourDesired(0xff, 0xff, 0xff);
colourUnSel.desired = ColourDesired(0x80, 0x80, 0x80);
+#endif
colourSel.desired = ColourDesired(0, 0, 0x80);
colourShade.desired = ColourDesired(0, 0, 0);
colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
@@ -170,6 +181,7 @@ int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
char *chunkVal = val;
bool moreChunks = true;
int maxWidth = 0;
+
while (moreChunks) {
char *chunkEnd = strchr(chunkVal, '\n');
if (chunkEnd == NULL) {
@@ -217,6 +229,8 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
offsetMain = insetX; // initial alignment assuming no arrows
PaintContents(surfaceWindow, true);
+#ifndef __APPLE__
+ // OSX doesn't put borders on "help tags"
// Draw a raised border around the edges of the window
surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
surfaceWindow->PenColour(colourShade.allocated);
@@ -225,6 +239,7 @@ void CallTip::PaintCT(Surface *surfaceWindow) {
surfaceWindow->PenColour(colourLight.allocated);
surfaceWindow->LineTo(0, 0);
surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
+#endif
}
void CallTip::MouseClick(Point pt) {
diff --git a/src/CallTip.h b/src/CallTip.h
index 9848a10af..bdf1123c7 100644
--- a/src/CallTip.h
+++ b/src/CallTip.h
@@ -8,6 +8,10 @@
#ifndef CALLTIP_H
#define CALLTIP_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class CallTip {
@@ -76,4 +80,8 @@ public:
void SetForeBack(const ColourPair &fore, const ColourPair &back);
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx
index d7c9c86f4..15db9a72a 100644
--- a/src/CellBuffer.cxx
+++ b/src/CellBuffer.cxx
@@ -18,6 +18,10 @@
#include "Partitioning.h"
#include "CellBuffer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
MarkerHandleSet::MarkerHandleSet() {
root = 0;
}
diff --git a/src/CellBuffer.h b/src/CellBuffer.h
index 9cece4854..e790a8196 100644
--- a/src/CellBuffer.h
+++ b/src/CellBuffer.h
@@ -8,6 +8,10 @@
#ifndef CELLBUFFER_H
#define CELLBUFFER_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
* This holds the marker identifier and the marker type to display.
* MarkerHandleNumbers are members of lists.
@@ -228,4 +232,8 @@ public:
void ClearLevels();
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/ContractionState.cxx b/src/ContractionState.cxx
index 49148317c..b44b4e742 100644
--- a/src/ContractionState.cxx
+++ b/src/ContractionState.cxx
@@ -9,6 +9,10 @@
#include "ContractionState.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
OneLine::OneLine() {
displayLine = 0;
//docLine = 0;
diff --git a/src/ContractionState.h b/src/ContractionState.h
index e15ee3bbe..dbee69db7 100644
--- a/src/ContractionState.h
+++ b/src/ContractionState.h
@@ -8,6 +8,10 @@
#ifndef CONTRACTIONSTATE_H
#define CONTRACTIONSTATE_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class OneLine {
@@ -62,4 +66,8 @@ public:
void ShowAll();
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/Decoration.cxx b/src/Decoration.cxx
index 6f19119e1..e4ac0e07c 100644
--- a/src/Decoration.cxx
+++ b/src/Decoration.cxx
@@ -17,6 +17,10 @@
#include "RunStyles.h"
#include "Decoration.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
Decoration::Decoration(int indicator_) : next(0), indicator(indicator_) {
}
diff --git a/src/Decoration.h b/src/Decoration.h
index 9f3473a3d..2809641af 100644
--- a/src/Decoration.h
+++ b/src/Decoration.h
@@ -7,6 +7,10 @@
#ifndef DECORATION_H
#define DECORATION_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
class Decoration {
public:
Decoration *next;
@@ -53,4 +57,8 @@ public:
int End(int indicator, int position);
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/Document.cxx b/src/Document.cxx
index 753d325ef..cfcda92be 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -23,6 +23,10 @@
#include "Document.h"
#include "RESearch.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// This is ASCII specific but is safe with chars >= 0x80
static inline bool isspacechar(unsigned char ch) {
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
diff --git a/src/Document.h b/src/Document.h
index 3659f86a4..b9774efe0 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -8,6 +8,10 @@
#ifndef DOCUMENT_H
#define DOCUMENT_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
* A Position is a position within a document between two characters or at the beginning or end.
* Sometimes used as a character index where it identifies the character after the position.
@@ -305,4 +309,8 @@ public:
virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0;
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/DocumentAccessor.cxx b/src/DocumentAccessor.cxx
index e28264f73..b46eeba85 100644
--- a/src/DocumentAccessor.cxx
+++ b/src/DocumentAccessor.cxx
@@ -25,6 +25,10 @@
#include "Decoration.h"
#include "Document.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
DocumentAccessor::~DocumentAccessor() {
}
diff --git a/src/DocumentAccessor.h b/src/DocumentAccessor.h
index 28f676db3..a3a939d0d 100644
--- a/src/DocumentAccessor.h
+++ b/src/DocumentAccessor.h
@@ -6,6 +6,10 @@
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
class Document;
/**
@@ -66,3 +70,7 @@ public:
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
void IndicatorFill(int start, int end, int indicator, int value);
};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 0147308ad..46684a7fc 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -34,6 +34,10 @@
#include "Document.h"
#include "Editor.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
/*
return whether this modification represents an operation that
may reasonably be deferred (not done now OR [possibly] at all)
@@ -594,6 +598,10 @@ public:
}
};
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
* Allows to iterate through the lines of a selection.
* Althought it can be called for a stream selection, in most cases
@@ -672,6 +680,10 @@ public:
}
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
Point Editor::LocationFromPosition(int pos) {
Point pt;
RefreshStyleData();
@@ -5343,6 +5355,14 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
else
inDragDrop = ddNone;
}
+#ifdef __APPLE__
+ // we need to additionaly check if the mouse moved before we
+ // decide that we can in fact start a drag session. Currently
+ // only OSX will return anything but true.
+ if (inDragDrop == ddInitial && !Platform::WaitMouseMoved(pt)) {
+ inDragDrop = ddNone;
+ }
+#endif
SetMouseCapture(true);
if (inDragDrop != ddInitial) {
SetDragPosition(invalidPosition);
diff --git a/src/Editor.h b/src/Editor.h
index 0ce6f27fb..a31777611 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -8,6 +8,10 @@
#ifndef EDITOR_H
#define EDITOR_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class Caret {
@@ -585,4 +589,8 @@ public:
}
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/ExternalLexer.cxx b/src/ExternalLexer.cxx
index acf45bc2d..0344debd7 100644
--- a/src/ExternalLexer.cxx
+++ b/src/ExternalLexer.cxx
@@ -21,6 +21,10 @@
#include "KeyWords.h"
#include "ExternalLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
LexerManager *LexerManager::theInstance = NULL;
//------------------------------------------
diff --git a/src/ExternalLexer.h b/src/ExternalLexer.h
index 23ee0412b..55e127b40 100644
--- a/src/ExternalLexer.h
+++ b/src/ExternalLexer.h
@@ -14,6 +14,10 @@
#define EXT_LEXER_DECL
#endif
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
// External Lexer function definitions...
typedef void (EXT_LEXER_DECL *ExtLexerFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
char *words[], WindowID window, char *props);
@@ -92,4 +96,8 @@ public:
~LMMinder();
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/Indicator.cxx b/src/Indicator.cxx
index 7624a4a52..139e2b0ea 100644
--- a/src/Indicator.cxx
+++ b/src/Indicator.cxx
@@ -10,6 +10,10 @@
#include "Scintilla.h"
#include "Indicator.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine) {
surface->PenColour(fore.allocated);
int ymid = (rc.bottom + rc.top) / 2;
diff --git a/src/Indicator.h b/src/Indicator.h
index cebc22d80..2081db544 100644
--- a/src/Indicator.h
+++ b/src/Indicator.h
@@ -8,6 +8,10 @@
#ifndef INDICATOR_H
#define INDICATOR_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class Indicator {
@@ -20,4 +24,8 @@ public:
void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/KeyMap.cxx b/src/KeyMap.cxx
index bfa6e2d78..c223d5b59 100644
--- a/src/KeyMap.cxx
+++ b/src/KeyMap.cxx
@@ -11,6 +11,10 @@
#include "KeyMap.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
KeyMap::KeyMap() : kmap(0), len(0), alloc(0) {
for (int i = 0; MapDefault[i].key; i++) {
AssignCmdKey(MapDefault[i].key,
diff --git a/src/KeyMap.h b/src/KeyMap.h
index 364df684f..fd9005de8 100644
--- a/src/KeyMap.h
+++ b/src/KeyMap.h
@@ -8,6 +8,10 @@
#ifndef KEYTOCOMMAND_H
#define KEYTOCOMMAND_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
#define SCI_NORM 0
#define SCI_SHIFT SCMOD_SHIFT
#define SCI_CTRL SCMOD_CTRL
@@ -40,4 +44,8 @@ public:
unsigned int Find(int key, int modifiers); // 0 returned on failure
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/KeyWords.cxx b/src/KeyWords.cxx
index 273b04779..9c65b81d2 100644
--- a/src/KeyWords.cxx
+++ b/src/KeyWords.cxx
@@ -19,6 +19,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
const LexerModule *LexerModule::base = 0;
int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
diff --git a/src/LexAPDL.cxx b/src/LexAPDL.cxx
index 1cf263e50..ba6a77ca6 100644
--- a/src/LexAPDL.cxx
+++ b/src/LexAPDL.cxx
@@ -21,6 +21,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80 && (isalnum(ch) || ch == '_'));
diff --git a/src/LexAU3.cxx b/src/LexAU3.cxx
index 1a260d337..ffd9f71fa 100644
--- a/src/LexAU3.cxx
+++ b/src/LexAU3.cxx
@@ -63,6 +63,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool IsTypeCharacter(const int ch)
{
return ch == '$';
diff --git a/src/LexAVE.cxx b/src/LexAVE.cxx
index e30ee7dc9..2b7029b1a 100644
--- a/src/LexAVE.cxx
+++ b/src/LexAVE.cxx
@@ -22,6 +22,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static inline bool IsAWordChar(const int ch) {
diff --git a/src/LexAda.cxx b/src/LexAda.cxx
index 0227ce110..f6c9e7ee7 100644
--- a/src/LexAda.cxx
+++ b/src/LexAda.cxx
@@ -19,6 +19,10 @@
#include "SciLexer.h"
#include "SString.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
/*
* Interface
*/
diff --git a/src/LexAsm.cxx b/src/LexAsm.cxx
index 93e0b3718..9dd4df456 100644
--- a/src/LexAsm.cxx
+++ b/src/LexAsm.cxx
@@ -23,6 +23,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
diff --git a/src/LexAsn1.cxx b/src/LexAsn1.cxx
index 1600e6329..36f1d5dc2 100644
--- a/src/LexAsn1.cxx
+++ b/src/LexAsn1.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Some char test functions
static bool isAsn1Number(int ch)
{
diff --git a/src/LexBaan.cxx b/src/LexBaan.cxx
index 3a36eb8f2..a6847db71 100644
--- a/src/LexBaan.cxx
+++ b/src/LexBaan.cxx
@@ -21,6 +21,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$' || ch == ':');
}
diff --git a/src/LexBash.cxx b/src/LexBash.cxx
index 242985a96..269192500 100644
--- a/src/LexBash.cxx
+++ b/src/LexBash.cxx
@@ -28,6 +28,10 @@
#define HERE_DELIM_MAX 256
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline int translateBashDigit(char ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
diff --git a/src/LexBasic.cxx b/src/LexBasic.cxx
index 79ba2b891..1c5d7b425 100644
--- a/src/LexBasic.cxx
+++ b/src/LexBasic.cxx
@@ -31,6 +31,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
/* Bits:
* 1 - whitespace
* 2 - operator
diff --git a/src/LexBullant.cxx b/src/LexBullant.cxx
index 902f89c1e..cc60cd2fc 100644
--- a/src/LexBullant.cxx
+++ b/src/LexBullant.cxx
@@ -15,6 +15,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100];
diff --git a/src/LexCLW.cxx b/src/LexCLW.cxx
index e28e4b13b..624ef0f2b 100644
--- a/src/LexCLW.cxx
+++ b/src/LexCLW.cxx
@@ -21,6 +21,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Is an end of line character
inline bool IsEOL(const int ch) {
diff --git a/src/LexCPP.cxx b/src/LexCPP.cxx
index 51f32430b..bc3177cb3 100644
--- a/src/LexCPP.cxx
+++ b/src/LexCPP.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
#define SET_LOWER "abcdefghijklmnopqrstuvwxyz"
#define SET_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define SET_DIGITS "0123456789"
diff --git a/src/LexCSS.cxx b/src/LexCSS.cxx
index 963a7b3ef..f5c112d6f 100644
--- a/src/LexCSS.cxx
+++ b/src/LexCSS.cxx
@@ -22,6 +22,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool IsAWordChar(const unsigned int ch) {
return (isalnum(ch) || ch == '-' || ch == '_' || ch >= 161); // _ is not in fact correct CSS word-character
diff --git a/src/LexCaml.cxx b/src/LexCaml.cxx
index 5f4fad5fb..539eee0de 100644
--- a/src/LexCaml.cxx
+++ b/src/LexCaml.cxx
@@ -42,6 +42,10 @@ static const int baseT[24] = {
0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */
};
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
#ifdef BUILD_AS_EXTERNAL_LEXER
/*
(actually seems to work!)
diff --git a/src/LexCmake.cxx b/src/LexCmake.cxx
index 3d5ee7581..f63eb399f 100644
--- a/src/LexCmake.cxx
+++ b/src/LexCmake.cxx
@@ -19,6 +19,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static bool isCmakeNumber(char ch)
{
diff --git a/src/LexConf.cxx b/src/LexConf.cxx
index c33cdb5ce..969275f92 100644
--- a/src/LexConf.cxx
+++ b/src/LexConf.cxx
@@ -23,6 +23,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
{
int state = SCE_CONF_DEFAULT;
diff --git a/src/LexCrontab.cxx b/src/LexCrontab.cxx
index d139bb4f1..62044c370 100644
--- a/src/LexCrontab.cxx
+++ b/src/LexCrontab.cxx
@@ -21,6 +21,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordList
*keywordLists[], Accessor &styler)
{
diff --git a/src/LexCsound.cxx b/src/LexCsound.cxx
index 27f7b990a..4162c9b3a 100644
--- a/src/LexCsound.cxx
+++ b/src/LexCsound.cxx
@@ -20,6 +20,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
diff --git a/src/LexD.cxx b/src/LexD.cxx
index 9103d25e7..95be129d5 100644
--- a/src/LexD.cxx
+++ b/src/LexD.cxx
@@ -21,6 +21,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
/*/ Nested comments require keeping the value of the nesting level for every
position in the document. But since scintilla always styles line by line,
we only need to store one value per line. The non-negative number indicates
diff --git a/src/LexEScript.cxx b/src/LexEScript.cxx
index 49411588a..295aaec53 100644
--- a/src/LexEScript.cxx
+++ b/src/LexEScript.cxx
@@ -19,6 +19,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static inline bool IsAWordChar(const int ch) {
diff --git a/src/LexEiffel.cxx b/src/LexEiffel.cxx
index 4aed7c6af..03dea5e73 100644
--- a/src/LexEiffel.cxx
+++ b/src/LexEiffel.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool isEiffelOperator(unsigned int ch) {
// '.' left out as it is used to make up numbers
return ch == '*' || ch == '/' || ch == '\\' || ch == '-' || ch == '+' ||
diff --git a/src/LexErlang.cxx b/src/LexErlang.cxx
index 9444eb950..809dcefe9 100644
--- a/src/LexErlang.cxx
+++ b/src/LexErlang.cxx
@@ -21,6 +21,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
/*
TODO:
o _Param should be a new lexical type
diff --git a/src/LexFlagship.cxx b/src/LexFlagship.cxx
index db0314eb9..baf2941a8 100644
--- a/src/LexFlagship.cxx
+++ b/src/LexFlagship.cxx
@@ -22,6 +22,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static bool IsFlagShipComment(Accessor &styler, int pos, int len) {
return len>0 && styler[pos]=='\'';
}
diff --git a/src/LexForth.cxx b/src/LexForth.cxx
index 3f128156d..f097b0e00 100644
--- a/src/LexForth.cxx
+++ b/src/LexForth.cxx
@@ -21,6 +21,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
bool is_whitespace(int ch){
return ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ';
}
diff --git a/src/LexFortran.cxx b/src/LexFortran.cxx
index 3ab1116ea..c68c5b62f 100644
--- a/src/LexFortran.cxx
+++ b/src/LexFortran.cxx
@@ -19,6 +19,11 @@
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
/***********************************************/
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
diff --git a/src/LexGAP.cxx b/src/LexGAP.cxx
index 6878ab76b..25bd33b90 100644
--- a/src/LexGAP.cxx
+++ b/src/LexGAP.cxx
@@ -21,6 +21,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static inline bool IsGAPOperator(char ch) {
if (isalnum(ch)) return false;
diff --git a/src/LexGen.py b/src/LexGen.py
index c4164b78a..26fb3a030 100644
--- a/src/LexGen.py
+++ b/src/LexGen.py
@@ -211,16 +211,17 @@ def RegenerateAll():
# Find all the SciTE properties files
otherProps = ["abbrev.properties", "Embedded.properties", "SciTEGlobal.properties", "SciTE.properties"]
- propFilePaths = glob.glob(root + "scite/src/*.properties")
- propFiles = [os.path.basename(f) for f in propFilePaths if os.path.basename(f) not in otherProps]
- propFiles.sort(ciCompare)
- print propFiles
-
- # Find all the menu command IDs in the SciTE header
- SciTEHeader = file(root + "scite/src/SciTE.h")
- lines = SciTEHeader.read().split("\n")
- SciTEHeader.close()
- ids = [id for id in [l.split()[1] for l in lines if l.startswith("#define")] if id.startswith("IDM_")]
+ if os.path.exists(root + "scite"):
+ propFilePaths = glob.glob(root + "scite/src/*.properties")
+ propFiles = [os.path.basename(f) for f in propFilePaths if os.path.basename(f) not in otherProps]
+ propFiles.sort(ciCompare)
+ print propFiles
+
+ # Find all the menu command IDs in the SciTE header
+ SciTEHeader = file(root + "scite/src/SciTE.h")
+ lines = SciTEHeader.read().split("\n")
+ SciTEHeader.close()
+ ids = [id for id in [l.split()[1] for l in lines if l.startswith("#define")] if id.startswith("IDM_")]
#print ids
Regenerate(root + "scintilla/src/KeyWords.cxx", "//", NATIVE, lexerModules)
@@ -232,10 +233,12 @@ def RegenerateAll():
# Windows).
Regenerate(root + "scintilla/gtk/makefile", "#", LF, lexFiles)
Regenerate(root + "scintilla/gtk/scintilla.mak", "#", NATIVE, lexFiles)
- Regenerate(root + "scite/win32/makefile", "#", NATIVE, lexFiles, propFiles)
- Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, lexFiles, propFiles)
- Regenerate(root + "scite/src/SciTEProps.cxx", "//", NATIVE, lexerProperties, ids)
- Generate(root + "scite/boundscheck/vcproj.gen",
+ Regenerate(root + "scintilla/macosx/makefile", "#", LF, lexFiles)
+ if os.path.exists(root + "scite"):
+ Regenerate(root + "scite/win32/makefile", "#", NATIVE, lexFiles, propFiles)
+ Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, lexFiles, propFiles)
+ Regenerate(root + "scite/src/SciTEProps.cxx", "//", NATIVE, lexerProperties, ids)
+ Generate(root + "scite/boundscheck/vcproj.gen",
root + "scite/boundscheck/SciTE.vcproj", "#", NATIVE, lexFiles)
RegenerateAll()
diff --git a/src/LexGui4Cli.cxx b/src/LexGui4Cli.cxx
index f76fff6cc..1c92de72e 100644
--- a/src/LexGui4Cli.cxx
+++ b/src/LexGui4Cli.cxx
@@ -36,6 +36,10 @@ val SCE_GC_OPERATOR=9
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
#define debug Platform::DebugPrintf
static inline bool IsAWordChar(const int ch) {
diff --git a/src/LexHTML.cxx b/src/LexHTML.cxx
index a816ea188..877f0881a 100644
--- a/src/LexHTML.cxx
+++ b/src/LexHTML.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
#define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START)
#define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
#define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
diff --git a/src/LexHaskell.cxx b/src/LexHaskell.cxx
index 0e4be85c6..da4349245 100644
--- a/src/LexHaskell.cxx
+++ b/src/LexHaskell.cxx
@@ -31,6 +31,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
#ifdef BUILD_AS_EXTERNAL_LEXER
#include "ExternalLexer.h"
diff --git a/src/LexInno.cxx b/src/LexInno.cxx
index 5985df23d..538175096 100644
--- a/src/LexInno.cxx
+++ b/src/LexInno.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {
int state = SCE_INNO_DEFAULT;
char chPrev;
diff --git a/src/LexKix.cxx b/src/LexKix.cxx
index e439d4d1d..06e7c1791 100644
--- a/src/LexKix.cxx
+++ b/src/LexKix.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
return ch >= 0x80 || isalnum(ch) || ch == '_';
diff --git a/src/LexLisp.cxx b/src/LexLisp.cxx
index 91385f0fd..1072e13a3 100644
--- a/src/LexLisp.cxx
+++ b/src/LexLisp.cxx
@@ -21,6 +21,10 @@
#include "SciLexer.h"
#include "StyleContext.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
#define SCE_LISP_CHARACTER 29
#define SCE_LISP_MACRO 30
#define SCE_LISP_MACRO_DISPATCH 31
diff --git a/src/LexLout.cxx b/src/LexLout.cxx
index 9d1a45a02..492e4ed6d 100644
--- a/src/LexLout.cxx
+++ b/src/LexLout.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');
}
diff --git a/src/LexLua.cxx b/src/LexLua.cxx
index 6dfa8ee1a..63114a976 100644
--- a/src/LexLua.cxx
+++ b/src/LexLua.cxx
@@ -22,6 +22,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
return ch >= 0x80 ||
diff --git a/src/LexMMIXAL.cxx b/src/LexMMIXAL.cxx
index f44789989..a00f35ca0 100644
--- a/src/LexMMIXAL.cxx
+++ b/src/LexMMIXAL.cxx
@@ -22,6 +22,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static inline bool IsAWordChar(const int ch) {
diff --git a/src/LexMPT.cxx b/src/LexMPT.cxx
index 1058b9b49..93b8caba7 100644
--- a/src/LexMPT.cxx
+++ b/src/LexMPT.cxx
@@ -20,6 +20,10 @@
#include "SciLexer.h"
#include "SString.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static int GetLotLineState(SString &line) {
if (line.length()) {
// Most of the time the first non-blank character in line determines that line's type
diff --git a/src/LexMSSQL.cxx b/src/LexMSSQL.cxx
index 5f5a562ad..4a3f3bed8 100644
--- a/src/LexMSSQL.cxx
+++ b/src/LexMSSQL.cxx
@@ -19,6 +19,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
#define KW_MSSQL_STATEMENTS 0
#define KW_MSSQL_DATA_TYPES 1
#define KW_MSSQL_SYSTEM_TABLES 2
diff --git a/src/LexMatlab.cxx b/src/LexMatlab.cxx
index 626001cd3..9652a6f60 100644
--- a/src/LexMatlab.cxx
+++ b/src/LexMatlab.cxx
@@ -25,6 +25,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static bool IsMatlabCommentChar(int c) {
return (c == '%') ;
diff --git a/src/LexMetapost.cxx b/src/LexMetapost.cxx
index b7d482c0f..f3fe77d0d 100644
--- a/src/LexMetapost.cxx
+++ b/src/LexMetapost.cxx
@@ -25,6 +25,10 @@
#include "SciLexer.h"
#include "StyleContext.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// val SCE_METAPOST_DEFAULT = 0
// val SCE_METAPOST_SPECIAL = 1
// val SCE_METAPOST_GROUP = 2
diff --git a/src/LexNsis.cxx b/src/LexNsis.cxx
index b26cf6b3f..93f0cd4d6 100644
--- a/src/LexNsis.cxx
+++ b/src/LexNsis.cxx
@@ -19,6 +19,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
/*
// located in SciLexer.h
#define SCLEX_NSIS 43
diff --git a/src/LexOpal.cxx b/src/LexOpal.cxx
index d1d188998..221f95597 100644
--- a/src/LexOpal.cxx
+++ b/src/LexOpal.cxx
@@ -19,6 +19,10 @@
#include "SciLexer.h"
#include "StyleContext.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
inline static void getRange( unsigned int start, unsigned int end, Accessor & styler, char * s, unsigned int len )
{
unsigned int i = 0;
diff --git a/src/LexOthers.cxx b/src/LexOthers.cxx
index 1f544497a..c4aca0c08 100644
--- a/src/LexOthers.cxx
+++ b/src/LexOthers.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static bool Is0To9(char ch) {
return (ch >= '0') && (ch <= '9');
}
diff --git a/src/LexPB.cxx b/src/LexPB.cxx
index 7878a6bf8..abc0ddc79 100644
--- a/src/LexPB.cxx
+++ b/src/LexPB.cxx
@@ -48,6 +48,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool IsTypeCharacter(const int ch)
{
return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$' || ch == '?';
diff --git a/src/LexPOV.cxx b/src/LexPOV.cxx
index 5cc05ce6a..b845b2d47 100644
--- a/src/LexPOV.cxx
+++ b/src/LexPOV.cxx
@@ -29,6 +29,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool IsAWordChar(int ch) {
return ch < 0x80 && (isalnum(ch) || ch == '_');
}
diff --git a/src/LexPS.cxx b/src/LexPS.cxx
index 3c75ae554..ff4521769 100644
--- a/src/LexPS.cxx
+++ b/src/LexPS.cxx
@@ -21,6 +21,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool IsASelfDelimitingChar(const int ch) {
return (ch == '[' || ch == ']' || ch == '{' || ch == '}' ||
ch == '/' || ch == '<' || ch == '>' ||
diff --git a/src/LexPascal.cxx b/src/LexPascal.cxx
index fdd12c470..0e4576064 100644
--- a/src/LexPascal.cxx
+++ b/src/LexPascal.cxx
@@ -21,6 +21,10 @@
#include "SciLexer.h"
#include "StyleContext.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static void getRange(unsigned int start,
unsigned int end,
Accessor &styler,
diff --git a/src/LexPerl.cxx b/src/LexPerl.cxx
index 4a42bc29f..bcc74d972 100644
--- a/src/LexPerl.cxx
+++ b/src/LexPerl.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
#define PERLNUM_BINARY 1 // order is significant: 1-4 cannot have a dot
#define PERLNUM_HEX 2
#define PERLNUM_OCTAL 3
diff --git a/src/LexPython.cxx b/src/LexPython.cxx
index 8c924a0e8..85fe7d658 100644
--- a/src/LexPython.cxx
+++ b/src/LexPython.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
enum kwType { kwOther, kwClass, kwDef, kwImport };
static const int indicatorWhitespace = 1;
diff --git a/src/LexRebol.cxx b/src/LexRebol.cxx
index f829c1e36..7139b8dbd 100644
--- a/src/LexRebol.cxx
+++ b/src/LexRebol.cxx
@@ -26,6 +26,9 @@
#include "SciLexer.h"
#include "StyleContext.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static inline bool IsAWordChar(const int ch) {
return (isalnum(ch) || ch == '?' || ch == '!' || ch == '.' || ch == '\'' || ch == '+' || ch == '-' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
diff --git a/src/LexSQL.cxx b/src/LexSQL.cxx
index d8e14b9eb..98ccdca8d 100644
--- a/src/LexSQL.cxx
+++ b/src/LexSQL.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool IsAWordChar(int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}
diff --git a/src/LexScriptol.cxx b/src/LexScriptol.cxx
index faaa2d46d..76c38e6b6 100644
--- a/src/LexScriptol.cxx
+++ b/src/LexScriptol.cxx
@@ -17,6 +17,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord)
{
char s[100];
diff --git a/src/LexSmalltalk.cxx b/src/LexSmalltalk.cxx
index 6f43ec3b3..265de3803 100644
--- a/src/LexSmalltalk.cxx
+++ b/src/LexSmalltalk.cxx
@@ -19,6 +19,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
/*
| lexTable classificationBlock charClasses |
charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).
diff --git a/src/LexSpecman.cxx b/src/LexSpecman.cxx
index bf5d639a1..093efae75 100644
--- a/src/LexSpecman.cxx
+++ b/src/LexSpecman.cxx
@@ -21,6 +21,9 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
diff --git a/src/LexSpice.cxx b/src/LexSpice.cxx
index 8a1683f05..b2953c001 100644
--- a/src/LexSpice.cxx
+++ b/src/LexSpice.cxx
@@ -19,6 +19,10 @@
#include "SciLexer.h"
#include "SString.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
/*
* Interface
*/
diff --git a/src/LexTADS3.cxx b/src/LexTADS3.cxx
index c9b1d2571..71f2919e7 100644
--- a/src/LexTADS3.cxx
+++ b/src/LexTADS3.cxx
@@ -46,6 +46,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static const int T3_SINGLE_QUOTE = 1;
static const int T3_INT_EXPRESSION = 2;
static const int T3_INT_EXPRESSION_IN_TAG = 4;
diff --git a/src/LexTCL.cxx b/src/LexTCL.cxx
index c78214116..3c175de2a 100644
--- a/src/LexTCL.cxx
+++ b/src/LexTCL.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
return ch >= 0x80 ||
diff --git a/src/LexTeX.cxx b/src/LexTeX.cxx
index 65e530adb..55f0d3405 100644
--- a/src/LexTeX.cxx
+++ b/src/LexTeX.cxx
@@ -27,6 +27,10 @@
#include "SciLexer.h"
#include "StyleContext.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// val SCE_TEX_DEFAULT = 0
// val SCE_TEX_SPECIAL = 1
// val SCE_TEX_GROUP = 2
diff --git a/src/LexVB.cxx b/src/LexVB.cxx
index 0a6a5e4ca..a1f9ec7ae 100644
--- a/src/LexVB.cxx
+++ b/src/LexVB.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Internal state, highlighted as number
#define SCE_B_FILENUMBER SCE_B_DEFAULT+100
diff --git a/src/LexVHDL.cxx b/src/LexVHDL.cxx
index 0feef9512..c082cdb92 100644
--- a/src/LexVHDL.cxx
+++ b/src/LexVHDL.cxx
@@ -25,6 +25,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static void ColouriseVHDLDoc(
unsigned int startPos,
int length,
diff --git a/src/LexVerilog.cxx b/src/LexVerilog.cxx
index 43ef7eb37..165537346 100644
--- a/src/LexVerilog.cxx
+++ b/src/LexVerilog.cxx
@@ -21,6 +21,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
}
diff --git a/src/LexYAML.cxx b/src/LexYAML.cxx
index e3053f814..0edd78691 100644
--- a/src/LexYAML.cxx
+++ b/src/LexYAML.cxx
@@ -20,6 +20,10 @@
#include "Scintilla.h"
#include "SciLexer.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static const char * const yamlWordListDesc[] = {
"Keywords",
0
diff --git a/src/LineMarker.cxx b/src/LineMarker.cxx
index 6ded13c73..ab0511654 100644
--- a/src/LineMarker.cxx
+++ b/src/LineMarker.cxx
@@ -13,6 +13,10 @@
#include "XPM.h"
#include "LineMarker.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(fore, want);
pal.WantFind(back, want);
diff --git a/src/LineMarker.h b/src/LineMarker.h
index 8ebdce491..3cb4139f0 100644
--- a/src/LineMarker.h
+++ b/src/LineMarker.h
@@ -8,6 +8,10 @@
#ifndef LINEMARKER_H
#define LINEMARKER_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class LineMarker {
@@ -51,4 +55,8 @@ public:
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter);
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/PropSet.cxx b/src/PropSet.cxx
index 26b6afa4b..3b142b978 100644
--- a/src/PropSet.cxx
+++ b/src/PropSet.cxx
@@ -15,6 +15,10 @@
#include "PropSet.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// The comparison and case changing functions here assume ASCII
// or extended ASCII such as the normal Windows code page.
diff --git a/src/RESearch.cxx b/src/RESearch.cxx
index 6dc5941bb..b1b226a05 100644
--- a/src/RESearch.cxx
+++ b/src/RESearch.cxx
@@ -206,6 +206,10 @@
#pragma warning(disable: 4514)
#endif
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
#define OKP 1
#define NOP 0
diff --git a/src/RESearch.h b/src/RESearch.h
index befd36790..0944fc398 100644
--- a/src/RESearch.h
+++ b/src/RESearch.h
@@ -9,6 +9,10 @@
#ifndef RESEARCH_H
#define RESEARCH_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/*
* The following defines are not meant to be changeable.
* They are for readability only.
@@ -63,5 +67,9 @@ private:
}
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/RunStyles.cxx b/src/RunStyles.cxx
index da7cba2f9..286734e9b 100644
--- a/src/RunStyles.cxx
+++ b/src/RunStyles.cxx
@@ -16,6 +16,10 @@
#include "Partitioning.h"
#include "RunStyles.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Find the first run at a position
int RunStyles::RunFromPosition(int position) {
int run = starts->PartitionFromPosition(position);
diff --git a/src/RunStyles.h b/src/RunStyles.h
index 009bb6739..f3f9fe314 100644
--- a/src/RunStyles.h
+++ b/src/RunStyles.h
@@ -7,6 +7,10 @@
/// Styling buffer using one element for each run rather than using
/// a filled buffer.
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
class RunStyles {
public:
Partitioning *starts;
@@ -30,3 +34,7 @@ public:
void DeleteAll();
void DeleteRange(int position, int deleteLength);
};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
diff --git a/src/SVector.h b/src/SVector.h
index c8edb513b..9f56da528 100644
--- a/src/SVector.h
+++ b/src/SVector.h
@@ -8,6 +8,10 @@
#ifndef SVECTOR_H
#define SVECTOR_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
* A simple expandable integer vector.
* Storage not allocated for elements until an element is used.
@@ -124,4 +128,8 @@ public:
}
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx
index 52a0e2c2c..e0ac652fb 100644
--- a/src/ScintillaBase.cxx
+++ b/src/ScintillaBase.cxx
@@ -40,6 +40,10 @@
#include "Editor.h"
#include "ScintillaBase.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
ScintillaBase::ScintillaBase() {
displayPopupMenu = true;
listType = 0;
diff --git a/src/ScintillaBase.h b/src/ScintillaBase.h
index cb85b55b5..0554d9457 100644
--- a/src/ScintillaBase.h
+++ b/src/ScintillaBase.h
@@ -8,6 +8,10 @@
#ifndef SCINTILLABASE_H
#define SCINTILLABASE_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class ScintillaBase : public Editor {
@@ -90,4 +94,8 @@ public:
virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/Style.cxx b/src/Style.cxx
index f01aee082..ad081a66d 100644
--- a/src/Style.cxx
+++ b/src/Style.cxx
@@ -12,6 +12,10 @@
#include "Scintilla.h"
#include "Style.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
Style::Style() {
aliasOfDefaultFont = true;
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
diff --git a/src/Style.h b/src/Style.h
index c0f7eca26..1caecaee7 100644
--- a/src/Style.h
+++ b/src/Style.h
@@ -8,6 +8,10 @@
#ifndef STYLE_H
#define STYLE_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class Style {
@@ -53,4 +57,8 @@ public:
bool IsProtected() const { return !(changeable && visible);};
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/StyleContext.cxx b/src/StyleContext.cxx
index d9da0edc4..4a1f71622 100644
--- a/src/StyleContext.cxx
+++ b/src/StyleContext.cxx
@@ -16,6 +16,10 @@
#include "Accessor.h"
#include "StyleContext.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static void getRange(unsigned int start,
unsigned int end,
Accessor &styler,
diff --git a/src/StyleContext.h b/src/StyleContext.h
index a670867ce..463aab462 100644
--- a/src/StyleContext.h
+++ b/src/StyleContext.h
@@ -5,6 +5,10 @@
// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
// This file is in the public domain.
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
// All languages handled so far can treat all characters >= 0x80 as one class
// which just continues the current token or starts an identifier if in default.
// DBCS treated specially as the second character can be < 0x80 and hence
@@ -148,6 +152,10 @@ public:
void GetCurrentLowered(char *s, unsigned int len);
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
inline bool IsASpace(unsigned int ch) {
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
}
diff --git a/src/ViewStyle.cxx b/src/ViewStyle.cxx
index 071171e68..8f51fd5b9 100644
--- a/src/ViewStyle.cxx
+++ b/src/ViewStyle.cxx
@@ -19,6 +19,10 @@
#include "Style.h"
#include "ViewStyle.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
MarginStyle::MarginStyle() :
style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false) {
}
diff --git a/src/ViewStyle.h b/src/ViewStyle.h
index 61ebe85ee..39adf81e8 100644
--- a/src/ViewStyle.h
+++ b/src/ViewStyle.h
@@ -8,6 +8,10 @@
#ifndef VIEWSTYLE_H
#define VIEWSTYLE_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
*/
class MarginStyle {
@@ -108,4 +112,8 @@ public:
bool ProtectionActive() const;
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif
diff --git a/src/WindowAccessor.cxx b/src/WindowAccessor.cxx
index 8132b584e..8093300bc 100644
--- a/src/WindowAccessor.cxx
+++ b/src/WindowAccessor.cxx
@@ -17,6 +17,10 @@
#include "WindowAccessor.h"
#include "Scintilla.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
WindowAccessor::~WindowAccessor() {
}
diff --git a/src/XPM.cxx b/src/XPM.cxx
index 36e7994f4..7fc05bb9b 100644
--- a/src/XPM.cxx
+++ b/src/XPM.cxx
@@ -12,6 +12,10 @@
#include "XPM.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
static const char *NextField(const char *s) {
// In case there are leading spaces in the string
while (*s && *s == ' ') {
diff --git a/src/XPM.h b/src/XPM.h
index 4d3da28d3..0ee68c072 100644
--- a/src/XPM.h
+++ b/src/XPM.h
@@ -8,6 +8,10 @@
#ifndef XPM_H
#define XPM_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
/**
* Hold a pixmap in XPM format.
*/
@@ -69,4 +73,8 @@ public:
int GetWidth();
};
+#ifdef SCI_NAMESPACE
+}
+#endif
+
#endif