aboutsummaryrefslogtreecommitdiff
path: root/include/mgl/window/window.h
blob: cbcdb1a531c3e8cdb7512d9f81dfbe05c4ed8f6e (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
#ifndef MGL_WINDOW_H
#define MGL_WINDOW_H

#include "../graphics/color.h"
#include "../system/vec.h"
#include "../system/clock.h"
#include "key.h"
#include "mouse_button.h"
#include <stdbool.h>
#include <stddef.h>

/* Vsync is automatically set for created windows, if supported by the system */

typedef struct mgl_event mgl_event;
/* x11 window handle. TODO: Add others when wayland, etc is added */
typedef unsigned long mgl_window_handle;

typedef struct mgl_window mgl_window;

typedef struct {
    mgl_vec2i position;
    mgl_vec2i size;
} mgl_view;

typedef struct {
    mgl_vec2i position;
    mgl_vec2i size;
} mgl_scissor;

typedef struct {
    int id; /* output id */
    int crtc_id;
    const char *name;
    mgl_vec2i pos;
    mgl_vec2i size;
    int refresh_rate;
} mgl_monitor;

struct mgl_window {
    mgl_window_handle window;
    void *context;
    mgl_vec2i pos;
    mgl_vec2i size;
    /* relative to the top left of the window. only updates when the cursor is inside the window */
    mgl_vec2i cursor_position;
    mgl_view view;
    mgl_scissor scissor;
    bool open;
    bool focused;
    bool key_repeat_enabled;
    bool vsync_enabled; /* true by default */
    double frame_time_limit;
    double frame_time_limit_monitor;
    mgl_clock frame_timer;
    char *clipboard_string;
    size_t clipboard_size;
    bool low_latency; /* false by default */

    mgl_monitor *monitors; /* TODO: Move these to mgl file */
    int num_monitors;
};

/* TODO: Some of these parameters only apply to new window */
typedef struct {
    mgl_vec2i position;
    mgl_vec2i size;
    mgl_vec2i min_size;              /* (0, 0) = no limit */
    mgl_vec2i max_size;              /* (0, 0) = no limit */
    mgl_window_handle parent_window; /* 0 = root window */
    bool hidden;                     /* false by default */
    bool override_redirect;          /* false by default */
    bool support_alpha;              /* support alpha for the window, false by default */
    mgl_color background_color;      /* default: black */
} mgl_window_create_params;

typedef enum {
    MGL_CLIPBOARD_TYPE_STRING       = 1 << 0,
    MGL_CLIPBOARD_TYPE_IMAGE_PNG    = 1 << 1,
    MGL_CLIPBOARD_TYPE_IMAGE_JPG    = 1 << 2,
    MGL_CLIPBOARD_TYPE_IMAGE_GIF    = 1 << 3,
} mgl_clipboard_type;

#define MGL_CLIPBOARD_TYPE_ALL 0xFFFFFFFF
#define MGL_CLIPBOARD_TYPE_IMAGE (MGL_CLIPBOARD_TYPE_IMAGE_PNG | MGL_CLIPBOARD_TYPE_IMAGE_JPG | MGL_CLIPBOARD_TYPE_IMAGE_GIF)

/*
    Return true to continue. |mgl_window_get_clipboard| returns false if this returns false.
    Note: |size| is the size of the current data, not the total data (if the callback only contains a part of the data).
*/
typedef bool (*mgl_clipboard_callback)(const unsigned char *data, size_t size, mgl_clipboard_type clipboard_type, void *userdata);

/* |params| can be NULL. Note: vsync is enabled by default */
int mgl_window_create(mgl_window *self, const char *title, const mgl_window_create_params *params);
int mgl_window_init_from_existing_window(mgl_window *self, mgl_window_handle existing_window);
void mgl_window_deinit(mgl_window *self);

void mgl_window_clear(mgl_window *self, mgl_color color);
bool mgl_window_poll_event(mgl_window *self, mgl_event *event);
void mgl_window_display(mgl_window *self);

/*
    This should be called every frame to retain the view.
    Make sure to set the view back to the previous view after rendering items
    by saving the previous view with |mgl_window_get_view| and then call
    |mgl_window_set_view| with that saved view.
    The view is set to the window size when the window is resized (window resize event).
*/
void mgl_window_set_view(mgl_window *self, mgl_view *new_view);
void mgl_window_get_view(mgl_window *self, mgl_view *view);

/*
    This should be called every frame to retain the scissor.
    Make sure to set the scissor back to the previous view after rendering items
    by saving the previous scissor with |mgl_window_get_scissor| and then call
    |mgl_window_set_scissor| with that saved scissor.
    The scissor is set to the window size when the window is resized (window resize event).
*/
void mgl_window_set_scissor(mgl_window *self, mgl_scissor *new_scissor);
void mgl_window_get_scissor(mgl_window *self, mgl_scissor *scissor);

void mgl_window_set_visible(mgl_window *self, bool visible);
bool mgl_window_is_open(const mgl_window *self);
bool mgl_window_has_focus(const mgl_window *self);
bool mgl_window_is_key_pressed(const mgl_window *self, mgl_key key);
bool mgl_window_is_mouse_button_pressed(const mgl_window *self, mgl_mouse_button button);

void mgl_window_close(mgl_window *self);
void mgl_window_set_title(mgl_window *self, const char *title);
void mgl_window_set_cursor_visible(mgl_window *self, bool visible);
/* 0 = no fps limit, or limit fps to vsync if vsync is enabled */
void mgl_window_set_framerate_limit(mgl_window *self, int fps);
void mgl_window_set_vsync_enabled(mgl_window *self, bool enabled);
bool mgl_window_is_vsync_enabled(const mgl_window *self);
void mgl_window_set_fullscreen(mgl_window *self, bool fullscreen);
bool mgl_window_is_fullscreen(const mgl_window *self);
/* Enabling low latency may slightly increase cpu usage */
void mgl_window_set_low_latency(mgl_window *self, bool low_latency);
bool mgl_window_is_low_latency_enabled(const mgl_window *self);

void mgl_window_set_position(mgl_window *self, mgl_vec2i position);
void mgl_window_set_size(mgl_window *self, mgl_vec2i size);
/* if |minimum| is (0, 0) then there is no minimum limit, if |maximum| is (0, 0) then there is no maximum limit */
void mgl_window_set_size_limits(mgl_window *self, mgl_vec2i minimum, mgl_vec2i maximum);

void mgl_window_set_clipboard(mgl_window *self, const char *str, size_t size);
/* clipboard_types should be a bit-or of mgl_clipboard_type */
bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback, void *userdata, uint32_t clipboard_types);
/*
    A new string is allocated and the pointer is copied to |str| with the size returned in |size|.
    |str| should be deallocated with |free| by the user.
    This function returns false if there is nothing to copy, or if the clipboard
    contains clipboard data that is not a string or if it fails to copy the data
    for any other reason.
    Note: The string is not null terminated.
*/
bool mgl_window_get_clipboard_string(mgl_window *self, char **str, size_t *size);
void mgl_window_set_key_repeat_enabled(mgl_window *self, bool enabled);

#endif /* MGL_WINDOW_H */