src/main/beos/SDL_BApp.h
author Sam Lantinga <slouken@libsdl.org>
Sat, 02 Mar 2013 20:44:16 -0800
changeset 6950 1ddb72193079
parent 6885 700f1b25f77f
child 7191 75360622e65f
permissions -rw-r--r--
Added a mouse ID to the mouse events, which set to the special value SDL_TOUCH_MOUSEID for mouse events simulated by touch input.
nathanheisey@5916
     1
/*
nathanheisey@5916
     2
  Simple DirectMedia Layer
slouken@6885
     3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
nathanheisey@5916
     4
nathanheisey@5916
     5
  This software is provided 'as-is', without any express or implied
nathanheisey@5916
     6
  warranty.  In no event will the authors be held liable for any damages
nathanheisey@5916
     7
  arising from the use of this software.
nathanheisey@5916
     8
nathanheisey@5916
     9
  Permission is granted to anyone to use this software for any purpose,
nathanheisey@5916
    10
  including commercial applications, and to alter it and redistribute it
nathanheisey@5916
    11
  freely, subject to the following restrictions:
nathanheisey@5916
    12
nathanheisey@5916
    13
  1. The origin of this software must not be misrepresented; you must not
nathanheisey@5916
    14
     claim that you wrote the original software. If you use this software
nathanheisey@5916
    15
     in a product, an acknowledgment in the product documentation would be
nathanheisey@5916
    16
     appreciated but is not required.
nathanheisey@5916
    17
  2. Altered source versions must be plainly marked as such, and must not be
nathanheisey@5916
    18
     misrepresented as being the original software.
nathanheisey@5916
    19
  3. This notice may not be removed or altered from any source distribution.
nathanheisey@5916
    20
*/
nathanheisey@5916
    21
#ifndef SDL_BAPP_H
nathanheisey@5916
    22
#define SDL_BAPP_H
nathanheisey@5916
    23
nathanheisey@5922
    24
#include <InterfaceKit.h>
nathanheisey@5931
    25
#include <OpenGLKit.h>
nathanheisey@5922
    26
nathanheisey@5928
    27
#include "../../video/bwindow/SDL_bkeyboard.h"
nathanheisey@5928
    28
nathanheisey@5928
    29
nathanheisey@5916
    30
#ifdef __cplusplus
nathanheisey@5916
    31
extern "C" {
nathanheisey@5916
    32
#endif
nathanheisey@5916
    33
nathanheisey@5916
    34
#include "SDL_config.h"
nathanheisey@5922
    35
nathanheisey@5916
    36
#include "SDL_video.h"
nathanheisey@5916
    37
nathanheisey@5916
    38
/* Local includes */
nathanheisey@5916
    39
#include "../../events/SDL_events_c.h"
nathanheisey@5928
    40
#include "../../video/bwindow/SDL_bkeyboard.h"
nathanheisey@5931
    41
#include "../../video/bwindow/SDL_bframebuffer.h"
nathanheisey@5916
    42
nathanheisey@5916
    43
#ifdef __cplusplus
nathanheisey@5916
    44
}
nathanheisey@5931
    45
#endif
nathanheisey@5919
    46
nathanheisey@5931
    47
#include <vector>
nathanheisey@5916
    48
nathanheisey@5916
    49
nathanheisey@5916
    50
nathanheisey@5916
    51
nathanheisey@5916
    52
/* Forward declarations */
nathanheisey@5916
    53
class SDL_BWin;
nathanheisey@5916
    54
nathanheisey@5916
    55
/* Message constants */
nathanheisey@5916
    56
