Skip to content

Latest commit

 

History

History
671 lines (572 loc) · 19.6 KB

SDL_BWin.h

File metadata and controls

671 lines (572 loc) · 19.6 KB
 
1
2
/*
Simple DirectMedia Layer
Jan 17, 2020
Jan 17, 2020
3
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
Aug 28, 2017
Aug 28, 2017
22
23
#ifndef SDL_BWin_h_
#define SDL_BWin_h_
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#ifdef __cplusplus
extern "C" {
#endif
#include "../../SDL_internal.h"
#include "SDL.h"
#include "SDL_syswm.h"
#include "SDL_bframebuffer.h"
#ifdef __cplusplus
}
#endif
#include <stdio.h>
#include <AppKit.h>
#include <InterfaceKit.h>
May 1, 2017
May 1, 2017
41
#include <game/DirectWindow.h>
May 1, 2017
May 1, 2017
43
#include <opengl/GLView.h>
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#endif
#include "SDL_events.h"
#include "../../main/haiku/SDL_BApp.h"
enum WinCommands {
BWIN_MOVE_WINDOW,
BWIN_RESIZE_WINDOW,
BWIN_SHOW_WINDOW,
BWIN_HIDE_WINDOW,
BWIN_MAXIMIZE_WINDOW,
BWIN_MINIMIZE_WINDOW,
BWIN_RESTORE_WINDOW,
BWIN_SET_TITLE,
BWIN_SET_BORDERED,
Sep 30, 2016
Sep 30, 2016
59
BWIN_SET_RESIZABLE,
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
BWIN_FULLSCREEN
};
class SDL_BWin:public BDirectWindow
{
public:
/* Constructor/Destructor */
SDL_BWin(BRect bounds, window_look look, uint32 flags)
: BDirectWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags)
{
_last_buttons = 0;
#if SDL_VIDEO_OPENGL
_SDL_GLView = NULL;
Jun 17, 2017
Jun 17, 2017
75
_gl_type = 0;
76
77
78
79
80
81
82
83
84
85
86
87
88
#endif
_shown = false;
_inhibit_resize = false;
_mouse_focused = false;
_prev_frame = NULL;
/* Handle framebuffer stuff */
_connected = _connection_disabled = false;
_buffer_created = _buffer_dirty = false;
_trash_window_buffer = false;
_buffer_locker = new BLocker();
_bitmap = NULL;
_clips = NULL;
Nov 12, 2019
Nov 12, 2019
89
_num_clips = 0;
Aug 7, 2018
Aug 7, 2018
92
_draw_thread_id = spawn_thread(HAIKU_DrawThread, "drawing_thread",
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
B_NORMAL_PRIORITY, (void*) this);
resume_thread(_draw_thread_id);
#endif
}
virtual ~ SDL_BWin()
{
Lock();
_connection_disabled = true;
int32 result;
#if SDL_VIDEO_OPENGL
if (_SDL_GLView) {
_SDL_GLView->UnlockGL();
RemoveChild(_SDL_GLView); /* Why was this outside the if
statement before? */
}
#endif
Unlock();
#if SDL_VIDEO_OPENGL
if (_SDL_GLView) {
delete _SDL_GLView;
}
#endif
Jul 1, 2017
Jul 1, 2017
119
120
delete _prev_frame;
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* Clean up framebuffer stuff */
_buffer_locker->Lock();
#ifdef DRAWTHREAD
wait_for_thread(_draw_thread_id, &result);
#endif
free(_clips);
delete _buffer_locker;
}
/* * * * * OpenGL functionality * * * * */
#if SDL_VIDEO_OPENGL
virtual BGLView *CreateGLView(Uint32 gl_flags) {
Lock();
if (_SDL_GLView == NULL) {
_SDL_GLView = new BGLView(Bounds(), "SDL GLView",
B_FOLLOW_ALL_SIDES,
(B_WILL_DRAW | B_FRAME_EVENTS),
gl_flags);
Jun 17, 2017
Jun 17, 2017
140
_gl_type = gl_flags;
141
142
}
AddChild(_SDL_GLView);
Dec 3, 2019
Dec 3, 2019
143
_SDL_GLView->SetEventMask(B_POINTER_EVENTS | B_KEYBOARD_EVENTS, B_NO_POINTER_HISTORY);
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
_SDL_GLView->EnableDirectMode(true);
_SDL_GLView->LockGL(); /* "New" GLViews are created */
Unlock();
return (_SDL_GLView);
}
virtual void RemoveGLView() {
Lock();
if(_SDL_GLView) {
_SDL_GLView->UnlockGL();
RemoveChild(_SDL_GLView);
}
Unlock();
}
virtual void SwapBuffers(void) {
_SDL_GLView->UnlockGL();
_SDL_GLView->LockGL();
_SDL_GLView->SwapBuffers();
}
#endif
/* * * * * Framebuffering* * * * */
virtual void DirectConnected(direct_buffer_info *info) {
if(!_connected && _connection_disabled) {
return;
}
/* Determine if the pixel buffer is usable after this update */
_trash_window_buffer = _trash_window_buffer
|| ((info->buffer_state & B_BUFFER_RESIZED)
|| (info->buffer_state & B_BUFFER_RESET)
|| (info->driver_state == B_MODE_CHANGED));
LockBuffer();
switch(info->buffer_state & B_DIRECT_MODE_MASK) {
case B_DIRECT_START:
_connected = true;
case B_DIRECT_MODIFY:
Nov 12, 2019
Nov 12, 2019
184
185
186
187
188
189
if (info->clip_list_count > _num_clips)
{
if(_clips) {
free(_clips);
_clips = NULL;
}
190
191
192
}
_num_clips = info->clip_list_count;
Nov 12, 2019
Nov 12, 2019
193
194
if (_clips == NULL)
_clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect));
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
if(_clips) {
memcpy(_clips, info->clip_list,
_num_clips*sizeof(clipping_rect));
_bits = (uint8*) info->bits;
_row_bytes = info->bytes_per_row;
_bounds = info->window_bounds;
_bytes_per_px = info->bits_per_pixel / 8;
_buffer_dirty = true;
}
break;
case B_DIRECT_STOP:
_connected = false;
break;
}
#if SDL_VIDEO_OPENGL
if(_SDL_GLView) {
_SDL_GLView->DirectConnected(info);
}
#endif
/* Call the base object directconnected */
BDirectWindow::DirectConnected(info);
UnlockBuffer();
}
/* * * * * Event sending * * * * */
/* Hook functions */
virtual void FrameMoved(BPoint origin) {
/* Post a message to the BApp so that it can handle the window event */
BMessage msg(BAPP_WINDOW_MOVED);
msg.AddInt32("window-x", (int)origin.x);
msg.AddInt32("window-y", (int)origin.y);
_PostWindowEvent(msg);
/* Perform normal hook operations */
BDirectWindow::FrameMoved(origin);
}
virtual void FrameResized(float width, float height) {
/* Post a message to the BApp so that it can handle the window event */
BMessage msg(BAPP_WINDOW_RESIZED);
msg.AddInt32("window-w", (int)width + 1);
msg.AddInt32("window-h", (int)height + 1);
_PostWindowEvent(msg);
/* Perform normal hook operations */
BDirectWindow::FrameResized(width, height);
}
virtual bool QuitRequested() {
BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED);
_PostWindowEvent(msg);
/* We won't allow a quit unless asked by DestroyWindow() */
return false;
}
virtual void WindowActivated(bool active) {
BMessage msg(BAPP_KEYBOARD_FOCUS); /* Mouse focus sold separately */
May 28, 2017
May 28, 2017
263
msg.AddBool("focusGained", active);
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
_PostWindowEvent(msg);
}
virtual void Zoom(BPoint origin,
float width,
float height) {
BMessage msg(BAPP_MAXIMIZE); /* Closest thing to maximization Haiku has */
_PostWindowEvent(msg);
/* Before the window zooms, record its size */
if( !_prev_frame )
_prev_frame = new BRect(Frame());
/* Perform normal hook operations */
BDirectWindow::Zoom(origin, width, height);
}
/* Member functions */
virtual void Show() {
while(IsHidden()) {
BDirectWindow::Show();
}
_shown = true;
BMessage msg(BAPP_SHOW);
_PostWindowEvent(msg);
}
virtual void Hide() {
BDirectWindow::Hide();
_shown = false;
BMessage msg(BAPP_HIDE);
_PostWindowEvent(msg);
}
virtual void Minimize(bool minimize) {
BDirectWindow::Minimize(minimize);
int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE);
BMessage msg(minState);
_PostWindowEvent(msg);
}
/* BView message interruption */
virtual void DispatchMessage(BMessage * msg, BHandler * target)
{
BPoint where; /* Used by mouse moved */
int32 buttons; /* Used for mouse button events */
int32 key; /* Used for key events */
switch (msg->what) {
case B_MOUSE_MOVED:
int32 transit;
if (msg->FindPoint("where", &where) == B_OK
&& msg->FindInt32("be:transit", &transit) == B_OK) {
_MouseMotionEvent(where, transit);
}
Nov 12, 2019
Nov 12, 2019
323
break;
Nov 12, 2019
Nov 12, 2019
325
case B_MOUSE_DOWN:
326
if (msg->FindInt32("buttons", &buttons) == B_OK) {
Nov 12, 2019
Nov 12, 2019
327
_MouseButtonEvent(buttons, SDL_PRESSED);
328
329
330
331
332
}
break;
case B_MOUSE_UP:
if (msg->FindInt32("buttons", &buttons) == B_OK) {
Nov 12, 2019
Nov 12, 2019
333
_MouseButtonEvent(buttons, SDL_RELEASED);
334
335
336
337
338
339
340
341
342
343
344
345
}
break;
case B_MOUSE_WHEEL_CHANGED:
float x, y;
if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK
&& msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
_MouseWheelEvent((int)x, (int)y);
}
break;
case B_KEY_DOWN:
Oct 20, 2016
Oct 20, 2016
346
347
348
349
350
351
352
353
354
355
356
357
358
359
{
int32 i = 0;
int8 byte;
int8 bytes[4] = { 0, 0, 0, 0 };
while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) {
bytes[i] = byte;
i++;
}
if (msg->FindInt32("key", &key) == B_OK) {
_KeyEvent((SDL_Scancode)key, &bytes[0], i, SDL_PRESSED);
}
}
break;
360
361
case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
if (msg->FindInt32("key", &key) == B_OK) {
Oct 20, 2016
Oct 20, 2016
362
_KeyEvent((SDL_Scancode)key, NULL, 0, SDL_PRESSED);
363
364
365
366
367
368
}
break;
case B_KEY_UP:
case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
if (msg->FindInt32("key", &key) == B_OK) {
Oct 20, 2016
Oct 20, 2016
369
_KeyEvent(key, NULL, 0, SDL_RELEASED);
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
}
break;
default:
/* move it after switch{} so it's always handled
that way we keep Haiku features like:
- CTRL+Q to close window (and other shortcuts)
- PrintScreen to make screenshot into /boot/home
- etc.. */
/* BDirectWindow::DispatchMessage(msg, target); */
break;
}
BDirectWindow::DispatchMessage(msg, target);
}
/* Handle command messages */
virtual void MessageReceived(BMessage* message) {
switch (message->what) {
/* Handle commands from SDL */
case BWIN_SET_TITLE:
_SetTitle(message);
break;
case BWIN_MOVE_WINDOW:
_MoveTo(message);
break;
case BWIN_RESIZE_WINDOW:
_ResizeTo(message);
break;
case BWIN_SET_BORDERED:
_SetBordered(message);
break;
Sep 30, 2016
Sep 30, 2016
402
403
404
case BWIN_SET_RESIZABLE:
_SetResizable(message);
break;
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
case BWIN_SHOW_WINDOW:
Show();
break;
case BWIN_HIDE_WINDOW:
Hide();
break;
case BWIN_MAXIMIZE_WINDOW:
BWindow::Zoom();
break;
case BWIN_MINIMIZE_WINDOW:
Minimize(true);
break;
case BWIN_RESTORE_WINDOW:
_Restore();
break;
case BWIN_FULLSCREEN:
_SetFullScreen(message);
break;
default:
/* Perform normal message handling */
BDirectWindow::MessageReceived(message);
break;
}
}
/* Accessor methods */
bool IsShown() { return _shown; }
int32 GetID() { return _id; }
uint32 GetRowBytes() { return _row_bytes; }
int32 GetFbX() { return _bounds.left; }
int32 GetFbY() { return _bounds.top; }
bool ConnectionEnabled() { return !_connection_disabled; }
bool Connected() { return _connected; }
clipping_rect *GetClips() { return _clips; }
int32 GetNumClips() { return _num_clips; }
uint8* GetBufferPx() { return _bits; }
int32 GetBytesPerPx() { return _bytes_per_px; }
bool CanTrashWindowBuffer() { return _trash_window_buffer; }
bool BufferExists() { return _buffer_created; }
bool BufferIsDirty() { return _buffer_dirty; }
BBitmap *GetBitmap() { return _bitmap; }
#if SDL_VIDEO_OPENGL
BGLView *GetGLView() { return _SDL_GLView; }
Jun 17, 2017
Jun 17, 2017
451
Uint32 GetGLType() { return _gl_type; }
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
#endif
/* Setter methods */
void SetID(int32 id) { _id = id; }
void SetBufferExists(bool bufferExists) { _buffer_created = bufferExists; }
void LockBuffer() { _buffer_locker->Lock(); }
void UnlockBuffer() { _buffer_locker->Unlock(); }
void SetBufferDirty(bool bufferDirty) { _buffer_dirty = bufferDirty; }
void SetTrashBuffer(bool trash) { _trash_window_buffer = trash; }
void SetBitmap(BBitmap *bitmap) { _bitmap = bitmap; }
private:
/* Event redirection */
void _MouseMotionEvent(BPoint &where, int32 transit) {
if(transit == B_EXITED_VIEW) {
/* Change mouse focus */
if(_mouse_focused) {
_MouseFocusEvent(false);
}
} else {
/* Change mouse focus */
if (!_mouse_focused) {
_MouseFocusEvent(true);
}
BMessage msg(BAPP_MOUSE_MOVED);
msg.AddInt32("x", (int)where.x);
msg.AddInt32("y", (int)where.y);
_PostWindowEvent(msg);
}
}
void _MouseFocusEvent(bool focusGained) {
_mouse_focused = focusGained;
BMessage msg(BAPP_MOUSE_FOCUS);
msg.AddBool("focusGained", focusGained);
_PostWindowEvent(msg);
/* FIXME: Why were these here?
if false: be_app->SetCursor(B_HAND_CURSOR);
if true: SDL_SetCursor(NULL); */
}
Nov 12, 2019
Nov 12, 2019
496
void _MouseButtonEvent(int32 buttons, Uint8 state) {
497
498
499
int32 buttonStateChange = buttons ^ _last_buttons;
if(buttonStateChange & B_PRIMARY_MOUSE_BUTTON) {
Nov 12, 2019
Nov 12, 2019
500
_SendMouseButton(SDL_BUTTON_LEFT, state);
501
502
}
if(buttonStateChange & B_SECONDARY_MOUSE_BUTTON) {
Nov 12, 2019
Nov 12, 2019
503
_SendMouseButton(SDL_BUTTON_RIGHT, state);
504
505
}
if(buttonStateChange & B_TERTIARY_MOUSE_BUTTON) {
Nov 12, 2019
Nov 12, 2019
506
_SendMouseButton(SDL_BUTTON_MIDDLE, state);
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
}
_last_buttons = buttons;
}
void _SendMouseButton(int32 button, int32 state) {
BMessage msg(BAPP_MOUSE_BUTTON);
msg.AddInt32("button-id", button);
msg.AddInt32("button-state", state);
_PostWindowEvent(msg);
}
void _MouseWheelEvent(int32 x, int32 y) {
/* Create a message to pass along to the BeApp thread */
BMessage msg(BAPP_MOUSE_WHEEL);
msg.AddInt32("xticks", x);
msg.AddInt32("yticks", y);
_PostWindowEvent(msg);
}
Oct 20, 2016
Oct 20, 2016
527
void _KeyEvent(int32 keyCode, const int8 *keyUtf8, const ssize_t & len, int32 keyState) {
528
529
530
531
/* Create a message to pass along to the BeApp thread */
BMessage msg(BAPP_KEY);
msg.AddInt32("key-state", keyState);
msg.AddInt32("key-scancode", keyCode);
Oct 20, 2016
Oct 20, 2016
532
if (keyUtf8 != NULL) {
Sep 24, 2018
Sep 24, 2018
533
msg.AddData("key-utf8", B_INT8_TYPE, (const void*)keyUtf8, len);
Oct 20, 2016
Oct 20, 2016
534
}
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
be_app->PostMessage(&msg);
}
void _RepaintEvent() {
/* Force a repaint: Call the SDL exposed event */
BMessage msg(BAPP_REPAINT);
_PostWindowEvent(msg);
}
void _PostWindowEvent(BMessage &msg) {
msg.AddInt32("window-id", _id);
be_app->PostMessage(&msg);
}
/* Command methods (functions called upon by SDL) */
void _SetTitle(BMessage *msg) {
const char *title;
if(
msg->FindString("window-title", &title) != B_OK
) {
return;
}
SetTitle(title);
}
void _MoveTo(BMessage *msg) {
int32 x, y;
if(
msg->FindInt32("window-x", &x) != B_OK ||
msg->FindInt32("window-y", &y) != B_OK
) {
return;
}
MoveTo(x, y);
}
void _ResizeTo(BMessage *msg) {
int32 w, h;
if(
msg->FindInt32("window-w", &w) != B_OK ||
msg->FindInt32("window-h", &h) != B_OK
) {
return;
}
ResizeTo(w, h);
}
void _SetBordered(BMessage *msg) {
bool bEnabled;
if(msg->FindBool("window-border", &bEnabled) != B_OK) {
return;
}
Jun 3, 2017
Jun 3, 2017
586
SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
Sep 30, 2016
Sep 30, 2016
589
590
591
592
593
594
void _SetResizable(BMessage *msg) {
bool bEnabled;
if(msg->FindBool("window-resizable", &bEnabled) != B_OK) {
return;
}
if (bEnabled) {
Sep 30, 2016
Sep 30, 2016
595
SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
Sep 30, 2016
Sep 30, 2016
596
} else {
Sep 30, 2016
Sep 30, 2016
597
SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
Sep 30, 2016
Sep 30, 2016
598
599
600
}
}
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
void _Restore() {
if(IsMinimized()) {
Minimize(false);
} else if(IsHidden()) {
Show();
} else if(_prev_frame != NULL) { /* Zoomed */
MoveTo(_prev_frame->left, _prev_frame->top);
ResizeTo(_prev_frame->Width(), _prev_frame->Height());
}
}
void _SetFullScreen(BMessage *msg) {
bool fullscreen;
if(
msg->FindBool("fullscreen", &fullscreen) != B_OK
) {
return;
}
SetFullScreen(fullscreen);
}
/* Members */
#if SDL_VIDEO_OPENGL
BGLView * _SDL_GLView;
Jun 17, 2017
Jun 17, 2017
625
Uint32 _gl_type;
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
#endif
int32 _last_buttons;
int32 _id; /* Window id used by SDL_BApp */
bool _mouse_focused; /* Does this window have mouse focus? */
bool _shown;
bool _inhibit_resize;
BRect *_prev_frame; /* Previous position and size of the window */
/* Framebuffer members */
bool _connected,
_connection_disabled,
_buffer_created,
_buffer_dirty,
_trash_window_buffer;
uint8 *_bits;
uint32 _row_bytes;
clipping_rect _bounds;
BLocker *_buffer_locker;
clipping_rect *_clips;
Nov 12, 2019
Nov 12, 2019
647
uint32 _num_clips;
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
int32 _bytes_per_px;
thread_id _draw_thread_id;
BBitmap *_bitmap;
};
/* FIXME:
* An explanation of framebuffer flags.
*
* _connected - Original variable used to let the drawing thread know
* when changes are being made to the other framebuffer
* members.
* _connection_disabled - Used to signal to the drawing thread that the window
* is closing, and the thread should exit.
* _buffer_created - True if the current buffer is valid
* _buffer_dirty - True if the window should be redrawn.
* _trash_window_buffer - True if the window buffer needs to be trashed partway
* through a draw cycle. Occurs when the previous
* buffer provided by DirectConnected() is invalidated.
*/
Aug 28, 2017
Aug 28, 2017
669
#endif /* SDL_BWin_h_ */
Dec 9, 2016
Dec 9, 2016
670
671
/* vi: set ts=4 sw=4 expandtab: */