Subversion Repositories Kolibri OS

Rev

Rev 6615 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6589 siemargl 1
#ifndef KOLIBRI_EDITOR_H
2
#define KOLIBRI_EDITOR_H
3
 
4
// (количество символов в новом документе + 2)
5
#define TE_MAXCHARS 100002
6
// максимальный размер файла синтаксиса
7
#define TE_MAX_SYNTAX_FILESIZE 410000
8
// buffer for copy|paste
9
#define TE_BUF_SIZE  4096
10
typedef void (*editor_callback)(void);
11
 
12
struct __attribute__ ((__packed__)) editor_symbol {
13
	uint8_t     c;      //  +0 символ
14
	uint8_t     col;    //  +1 цвет
6615 siemargl 15
	uint32_t    prev;   //  +2 индекс предыдущего
16
	uint32_t    next;   //  +6 указатели (индекс следующего)
6589 siemargl 17
	uint32_t    tc;     //  +10 врем. создания
18
	uint32_t    td;     // +14 врем. удаления
19
};
20
 
21
/// структура текстового редактора
22
typedef struct __attribute__ ((__packed__)) {
23
    uint32_t    x_pos;  //0
24
    uint32_t    y_pos;  //50
25
    uint32_t    width;  //440
26
    uint32_t    hight;  //150
6612 siemargl 27
    uint32_t    w_pane;      //30 ширина панели в окне, width of left pane with line numbers
28
    uint32_t    h_pane;      //25 высота панели в окне, hight of top pane with Rows, Cols Undo info
6589 siemargl 29
    uint32_t    width_sym;  //9 ширина символа (знакоместа) в окне
30
    uint32_t    hight_sym;  //16 высота символа (знакоместа) в окне
31
	uint8_t     drag_m;     // выделение от мыши
32
	uint8_t     drag_k;     // выделение от клавиатуры
33
	uint32_t    sel_x0;     // структура выделения
34
	uint32_t    sel_y0;
35
	uint32_t    sel_x1;
36
	uint32_t    sel_y1;
37
	uint32_t    seln_x0;    //дополнительная структура выделения
38
	uint32_t    seln_y0;
39
	uint32_t    seln_x1;
40
	uint32_t    seln_y1;
41
	struct editor_symbol   *tex;    // text memory pointer
6615 siemargl 42
	struct editor_symbol   *tex_1;  // указатель за последним существующим символом (конец файла)
43
	struct editor_symbol   *tex_end;// text end memory pointer (указатель за концом выделенного буфера для текста)
6589 siemargl 44
	uint32_t    cur_x;      //координата x курсора
45
	uint32_t    cur_y;      //координата y курсора
46
	uint32_t    max_chars;  // TE_MAXCHARS ;+86 максимальное число символов в одном документе
47
	uint32_t    count_colors_text; // 1 ;+90 количество цветов текста
48
	uint32_t    count_key_words;   //+94 колличество ключевых слов
49
	color_t     color_cursor;   // 0x808080 ;+98 цвет курсора
50
	color_t     color_wnd_capt; // 0x80 ;+102 цвет полей вокруг окна
51
	color_t     color_wnd_work; // 0x0 ;+106 цвет фона окна
52
	color_t     color_wnd_bord; //0xd0d0d0 ;+110 цвет текста на полях
53
	color_t     color_select;   // 0x208080 ;+114 цвет выделения
54
	color_t     color_cur_text; // 0xff0000 ;+118 цвет символа под курсором
55
	color_t     color_wnd_text; // 0xffff00 ;+122 цвет текста в окне
56
	char       *syntax_file;    // указатель на начало файла синтаксиса
57
	uint32_t    syntax_file_size;   // TE_MAX_SYNTAX_FILESIZE ;+130 максимальный размер файла синтаксиса
58
	void       *text_colors;    // указатель на массив цветов текста
59
	char       *help_text_f1;   // указатель на текст справки (по нажатии F1)
60
	int         help_id;	    // -1 ;+142 идентификатор для справки
61
	void       *key_words_data; // указатель на структуры ключевых слов TexColViv
62
	uint32_t    tim_ch;     // количество изменений в файле
63
	uint32_t    tim_undo;   // количество отмененных действий
64
	uint32_t    tim_ls;     // время последнего сохранения
65
	uint32_t    tim_co;     // время последней цветовой разметки
66
	void       *el_focus;   // указатель на переменную элемента в фокусе pointer to pointer**
67
	uint8_t     err_save;   // ошибка сохранения файла
68
	uint8_t     panel_id;   // номер открытой панели
69
	uint8_t     key_new;    // символ, который будет добавлятся с клавиатуры
70
	uint8_t     symbol_new_line; // ascii 20 символ завершения строки
71
	scrollbar  *scr_w;      // вертикальный скроллинг != NULL
72
	scrollbar  *scr_h;      // горизонтальный скроллинг != NULL
73
	char       *arr_key_pos;// указатель на массив позиций ключевых слов
74
	char       *buffer;     // указатель на буфер копирования/вставки != NULL, also size
75
	char       *buffer_find;// указатель на буфер для поиска (sized 302)
76
	uint8_t     cur_ins;    // 1 режим работы курсора (обычный или замена)
77
	uint8_t     mode_color; // 1 режим выделения слов цветом (0-выкл. 1-вкл.)
78
	uint8_t     mode_invis; // 0 режим показа непечатаемых символов
79
	uint8_t     gp_opt;     // 0 опции возвращаемые функцией ted_get_pos_by_cursor
80
	editor_callback fun_on_key_ctrl_o;  // указатель на функцию вызываемую при нажатии Ctrl+O (открытие файла), can be NULL
81
	editor_callback fun_on_key_ctrl_f;  // ... Ctrl+F (вызова/скрытия панели поиска)
82
	editor_callback fun_on_key_ctrl_n;  // ... Ctrl+N (создание нового документа)
83
	editor_callback fun_on_key_ctrl_s;  // ... Ctrl+S
84
	uint32_t    buffer_size;// BUF_SIZE размер буфера копирования/вставки
85
	editor_callback fun_find_err;       // указатель на функцию вызываемую если поиск закончился неудачно
86
	editor_callback fun_init_synt_err;  // unused указатель на функцию вызываемую при ошибочном открытии файла синтаксиса
87
	editor_callback fun_draw_panel_buttons; // указатель на функцию рисования панели с кнопками
88
	editor_callback fun_draw_panel_find;    // указатель на функцию рисования панели поиска
89
	editor_callback fun_draw_panel_syntax;  // указатель на функцию рисования панели синтаксиса
90
	editor_callback fun_save_err;   // указатель на функцию вызываемую если сохранение файла закончилось неудачно
91
	uint32_t    increase_size;  //200 число символов на которые будет увечиваться память при нехватке
92
	void       *ptr_free_symb;  // используется внутри элемента для ускорения вставки текста
93
	uint32_t    font_size;       // ;+250 множитель для размера шрифта // binary OR mask for ECX SysFn4
94
} editor;
95
 