enum ToSDL {
nathanheisey@5916
    57
	/* Intercepted by BWindow on its way to BView */
nathanheisey@5916
    58
	BAPP_MOUSE_MOVED,
nathanheisey@5916
    59
	BAPP_MOUSE_BUTTON,
nathanheisey@5916
    60
	BAPP_MOUSE_WHEEL,
nathanheisey@5916
    61
	BAPP_KEY,
nathanheisey@5916
    62
	BAPP_REPAINT,           /* from _UPDATE_ */
nathanheisey@5916
    63
	/* From BWindow */
nathanheisey@5916
    64
	BAPP_MAXIMIZE,          /* from B_ZOOM */
nathanheisey@5916
    65
	BAPP_MINIMIZE,
nathanheisey@5916
    66
	BAPP_RESTORE,			/* TODO: IMPLEMENT! */
nathanheisey@5916
    67
	BAPP_SHOW,
nathanheisey@5916
    68
	BAPP_HIDE,
nathanheisey@5916
    69
	BAPP_MOUSE_FOCUS,		/* caused by MOUSE_MOVE */
nathanheisey@5916
    70
	BAPP_KEYBOARD_FOCUS,	/* from WINDOW_ACTIVATED */
nathanheisey@5916
    71
	BAPP_WINDOW_CLOSE_REQUESTED,
nathanheisey@5916
    72
	BAPP_WINDOW_MOVED,
nathanheisey@5916
    73
	BAPP_WINDOW_RESIZED,
nathanheisey@5916
    74
	BAPP_SCREEN_CHANGED
nathanheisey@5916
    75
};
nathanheisey@5916
    76
nathanheisey@5916
    77
nathanheisey@5916
    78
nathanheisey@5916
    79
/* Create a descendant of BApplication */
nathanheisey@5916
    80
class SDL_BApp : public BApplication {
nathanheisey@5916
    81
public:
nathanheisey@5916
    82
	SDL_BApp(const char* signature) :
nathanheisey@5916
    83
		BApplication(signature) {
nathanheisey@5931
    84
		_current_context = NULL;
nathanheisey@5919
    85
	}
nathanheisey@5931
    86
	
nathanheisey@5931
    87
	
nathanheisey@5919
    88
	virtual ~SDL_BApp() {
nathanheisey@5916
    89
	}
nathanheisey@5931
    90
	
nathanheisey@5931
    91
	
nathanheisey@5931
    92
	
nathanheisey@5916
    93
		/* Event-handling functions */
nathanheisey@5916
    94
	virtual void MessageReceived(BMessage* message) {
nathanheisey@5916
    95
		/* Sort out SDL-related messages */
nathanheisey@5916
    96
        switch ( message->what ) {
nathanheisey@5916
    97
        case BAPP_MOUSE_MOVED:
nathanheisey@5916
    98
        	_HandleMouseMove(message);
nathanheisey@5916
    99
        	break;
nathanheisey@5916
   100
nathanheisey@5916
   101
		case BAPP_MOUSE_BUTTON:
nathanheisey@5916
   102
			_HandleMouseButton(message);
nathanheisey@5916
   103
			break;
nathanheisey@5916
   104
			
nathanheisey@5916
   105
		case BAPP_MOUSE_WHEEL:
nathanheisey@5916
   106
			_HandleMouseWheel(message);
nathanheisey@5916
   107
			break;
nathanheisey@5916
   108
			
nathanheisey@5916
   109
		case BAPP_KEY:
nathanheisey@5916
   110
			_HandleKey(message);
nathanheisey@5916
   111
			break;
nathanheisey@5916
   112
nathanheisey@5916
   113
		case BAPP_REPAINT:
nathanheisey@5916
   114
			_HandleBasicWindowEvent(message, SDL_WINDOWEVENT_EXPOSED);
nathanheisey@5916
   115
			break;
nathanheisey@5916
   116
			
nathanheisey@5916
   117
		case BAPP_MAXIMIZE:
nathanheisey@5916
   118
			_HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MAXIMIZED);
nathanheisey@5916
   119
			break;
nathanheisey@5916
   120
			
nathanheisey@5916
   121
		case BAPP_MINIMIZE:
nathanheisey@5916
   122
			_HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MINIMIZED);
nathanheisey@5916
   123
			break;
nathanheisey@5916
   124
			
nathanheisey@5916
   125
		case BAPP_SHOW:
nathanheisey@5916
   126
			_HandleBasicWindowEvent(message, SDL_WINDOWEVENT_SHOWN);
nathanheisey@5916
   127
			break;
nathanheisey@5916
   128
			
nathanheisey@5916
   129
		case BAPP_HIDE:
nathanheisey@5916
   130
			_HandleBasicWindowEvent(message, SDL_WINDOWEVENT_HIDDEN);
nathanheisey@5916
   131
			break;
nathanheisey@5916
   132
			
nathanheisey@5916
   133
		case BAPP_MOUSE_FOCUS:
nathanheisey@5916
   134
			_HandleMouseFocus(message);
nathanheisey@5916
   135
			break;
nathanheisey@5916
   136
			
nathanheisey@5916
   137
		case BAPP_KEYBOARD_FOCUS:
nathanheisey@5916
   138
			_HandleKeyboardFocus(message);
nathanheisey@5916
   139
			break;
nathanheisey@5916
   140
			
nathanheisey@5916
   141
		case BAPP_WINDOW_CLOSE_REQUESTED:
nathanheisey@5916
   142
			_HandleBasicWindowEvent(message, SDL_WINDOWEVENT_CLOSE);
nathanheisey@5916
   143
			break;
nathanheisey@5916
   144
			
nathanheisey@5916
   145
		case BAPP_WINDOW_MOVED:
nathanheisey@5916
   146
			_HandleWindowMoved(message);
nathanheisey@5916
   147
			break;
nathanheisey@5916
   148
			
nathanheisey@5916
   149
		case BAPP_WINDOW_RESIZED:
nathanheisey@5916
   150
			_HandleWindowResized(message);
nathanheisey@5916
   151
			break;
nathanheisey@5916
   152
			
nathanheisey@5916
   153
		case BAPP_SCREEN_CHANGED:
nathanheisey@5916
   154
			/* TODO: Handle screen resize or workspace change */
nathanheisey@5916
   155
			break;
nathanheisey@5916
   156
nathanheisey@5916
   157
        default:
nathanheisey@5916
   158
           BApplication::MessageReceived(message);
nathanheisey@5916
   159
           break;
nathanheisey@5916
   160
        }
