summaryrefslogtreecommitdiff
path: root/main.lua
blob: 1e904f8413a8c6691019775d28eceb49d9f4eafe (plain)
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
dofile("require.lua")

local util = require("util")
local ffi = require("ffi")

ffi.cdef [[
typedef unsigned char Eina_Bool;
typedef int Evas_Coord;
typedef int Evas_Font_Size;

typedef struct _Evas_Point Evas_Point;
struct _Evas_Point {
    int x, y;
};

typedef struct _Evas_Coord_Point Evas_Coord_Point;
struct _Evas_Coord_Point {
    Evas_Coord x;
    Evas_Coord y;
};

typedef struct _Evas_Position Evas_Position;
struct _Evas_Position {
    Evas_Point output;
    Evas_Coord_Point canvas;
};

typedef struct _Evas_Modifier Evas_Modifier;
typedef struct _Evas_Lock Evas_Lock;
typedef struct _Evas_Device Evas_Device;
typedef struct _Evas_Object Evas_Object;
typedef struct _Evas_Map Evas_Map;
typedef struct _Evas Evas;

typedef enum _Evas_Engine_Render_Mode {
    EVAS_RENDER_MODE_BLOCKING = 0,
    EVAS_RENDER_MODE_NONBLOCKING = 1,
} Evas_Engine_Render_Mode;

int evas_init(void);
int evas_shutdown(void);

typedef struct _Evas_Version {
    int major, minor, micro, revision;
} Evas_Version;
extern Evas_Version *evas_version;

typedef struct _Evas_Engine_Info Evas_Engine_Info;
struct _Evas_Engine_Info {
    int magic;
};

Evas_Engine_Info *evas_engine_info_get(const Evas *e);
Eina_Bool evas_engine_info_set(Evas *e, Evas_Engine_Info *info);

void evas_output_method_get(Evas *e);
void evas_output_method_set(Evas *e, int render_method);
void evas_output_size_set(Evas *e, int w, int h);
void evas_output_viewport_set(Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);

void evas_render(Evas *e);
Eina_Bool evas_render_async(Evas *e);
void evas_sync(Evas *e);
int evas_render_method_lookup(const char *name);

void evas_damage_rectangle_add(Evas *e, int x, int y, int w, int h);

typedef enum _Evas_Button_Flags {
    EVAS_BUTTON_NONE = 0,
    EVAS_BUTTON_DOUBLE_CLICK = (1 << 0),
    EVAS_BUTTON_TRIPLE_CLICK = (1 << 1)
} Evas_Button_Flags;

typedef enum _Evas_Event_Flags {
    EVAS_EVENT_FLAG_NONE = 0,
    EVAS_EVENT_FLAG_ON_HOLD = (1 << 0),
    EVAS_EVENT_FLAG_ON_SCROLL = (1 << 1)
} Evas_Event_Flags;

typedef struct _Evas_Event_Key_Down Evas_Event_Key_Down;
typedef struct _Evas_Event_Mouse_Down Evas_Event_Mouse_Down;
typedef struct _Evas_Event_Mouse_Up Evas_Event_Mouse_Up;
typedef struct _Evas_Event_Mouse_Move Evas_Event_Mouse_Move;

struct _Evas_Event_Mouse_Down {
    int button;
    Evas_Point output;
    Evas_Coord_Point canvas;
    void *data;
    Evas_Modifier *modifiers;
    Evas_Lock *locks;
    Evas_Button_Flags flags;
    unsigned int timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device *dev;
    Evas_Object *event_src;
};
struct _Evas_Event_Mouse_Up {
    int button;
    Evas_Point output;
    Evas_Coord_Point canvas;
    void *data;
    Evas_Modifier *modifiers;
    Evas_Lock *locks;
    Evas_Button_Flags flags;
    unsigned int timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device *dev;
    Evas_Object *event_src;
};
struct _Evas_Event_Mouse_Move {
    int buttons;
    Evas_Position cur;
    Evas_Position prev;
    void *data;
    Evas_Modifier *modifiers;
    Evas_Lock *locks;
    unsigned int timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device *dev;
    Evas_Object *event_src;
};
struct _Evas_Event_Key_Down {
    char *keyname;
    void *data;
    Evas_Modifier *modifiers;
    Evas_Lock *locks;
    const char *key;
    const char *string;
    const char *compose;
    unsigned int timestamp;
    Evas_Event_Flags event_flags;
    Evas_Device *dev;
};

typedef enum _Evas_Callback_Type {
    EVAS_CALLBACK_MOUSE_IN,
    EVAS_CALLBACK_MOUSE_OUT,
    EVAS_CALLBACK_MOUSE_DOWN,
    EVAS_CALLBACK_MOUSE_UP,
    EVAS_CALLBACK_MOUSE_MOVE,
    EVAS_CALLBACK_MOUSE_WHEEL,
    EVAS_CALLBACK_MULTI_DOWN,
    EVAS_CALLBACK_MULTI_UP,
    EVAS_CALLBACK_MULTI_MOVE,
    EVAS_CALLBACK_FREE,
    EVAS_CALLBACK_KEY_DOWN,
    EVAS_CALLBACK_KEY_UP,
    EVAS_CALLBACK_FOCUS_IN,
    EVAS_CALLBACK_FOCUS_OUT,
    EVAS_CALLBACK_SHOW,
    EVAS_CALLBACK_HIDE,
    EVAS_CALLBACK_MOVE,
    EVAS_CALLBACK_RESIZE,
    EVAS_CALLBACK_RESTACK,
    EVAS_CALLBACK_DEL,
    EVAS_CALLBACK_HOLD,
    EVAS_CALLBACK_CHANGED_SIZE_HINTS,
    EVAS_CALLBACK_IMAGE_PRELOADED,
    EVAS_CALLBACK_CANVAS_FOCUS_IN,
    EVAS_CALLBACK_CANVAS_FOCUS_OUT,
    EVAS_CALLBACK_RENDER_FLUSH_PRE,
    EVAS_CALLBACK_RENDER_FLUSH_POST,
    EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
    EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
    EVAS_CALLBACK_IMAGE_UNLOADED,
    EVAS_CALLBACK_RENDER_PRE,
    EVAS_CALLBACK_RENDER_POST,
    EVAS_CALLBACK_IMAGE_RESIZE,
    EVAS_CALLBACK_DEVICE_CHANGED,
    EVAS_CALLBACK_LAST
} Evas_Callback_Type;

typedef void (*Evas_Object_Event_Cb)(void *data, Evas *e, Evas_Object *obj, void *event_info);

void evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data);
void evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data);

void evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
void evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
void evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data);
void evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data);
void evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const void *data);

void evas_font_path_append(Evas *e, const char *path);
void evas_font_cache_set(Evas *e, int size);

typedef enum _Evas_Font_Hinting_Flags {
    EVAS_FONT_HINTING_NONE,
    EVAS_FONT_HINTING_AUTO,
    EVAS_FONT_HINTING_BYTECODE
} Evas_Font_Hinting_Flags;

void evas_font_hinting_set(Evas *e, Evas_Font_Hinting_Flags hinting);

void evas_free(Evas *e);
void evas_image_cache_set(Evas *e, int size);

void evas_key_lock_add(Evas *e, const char *keyname);
Eina_Bool evas_key_lock_is_set(const Evas_Lock *l, const char *keyname);
Evas_Lock *evas_key_lock_get(const Evas *e);
void evas_key_lock_on(Evas *e, const char *keyname);
void evas_key_lock_off(Evas *e, const char *keyname);

void evas_key_modifier_add(Evas *e, const char *keyname);
void evas_key_modifier_on(Evas *e, const char *keyname);
void evas_key_modifier_off(Evas *e, const char *keyname);


Evas_Map *evas_map_new(int count);
void evas_map_point_color_set(Evas_Map *m, int idx, int r, int g, int b, int a);
void evas_map_point_coord_set(Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_Coord z);
void evas_map_point_coord_get(const Evas_Map *m, int idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z);
void evas_map_point_image_uv_set(Evas_Map *m, int idx, double u, double v);
void evas_map_smooth_set(Evas_Map *m, Eina_Bool enabled);
Eina_Bool evas_map_util_clockwise_get(Evas_Map *m);
void evas_map_util_points_populate_from_geometry(Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Evas_Coord z);
void evas_map_util_rotate(Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy);
void evas_map_util_3d_lighting(Evas_Map *m, Evas_Coord lx, Evas_Coord ly, Evas_Coord lz, int lr, int lg, int lb, int ar, int ag, int ab);
void evas_map_util_3d_perspective(Evas_Map *m, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc);
void evas_map_util_3d_rotate(Evas_Map *m, double dx, double dy, double dz, Evas_Coord cx, Evas_Coord cy, Evas_Coord cz);

Evas *evas_new(void);

void evas_object_color_set(Evas_Object *obj, int r, int g, int b, int a);
void evas_object_show(Evas_Object *obj);
void evas_object_hide(Evas_Object *obj);
void evas_object_del(Evas_Object *obj);
void evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
void evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
void evas_object_event_callback_add(Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data);
void evas_object_focus_set(Evas_Object *obj, Eina_Bool focus);
void evas_object_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);

