diff options
Diffstat (limited to 'gtk/ScintillaGTK.cxx')
-rwxr-xr-x | gtk/ScintillaGTK.cxx | 148 |
1 files changed, 54 insertions, 94 deletions
diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index 8a188d769..5c6161cc2 100755 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -80,10 +80,10 @@ #include "AutoComplete.h" #include "ScintillaBase.h" +#include "Wrappers.h" #include "ScintillaGTK.h" #include "scintilla-marshal.h" #include "ScintillaGTKAccessible.h" - #include "Converter.h" #define IS_WIDGET_REALIZED(w) (gtk_widget_get_realized(GTK_WIDGET(w))) @@ -135,10 +135,6 @@ constexpr gint nClipboardPasteTargets = static_cast<gint>(std::size(clipboardPas const GdkDragAction actionCopyOrMove = static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE); -GdkWindow *WindowFromWidget(GtkWidget *w) noexcept { - return gtk_widget_get_window(w); -} - GtkWidget *PWidget(const Window &w) noexcept { return static_cast<GtkWidget *>(w.GetID()); } @@ -148,14 +144,6 @@ GdkWindow *PWindow(const Window &w) noexcept { return gtk_widget_get_window(widget); } -void UnRefCursor(GdkCursor *cursor) noexcept { -#if GTK_CHECK_VERSION(3,0,0) - g_object_unref(cursor); -#else - gdk_cursor_unref(cursor); -#endif -} - void MapWidget(GtkWidget *widget) noexcept { if (widget && gtk_widget_get_visible(GTK_WIDGET(widget)) && @@ -195,9 +183,9 @@ bool SettingGet(GtkSettings *settings, const gchar *name, gpointer value) noexce } FontOptions::FontOptions(GtkWidget *widget) noexcept { - PangoContext *pcontext = gtk_widget_create_pango_context(widget); + UniquePangoContext pcontext(gtk_widget_create_pango_context(widget)); PLATFORM_ASSERT(pcontext); - const cairo_font_options_t *options = pango_cairo_context_get_font_options(pcontext); + const cairo_font_options_t *options = pango_cairo_context_get_font_options(pcontext.get()); // options is owned by the PangoContext so must not be freed. if (options) { // options is NULL on Win32 @@ -205,7 +193,6 @@ FontOptions::FontOptions(GtkWidget *widget) noexcept { order = cairo_font_options_get_subpixel_order(options); hint = cairo_font_options_get_hint_style(options); } - g_object_unref(pcontext); } bool FontOptions::operator==(const FontOptions &other) const noexcept { @@ -222,7 +209,6 @@ ScintillaGTK *ScintillaGTK::FromWidget(GtkWidget *widget) noexcept { ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) : adjustmentv(nullptr), adjustmenth(nullptr), verticalScrollBarWidth(30), horizontalScrollBarHeight(30), - evbtn(nullptr), buttonMouse(0), capturedMouse(false), dragWasDropped(false), lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), @@ -273,10 +259,6 @@ ScintillaGTK::~ScintillaGTK() { g_source_remove(styleIdleID); styleIdleID = 0; } - if (evbtn) { - gdk_event_free(evbtn); - evbtn = nullptr; - } ClearPrimarySelection(); wPreedit.Destroy(); if (settingsHandlerId) { @@ -317,7 +299,6 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { gtk_widget_get_window(widget)); #endif gdk_window_show(gtk_widget_get_window(widget)); - UnRefCursor(cursor); #else widget->window = gdk_window_new(gtk_widget_get_parent_window(widget), &attrs, GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR); @@ -325,19 +306,19 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) { widget->style = gtk_style_attach(widget->style, widget->window); gdk_window_set_background(widget->window, &widget->style->bg[GTK_STATE_NORMAL]); gdk_window_show(widget->window); - UnRefCursor(cursor); #endif + UnRefCursor(cursor); preeditInitialized = false; gtk_widget_realize(PWidget(wPreedit)); gtk_widget_realize(PWidget(wPreeditDraw)); - im_context = gtk_im_multicontext_new(); - g_signal_connect(G_OBJECT(im_context), "commit", + im_context.reset(gtk_im_multicontext_new()); + g_signal_connect(G_OBJECT(im_context.get()), "commit", G_CALLBACK(Commit), this); - g_signal_connect(G_OBJECT(im_context), "preedit_changed", + g_signal_connect(G_OBJECT(im_context.get()), "preedit_changed", G_CALLBACK(PreeditChanged), this); - gtk_im_context_set_client_window(im_context, WindowFromWidget(widget)); + gtk_im_context_set_client_window(im_context.get(), WindowFromWidget(widget)); GtkWidget *widtxt = PWidget(wText); // // No code inside the G_OBJECT macro g_signal_connect_after(G_OBJECT(widtxt), "style_set", @@ -388,8 +369,7 @@ void ScintillaGTK::UnRealizeThis(GtkWidget *widget) { gtk_widget_unrealize(PWidget(scrollbarh)); gtk_widget_unrealize(PWidget(wPreedit)); gtk_widget_unrealize(PWidget(wPreeditDraw)); - g_object_unref(im_context); - im_context = nullptr; + im_context.reset(); if (GTK_WIDGET_CLASS(parentClass)->unrealize) GTK_WIDGET_CLASS(parentClass)->unrealize(widget); @@ -504,8 +484,8 @@ gint ScintillaGTK::FocusInThis(GtkWidget *) { SetFocusState(true); if (im_context) { - gtk_im_context_focus_in(im_context); - PreEditString pes(im_context); + gtk_im_context_focus_in(im_context.get()); + PreEditString pes(im_context.get()); if (PWidget(wPreedit)) { if (!preeditInitialized) { GtkWidget *top = gtk_widget_get_toplevel(PWidget(wMain)); @@ -538,7 +518,7 @@ gint ScintillaGTK::FocusOutThis(GtkWidget *) { if (PWidget(wPreedit)) gtk_widget_hide(PWidget(wPreedit)); if (im_context) - gtk_im_context_focus_out(im_context); + gtk_im_context_focus_out(im_context.get()); } catch (...) { errorStatus = Status::Failure; @@ -765,14 +745,14 @@ void ScintillaGTK::StartDrag() { tl, actionCopyOrMove, buttonMouse, - evbtn, + evbtn.get(), -1, -1); #else gtk_drag_begin(GTK_WIDGET(PWidget(wMain)), tl, actionCopyOrMove, buttonMouse, - evbtn); + evbtn.get()); #endif } @@ -1221,15 +1201,14 @@ public: std::string sUTF8 = ConvertText(mixed, lenMixed, "UTF-8", charSet, false); if (!sUTF8.empty()) { - gchar *mapped = g_utf8_casefold(sUTF8.c_str(), sUTF8.length()); - size_t lenMapped = strlen(mapped); + UniqueStr mapped(g_utf8_casefold(sUTF8.c_str(), sUTF8.length())); + size_t lenMapped = strlen(mapped.get()); if (lenMapped < sizeFolded) { - memcpy(folded, mapped, lenMapped); + memcpy(folded, mapped.get(), lenMapped); } else { folded[0] = '\0'; lenMapped = 1; } - g_free(mapped); return lenMapped; } } @@ -1256,14 +1235,13 @@ std::unique_ptr<CaseFolder> ScintillaGTK::CaseFolderForEncoding() { std::string sUTF8 = ConvertText(sCharacter, 1, "UTF-8", charSetBuffer, false, true); if (!sUTF8.empty()) { - gchar *mapped = g_utf8_casefold(sUTF8.c_str(), sUTF8.length()); + UniqueStr mapped(g_utf8_casefold(sUTF8.c_str(), sUTF8.length())); if (mapped) { - std::string mappedBack = ConvertText(mapped, strlen(mapped), + std::string mappedBack = ConvertText(mapped.get(), strlen(mapped.get()), charSetBuffer, "UTF-8", false, true); if ((mappedBack.length() == 1) && (mappedBack[0] != sCharacter[0])) { pcf->SetTranslation(sCharacter[0], mappedBack[0]); } - g_free(mapped); } } } @@ -1279,22 +1257,14 @@ std::unique_ptr<CaseFolder> ScintillaGTK::CaseFolderForEncoding() { namespace { struct CaseMapper { - gchar *mapped; // Must be freed with g_free + UniqueStr mapped; CaseMapper(const std::string &sUTF8, bool toUpperCase) noexcept { if (toUpperCase) { - mapped = g_utf8_strup(sUTF8.c_str(), sUTF8.length()); + mapped.reset(g_utf8_strup(sUTF8.c_str(), sUTF8.length())); } else { - mapped = g_utf8_strdown(sUTF8.c_str(), sUTF8.length()); + mapped.reset(g_utf8_strdown(sUTF8.c_str(), sUTF8.length())); } } - // Deleted so CaseMapper objects can not be copied. - CaseMapper(const CaseMapper&) = delete; - CaseMapper(CaseMapper&&) = delete; - CaseMapper&operator=(const CaseMapper&) = delete; - CaseMapper&operator=(CaseMapper&&) = delete; - ~CaseMapper() noexcept { - g_free(mapped); - } }; } @@ -1315,13 +1285,13 @@ std::string ScintillaGTK::CaseMapString(const std::string &s, CaseMapping caseMa if (!*charSetBuffer) { CaseMapper mapper(s, caseMapping == CaseMapping::upper); - return std::string(mapper.mapped, strlen(mapper.mapped)); + return std::string(mapper.mapped.get()); } else { // Change text to UTF-8 std::string sUTF8 = ConvertText(s.c_str(), s.length(), "UTF-8", charSetBuffer, false); CaseMapper mapper(sUTF8, caseMapping == CaseMapping::upper); - return ConvertText(mapper.mapped, strlen(mapper.mapped), charSetBuffer, "UTF-8", false); + return ConvertText(mapper.mapped.get(), strlen(mapper.mapped.get()), charSetBuffer, "UTF-8", false); } } @@ -1849,10 +1819,7 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { if (event->type != GDK_BUTTON_PRESS) return FALSE; - if (evbtn) { - gdk_event_free(evbtn); - } - evbtn = gdk_event_copy(reinterpret_cast<GdkEvent *>(event)); + evbtn.reset(gdk_event_copy(reinterpret_cast<GdkEvent *>(event))); buttonMouse = event->button; const Point pt = PointOfEvent(event); const PRectangle rcClient = GetClientRectangle(); @@ -2249,7 +2216,7 @@ gboolean ScintillaGTK::KeyThis(GdkEventKey *event) { try { //fprintf(stderr, "SC-key: %d %x [%s]\n", // event->keyval, event->state, (event->length > 0) ? event->string : "empty"); - if (gtk_im_context_filter_keypress(im_context, event)) { + if (gtk_im_context_filter_keypress(im_context.get(), event)) { return 1; } if (!event->keyval) { @@ -2307,7 +2274,7 @@ gboolean ScintillaGTK::KeyPress(GtkWidget *widget, GdkEventKey *event) { gboolean ScintillaGTK::KeyRelease(GtkWidget *widget, GdkEventKey *event) { //Platform::DebugPrintf("SC-keyrel: %d %x %3s\n",event->keyval, event->state, event->string); ScintillaGTK *sciThis = FromWidget(widget); - if (gtk_im_context_filter_keypress(sciThis->im_context, event)) { + if (gtk_im_context_filter_keypress(sciThis->im_context.get(), event)) { return TRUE; } return FALSE; @@ -2317,14 +2284,12 @@ gboolean ScintillaGTK::KeyRelease(GtkWidget *widget, GdkEventKey *event) { gboolean ScintillaGTK::DrawPreeditThis(GtkWidget *, cairo_t *cr) { try { - PreEditString pes(im_context); - PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), pes.str); - pango_layout_set_attributes(layout, pes.attrs); + PreEditString pes(im_context.get()); + UniquePangoLayout layout(gtk_widget_create_pango_layout(PWidget(wText), pes.str)); + pango_layout_set_attributes(layout.get(), pes.attrs); cairo_move_to(cr, 0, 0); - pango_cairo_show_layout(cr, layout); - - g_object_unref(layout); + pango_cairo_show_layout(cr, layout.get()); } catch (...) { errorStatus = Status::Failure; } @@ -2339,15 +2304,13 @@ gboolean ScintillaGTK::DrawPreedit(GtkWidget *widget, cairo_t *cr, ScintillaGTK gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *) { try { - PreEditString pes(im_context); - PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), pes.str); - pango_layout_set_attributes(layout, pes.attrs); - - cairo_t *context = gdk_cairo_create(WindowFromWidget(widget)); - cairo_move_to(context, 0, 0); - pango_cairo_show_layout(context, layout); - cairo_destroy(context); - g_object_unref(layout); + PreEditString pes(im_context.get()); + UniquePangoLayout layout(gtk_widget_create_pango_layout(PWidget(wText), pes.str)); + pango_layout_set_attributes(layout.get(), pes.attrs); + + UniqueCairo context(gdk_cairo_create(WindowFromWidget(widget))); + cairo_move_to(context.get(), 0, 0); + pango_cairo_show_layout(context.get(), layout.get()); } catch (...) { errorStatus = Status::Failure; } @@ -2361,7 +2324,7 @@ gboolean ScintillaGTK::ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, Sci #endif bool ScintillaGTK::KoreanIME() { - PreEditString pes(im_context); + PreEditString pes(im_context.get()); if (pes.pscript != G_UNICODE_SCRIPT_COMMON) lastNonCommonScript = pes.pscript; return lastNonCommonScript == G_UNICODE_SCRIPT_HANGUL; @@ -2456,7 +2419,7 @@ void ScintillaGTK::SetCandidateWindowPos() { imeBox.y = static_cast<gint>(pt.y + std::max(4, vs.lineHeight/4)); // prevent overlapping with current line imeBox.height = vs.lineHeight; - gtk_im_context_set_cursor_location(im_context, &imeBox); + gtk_im_context_set_cursor_location(im_context.get(), &imeBox); } void ScintillaGTK::CommitThis(char *commitStr) { @@ -2497,7 +2460,7 @@ void ScintillaGTK::PreeditChangedInlineThis() { // Great thanks for my foreruners, jiniya and BLUEnLIVE try { if (pdoc->IsReadOnly() || SelectionContainsProtected()) { - gtk_im_context_reset(im_context); + gtk_im_context_reset(im_context.get()); return; } @@ -2512,7 +2475,7 @@ void ScintillaGTK::PreeditChangedInlineThis() { initialCompose = true; } - PreEditString preeditStr(im_context); + PreEditString preeditStr(im_context.get()); const char *charSetSource = CharacterSetID(); if (!preeditStr.validUTF8 || (charSetSource == nullptr)) { @@ -2571,16 +2534,15 @@ void ScintillaGTK::PreeditChangedInlineThis() { void ScintillaGTK::PreeditChangedWindowedThis() { try { - PreEditString pes(im_context); + PreEditString pes(im_context.get()); if (strlen(pes.str) > 0) { SetCandidateWindowPos(); - PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), pes.str); - pango_layout_set_attributes(layout, pes.attrs); + UniquePangoLayout layout(gtk_widget_create_pango_layout(PWidget(wText), pes.str)); + pango_layout_set_attributes(layout.get(), pes.attrs); gint w, h; - pango_layout_get_pixel_size(layout, &w, &h); - g_object_unref(layout); + pango_layout_get_pixel_size(layout.get(), &w, &h); gint x, y; gdk_window_get_origin(PWindow(wText), &x, &y); @@ -2797,12 +2759,12 @@ gboolean ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *os rgnUpdate = gdk_region_copy(ose->region); const PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); - std::unique_ptr<Surface> surfaceWindow(Surface::Allocate(Technology::Default)); - cairo_t *cr = gdk_cairo_create(PWindow(wText)); - surfaceWindow->Init(cr, PWidget(wText)); - Paint(surfaceWindow.get(), rcPaint); - surfaceWindow->Release(); - cairo_destroy(cr); + { + std::unique_ptr<Surface> surfaceWindow(Surface::Allocate(Technology::Default)); + UniqueCairo cr(gdk_cairo_create(PWindow(wText))); + surfaceWindow->Init(cr.get(), PWidget(wText)); + Paint(surfaceWindow.get(), rcPaint); + } if ((paintState == PaintState::abandoned) || repaintFullWindow) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); @@ -3105,12 +3067,10 @@ gboolean ScintillaGTK::DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip) { gboolean ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip *ctip) { try { std::unique_ptr<Surface> surfaceWindow(Surface::Allocate(Technology::Default)); - cairo_t *cr = gdk_cairo_create(WindowFromWidget(widget)); - surfaceWindow->Init(cr, widget); + UniqueCairo cr(gdk_cairo_create(WindowFromWidget(widget))); + surfaceWindow->Init(cr.get(), widget); surfaceWindow->SetMode(SurfaceMode(ctip->codePage, false)); ctip->PaintCT(surfaceWindow.get()); - surfaceWindow->Release(); - cairo_destroy(cr); } catch (...) { // No pointer back to Scintilla to save status } |