nathanheisey@5916
   161
    }
nathanheisey@5916
   162
    
nathanheisey@5916
   163
    /* Window creation/destruction methods */
nathanheisey@5916
   164
    int32 GetID(SDL_Window *win) {
nathanheisey@5916
   165
    	int32 i;
nathanheisey@5919
   166
    	for(i = 0; i < _GetNumWindowSlots(); ++i) {
nathanheisey@5929
   167
    		if( GetSDLWindow(i) == NULL ) {
nathanheisey@5919
   168
    			_SetSDLWindow(win, i);
nathanheisey@5916
   169
    			return i;
nathanheisey@5916
   170
    		}
nathanheisey@5916
   171
    	}
nathanheisey@5916
   172
    	
nathanheisey@5916
   173
    	/* Expand the vector if all slots are full */
nathanheisey@5919
   174
    	if( i == _GetNumWindowSlots() ) {
nathanheisey@5919
   175
    		_PushBackWindow(win);
nathanheisey@5916
   176
    		return i;
nathanheisey@5916
   177
    	}
aschiffler@6037
   178
    	
aschiffler@6037
   179
    	/* TODO: error handling */
aschiffler@6037
   180
    	return 0;
nathanheisey@5916
   181
    }
nathanheisey@5916
   182
    
nathanheisey@5919
   183
    /* FIXME: Bad coding practice, but I can't include SDL_BWin.h here.  Is
nathanheisey@5919
   184
       there another way to do this? */
nathanheisey@5916
   185
    void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */
nathanheisey@5916
   186
    
nathanheisey@5929
   187
    
nathanheisey@5929
   188
	SDL_Window *GetSDLWindow(int32 winID) {
nathanheisey@5931
   189
		return _window_map[winID];
nathanheisey@5929
   190
	}