void evas_object_layer_set(Evas_Object *obj, short l);
Evas_Object *evas_object_line_add(Evas *e);
void evas_object_line_xy_set(Evas_Object *obj, Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2);
void evas_object_line_xy_get(const Evas_Object *obj, Evas_Coord *x1, Evas_Coord *y1, Evas_Coord *x2, Evas_Coord *y2);

void evas_object_lower(Evas_Object *obj);
void evas_object_raise(Evas_Object *obj);

void evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled);
void evas_object_map_set(Evas_Object *obj, const Evas_Map *map);
void evas_object_pass_events_set(Evas_Object *obj, Eina_Bool pass);

void evas_object_stack_above(Evas_Object *obj, Evas_Object *above);
void evas_object_stack_below(Evas_Object *obj, Evas_Object *below);

typedef enum _Evas_Border_Fill_Mode {
    EVAS_BORDER_FILL_NONE = 0,
    EVAS_BORDER_FILL_DEFAULT = 1,
    EVAS_BORDER_FILL_SOLID = 2
} Evas_Border_Fill_Mode;

typedef enum _Evas_Colorspace {
    EVAS_COLORSPACE_ARGB8888,
    EVAS_COLORSPACE_YCBCR422P601_PL,
    EVAS_COLORSPACE_YCBCR422P709_PL,
    EVAS_COLORSPACE_RGB565_A5P,
    EVAS_COLORSPACE_GRY8,
    EVAS_COLORSPACE_YCBCR422601_PL,
    EVAS_COLORSPACE_YCBCR420NV12601_PL,
    EVAS_COLORSPACE_YCBCR420TM12601_PL,
} Evas_Colorspace;

typedef enum _Evas_Image_Content_Hint {
    EVAS_IMAGE_CONTENT_HINT_NONE = 0,
    EVAS_IMAGE_CONTENT_HINT_DYNAMIC = 1,
    EVAS_IMAGE_CONTENT_HINT_STATIC = 2
} Evas_Image_Content_Hint;

Evas_Object *evas_object_image_add(Evas *e);
void evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha);
void evas_object_image_border_center_fill_set(Evas_Object *obj, Evas_Border_Fill_Mode fill);
void evas_object_image_border_set(Evas_Object *obj, int l, int r, int t, int b);
void evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace);
void evas_object_image_content_hint_set(Evas_Object *obj, Evas_Image_Content_Hint hint);
void *evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing);
void evas_object_image_data_set(Evas_Object *obj, void *data);
void evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h);
void evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key);
void evas_object_image_filled_set(Evas_Object *obj, Eina_Bool setting);
void evas_object_image_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
void evas_object_image_size_set(Evas_Object *obj, int w, int h);
void evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth_scale);
Eina_Bool evas_object_image_source_set(Evas_Object *obj, Evas_Object *src);
int evas_object_image_stride_get(const Evas_Object *obj);

Evas_Object *evas_object_polygon_add(Evas *e);
void evas_object_polygon_point_add(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
void evas_object_polygon_points_clear(Evas_Object *obj);

Evas_Object *evas_object_rectangle_add(Evas *e);

typedef enum _Evas_Text_Style_Type {
    EVAS_TEXT_STYLE_PLAIN,
    EVAS_TEXT_STYLE_SHADOW,
    EVAS_TEXT_STYLE_OUTLINE,
    EVAS_TEXT_STYLE_SOFT_OUTLINE,
    EVAS_TEXT_STYLE_GLOW,
    EVAS_TEXT_STYLE_OUTLINE_SHADOW,
    EVAS_TEXT_STYLE_FAR_SHADOW,
    EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW,
    EVAS_TEXT_STYLE_SOFT_SHADOW,
    EVAS_TEXT_STYLE_FAR_SOFT_SHADOW,
    EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT = (0x0 << 4),
    EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM = (0x1 << 4),
    EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT = (0x2 << 4),
    EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT = (0x3 << 4),
    EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT = (0x4 << 4),
    EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP = (0x5 << 4),
    EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT = (0x6 << 4),
    EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT = (0x7 << 4)
} Evas_Text_Style_Type;

Evas_Object *evas_object_text_add(Evas *e);
void evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size size);
void evas_object_text_glow_color_set(Evas_Object *obj, int r, int g, int b, int a);
void evas_object_text_glow2_color_set(Evas_Object *obj, int r, int g, int b, int a);
void evas_object_text_outline_color_set(Evas_Object *obj, int r, int g, int b, int a);
void evas_object_text_shadow_color_set(Evas_Object *obj, int r, int g, int b, int a);
void evas_object_text_style_set(Evas_Object *obj, Evas_Text_Style_Type type);
void evas_object_text_text_set(Evas_Object *obj, const char *text);

