Browse Source

Haiku: handle mouse movement and click events

Kostadin Damyanov 10 years ago
parent
commit
1505d65ac9

+ 9 - 18
platform/haiku/context_gl_haiku.cpp

@@ -2,18 +2,11 @@
 
 #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
 
-ContextGL_Haiku::ContextGL_Haiku(HaikuDirectWindow** p_window, OS::VideoMode& p_default_video_mode) {
-	video_mode = p_default_video_mode;
-	
-	uint32 type = BGL_RGB|BGL_DOUBLE|BGL_DEPTH;
+ContextGL_Haiku::ContextGL_Haiku(HaikuDirectWindow* p_window) {
+	window = p_window;
 
-	BRect windowRect;
-	windowRect.Set(50, 50, 800, 600);
-
-	window = new HaikuDirectWindow(windowRect);
+	uint32 type = BGL_RGB | BGL_DOUBLE | BGL_DEPTH;
 	view = new HaikuGLView(window->Bounds(), type);
-
-	*p_window = window;
 }
 
 ContextGL_Haiku::~ContextGL_Haiku() {
@@ -24,18 +17,18 @@ Error ContextGL_Haiku::initialize() {
 	window->AddChild(view);
 	view->LockGL();
 	window->SetHaikuGLView(view);
-	window->InitMessageRunner();
-	window->Show();
 
 	return OK;
 }
 
 void ContextGL_Haiku::release_current() {
-	ERR_PRINT("release_current() NOT IMPLEMENTED");
+	//ERR_PRINT("release_current() NOT IMPLEMENTED");
+	view->UnlockGL();
 }
 
 void ContextGL_Haiku::make_current() {
-	ERR_PRINT("make_current() NOT IMPLEMENTED");
+	view->LockGL();
+	//ERR_PRINT("make_current() NOT IMPLEMENTED");
 }
 
 void ContextGL_Haiku::swap_buffers() {
@@ -43,13 +36,11 @@ void ContextGL_Haiku::swap_buffers() {
 }
 
 int ContextGL_Haiku::get_window_width() {
-	// TODO: implement
-	return 800;
+	return window->Bounds().IntegerWidth();
 }
 
 int ContextGL_Haiku::get_window_height() {
-	// TODO: implement
-	return 600;
+	return window->Bounds().IntegerHeight();
 } 
 
 #endif

+ 1 - 3
platform/haiku/context_gl_haiku.h

@@ -3,7 +3,6 @@
 
 #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
 
-#include "os/os.h"
 #include "drivers/gl_context/context_gl.h"
 
 #include "haiku_direct_window.h"
@@ -13,10 +12,9 @@ class ContextGL_Haiku : public ContextGL {
 private:
 	HaikuGLView* view;
 	HaikuDirectWindow* window;
-	OS::VideoMode video_mode;
 
 public:
-	ContextGL_Haiku(HaikuDirectWindow** p_window, OS::VideoMode& default_video_mode);
+	ContextGL_Haiku(HaikuDirectWindow* p_window);
 	~ContextGL_Haiku();
 
 	virtual Error initialize();

+ 159 - 18
platform/haiku/haiku_direct_window.cpp

@@ -1,45 +1,186 @@
+#include "main/main.h"
 #include "haiku_direct_window.h"
 
 HaikuDirectWindow::HaikuDirectWindow(BRect p_frame)
    : BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, 0)
 {
-	// TODO: formatting
-   float minWidth = 0.0f; 
-   float maxWidth = 0.0f; 
-   float minHeight = 0.0f; 
-   float maxHeight = 0.0f; 
- 	
-   GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); 
-   SetSizeLimits(50.0f, maxWidth, 50.0f, maxHeight);
+	last_mouse_pos_valid = false;
+	last_buttons_state = 0;
 }
 
 
-HaikuDirectWindow::~HaikuDirectWindow()
-{
-	delete update_runner;
+HaikuDirectWindow::~HaikuDirectWindow() {
+	if (update_runner) {
+		delete update_runner;
+	}
 }
 
 void HaikuDirectWindow::SetHaikuGLView(HaikuGLView* p_view) {
 	view = p_view;
 }
 
-void HaikuDirectWindow::InitMessageRunner() {
-	update_runner = new BMessageRunner(BMessenger(view),
+void HaikuDirectWindow::StartMessageRunner() {
+	update_runner = new BMessageRunner(BMessenger(this),
 		new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */);
 }
 
+void HaikuDirectWindow::StopMessageRunner() {
+	delete update_runner;
+}
 
-bool HaikuDirectWindow::QuitRequested()
-{
+void HaikuDirectWindow::SetInput(InputDefault* p_input) {
+	input = p_input;
+}
+
+bool HaikuDirectWindow::QuitRequested() {
 	view->EnableDirectMode(false);
 	be_app->PostMessage(B_QUIT_REQUESTED);
 	return true;
 }
 
-
-void HaikuDirectWindow::DirectConnected(direct_buffer_info *info)
-{
+void HaikuDirectWindow::DirectConnected(direct_buffer_info* info) {
 	view->DirectConnected(info);	
 	view->EnableDirectMode(true);
 }
 
+void HaikuDirectWindow::MessageReceived(BMessage* message)
+{
+	switch (message->what) {
+		case REDRAW_MSG:
+			//ERR_PRINT("iteration 1");
+			Main::iteration();
+			
+			//if (NeedsUpdate()) {
+			//	ERR_PRINT("NEEDS UPDATE");
+			//	Main::force_redraw();
+			//}
+			
+			//ERR_PRINT("iteration 2");
+			break;
+		
+		case B_INVALIDATE:
+			ERR_PRINT("WINDOW B_INVALIDATE");
+			//Main::force_redraw();
+			break;
+
+		default:	
+			BDirectWindow::MessageReceived(message);
+	}
+}
+
+void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) {
+	switch (message->what) {
+		case B_MOUSE_DOWN:
+		case B_MOUSE_UP:
+			DispatchMouseButton(message);
+			break;
+
+		case B_MOUSE_MOVED:
+			DispatchMouseMoved(message);
+			break;
+
+		default:
+			BDirectWindow::DispatchMessage(message, handler);
+	}
+}
+
+void HaikuDirectWindow::DispatchMouseButton(BMessage* message) {
+	message->PrintToStream();
+
+	BPoint where;
+	if (message->FindPoint("where", &where) != B_OK) {
+		return;
+	}
+
+	uint32 buttons = message->FindInt32("buttons");
+	uint32 button = buttons ^ last_buttons_state;
+	last_buttons_state = buttons;
+
+	// TODO: implement the mouse_mode checks
+	//if (mouse_mode == MOUSE_MODE_CAPTURED) {
+	//	event.xbutton.x=last_mouse_pos.x;
+	//	event.xbutton.y=last_mouse_pos.y;
+	//}
+	
+	InputEvent mouse_event;
+	mouse_event.ID = ++event_id;
+	mouse_event.type = InputEvent::MOUSE_BUTTON;
+	mouse_event.device = 0;
+
+	// TODO: implement the modifier state getters
+	//mouse_event.mouse_button.mod = get_key_modifier_state(event.xbutton.state);
+	//mouse_event.mouse_button.button_mask = get_mouse_button_state(event.xbutton.state);
+	mouse_event.mouse_button.x = where.x;
+	mouse_event.mouse_button.y = where.y;
+	mouse_event.mouse_button.global_x = where.x;
+	mouse_event.mouse_button.global_y = where.y;
+
+	switch (button) {
+		default:
+		case B_PRIMARY_MOUSE_BUTTON:
+			ERR_PRINT("PRIMARY");
+			mouse_event.mouse_button.button_index = 1;
+			break;
+
+		case B_SECONDARY_MOUSE_BUTTON:
+			ERR_PRINT("SECONDARY");
+			mouse_event.mouse_button.button_index = 2;
+			break;
+
+		case B_TERTIARY_MOUSE_BUTTON:
+			ERR_PRINT("MIDDLE");
+			mouse_event.mouse_button.button_index = 3;
+			break;
+	}
+		
+	mouse_event.mouse_button.pressed = (message->what == B_MOUSE_DOWN);
+
+	if (message->what == B_MOUSE_DOWN && mouse_event.mouse_button.button_index == 1) {
+		int32 clicks = message->FindInt32("clicks");
+		
+		if (clicks > 1) {
+			mouse_event.mouse_button.doubleclick=true;
+		}
+	}	
+
+	input->parse_input_event(mouse_event);
+}
+
+void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) {
+	BPoint where;
+	if (message->FindPoint("where", &where) != B_OK) {
+		return;
+	}
+			
+	Point2i pos(where.x, where.y);
+	
+	if (!last_mouse_pos_valid) {
+		last_mouse_pos=pos;
+		last_mouse_pos_valid=true;
+	}
+
+	Point2i rel = pos - last_mouse_pos;
+
+	InputEvent motion_event;
+	motion_event.ID = ++event_id;
+	motion_event.type = InputEvent::MOUSE_MOTION;
+	motion_event.device = 0;
+
+	// TODO: implement the modifier state getters
+	//motion_event.mouse_motion.mod = get_key_modifier_state(event.xmotion.state);
+	//motion_event.mouse_motion.button_mask = get_mouse_button_state(event.xmotion.state);
+	motion_event.mouse_motion.x = pos.x;
+	motion_event.mouse_motion.y = pos.y;
+	input->set_mouse_pos(pos);
+	motion_event.mouse_motion.global_x = pos.x;
+	motion_event.mouse_motion.global_y = pos.y;
+	motion_event.mouse_motion.speed_x = input->get_mouse_speed().x;
+	motion_event.mouse_motion.speed_y = input->get_mouse_speed().y;
+
+	motion_event.mouse_motion.relative_x = rel.x;
+	motion_event.mouse_motion.relative_y = rel.y;
+
+	last_mouse_pos=pos;
+
+	input->parse_input_event(motion_event);
+}

+ 20 - 6
platform/haiku/haiku_direct_window.h

@@ -4,24 +4,38 @@
 #include <kernel/image.h> // needed for image_id
 #include <DirectWindow.h>
 
+#include "os/input.h"
 #include "haiku_gl_view.h"
 
 #define REDRAW_MSG 'rdrw'
 
 class HaikuDirectWindow : public BDirectWindow 
 {
+private:
+	unsigned int event_id;
+	Point2i last_mouse_pos;
+	bool last_mouse_pos_valid;
+	uint32 last_buttons_state;
+
+	InputDefault* input;
+	HaikuGLView* view;
+	BMessageRunner* update_runner;
+
+	void DispatchMouseButton(BMessage* message);
+	void DispatchMouseMoved(BMessage* message);
+
 public:
 	HaikuDirectWindow(BRect p_frame);
 	~HaikuDirectWindow();
 
 	void SetHaikuGLView(HaikuGLView* p_view);
-	void InitMessageRunner();
+	void StartMessageRunner();
+	void StopMessageRunner();
+	void SetInput(InputDefault* p_input);
 	virtual bool QuitRequested();
-	virtual void DirectConnected(direct_buffer_info *info);
-
-private:
-	HaikuGLView* view;
-	BMessageRunner* update_runner;
+	virtual void DirectConnected(direct_buffer_info* info);
+	virtual void MessageReceived(BMessage* message);
+	virtual void DispatchMessage(BMessage* message, BHandler* handler);
 };
 
 #endif

+ 11 - 34
platform/haiku/haiku_gl_view.cpp

@@ -1,54 +1,31 @@
+#include "main/main.h"
 #include "haiku_gl_view.h"
 
 HaikuGLView::HaikuGLView(BRect frame, uint32 type)
-   : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type), rotate(0)
+   : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type)
 {
-	width = frame.right-frame.left;
-	height = frame.bottom-frame.top;
 }
 
-void HaikuGLView::AttachedToWindow(void)
-{
+void HaikuGLView::AttachedToWindow(void) {
 	LockGL();
 	BGLView::AttachedToWindow();
 	UnlockGL();
 	MakeFocus();
 }
 
-void HaikuGLView::FrameResized(float newWidth, float newHeight) 
-{
-}
-
-void HaikuGLView::gDraw(float rotation)
-{
-}
-
-void HaikuGLView::gReshape(int width, int height)
-{
-}
-
-void HaikuGLView::Render(void)
-{
-	LockGL();
-	SwapBuffers();
-	UnlockGL();
+void HaikuGLView::Draw(BRect updateRect) {
+	Main::force_redraw();
 }
 
-void HaikuGLView::MessageReceived(BMessage * msg)
+void HaikuGLView::MessageReceived(BMessage* msg)
 {
+	// TODO: remove if not needed
 	switch (msg->what) {
-	case 'rdrw':
-		Render();
-		/* Rotate a bit more */
-		rotate++;
-		break;
-
-	default:	
-		BGLView::MessageReceived(msg);
+		default:	
+			BGLView::MessageReceived(msg);
 	}
 }
 
-void HaikuGLView::KeyDown(const char *bytes, int32 numBytes)
-{
-
+void HaikuGLView::MouseMoved (BPoint where, uint32 code, const BMessage *dragMessage) {
+	ERR_PRINT("MouseMoved()");
 }

+ 5 - 15
platform/haiku/haiku_gl_view.h

@@ -7,21 +7,11 @@
 class HaikuGLView : public BGLView
 {
 public:
-   HaikuGLView(BRect frame, uint32 type);
-   virtual void   AttachedToWindow(void);
-   virtual void   FrameResized(float newWidth, float newHeight);
-   virtual void   MessageReceived(BMessage * msg);
-   virtual void   KeyDown(const char* bytes, int32 numBytes);
-   
-   void         Render(void);
-   
-private:
-   void         gDraw(float rotation = 0);
-   void         gReshape(int width, int height);
-         
-   float        width;
-   float        height;
-   float		rotate;
+	HaikuGLView(BRect frame, uint32 type);
+	virtual void AttachedToWindow(void);
+	virtual void MessageReceived(BMessage* msg);
+	virtual void MouseMoved (BPoint where, uint32 code, const BMessage *dragMessage);
+	virtual void Draw(BRect updateRect);
 };
 
 #endif

+ 20 - 9
platform/haiku/os_haiku.cpp

@@ -17,6 +17,8 @@ void OS_Haiku::run() {
 	}
 
 	main_loop->init();
+	window->Show();
+	window->StartMessageRunner();
 
 	/*
 	while (true) {
@@ -29,6 +31,7 @@ void OS_Haiku::run() {
 	*/
 
 	app->Run();
+	window->StopMessageRunner();
 	delete app;
 
 	main_loop->finish();
@@ -56,8 +59,13 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_
 
 	app = new HaikuApplication();
 
+	BRect frame;
+	frame.Set(50, 50, 50 + current_video_mode.width - 1, 50 + current_video_mode.height - 1);
+
+	window = new HaikuDirectWindow(frame);
+
 #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
-	context_gl = memnew(ContextGL_Haiku(&window, current_video_mode));
+	context_gl = memnew(ContextGL_Haiku(window));
 	context_gl->initialize();
 
 	rasterizer = memnew(RasterizerGLES2);
@@ -67,9 +75,9 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_
 
 	ERR_FAIL_COND(!visual_server);
 
-	if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
-		visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
-	}
+	//if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
+	//	visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
+	//}
 
 	visual_server->init();
 
@@ -92,6 +100,9 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_
 	spatial_sound_server->init();
 	spatial_sound_2d_server = memnew(SpatialSound2DServerSW);
 	spatial_sound_2d_server->init();
+
+	input = memnew(InputDefault);
+	window->SetInput(input);
 }
 
 void OS_Haiku::finalize() {
@@ -121,6 +132,8 @@ void OS_Haiku::finalize() {
 	physics_2d_server->finish();
 	memdelete(physics_2d_server);
 
+	memdelete(input);
+
 #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
 	memdelete(context_gl);
 #endif
@@ -128,9 +141,7 @@ void OS_Haiku::finalize() {
 
 void OS_Haiku::set_main_loop(MainLoop* p_main_loop) {
 	main_loop = p_main_loop;
-	
-	// TODO: enable
-	//input->set_main_loop(p_main_loop);
+	input->set_main_loop(p_main_loop);
 }
 
 MainLoop* OS_Haiku::get_main_loop() const {
@@ -146,11 +157,11 @@ void OS_Haiku::delete_main_loop() {
 }
 
 void OS_Haiku::release_rendering_thread() {
-	ERR_PRINT("release_rendering_thread() NOT IMPLEMENTED");
+	context_gl->release_current();
 }
 
 void OS_Haiku::make_rendering_thread() {
-	ERR_PRINT("make_rendering_thread() NOT IMPLEMENTED");
+	context_gl->make_current();
 }
 
 bool OS_Haiku::can_draw() const {

+ 2 - 0
platform/haiku/os_haiku.h

@@ -1,6 +1,7 @@
 #ifndef OS_HAIKU_H
 #define OS_HAIKU_H
 
+#include "os/input.h"
 #include "drivers/unix/os_unix.h"
 #include "servers/visual_server.h"
 #include "servers/visual/rasterizer.h"
@@ -22,6 +23,7 @@ private:
 	HaikuApplication* app;
 	HaikuDirectWindow* window;
 	MainLoop* main_loop;
+	InputDefault* input;
 	Rasterizer* rasterizer;
 	VisualServer* visual_server;
 	VideoMode current_video_mode;