96
struct __attribute__ ((__packed__)) editor_color_item
97
{
98
    char        word[40];   // слово для подсветки
99
    uint32_t    f1_offset;  // смещение в таблице F1 подсказок
100
	uint8_t     flags;      // флаги используемые при выделении
101
	uint8_t     endc;       // символ конца выделения (используется при flags&4)
102
	uint8_t     escc;       // экранирующий символ (используется при flags&4)  ascii(34) примеры экранирования \r \n \t
103
    uint8_t     color;      // цвет по таблице цветов
104
};
105
 
106
struct editor_syntax_file
107
{
108
    uint32_t    count_colors_text;  // кол-во цветов текста dd (text-color_wnd_text)/4
109
    uint32_t    count_key_words;    // кол-во ключевых слов dd (f1-text)/48
110
    color_t     color_cursor;       // dd 0xf1fcd0
111
    color_t     color_wnd_capt;     // dd 0x080808
112
    color_t     color_wnd_work;     // dd 0x1C1C1C
113
    color_t     color_wnd_bord;     // dd 0xc0c0c0
114
    color_t     color_select;       // dd 0x3E3D32
115
    color_t     color_cur_text;     // dd 0x808080
116
    color_t     color_wnd_text[];   // таблица цветов размером count_colors_text
117
    // editor_color_item[];         // таблица ключевых подсвеченных слов размером count_key_words
118
};
119
 