typedef struct _Evas_Textblock_Style Evas_Textblock_Style;
typedef struct _Evas_Textblock_Cursor Evas_Textblock_Cursor;

Evas_Object *evas_object_textblock_add(Evas *e);
void evas_object_textblock_style_set(Evas_Object *obj, const Evas_Textblock_Style *ts);
void evas_object_textblock_text_markup_set(Evas_Object *obj, const char *text);
Evas_Textblock_Cursor *evas_object_textblock_cursor_get(const Evas_Object *obj);
Evas_Textblock_Cursor *evas_object_textblock_cursor_new(const Evas_Object *obj);
void evas_object_textblock_clear(Evas_Object *obj);
void evas_object_textblock_size_native_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);

void evas_textblock_cursor_free(Evas_Textblock_Cursor *cur);
void evas_textblock_cursor_paragraph_first(Evas_Textblock_Cursor *cur);
void evas_textblock_cursor_paragraph_last(Evas_Textblock_Cursor *cur);
void evas_textblock_cursor_paragraph_char_first(Evas_Textblock_Cursor *cur);
Eina_Bool evas_textblock_cursor_paragraph_next(Evas_Textblock_Cursor *cur);
void evas_textblock_cursor_char_delete(Evas_Textblock_Cursor *cur);
int evas_textblock_cursor_compare(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2);
int evas_textblock_cursor_text_append(Evas_Textblock_Cursor *cur, const char *text);

Evas_Textblock_Style *evas_textblock_style_new(void);
void evas_textblock_style_free(Evas_Textblock_Style *ts);
void evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text);
]]

local levas = assert(util.load_lib("evas"), "could not load evas")

local ui = require("ui")

local go = true
local loop_func

engine_abort = function()
    go = false
    return go
end

engine_loop = function()
    loop_func()
end
local engine_loop = engine_loop

local engines = {}

have_engine_x11 = false

require("engine_x11").init(engines, "software_x11")
require("engine_x11").init(engines, "gl_x11")

local C = ffi.C

local main = function(args)
    local xlib = util.get_lib("X11")
    if xlib then xlib.XInitThreads() end -- only use if X11 engine is available
    levas.evas_init()
    local evas = levas.evas_new()

    local engine
    local dtdir

    local conf = {
        ["engine"] = function(val)
            for i = 1, #engines do
                local eng = engines[i]
                if val == eng[1] then
                    engine = eng
                    break
                end
            end
            return engine
        end,
        ["datadir"] = function(val)
            dtdir = val
            return val
        end
    }
    conf.evas = evas
    conf.engines = engines

    util.parse_args(args, conf, engines)

    if not engine then util.help() end

    local w, h = conf.profile.w, conf.profile.h
    levas.evas_output_size_set(evas, w, h)
    levas.evas_output_viewport_set(evas, 0, 0, w, h)

    local engine_shutdown
    if engine[2](engine[1], conf.profile.w, conf.profile.h) then
        loop_func, engine_shutdown = engine[3], engine[4]
    end

    if not loop_func then util.help() end

    levas.evas_key_modifier_add(evas, "Shift")
    levas.evas_key_modifier_add(evas, "Control")
    levas.evas_key_modifier_add(evas, "Alt")
    levas.evas_key_modifier_add(evas, "Super")
    levas.evas_key_lock_add(evas, "Caps_Lock")
    levas.evas_key_lock_add(evas, "Num_Lock")
    levas.evas_key_lock_add(evas, "Scroll_Lock")
    -- levas.evas_image_cache_set(evas, 4 * 1024 * 1024)
    -- levas.evas_font_cache_set(evas, 1 * 1024 * 1024)

    local prefix = dtdir
    if not prefix then
        prefix = util.getenv("LUAXPEDITE_FONTS_DIR")
    end
    if not prefix then
        prefix = "./data"
    end
    levas.evas_font_path_append(evas, prefix)

    ui.setup(conf)
    levas.evas_font_hinting_set(evas, 1) -- autohint
    local async = conf.async
    local ui_loop = ui.loop

    if async then goto async_loop end

    while go do
        engine_loop()
        ui_loop()
        levas.evas_render(evas)
    end
    goto finish

    ::async_loop::
    while go do
        engine_loop()
        ui_loop()
        levas.evas_sync(evas)
        levas.evas_render_async(evas)
    end

    ::finish::
    levas.evas_free(evas)
    engine_shutdown()
    levas.evas_shutdown()
    return 0
end
main(arg)