Home | History | Annotate | Download | only in bwindow
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2012 Sam Lantinga
      4 
      5     This library is free software; you can redistribute it and/or
      6     modify it under the terms of the GNU Lesser General Public
      7     License as published by the Free Software Foundation; either
      8     version 2.1 of the License, or (at your option) any later version.
      9 
     10     This library is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13     Lesser General Public License for more details.
     14 
     15     You should have received a copy of the GNU Lesser General Public
     16     License along with this library; if not, write to the Free Software
     17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     18 
     19     Sam Lantinga
     20     slouken (at) libsdl.org
     21 */
     22 
     23 #ifndef _SDL_BWin_h
     24 #define _SDL_BWin_h
     25 
     26 #include "SDL_config.h"
     27 
     28 #include <stdio.h>
     29 #include <AppKit.h>
     30 #include <InterfaceKit.h>
     31 #include <be/game/DirectWindow.h>
     32 #if SDL_VIDEO_OPENGL
     33 #include "SDL_opengl.h"
     34 #include <be/opengl/GLView.h>
     35 #endif
     36 #include <support/UTF8.h>
     37 
     38 #include "../../main/beos/SDL_BeApp.h"
     39 #include "SDL_events.h"
     40 #include "SDL_BView.h"
     41 
     42 extern "C" {
     43 #include "../../events/SDL_events_c.h"
     44 
     45 extern int mouse_relative;
     46 };
     47 
     48 class SDL_BWin : public BDirectWindow
     49 {
     50 public:
     51 	SDL_BWin(BRect bounds) :
     52 			BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) {
     53 		last_buttons = 0;
     54 		the_view = NULL;
     55 #if SDL_VIDEO_OPENGL
     56 		SDL_GLView = NULL;
     57 #endif
     58 		SDL_View = NULL;
     59 		Unlock();
     60 		shown = false;
     61 		inhibit_resize = false;
     62 	}
     63 
     64 	virtual ~SDL_BWin() {
     65 		Lock();
     66 		if ( the_view ) {
     67 #if SDL_VIDEO_OPENGL
     68 			if ( the_view == SDL_GLView ) {
     69 				SDL_GLView->UnlockGL();
     70 			}
     71 #endif
     72 			RemoveChild(the_view);
     73 			the_view = NULL;
     74 		}
     75 		Unlock();
     76 #if SDL_VIDEO_OPENGL
     77 		if ( SDL_GLView ) {
     78 			delete SDL_GLView;
     79 		}
     80 #endif
     81 		if ( SDL_View ) {
     82 			delete SDL_View;
     83 		}
     84 	}
     85 
     86 
     87 	/* Override the Show() method so we can tell when we've been shown */
     88 	virtual void Show(void) {
     89 		BWindow::Show();
     90 		shown = true;
     91 	}
     92 	virtual bool Shown(void) {
     93 		return (shown);
     94 	}
     95 	/* If called, the next resize event will not be forwarded to SDL. */
     96 	virtual void InhibitResize(void) {
     97 		inhibit_resize=true;
     98 	}
     99 	/* Handle resizing of the window */
    100 	virtual void FrameResized(float width, float height) {
    101 		if(inhibit_resize)
    102 			inhibit_resize = false;
    103 		else
    104 			SDL_PrivateResize((int)width, (int)height);
    105 	}
    106 	virtual int CreateView(Uint32 flags, Uint32 gl_flags) {
    107 		int retval;
    108 
    109 		retval = 0;
    110 		Lock();
    111 		if ( flags & SDL_OPENGL ) {
    112 #if SDL_VIDEO_OPENGL
    113 			if ( SDL_GLView == NULL ) {
    114 				SDL_GLView = new BGLView(Bounds(), "SDL GLView",
    115 					 	B_FOLLOW_ALL_SIDES, (B_WILL_DRAW|B_FRAME_EVENTS),
    116 					 	gl_flags|BGL_DOUBLE);
    117 				SDL_GLView->EnableDirectMode(true);
    118 			}
    119 			if ( the_view != SDL_GLView ) {
    120 				if ( the_view ) {
    121 					RemoveChild(the_view);
    122 				}
    123 				AddChild(SDL_GLView);
    124 				SDL_GLView->LockGL();
    125 				the_view = SDL_GLView;
    126 			}
    127 #else
    128 			SDL_SetError("OpenGL support not enabled");
    129 			retval = -1;
    130 #endif
    131 		} else {
    132 			if ( SDL_View == NULL ) {
    133 				SDL_View = new SDL_BView(Bounds());
    134 			}
    135 			if ( the_view != SDL_View ) {
    136 				if ( the_view ) {
    137 					RemoveChild(the_view);
    138 				}
    139 				AddChild(SDL_View);
    140 				the_view = SDL_View;
    141 			}
    142 		}
    143 #if SDL_VIDEO_OPENGL
    144 		if ( the_view == SDL_GLView ) {
    145 			SDL_GLView->UnlockGL();
    146 		}
    147 #endif
    148 		Unlock();
    149 		return(retval);
    150 	}
    151 	virtual void SetBitmap(BBitmap *bitmap) {
    152 		SDL_View->SetBitmap(bitmap);
    153 	}
    154 	virtual void SetXYOffset(int x, int y) {
    155 #if SDL_VIDEO_OPENGL
    156 		if ( the_view == SDL_GLView ) {
    157 			return;
    158 		}
    159 #endif
    160 		SDL_View->SetXYOffset(x, y);
    161 	}
    162 	virtual void GetXYOffset(int &x, int &y) {
    163 #if SDL_VIDEO_OPENGL
    164 		if ( the_view == SDL_GLView ) {
    165 			x = 0;
    166 			y = 0;
    167 			return;
    168 		}
    169 #endif
    170 		SDL_View->GetXYOffset(x, y);
    171 	}
    172 	virtual void GetXYOffset(float &x, float &y) {
    173 #if SDL_VIDEO_OPENGL
    174 		if ( the_view == SDL_GLView ) {
    175 			x = 0.0f;
    176 			y = 0.0f;
    177 			return;
    178 		}
    179 #endif
    180 		SDL_View->GetXYOffset(x, y);
    181 	}
    182 	virtual bool BeginDraw(void) {
    183 		return(Lock());
    184 	}
    185 	virtual void DrawAsync(BRect updateRect) {
    186 		SDL_View->DrawAsync(updateRect);
    187 	}
    188 	virtual void EndDraw(void) {
    189 		SDL_View->Sync();
    190 		Unlock();
    191 	}
    192 #if SDL_VIDEO_OPENGL
    193 	virtual void SwapBuffers(void) {
    194 		SDL_GLView->UnlockGL();
    195 		SDL_GLView->SwapBuffers();
    196 		SDL_GLView->LockGL();
    197 	}
    198 #endif
    199 	virtual BView *View(void) {
    200 		return(the_view);
    201 	}
    202 
    203 	/* Hook functions -- overridden */
    204 	virtual void Minimize(bool minimize) {
    205 		/* This is only called when mimimized, not when restored */
    206 		//SDL_PrivateAppActive(minimize, SDL_APPACTIVE);
    207 		BWindow::Minimize(minimize);
    208 	}
    209 	virtual void WindowActivated(bool active) {
    210 		SDL_PrivateAppActive(active, SDL_APPINPUTFOCUS);
    211 	}
    212 	virtual bool QuitRequested(void) {
    213 		if ( SDL_BeAppActive > 0 ) {
    214 			SDL_PrivateQuit();
    215 			/* We don't ever actually close the window here because
    216 			   the application should respond to the quit request,
    217 			   or ignore it as desired.
    218 			 */
    219 #if SDL_VIDEO_OPENGL
    220 			if ( SDL_GLView != NULL ) {
    221 				SDL_GLView->EnableDirectMode(false);
    222 			}
    223 #endif
    224 			return(false);
    225 		}
    226 		return(true);	/* Close the app window */
    227 	}
    228 	virtual void Quit() {
    229 		if (!IsLocked())
    230 			Lock();
    231 		BDirectWindow::Quit();
    232 	}
    233 
    234 	virtual int16 Translate2Unicode(const char *buf) {
    235 		int32 state, srclen, dstlen;
    236 		unsigned char destbuf[2];
    237 		Uint16 unicode = 0;
    238 
    239 		if ((uchar)buf[0] > 127) {
    240 			state = 0;
    241 			srclen = SDL_strlen(buf);
    242 			dstlen = sizeof(destbuf);
    243 			convert_from_utf8(B_UNICODE_CONVERSION, buf, &srclen, (char *)destbuf, &dstlen, &state);
    244 			unicode = destbuf[0];
    245 			unicode <<= 8;
    246 			unicode |= destbuf[1];
    247 		} else
    248 			unicode = buf[0];
    249 
    250 		/* For some reason function keys map to control characters */
    251 # define CTRL(X)	((X)-'@')
    252 		switch (unicode) {
    253 		    case CTRL('A'):
    254 		    case CTRL('B'):
    255 		    case CTRL('C'):
    256 		    case CTRL('D'):
    257 		    case CTRL('E'):
    258 		    case CTRL('K'):
    259 		    case CTRL('L'):
    260 		    case CTRL('P'):
    261 			if ( ! (SDL_GetModState() & KMOD_CTRL) )
    262 				unicode = 0;
    263 			break;
    264 			/* Keyboard input maps newline to carriage return */
    265 			case '\n':
    266 				unicode = '\r';
    267 			break;
    268 		    default:
    269 			break;
    270 		}
    271 
    272 		return unicode;
    273 	}
    274 
    275 	virtual void DispatchMessage(BMessage *msg, BHandler *target);
    276 
    277 	virtual void DirectConnected(direct_buffer_info *info);
    278 
    279 private:
    280 #if SDL_VIDEO_OPENGL
    281 	BGLView *SDL_GLView;
    282 #endif
    283 	SDL_BView *SDL_View;
    284 	BView *the_view;
    285 	bool shown;
    286 	bool inhibit_resize;
    287 	int32 last_buttons;
    288 };
    289 
    290 #endif /* _SDL_BWin_h */
    291