120
 
121
static struct editor_syntax_file default_syntax = {
122
    10,     //count_colors_text
6601 siemargl 123
    1,      // count_key_words dd (f1-text)/48, minimum 1
6589 siemargl 124
    0xf1fcd0, //color_cursor dd 0xf1fcd0
125
    0x080808, //color_wnd_capt dd 0x080808
126
    0x1C1C1C, //color_wnd_work dd 0x1C1C1C
127
    0xc0c0c0, //color_wnd_bord dd 0xc0c0c0
128
    0x3E3D32, //color_select dd 0x3E3D32
129
    0x808080, //color_cur_text dd 0x808080
130
	{0xD0D0D0, 0xffff00, 0x00ff00, 0x00ffff, 0x808080, 0xff40ff, 0x4080ff, 0xff0000, 0x8080ff, 0x00ccff}
131
};
132
// next structure must follow syntax definition, at least has 1 element !!!
133
static struct editor_color_item  word1 = {
134
    "siemargl", 1, 0, 0, 1  // test word colored as 1st in table
135
};
136
// next structure preferably follow syntax definition, at least has 1 element !!!
137
static char f1_table[] = {
138
    "\0"
139
    "First\0"
140
    "Last\0"
141
};
142
 
143
 
144
extern void (*ted_draw)(editor *) __attribute__((__stdcall__));
145
extern void (*ted_init_scroll_bars)(editor *, int opt) __attribute__((__stdcall__));
146
/// opt bits = 1 - менять цвет скроллингов, 2 - изменились размеры окна, 4 - изменились размеры документа
147
extern void (*ted_init_syntax_file)(editor *) __attribute__((__stdcall__));
148
extern void (*ted_mouse)(editor *) __attribute__((__stdcall__));
149
extern void (*ted_text_add)(editor *, char *text, int textlen, int opt) __attribute__((__stdcall__));
150
/// add text to cursor pos
151
/// opt == ted_opt_ed_change_time, ted_opt_ed_move_cursor
152
///ted_opt_ed_move_cursor equ 1 ;двигать курсор после добавления текста
153
///ted_opt_ed_change_time equ 2 ;добавлять изменения при редактировании текста
154
extern void (*ted_but_select_word)(editor *) __attribute__((__stdcall__));
155
/// select word under cursor
156
extern void (*ted_but_copy)(editor *) __attribute__((__stdcall__));
157
extern void (*ted_but_paste)(editor *) __attribute__((__stdcall__));
158
 
7577 IgorA 159
extern void (*ted_but_find)(editor *) __attribute__((__stdcall__));
160
extern void (*ted_but_replace)(editor *) __attribute__((__stdcall__));
6589 siemargl 161
///move cursor to , calls ted_fun_find_err() if exist
162
 
163
 
164
 
6615 siemargl 165
extern void (*ted_but_sumb_upper)(editor *) __attribute__((__stdcall__));
6589 siemargl 166
 
6615 siemargl 167
extern void (*ted_but_sumb_lover)(editor *) __attribute__((__stdcall__));
6589 siemargl 168
 
6615 siemargl 169
extern void (*ted_but_convert_by_table)(editor *, char* table) __attribute__((__stdcall__));
6589 siemargl 170
 
6601 siemargl 171
/// return 1 if need to be saved (has changes), 0 otherwise
6615 siemargl 172
extern int (*ted_can_save)(editor *) __attribute__((__stdcall__));
6589 siemargl 173
 