nathanheisey@5929
   191
    
nathanheisey@5931
   192
    void SetCurrentContext(BGLView *newContext) {
nathanheisey@5931
   193
    	if(_current_context)
nathanheisey@5931
   194
    		_current_context->UnlockGL();
nathanheisey@5931
   195
    	_current_context = newContext;
nathanheisey@5931
   196
    	_current_context->LockGL();
nathanheisey@5931
   197
    }
nathanheisey@5916
   198
private:
nathanheisey@5916
   199
	/* Event management */
nathanheisey@5916
   200
	void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) {
nathanheisey@5916
   201
		SDL_Window *win;
nathanheisey@5916
   202
		int32 winID;
nathanheisey@5916
   203
		if(
nathanheisey@5916
   204
			!_GetWinID(msg, &winID)
nathanheisey@5916
   205
		) {
nathanheisey@5916
   206
			return;
nathanheisey@5916
   207
		}
nathanheisey@5929
   208
		win = GetSDLWindow(winID);
nathanheisey@5916
   209
		SDL_SendWindowEvent(win, sdlEventType, 0, 0);
nathanheisey@5916
   210
	}
nathanheisey@5916
   211
	
nathanheisey@5916
   212
	void _HandleMouseMove(BMessage *msg) {
nathanheisey@5916
   213
		SDL_Window *win;
nathanheisey@5916
   214
		int32 winID;
nathanheisey@5927
   215
		int32 x = 0, y = 0;
nathanheisey@5916
   216
		if(	
nathanheisey@5916
   217
			!_GetWinID(msg, &winID) ||
nathanheisey@5927
   218
			msg->FindInt32("x", &x) != B_OK || /* x movement */
nathanheisey@5927
   219
			msg->FindInt32("y", &y) != B_OK    /* y movement */
nathanheisey@5916
   220
		) {
nathanheisey@5916
   221
			return;
nathanheisey@5916
   222
		}
nathanheisey@5929
   223
		win = GetSDLWindow(winID);
slouken@6950
   224
		SDL_SendMouseMotion(win, 0, 0, x, y);
nathanheisey@5929
   225
		
nathanheisey@5939
   226
		/* Tell the application that the mouse passed over, redraw needed */
nathanheisey@5929
   227
		BE_UpdateWindowFramebuffer(NULL,win,NULL,-1);
nathanheisey@5916
   228
	}
nathanheisey@5916
   229
	
nathanheisey@5916
   230
	void _HandleMouseButton(BMessage *msg) {
nathanheisey@5916
   231
		SDL_Window *win;
nathanheisey@5916
   232
		int32 winID;
nathanheisey@5916
   233
		int32 button, state;	/* left/middle/right, pressed/released */
nathanheisey@5916
   234
		if(
nathanheisey@5916
   235
			!_GetWinID(msg, &winID) ||
nathanheisey@5916
   236
			msg->FindInt32("button-id", &button) != B_OK ||
nathanheisey@5916
   237
			msg->FindInt32("button-state", &state) != B_OK
nathanheisey@5916
   238
		) {
nathanheisey@5916
   239
			return;
nathanheisey@5916
   240
		}
nathanheisey@5929
   241
		win = GetSDLWindow(winID);
slouken@6950
   242
		SDL_SendMouseButton(win, 0, state, button);
nathanheisey@5916
   243
	}
nathanheisey@5916
   244
	
nathanheisey@5916
   245
	void _HandleMouseWheel(BMessage *msg) {
nathanheisey@5916
   246
		SDL_Window *win;
nathanheisey@5916
   247
		int32 winID;
nathanheisey@5916
   248
		int32 xTicks, yTicks;
nathanheisey@5916
   249
		if(
nathanheisey@5916
   250
			!_GetWinID(msg, &winID) ||
nathanheisey@5916
   251
			msg->FindInt32("xticks", &xTicks) != B_OK ||
nathanheisey@5916
   252
			msg->FindInt32("yticks", &yTicks) != B_OK
nathanheisey@5916
   253
		) {
nathanheisey@5916
   254
			return;
nathanheisey@5916
   255
		}
nathanheisey@5929
   256
		win = GetSDLWindow(winID);
slouken@6950
   257
		SDL_SendMouseWheel(win, 0, xTicks, yTicks);
nathanheisey@5916
   258
	}
