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