174
/// all==1 - clear all memory
6615 siemargl 175
extern void (*ted_clear)(editor *, int all) __attribute__((__stdcall__));
6589 siemargl 176
 
6615 siemargl 177
extern void (*ted_delete)(editor *) __attribute__((__stdcall__));
6589 siemargl 178
static inline void editor_delete(editor *ed)
179
/// frees all memory (destroy)
180
{
6615 siemargl 181
    (*ted_delete)(ed);
6589 siemargl 182
    free(ed->scr_w);
183
    free(ed->scr_h);
184
    free(ed->buffer);
185
    free(ed->buffer_find);
186
}
187
 
188
/// allocate memory
6615 siemargl 189
extern void (*ted_init)(editor *) __attribute__((__stdcall__));
6589 siemargl 190
 
6615 siemargl 191
/// return 1 if have selection
6589 siemargl 192
extern int (*ted_is_select)(editor *) __attribute__((__stdcall__));
193
 
194
enum control_keys {
195
    KM_SHIFT = 0x00010000,
196
    KM_CTRL = 0x00020000,
197
    KM_ALT = 0x00040000,
198
    KM_NUMLOCK = 0x00080000
199
};
200
 
201
extern void (*ted_key_asm)(editor *, char* table, int control) __attribute__((__stdcall__));
6612 siemargl 202
static inline __attribute__((__stdcall__)) void editor_keyboard(editor *ed, char* table, enum control_keys control, int ch)
6589 siemargl 203
/// control is KM_SHIFT, KM_ALT, KM_CTRL, KM_NUMLOCK,
204
/// ch = GET_KEY
205
/// table = SF_SYSTEM_GET,SSF_KEYBOARD_LAYOUT
206
{
207
    __asm__ __volatile__ (
6612 siemargl 208
             "push %4\n\t"
209
             "push %3\n\t"
210
             "push %2\n\t"
211
             "call *%1 \n\t"::"a"(ch), "m"(ted_key_asm), "m"(ed), "m"(table), "m"(control):);
212
/*
213
    __asm__ __volatile__ (
6589 siemargl 214
             "nop \n\t"::"a"(ch):);
215
    (*ted_key_asm)(ed, table, control);
6612 siemargl 216
*/
6589 siemargl 217
}
218
 
219
extern void (*ted_open_file_asm)(editor *, struct fs_dirinfo*, char *fname) __attribute__((__stdcall__));
220
static inline int editor_openfile(editor *ed, char *fname, int *readbytes)
221
/// returns errcode as SysFn70
222
{
223
    int     ret;
224
    struct fs_dirinfo   di;
225
    __asm__ __volatile__ (
6601 siemargl 226
             "push %%edi \n\t":::);
6589 siemargl 227
 
228
    (*ted_open_file_asm)(ed, &di, fname);
229
 
230
    __asm__ __volatile__ (
6601 siemargl 231
             "pop %%edi \n\t":"=b"(*readbytes), "=a"(ret)::);
6589 siemargl 232
    return ret;
233
}
234
 
235
extern void (*ted_save_file_asm)(editor *, struct fs_dirinfo*, char *fname) __attribute__((__stdcall__));
236
static inline int editor_savefile(editor *ed, char *fname)
237
/// returns errcode, calls fun_save_err() if exists
238
{
239
    struct fs_dirinfo   di;
240
 
241
    (*ted_save_file_asm)(ed, &di, fname);
242
 
243
    return ed->err_save;
244
}
245
 
246
extern void (*ted_but_cut)(editor *) __attribute__((__stdcall__));
247
 
248
extern void (*ted_but_undo)(editor *) __attribute__((__stdcall__));
249
 
250
extern void (*ted_but_redo)(editor *) __attribute__((__stdcall__));
251
 
252
extern void (*ted_but_reverse)(editor *) __attribute__((__stdcall__));
253
 