nathanheisey@5916
   259
	
nathanheisey@5916
   260
	void _HandleKey(BMessage *msg) {
nathanheisey@5916
   261
		int32 scancode, state;	/* scancode, pressed/released */
nathanheisey@5916
   262
		if(
nathanheisey@5916
   263
			msg->FindInt32("key-state", &state) != B_OK ||
nathanheisey@5916
   264
			msg->FindInt32("key-scancode", &scancode) != B_OK
nathanheisey@5916
   265
		) {
nathanheisey@5916
   266
			return;
nathanheisey@5916
   267
		}
nathanheisey@5928
   268
		
nathanheisey@5928
   269
		/* Make sure this isn't a repeated event (key pressed and held) */
nathanheisey@5928
   270
		if(state == SDL_PRESSED && BE_GetKeyState(scancode) == SDL_PRESSED) {
nathanheisey@5928
   271
			return;
nathanheisey@5928
   272
		}
nathanheisey@5928
   273
		BE_SetKeyState(scancode, state);
nathanheisey@5928
   274
		SDL_SendKeyboardKey(state, BE_GetScancodeFromBeKey(scancode));
nathanheisey@5916
   275
	}
nathanheisey@5916
   276
	
nathanheisey@5916
   277
	void _HandleMouseFocus(BMessage *msg) {
nathanheisey@5916
   278
		SDL_Window *win;
nathanheisey@5916
   279
		int32 winID;
nathanheisey@5916
   280
		bool bSetFocus;	/* If false, lose focus */
nathanheisey@5916
   281
		if(
nathanheisey@5916
   282
			!_GetWinID(msg, &winID) ||
nathanheisey@5916
   283
			msg->FindBool("focusGained", &bSetFocus) != B_OK
nathanheisey@5916
   284
		) {
nathanheisey@5916
   285
			return;
nathanheisey@5916
   286
		}
nathanheisey@5929
   287
		win = GetSDLWindow(winID);
nathanheisey@5916
   288
		if(bSetFocus) {
nathanheisey@5916
   289
			SDL_SetMouseFocus(win);
nathanheisey@5916
   290
		} else if(SDL_GetMouseFocus() == win) {
nathanheisey@5916
   291
			/* Only lose all focus if this window was the current focus */
nathanheisey@5916
   292
			SDL_SetMouseFocus(NULL);
nathanheisey@5916
   293
		}
nathanheisey@5916
   294
	}
nathanheisey@5916
   295
	
nathanheisey@5916
   296
	void _HandleKeyboardFocus(BMessage *msg) {
nathanheisey@5916
   297
		SDL_Window *win;
nathanheisey@5916
   298
		int32 winID;
nathanheisey@5916
   299
		bool bSetFocus;	/* If false, lose focus */
nathanheisey@5916
   300
		if(
nathanheisey@5916
   301
			!_GetWinID(msg, &winID) ||
nathanheisey@5916
   302
			msg->FindBool("focusGained", &bSetFocus) != B_OK
nathanheisey@5916
   303
		) {
nathanheisey@5916
   304
			return;
nathanheisey@5916
   305
		}
nathanheisey@5929
   306
		win = GetSDLWindow(winID);
nathanheisey@5916
   307
		if(bSetFocus) {
nathanheisey@5916
   308
			SDL_SetKeyboardFocus(win);
nathanheisey@5916
   309
		} else if(SDL_GetKeyboardFocus() == win) {
nathanheisey@5916
   310
			/* Only lose all focus if this window was the current focus */
nathanheisey@5916
   311
			SDL_SetKeyboardFocus(NULL);
nathanheisey@5916
   312
		}
nathanheisey@5916
   313
	}
