1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
/*
* Copyright (C) 2012-2024 Robin Haberkorn
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdarg.h>
#include <signal.h>
#include <glib.h>
#include <Scintilla.h>
#include "sciteco.h"
#include "qreg.h"
#include "ring.h"
#include "cmdline.h"
#include "view.h"
/**
* @file
* Abstract user interface.
*
* Interface of all SciTECO user interfaces (e.g. Curses or GTK+).
* All functions that must be provided are marked with the \@pure tag.
*
* @note
* We do not provide default implementations for any of the interface
* functions by declaring them "weak" since this is a non-portable linker
* feature.
*/
/** @protected */
extern teco_view_t *teco_interface_current_view;
/** @pure */
void teco_interface_init(void);
/** @pure */
GOptionGroup *teco_interface_get_options(void);
/** @pure makes sense only on Curses */
void teco_interface_init_color(guint color, guint32 rgb);
typedef enum {
TECO_MSG_USER,
TECO_MSG_INFO,
TECO_MSG_WARNING,
TECO_MSG_ERROR
} teco_msg_t;
/** @pure */
void teco_interface_vmsg(teco_msg_t type, const gchar *fmt, va_list ap);
static inline void G_GNUC_PRINTF(2, 3)
teco_interface_msg(teco_msg_t type, const gchar *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
teco_interface_vmsg(type, fmt, ap);
va_end(ap);
}
/** @pure */
void teco_interface_msg_clear(void);
/** @pure */
void teco_interface_show_view(teco_view_t *view);
void undo__teco_interface_show_view(teco_view_t *);
static inline sptr_t
teco_interface_ssm(unsigned int iMessage, uptr_t wParam, sptr_t lParam)
{
return teco_view_ssm(teco_interface_current_view, iMessage, wParam, lParam);
}
/*
* NOTE: You could simply call undo__teco_view_ssm(teco_interface_current_view, ...).
* undo__teco_interface_ssm(...) exists for brevity and aestethics.
*/
void undo__teco_interface_ssm(unsigned int, uptr_t, sptr_t);
/** @pure */
void teco_interface_info_update_qreg(const teco_qreg_t *reg);
/** @pure */
void teco_interface_info_update_buffer(const teco_buffer_t *buffer);
#define teco_interface_info_update(X) \
(_Generic((X), teco_qreg_t * : teco_interface_info_update_qreg, \
const teco_qreg_t * : teco_interface_info_update_qreg, \
teco_buffer_t * : teco_interface_info_update_buffer, \
const teco_buffer_t * : teco_interface_info_update_buffer)(X))
void undo__teco_interface_info_update_qreg(const teco_qreg_t *);
void undo__teco_interface_info_update_buffer(const teco_buffer_t *);
/** @pure */
void teco_interface_cmdline_update(const teco_cmdline_t *cmdline);
/** @pure */
gboolean teco_interface_set_clipboard(const gchar *name, const gchar *str, gsize str_len,
GError **error);
void teco_interface_undo_set_clipboard(const gchar *name, gchar *str, gsize len);
/**
* Semantics are compatible with teco_qreg_vtable_t::get_string() since that is the
* main user of this function.
*
* @pure
*/
gboolean teco_interface_get_clipboard(const gchar *name, gchar **str, gsize *len, GError **error);
typedef enum {
TECO_POPUP_PLAIN,
TECO_POPUP_FILE,
TECO_POPUP_DIRECTORY
} teco_popup_entry_type_t;
/** @pure */
void teco_interface_popup_add(teco_popup_entry_type_t type,
const gchar *name, gsize name_len, gboolean highlight);
/** @pure */
void teco_interface_popup_show(void);
/** @pure */
gboolean teco_interface_popup_is_shown(void);
/** @pure */
void teco_interface_popup_clear(void);
/** @pure */
gboolean teco_interface_is_interrupted(void);
/** @pure main entry point */
gboolean teco_interface_event_loop(GError **error);
/*
* Interfacing to the external SciTECO world
*/
/** @protected */
void teco_interface_stdio_vmsg(teco_msg_t type, const gchar *fmt, va_list ap);
void teco_interface_process_notify(SCNotification *notify);
/** @pure */
void teco_interface_cleanup(void);
static inline gssize
teco_glyphs2bytes(teco_int_t pos)
{
return teco_view_glyphs2bytes(teco_interface_current_view, pos);
}
static inline teco_int_t
teco_bytes2glyphs(gsize pos)
{
return teco_view_bytes2glyphs(teco_interface_current_view, pos);
}
static inline gssize
teco_glyphs2bytes_relative(gsize pos, teco_int_t n)
{
return teco_view_glyphs2bytes_relative(teco_interface_current_view, pos, n);
}
static inline teco_int_t
teco_interface_get_character(gsize pos, gsize len)
{
return teco_view_get_character(teco_interface_current_view, pos, len);
}
/*
* The following functions are here for lack of a better place.
* They could also be in sciteco.h, but only if declared as non-inline
* since sciteco.h should not depend on interface.h.
*/
static inline gboolean
teco_validate_line(teco_int_t n)
{
return 0 <= n && n < teco_interface_ssm(SCI_GETLINECOUNT, 0, 0);
}
|