254
extern void (*ted_text_colored_asm)() __attribute__((__stdcall__));
255
static inline void editor_text_colored(editor *ed)
256
{
257
    __asm__ __volatile__ (
6615 siemargl 258
             "call *%0 \n\t"::"m"(ted_text_colored_asm), "D"(ed):);
6589 siemargl 259
 
260
}
261
 
262
static inline
263
uint32_t get_control_keys(void)
264
{
265
    uint32_t ctrl;
266
 
267
    __asm__ __volatile__(
268
    "int $0x40 \n\t"
269
    :"=a"(ctrl)
270
    :"a"(66),"b"(3));
271
 
272
    return ctrl;
273
};
274
 
275
static inline
276
int get_keyboard_layout(int opt, char* buf)
277
/// 128 byte buffer
278
/// opt: 1 - normal, 2 - shifted, 3 - alted, or 9 - return language
279
{
280
    uint32_t lang;
281
 
282
    __asm__ __volatile__(
283
    "int $0x40 \n\t"
284
    :"=a"(lang)
285
    :"a"(26),"b"(2), "c"(opt), "d"(buf));
286
 
287
    return lang;
288
};
289
 
6612 siemargl 290
__attribute__((__stdcall__))
291
static void editor_key(editor* ed, oskey_t key)
6589 siemargl 292
// callback for gui
293
{
6612 siemargl 294
    //if(ed->el_focus != ed) return;  // need to check not to lose keyb buffer
295
 
6589 siemargl 296
    uint32_t control = get_control_keys();
297
    enum control_keys ed_ctrl = 0;
298
    int ly_opt = 1;
299
    if (control & 3) { ed_ctrl |= KM_SHIFT; ly_opt = 2; }
300
    if (control & 0xC) ed_ctrl |= KM_CTRL;
301
    if (control & 0x30){ ed_ctrl |= KM_ALT; ly_opt = 3; }
302
    if (control & 0x80) ed_ctrl |= KM_NUMLOCK;
303
 
304
    char conv_table[128];
305
    get_keyboard_layout(ly_opt, conv_table);
306
 
6612 siemargl 307
    editor_keyboard(ed, conv_table, ed_ctrl, key.val);
6589 siemargl 308
}
309
 
6601 siemargl 310
static inline void gui_add_editor(kolibri_window *wnd, editor* e)
6589 siemargl 311
{
312
    kolibri_window_add_element(wnd, KOLIBRI_EDITOR, e);
313
}
314
 
6612 siemargl 315
static inline editor* kolibri_new_editor(uint32_t x_w, uint32_t y_h, uint32_t font, uint32_t max_chars, void *editor_interlock)
6589 siemargl 316
/// font - 0b10SSS 8x16 size multiply (SSS+1), 0xSSS - 6x9 multiply (SSS+1)
317
 