nathanheisey@5916
   314
	
nathanheisey@5916
   315
	void _HandleWindowMoved(BMessage *msg) {
nathanheisey@5916
   316
		SDL_Window *win;
nathanheisey@5916
   317
		int32 winID;
nathanheisey@5916
   318
		int32 xPos, yPos;
nathanheisey@5916
   319
		/* Get the window id and new x/y position of the window */
nathanheisey@5916
   320
		if(
nathanheisey@5916
   321
			!_GetWinID(msg, &winID) ||
nathanheisey@5916
   322
			msg->FindInt32("window-x", &xPos) != B_OK ||
nathanheisey@5916
   323
			msg->FindInt32("window-y", &yPos) != B_OK
nathanheisey@5916
   324
		) {
nathanheisey@5916
   325
			return;
nathanheisey@5916
   326
		}
nathanheisey@5929
   327
		win = GetSDLWindow(winID);
nathanheisey@5916
   328
		SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos);
nathanheisey@5916
   329
	}
nathanheisey@5916
   330
	
nathanheisey@5916
   331
	void _HandleWindowResized(BMessage *msg) {
nathanheisey@5916
   332
		SDL_Window *win;
nathanheisey@5916
   333
		int32 winID;
nathanheisey@5916
   334
		int32 w, h;
nathanheisey@5916
   335
		/* Get the window id ]and new x/y position of the window */
nathanheisey@5916
   336
		if(
nathanheisey@5916
   337
			!_GetWinID(msg, &winID) ||
nathanheisey@5916
   338
			msg->FindInt32("window-w", &w) != B_OK ||
nathanheisey@5916
   339
			msg->FindInt32("window-h", &h) != B_OK
nathanheisey@5916
   340
		) {
nathanheisey@5916
   341
			return;
nathanheisey@5916
   342
		}
nathanheisey@5929
   343
		win = GetSDLWindow(winID);
nathanheisey@5916
   344
		SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h);
nathanheisey@5916
   345
	}
nathanheisey@5916
   346
nathanheisey@5916
   347
	bool _GetWinID(BMessage *msg, int32 *winID) {
nathanheisey@5916
   348
		return msg->FindInt32("window-id", winID) == B_OK;
nathanheisey@5916
   349
	}
nathanheisey@5919
   350
nathanheisey@5919
   351
nathanheisey@5919
   352
nathanheisey@5930
   353
	/* Vector functions: Wraps vector stuff in case we need to change 
nathanheisey@5930
   354
	   implementation */
nathanheisey@5919
   355
	void _SetSDLWindow(SDL_Window *win, int32 winID) {
nathanheisey@5931
   356
		_window_map[winID] = win;
nathanheisey@5919
   357
	}
nathanheisey@5919
   358
	
nathanheisey@5919
   359
	int32 _GetNumWindowSlots() {
nathanheisey@5931
   360
		return _window_map.size();
nathanheisey@5919
   361
	}
nathanheisey@5919
   362
	
nathanheisey@5919
   363
	
nathanheisey@5919
   364
	void _PopBackWindow() {
nathanheisey@5931
   365
		_window_map.pop_back();
nathanheisey@5919
   366
	}
nathanheisey@5919
   367
nathanheisey@5919
   368
	void _PushBackWindow(SDL_Window *win) {
nathanheisey@5931
   369
		_window_map.push_back(win);
nathanheisey@5919
   370
	}
nathanheisey@5919
   371
nathanheisey@5919
   372
nathanheisey@5916
   373
	/* Members */
nathanheisey@5939
   374
	vector<SDL_Window*> _window_map; /* Keeps track of SDL_Windows by index-id*/
nathanheisey@5922
   375
nathanheisey@5931
   376
	display_mode *_saved_mode;
nathanheisey@5931
   377
	BGLView      *_current_context;
nathanheisey@5916
   378
};
nathanheisey@5916
   379
nathanheisey@5916
   380
#endif