1 /*
2   Copyright 2012-2014 David Robillard <http://drobilla.net>
3   Copyright 2012-2019 Filipe Coelho <falktx@falktx.com>
4 
5   Permission to use, copy, modify, and/or distribute this software for any
6   purpose with or without fee is hereby granted, provided that the above
7   copyright notice and this permission notice appear in all copies.
8 
9   THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 
18 /**
19    @file pugl_internal.h Private platform-independent definitions.
20 
21    Note this file contains function definitions, so it must be compiled into
22    the final binary exactly once.  Each platform specific implementation file
23    including it once should achieve this.
24 */
25 
26 #include "pugl.h"
27 
28 typedef struct PuglInternalsImpl PuglInternals;
29 
30 struct PuglViewImpl {
31 	PuglHandle       handle;
32 	PuglCloseFunc    closeFunc;
33 	PuglDisplayFunc  displayFunc;
34 	PuglKeyboardFunc keyboardFunc;
35 	PuglMotionFunc   motionFunc;
36 	PuglMouseFunc    mouseFunc;
37 	PuglReshapeFunc  reshapeFunc;
38 	PuglResizeFunc   resizeFunc;
39 	PuglScrollFunc   scrollFunc;
40 	PuglSpecialFunc  specialFunc;
41 	PuglFileSelectedFunc fileSelectedFunc;
42 
43 	PuglInternals*   impl;
44 	PuglNativeWindow parent;
45 	uintptr_t        transient_parent;
46 
47 	int      width;
48 	int      height;
49 	int      min_width;
50 	int      min_height;
51 	int      mods;
52 	bool     mouse_in_view;
53 	bool     ignoreKeyRepeat;
54 	bool     redisplay;
55 	bool     user_resizable;
56 	bool     pending_resize;
57 	uint32_t event_timestamp_ms;
58 };
59 
60 PuglInternals* puglInitInternals(void);
61 
62 PuglView*
puglInit(void)63 puglInit(void)
64 {
65 	PuglView* view = (PuglView*)calloc(1, sizeof(PuglView));
66 	if (!view) {
67 		return NULL;
68 	}
69 
70 	PuglInternals* impl = puglInitInternals();
71 	if (!impl) {
72 		free(view);
73 		return NULL;
74 	}
75 
76 	view->impl   = impl;
77 	view->width  = 640;
78 	view->height = 480;
79 
80 	return view;
81 }
82 
83 void
puglInitWindowSize(PuglView * view,int width,int height)84 puglInitWindowSize(PuglView* view, int width, int height)
85 {
86 	view->width  = width;
87 	view->height = height;
88 }
89 
90 void
puglInitWindowMinSize(PuglView * view,int width,int height)91 puglInitWindowMinSize(PuglView* view, int width, int height)
92 {
93 	view->min_width  = width;
94 	view->min_height = height;
95 }
96 
97 void
puglInitWindowParent(PuglView * view,PuglNativeWindow parent)98 puglInitWindowParent(PuglView* view, PuglNativeWindow parent)
99 {
100 	view->parent = parent;
101 }
102 
103 void
puglInitUserResizable(PuglView * view,bool resizable)104 puglInitUserResizable(PuglView* view, bool resizable)
105 {
106 	view->user_resizable = resizable;
107 }
108 
109 void
puglInitTransientFor(PuglView * view,uintptr_t parent)110 puglInitTransientFor(PuglView* view, uintptr_t parent)
111 {
112 	view->transient_parent = parent;
113 }
114 
115 PuglView*
puglCreate(PuglNativeWindow parent,const char * title,int min_width,int min_height,int width,int height,bool resizable,unsigned long transientId)116 puglCreate(PuglNativeWindow parent,
117            const char*      title,
118            int              min_width,
119            int              min_height,
120            int              width,
121            int              height,
122            bool             resizable,
123            unsigned long    transientId)
124 {
125 	PuglView* view = puglInit();
126 	if (!view) {
127 		return NULL;
128 	}
129 
130 	puglInitWindowParent(view, parent);
131 	puglInitWindowMinSize(view, min_width, min_height);
132 	puglInitWindowSize(view, width, height);
133 	puglInitUserResizable(view, resizable);
134 	puglInitTransientFor(view, transientId);
135 
136 	if (!puglCreateWindow(view, title)) {
137 		free(view);
138 		return NULL;
139 	}
140 
141 	return view;
142 }
143 
144 void
puglSetHandle(PuglView * view,PuglHandle handle)145 puglSetHandle(PuglView* view, PuglHandle handle)
146 {
147 	view->handle = handle;
148 }
149 
150 PuglHandle
puglGetHandle(PuglView * view)151 puglGetHandle(PuglView* view)
152 {
153 	return view->handle;
154 }
155 
156 uint32_t
puglGetEventTimestamp(PuglView * view)157 puglGetEventTimestamp(PuglView* view)
158 {
159 	return view->event_timestamp_ms;
160 }
161 
162 int
puglGetModifiers(PuglView * view)163 puglGetModifiers(PuglView* view)
164 {
165 	return view->mods;
166 }
167 
168 void
puglIgnoreKeyRepeat(PuglView * view,bool ignore)169 puglIgnoreKeyRepeat(PuglView* view, bool ignore)
170 {
171 	view->ignoreKeyRepeat = ignore;
172 }
173 
174 void
puglSetCloseFunc(PuglView * view,PuglCloseFunc closeFunc)175 puglSetCloseFunc(PuglView* view, PuglCloseFunc closeFunc)
176 {
177 	view->closeFunc = closeFunc;
178 }
179 
180 void
puglSetDisplayFunc(PuglView * view,PuglDisplayFunc displayFunc)181 puglSetDisplayFunc(PuglView* view, PuglDisplayFunc displayFunc)
182 {
183 	view->displayFunc = displayFunc;
184 }
185 
186 void
puglSetKeyboardFunc(PuglView * view,PuglKeyboardFunc keyboardFunc)187 puglSetKeyboardFunc(PuglView* view, PuglKeyboardFunc keyboardFunc)
188 {
189 	view->keyboardFunc = keyboardFunc;
190 }
191 
192 void
puglSetMotionFunc(PuglView * view,PuglMotionFunc motionFunc)193 puglSetMotionFunc(PuglView* view, PuglMotionFunc motionFunc)
194 {
195 	view->motionFunc = motionFunc;
196 }
197 
198 void
puglSetMouseFunc(PuglView * view,PuglMouseFunc mouseFunc)199 puglSetMouseFunc(PuglView* view, PuglMouseFunc mouseFunc)
200 {
201 	view->mouseFunc = mouseFunc;
202 }
203 
204 void
puglSetReshapeFunc(PuglView * view,PuglReshapeFunc reshapeFunc)205 puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc)
206 {
207 	view->reshapeFunc = reshapeFunc;
208 }
209 
210 void
puglSetResizeFunc(PuglView * view,PuglResizeFunc resizeFunc)211 puglSetResizeFunc(PuglView* view, PuglResizeFunc resizeFunc)
212 {
213 	view->resizeFunc = resizeFunc;
214 }
215 
216 void
puglSetScrollFunc(PuglView * view,PuglScrollFunc scrollFunc)217 puglSetScrollFunc(PuglView* view, PuglScrollFunc scrollFunc)
218 {
219 	view->scrollFunc = scrollFunc;
220 }
221 
222 void
puglSetSpecialFunc(PuglView * view,PuglSpecialFunc specialFunc)223 puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc)
224 {
225 	view->specialFunc = specialFunc;
226 }
227 
228 void
puglSetFileSelectedFunc(PuglView * view,PuglFileSelectedFunc fileSelectedFunc)229 puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc)
230 {
231 	view->fileSelectedFunc = fileSelectedFunc;
232 }
233 
234 void
235 puglEnterContext(PuglView* view);
236 
237 void
238 puglLeaveContext(PuglView* view, bool flush);
239 
240 static void
puglDefaultReshape(int width,int height)241 puglDefaultReshape(int width, int height)
242 {
243 #ifdef PUGL_OPENGL
244 #ifdef ROBTK_HERE
245 	glViewport(0, 0, width, height);
246 	glMatrixMode(GL_PROJECTION);
247 	glLoadIdentity();
248 	glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
249 	glClear(GL_COLOR_BUFFER_BIT);
250 
251 	glMatrixMode(GL_MODELVIEW);
252 	glLoadIdentity();
253 #else
254 	glMatrixMode(GL_PROJECTION);
255 	glLoadIdentity();
256 	glOrtho(0, width, height, 0, 0, 1);
257 	glViewport(0, 0, width, height);
258 
259 	glMatrixMode(GL_MODELVIEW);
260 	glLoadIdentity();
261 #endif
262 #endif // PUGL_OPENGL
263 }
264