1 // Scintilla source code edit control
2 // ScintillaGTK.h - GTK+ specific subclass of ScintillaBase
3 // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
4 // The License.txt file describes the conditions under which this software may be distributed.
13 class ScintillaGTKAccessible
;
15 #define OBJECT_CLASS GObjectClass
17 class ScintillaGTK
: public ScintillaBase
{
18 friend class ScintillaGTKAccessible
;
20 _ScintillaObject
*sci
;
24 GtkAdjustment
*adjustmentv
;
25 GtkAdjustment
*adjustmenth
;
26 int verticalScrollBarWidth
;
27 int horizontalScrollBarHeight
;
29 SelectionText primary
;
31 GdkEventButton
*evbtn
;
35 int rectangularSelectionModifier
;
37 GtkWidgetClass
*parentClass
;
39 static GdkAtom atomClipboard
;
40 static GdkAtom atomUTF8
;
41 static GdkAtom atomString
;
42 static GdkAtom atomUriList
;
43 static GdkAtom atomDROPFILES_DND
;
47 CLIPFORMAT cfColumnSelect
;
52 GtkIMContext
*im_context
;
53 PangoScript lastNonCommonScript
;
55 // Wheel mouse support
56 unsigned int linesPerScroll
;
57 GTimeVal lastWheelMouseTime
;
58 gint lastWheelMouseDirection
;
59 gint wheelMouseIntensity
;
61 #if GTK_CHECK_VERSION(3,0,0)
62 cairo_rectangle_list_t
*rgnUpdate
;
66 bool repaintFullWindow
;
69 AtkObject
*accessible
;
71 // Private so ScintillaGTK objects can not be copied
72 ScintillaGTK(const ScintillaGTK
&);
73 ScintillaGTK
&operator=(const ScintillaGTK
&);
76 explicit ScintillaGTK(_ScintillaObject
*sci_
);
77 virtual ~ScintillaGTK();
78 static ScintillaGTK
*FromWidget(GtkWidget
*widget
);
79 static void ClassInit(OBJECT_CLASS
* object_class
, GtkWidgetClass
*widget_class
, GtkContainerClass
*container_class
);
81 virtual void Initialise();
82 virtual void Finalise();
83 virtual bool AbandonPaint();
84 virtual void DisplayCursor(Window::Cursor c
);
85 virtual bool DragThreshold(Point ptStart
, Point ptNow
);
86 virtual void StartDrag();
87 int TargetAsUTF8(char *text
);
88 int EncodedFromUTF8(char *utf8
, char *encoded
) const;
89 virtual bool ValidCodePage(int codePage
) const;
90 public: // Public for scintilla_send_message
91 virtual sptr_t
WndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
93 virtual sptr_t
DefWndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
96 ScintillaGTK
*scintilla
;
98 TimeThunk() : reason(tickCaret
), scintilla(NULL
), timer(0) {}
100 TimeThunk timers
[tickDwell
+1];
101 virtual bool FineTickerAvailable();
102 virtual bool FineTickerRunning(TickReason reason
);
103 virtual void FineTickerStart(TickReason reason
, int millis
, int tolerance
);
104 virtual void FineTickerCancel(TickReason reason
);
105 virtual bool SetIdle(bool on
);
106 virtual void SetMouseCapture(bool on
);
107 virtual bool HaveMouseCapture();
108 virtual bool PaintContains(PRectangle rc
);
110 virtual PRectangle
GetClientRectangle() const;
111 virtual void ScrollText(int linesToMove
);
112 virtual void SetVerticalScrollPos();
113 virtual void SetHorizontalScrollPos();
114 virtual bool ModifyScrollBars(int nMax
, int nPage
);
115 void ReconfigureScrollBars();
116 virtual void NotifyChange();
117 virtual void NotifyFocus(bool focus
);
118 virtual void NotifyParent(SCNotification scn
);
119 void NotifyKey(int key
, int modifiers
);
120 void NotifyURIDropped(const char *list
);
121 const char *CharacterSetID() const;
122 virtual CaseFolder
*CaseFolderForEncoding();
123 virtual std::string
CaseMapString(const std::string
&s
, int caseMapping
);
124 virtual int KeyDefault(int key
, int modifiers
);
125 virtual void CopyToClipboard(const SelectionText
&selectedText
);
127 virtual void Paste();
128 virtual void CreateCallTipWindow(PRectangle rc
);
129 virtual void AddToPopUp(const char *label
, int cmd
= 0, bool enabled
= true);
130 bool OwnPrimarySelection();
131 virtual void ClaimSelection();
132 void GetGtkSelectionText(GtkSelectionData
*selectionData
, SelectionText
&selText
);
133 void ReceivedSelection(GtkSelectionData
*selection_data
);
134 void ReceivedDrop(GtkSelectionData
*selection_data
);
135 static void GetSelection(GtkSelectionData
*selection_data
, guint info
, SelectionText
*selected
);
136 void StoreOnClipboard(SelectionText
*clipText
);
137 static void ClipboardGetSelection(GtkClipboard
* clip
, GtkSelectionData
*selection_data
, guint info
, void *data
);
138 static void ClipboardClearSelection(GtkClipboard
* clip
, void *data
);
140 void UnclaimSelection(GdkEventSelection
*selection_event
);
141 void Resize(int width
, int height
);
143 // Callback functions
144 void RealizeThis(GtkWidget
*widget
);
145 static void Realize(GtkWidget
*widget
);
146 void UnRealizeThis(GtkWidget
*widget
);
147 static void UnRealize(GtkWidget
*widget
);
149 static void Map(GtkWidget
*widget
);
151 static void UnMap(GtkWidget
*widget
);
152 gint
FocusInThis(GtkWidget
*widget
);
153 static gint
FocusIn(GtkWidget
*widget
, GdkEventFocus
*event
);
154 gint
FocusOutThis(GtkWidget
*widget
);
155 static gint
FocusOut(GtkWidget
*widget
, GdkEventFocus
*event
);
156 static void SizeRequest(GtkWidget
*widget
, GtkRequisition
*requisition
);
157 #if GTK_CHECK_VERSION(3,0,0)
158 static void GetPreferredWidth(GtkWidget
*widget
, gint
*minimalWidth
, gint
*naturalWidth
);
159 static void GetPreferredHeight(GtkWidget
*widget
, gint
*minimalHeight
, gint
*naturalHeight
);
161 static void SizeAllocate(GtkWidget
*widget
, GtkAllocation
*allocation
);
162 #if GTK_CHECK_VERSION(3,0,0)
163 gboolean
DrawTextThis(cairo_t
*cr
);
164 static gboolean
DrawText(GtkWidget
*widget
, cairo_t
*cr
, ScintillaGTK
*sciThis
);
165 gboolean
DrawThis(cairo_t
*cr
);
166 static gboolean
DrawMain(GtkWidget
*widget
, cairo_t
*cr
);
168 gboolean
ExposeTextThis(GtkWidget
*widget
, GdkEventExpose
*ose
);
169 static gboolean
ExposeText(GtkWidget
*widget
, GdkEventExpose
*ose
, ScintillaGTK
*sciThis
);
170 gboolean
Expose(GtkWidget
*widget
, GdkEventExpose
*ose
);
171 static gboolean
ExposeMain(GtkWidget
*widget
, GdkEventExpose
*ose
);
173 void ForAll(GtkCallback callback
, gpointer callback_data
);
174 static void MainForAll(GtkContainer
*container
, gboolean include_internals
, GtkCallback callback
, gpointer callback_data
);
176 static void ScrollSignal(GtkAdjustment
*adj
, ScintillaGTK
*sciThis
);
177 static void ScrollHSignal(GtkAdjustment
*adj
, ScintillaGTK
*sciThis
);
178 gint
PressThis(GdkEventButton
*event
);
179 static gint
Press(GtkWidget
*widget
, GdkEventButton
*event
);
180 static gint
MouseRelease(GtkWidget
*widget
, GdkEventButton
*event
);
181 static gint
ScrollEvent(GtkWidget
*widget
, GdkEventScroll
*event
);
182 static gint
Motion(GtkWidget
*widget
, GdkEventMotion
*event
);
183 gboolean
KeyThis(GdkEventKey
*event
);
184 static gboolean
KeyPress(GtkWidget
*widget
, GdkEventKey
*event
);
185 static gboolean
KeyRelease(GtkWidget
*widget
, GdkEventKey
*event
);
186 #if GTK_CHECK_VERSION(3,0,0)
187 gboolean
DrawPreeditThis(GtkWidget
*widget
, cairo_t
*cr
);
188 static gboolean
DrawPreedit(GtkWidget
*widget
, cairo_t
*cr
, ScintillaGTK
*sciThis
);
190 gboolean
ExposePreeditThis(GtkWidget
*widget
, GdkEventExpose
*ose
);
191 static gboolean
ExposePreedit(GtkWidget
*widget
, GdkEventExpose
*ose
, ScintillaGTK
*sciThis
);
193 AtkObject
* GetAccessibleThis(GtkWidget
*widget
);
194 static AtkObject
* GetAccessible(GtkWidget
*widget
);
197 void CommitThis(char *str
);
198 static void Commit(GtkIMContext
*context
, char *str
, ScintillaGTK
*sciThis
);
199 void PreeditChangedInlineThis();
200 void PreeditChangedWindowedThis();
201 static void PreeditChanged(GtkIMContext
*context
, ScintillaGTK
*sciThis
);
202 void MoveImeCarets(int pos
);
203 void DrawImeIndicator(int indicator
, int len
);
204 void SetCandidateWindowPos();
206 static void StyleSetText(GtkWidget
*widget
, GtkStyle
*previous
, void*);
207 static void RealizeText(GtkWidget
*widget
, void*);
208 static void Dispose(GObject
*object
);
209 static void Destroy(GObject
*object
);
210 static void SelectionReceived(GtkWidget
*widget
, GtkSelectionData
*selection_data
,
212 static void SelectionGet(GtkWidget
*widget
, GtkSelectionData
*selection_data
,
213 guint info
, guint time
);
214 static gint
SelectionClear(GtkWidget
*widget
, GdkEventSelection
*selection_event
);
215 gboolean
DragMotionThis(GdkDragContext
*context
, gint x
, gint y
, guint dragtime
);
216 static gboolean
DragMotion(GtkWidget
*widget
, GdkDragContext
*context
,
217 gint x
, gint y
, guint dragtime
);
218 static void DragLeave(GtkWidget
*widget
, GdkDragContext
*context
,
220 static void DragEnd(GtkWidget
*widget
, GdkDragContext
*context
);
221 static gboolean
Drop(GtkWidget
*widget
, GdkDragContext
*context
,
222 gint x
, gint y
, guint time
);
223 static void DragDataReceived(GtkWidget
*widget
, GdkDragContext
*context
,
224 gint x
, gint y
, GtkSelectionData
*selection_data
, guint info
, guint time
);
225 static void DragDataGet(GtkWidget
*widget
, GdkDragContext
*context
,
226 GtkSelectionData
*selection_data
, guint info
, guint time
);
227 static gboolean
TimeOut(gpointer ptt
);
228 static gboolean
IdleCallback(gpointer pSci
);
229 static gboolean
StyleIdle(gpointer pSci
);
230 virtual void IdleWork();
231 virtual void QueueIdleWork(WorkNeeded::workItems items
, int upTo
);
232 virtual void SetDocPointer(Document
*document
);
233 static void PopUpCB(GtkMenuItem
*menuItem
, ScintillaGTK
*sciThis
);
235 #if GTK_CHECK_VERSION(3,0,0)
236 static gboolean
DrawCT(GtkWidget
*widget
, cairo_t
*cr
, CallTip
*ctip
);
238 static gboolean
ExposeCT(GtkWidget
*widget
, GdkEventExpose
*ose
, CallTip
*ct
);
240 static gboolean
PressCT(GtkWidget
*widget
, GdkEventButton
*event
, ScintillaGTK
*sciThis
);
242 static sptr_t
DirectFunction(sptr_t ptr
,
243 unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
246 // helper class to watch a GObject lifetime and get notified when it dies
247 class GObjectWatcher
{
250 void WeakNotifyThis(GObject
*obj G_GNUC_UNUSED
) {
251 PLATFORM_ASSERT(obj
== weakRef
);
257 static void WeakNotify(gpointer data
, GObject
*obj
) {
258 static_cast<GObjectWatcher
*>(data
)->WeakNotifyThis(obj
);
262 GObjectWatcher(GObject
*obj
) :
264 g_object_weak_ref(weakRef
, WeakNotify
, this);
267 virtual ~GObjectWatcher() {
269 g_object_weak_unref(weakRef
, WeakNotify
, this);
273 virtual void Destroyed() {}
275 bool IsDestroyed() const {
280 std::string
ConvertText(const char *s
, size_t len
, const char *charSetDest
,
281 const char *charSetSource
, bool transliterations
, bool silent
=false);