318
{
319
    editor *ed = (editor *)calloc(1, sizeof(editor));
320
    ed->x_pos = x_w >> 16;
321
    ed->width = x_w & 0xFFFF;
322
    ed->y_pos = y_h >> 16;
323
    ed->hight = y_h & 0xFFFF;
324
 
6612 siemargl 325
    ed->w_pane = 30;
326
    ed->h_pane = 20;
6589 siemargl 327
    // font
328
    if (font == 0) font = 0x10;  // default 16 = 8x16
329
    int font_multipl = (font & 7) + 1;
330
    ed->font_size = font << 24;
331
    if (font & 0x10) // 8x16
332
    {
333
        ed->width_sym = 8 * font_multipl;
334
        ed->hight_sym = 16 * font_multipl;
335
    } else   // 6x9
336
    {
337
        ed->width_sym = 6 * font_multipl;
338
        ed->hight_sym = 9 * font_multipl;
339
    }
340
    // memory sizing for text & syntax
341
    ed->max_chars = max_chars;
342
    ed->increase_size = max_chars / 2;
343
    ed->syntax_file_size = sizeof (default_syntax);
344
 
345
/* // loaded auto from syntax
346
    ed->color_cursor = 0x808080;
347
    ed->color_wnd_capt = 0x80;
348
    ed->color_wnd_bord = 0xd0d0d0;
349
    ed->color_select = 0x208080;
350
    ed->color_cur_text = 0xff0000;
351
    ed->color_wnd_text = 0xffff00;
352
*/
353
    ed->symbol_new_line = 20;  // ascii(20)
354
 
6612 siemargl 355
    ed->scr_w = kolibri_new_scrollbar_def(X_Y(0, 16), X_Y(0, 0), 100, 30, 0);  // cur_area will be inited ltr, max & pos undef
356
    ed->scr_h = kolibri_new_scrollbar_def(X_Y(0, 0), X_Y(0, 16), 100, 30, 0);  // cur_area will be inited ltr, max & pos undef
6589 siemargl 357
 
358
    ed->buffer_size = TE_BUF_SIZE;
359
    ed->buffer = malloc(TE_BUF_SIZE);
360
    ed->buffer_find = malloc(TE_BUF_SIZE / 8);  //where to store text to search
361
 
362
    ed->cur_ins = 1; // insert mode default
363
    ed->mode_color = 1; // can select text
364
    ed->mode_invis = 1; // show nonprinted symbols
365
 
6612 siemargl 366
    ed->el_focus = editor_interlock;
367
 
6615 siemargl 368
    (*ted_init)(ed);  // memory allocation, cleaning
6589 siemargl 369
    ed->syntax_file = (char*)&default_syntax;
370
    (*ted_init_syntax_file)(ed); // load colors and syntax highlight
371
    ed->help_text_f1 = f1_table; // override if not aligned immediately after syntax words
372
    ed->key_words_data = &word1;
373
 
374
    return ed;
375
}
376
 
6615 siemargl 377
/// return 1 if symbol is not visible (deleted or undo-ed)
378
static inline int editor_symbol_not_vis(editor* ed, struct editor_symbol* sym)
379
{
380
    return (sym->td && sym->td + ed->tim_undo <= ed->tim_ch) || (sym->tc > ed->tim_ch - ed->tim_undo);
381
}
6589 siemargl 382
 
6615 siemargl 383
/// returns next good symbol by index
384
static inline
385
uint32_t editor_iterat_next(editor* ed, uint32_t idx)
386
{
387
    uint32_t  i;
388
    if (ed->tim_undo)
389
    {
390
        for (i = ed->tex[idx].next; i != 0 && (ed->tex[i].c == '\n' || editor_symbol_not_vis(ed, ed->tex + i)); i = ed->tex[i].next);
391
    } else
392
    {
393
        for (i = ed->tex[idx].next; i != 0 && (ed->tex[i].c == '\n' || ed->tex[i].td); i = ed->tex[i].next);
394
    }
395
    return i;
396
}
397
 
398
// returns malloc'ed mem
399
static inline
400
char*  editor_get_text(editor* ed)
401
{
402
    char    *buf = malloc(ed->max_chars), *pc = buf;
403
    if (!pc) return NULL;
404
 
405
    int  i;
406
//    *pc++ = ed->tex[0].c;
407
    for (i = ed->tex[0].next; i; i = editor_iterat_next(ed, i)) *pc++ = ed->tex[i].c;
408
    *pc++ = '\0';
409
 
410
    return buf;
411
}
412
 
413
/*
414
char*  editor_get_text20(editor* ed)
415
{
416
    char    *buf = malloc(ed->max_chars), *pc = buf;
417
    if (!pc) return NULL;
418
 
419
    int  i = ed->tex[0].next, c = 0;
420
    for (; i > 0 && c < 30; c++, i = ed->tex[i].next) *pc++ = ed->tex[i].c;
421
    *pc++ = '\0';
422
 
423
    return buf;
424
}
425
*/
6589 siemargl 426
#endif // KOLIBRI_EDITOR_H