Ejemplo n.º 1
0
void OS_X11::probe_joystick(int p_id) {
	#ifndef __FreeBSD__

	if (p_id == -1) {

		for (int i=0; i<JOYSTICKS_MAX; i++) {

			probe_joystick(i);
		};
		return;
	};

	if (joysticks[p_id].fd != -1)
		close_joystick(p_id);

	const char *joy_names[] = {
		"/dev/input/js%d",
		"/dev/js%d",
		NULL
	};

	int i=0;
	while(joy_names[i]) {

		char fname[64];
		sprintf(fname, joy_names[i], p_id);
		int fd = open(fname, O_RDONLY|O_NONBLOCK);
		if (fd != -1) {

			//fcntl( fd, F_SETFL, O_NONBLOCK );
			joysticks[p_id] = Joystick(); // this will reset the axis array
			joysticks[p_id].fd = fd;

			String name;
			char namebuf[255] = {0};
			if (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) >= 0) {
				name = namebuf;
			} else {
				name = "error";
			};

			input->joy_connection_changed(p_id, true, name);
			break; // don't try the next name
		};

		++i;
	};
	#endif
};
Ejemplo n.º 2
0
void OS_X11::probe_joystick(int p_id) {
	#ifndef __FreeBSD__
	if (p_id == -1) {

		for (int i=0; i<JOYSTICKS_MAX; i++) {

			probe_joystick(i);
		};
		return;
	};

	close_joystick(p_id);

	const char *joy_names[] = {
		"/dev/input/js%d",
		"/dev/js%d",
		NULL
	};

	int i=0;
	while(joy_names[i]) {

		char fname[64];
		sprintf(fname, joy_names[i], p_id);
		int fd = open(fname, O_RDONLY);
		if (fd != -1) {

			fcntl( fd, F_SETFL, O_NONBLOCK );
			joysticks[p_id] = Joystick(); // this will reset the axis array
			joysticks[p_id].fd = fd;
			break; // don't try the next name
		};

		++i;
	};
	#endif
};
Ejemplo n.º 3
0
void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {

	last_button_state=0;
	dpad_last[0]=0;
	dpad_last[1]=0;

	xmbstring=NULL;
	event_id=0;
	x11_window=0;
	last_click_ms=0;
	args=OS::get_singleton()->get_cmdline_args();
	current_videomode=p_desired;
	main_loop=NULL;
	last_timestamp=0;
	last_mouse_pos_valid=false;
	last_keyrelease_time=0;

	if (get_render_thread_mode()==RENDER_SEPARATE_THREAD) {
		XInitThreads();
	}
	
	/** XLIB INITIALIZATION **/
	x11_display = XOpenDisplay(NULL);
	
	char * modifiers = XSetLocaleModifiers ("@im=none");
	ERR_FAIL_COND( modifiers == NULL );
	
	xim = XOpenIM (x11_display, NULL, NULL, NULL);
	

	if (xim == NULL) {
		WARN_PRINT("XOpenIM failed");
		xim_style=NULL;
	} else {
		::XIMStyles *xim_styles=NULL;
		xim_style=0;
		char *imvalret=NULL;
		imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL);
		if (imvalret != NULL || xim_styles == NULL) {
			fprintf (stderr, "Input method doesn't support any styles\n");
		}
		
		if (xim_styles) {
			xim_style = 0;
			for (int i=0;i<xim_styles->count_styles;i++) {
				
				if (xim_styles->supported_styles[i] ==
				    (XIMPreeditNothing | XIMStatusNothing)) {
					    
					    xim_style = xim_styles->supported_styles[i];
					    break;
				    }
			}
			
			XFree (xim_styles);
		}
	}

	/*
	char* windowid = getenv("GODOT_WINDOWID");
	if (windowid) {

		//freopen("/home/punto/stdout", "w", stdout);
		//reopen("/home/punto/stderr", "w", stderr);
		x11_window = atol(windowid);

		XWindowAttributes xwa;
		XGetWindowAttributes(x11_display,x11_window,&xwa);

		current_videomode.width = xwa.width;
		current_videomode.height = xwa.height;
	};
	*/

	// maybe contextgl wants to be in charge of creating the window
	//print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height));
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
	context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) );
	context_gl->initialize();

	if (true) {
		rasterizer = memnew( RasterizerGLES2 );
	} else {
		//rasterizer = memnew( RasterizerGLES1 );
	};

#endif
	visual_server = memnew( VisualServerRaster(rasterizer) );

	if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {

		visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
	}

	// borderless fullscreen window mode
	if (current_videomode.fullscreen) {
		// needed for lxde/openbox, possibly others
		Hints hints;
		Atom property;
		hints.flags = 2;
		hints.decorations = 0;
		property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
		XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
		XMapRaised(x11_display, x11_window);
		XWindowAttributes xwa;
		XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa);
		XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height);

		// code for netwm-compliants
		XEvent xev;
		Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
		Atom fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);

		memset(&xev, 0, sizeof(xev));
		xev.type = ClientMessage;
		xev.xclient.window = x11_window;
		xev.xclient.message_type = wm_state;
		xev.xclient.format = 32;
		xev.xclient.data.l[0] = 1;
		xev.xclient.data.l[1] = fullscreen;
		xev.xclient.data.l[2] = 0;

		XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
	}

	// disable resizeable window
	if (!current_videomode.resizable) {
		XSizeHints *xsh;
		xsh = XAllocSizeHints();
		xsh->flags = PMinSize | PMaxSize;
		XWindowAttributes xwa;
		if (current_videomode.fullscreen) {
			XGetWindowAttributes(x11_display,DefaultRootWindow(x11_display),&xwa);
		} else {
			XGetWindowAttributes(x11_display,x11_window,&xwa);
		}
		xsh->min_width = xwa.width; 
		xsh->max_width = xwa.width;
		xsh->min_height = xwa.height;
		xsh->max_height = xwa.height;
		XSetWMNormalHints(x11_display, x11_window, xsh);
	}

	AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();

	if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) {

		ERR_PRINT("Initializing audio failed.");
	}

	sample_manager = memnew( SampleManagerMallocSW );
	audio_server = memnew( AudioServerSW(sample_manager) );
	audio_server->init();
	spatial_sound_server = memnew( SpatialSoundServerSW );
	spatial_sound_server->init();
	spatial_sound_2d_server = memnew( SpatialSound2DServerSW );
	spatial_sound_2d_server->init();

	
	ERR_FAIL_COND(!visual_server);
	ERR_FAIL_COND(x11_window==0);

	XSetWindowAttributes new_attr;

	new_attr.event_mask=KeyPressMask | KeyReleaseMask | ButtonPressMask |
			   ButtonReleaseMask | EnterWindowMask |
			   LeaveWindowMask | PointerMotionMask |
			   Button1MotionMask |
			   Button2MotionMask | Button3MotionMask |
			   Button4MotionMask | Button5MotionMask |
			   ButtonMotionMask | KeymapStateMask |
			   ExposureMask | VisibilityChangeMask |
			   StructureNotifyMask |
			   SubstructureNotifyMask | SubstructureRedirectMask |
			   FocusChangeMask | PropertyChangeMask |
			   ColormapChangeMask | OwnerGrabButtonMask;

	XChangeWindowAttributes(x11_display, x11_window,CWEventMask,&new_attr);
	
    XClassHint* classHint;

    /* set the titlebar name */
    XStoreName(x11_display, x11_window, "Godot");

    /* set the name and class hints for the window manager to use */
    classHint = XAllocClassHint();
    if (classHint) {
        classHint->res_name = "Godot";
        classHint->res_class = "Godot";
    }
    XSetClassHint(x11_display, x11_window, classHint);
    XFree(classHint);

	wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true);	
	XSetWMProtocols(x11_display, x11_window, &wm_delete, 1);
		

	if (xim && xim_style) {
		
		xic = XCreateIC (xim,XNInputStyle, xim_style,XNClientWindow,x11_window,XNFocusWindow, x11_window, (char*)NULL);
	} else {
		
		xic=NULL;
		WARN_PRINT("XCreateIC couldn't create xic");

	}	

	XcursorSetTheme(x11_display,"default");
	cursor_size = XcursorGetDefaultSize(x11_display);
	cursor_theme = XcursorGetTheme(x11_display);

	if (!cursor_theme) {
		print_line("not found theme");
		cursor_theme="default";
	}

	for(int i=0;i<CURSOR_MAX;i++) {

		cursors[i]=None;
	}

	current_cursor=CURSOR_ARROW;

	if (cursor_theme) {
		//print_line("cursor theme: "+String(cursor_theme));
		for(int i=0;i<CURSOR_MAX;i++) {

			static const char *cursor_file[]={
				"left_ptr",
				"xterm",
				"hand2",
				"cross",
				"watch",
				"left_ptr_watch",
				"fleur",
				"hand1",
				"X_cursor",
				"sb_v_double_arrow",
				"sb_h_double_arrow",
				"size_bdiag",
				"size_fdiag",
				"hand1",
				"sb_v_double_arrow",
				"sb_h_double_arrow",
				"question_arrow"
			};

			XcursorImage *img = XcursorLibraryLoadImage(cursor_file[i],cursor_theme,cursor_size);
			if (img) {
				cursors[i]=XcursorImageLoadCursor(x11_display,img);
				//print_line("found cursor: "+String(cursor_file[i])+" id "+itos(cursors[i]));
			} else {
				if (OS::is_stdout_verbose())
					print_line("failed cursor: "+String(cursor_file[i]));
			}
		}

	}


	{
		Pixmap cursormask;
		 XGCValues xgc;
		 GC gc;
		 XColor col;
		 Cursor cursor;

		 cursormask = XCreatePixmap(x11_display, RootWindow(x11_display,DefaultScreen(x11_display)), 1, 1, 1);
		 xgc.function = GXclear;
		 gc = XCreateGC(x11_display, cursormask, GCFunction, &xgc);
		XFillRectangle(x11_display, cursormask, gc, 0, 0, 1, 1);
		col.pixel = 0;
		col.red = 0;
		col.flags = 4;
		cursor = XCreatePixmapCursor(x11_display,
			      cursormask, cursormask,
			      &col, &col, 0, 0);
		 XFreePixmap(x11_display, cursormask);
		 XFreeGC(x11_display, gc);



		 if (cursor == None)
		 {
			 ERR_PRINT("FAILED CREATING CURSOR");
		 }

		 null_cursor=cursor;
	}
	set_cursor_shape(CURSOR_BUSY);


	visual_server->init();
	//
	physics_server = memnew( PhysicsServerSW );
	physics_server->init();
	physics_2d_server = memnew( Physics2DServerSW );
	physics_2d_server->init();

	input = memnew( InputDefault );

	probe_joystick();

	_ensure_data_dir();

	net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False);


	//printf("got map notify\n");
		
}
Ejemplo n.º 4
0
void OS_X11::process_joysticks() {
	#ifndef __FreeBSD__
	int bytes;
	js_event events[32];
	InputEvent ievent;
	for (int i=0; i<JOYSTICKS_MAX; i++) {

		if (joysticks[i].fd == -1) {
			probe_joystick(i);
			if (joysticks[i].fd == -1)
				continue;
		};
		ievent.device = i;

		while ( (bytes = read(joysticks[i].fd, &events, sizeof(events))) > 0) {

			int ev_count = bytes / sizeof(js_event);
			for (int j=0; j<ev_count; j++) {

				js_event& event = events[j];

				//printf("got event on joystick %i, %i, %i, %i, %i\n", i, joysticks[i].fd, event.type, event.number, event.value);
				if (event.type & JS_EVENT_INIT)
					continue;

				switch (event.type & ~JS_EVENT_INIT) {

				case JS_EVENT_AXIS:

					//if (joysticks[i].last_axis[event.number] != event.value) {

						/*
						if (event.number==5 || event.number==6) {

							int axis=event.number-5;
							int val = event.value;
							if (val<0)
								val=-1;
							if (val>0)
								val=+1;

							InputEvent ev;
							ev.type = InputEvent::JOYSTICK_BUTTON;
							ev.ID = ++event_id;


							if (val!=dpad_last[axis]) {

								int prev_val = dpad_last[axis];
								if (prev_val!=0) {

									ev.joy_button.pressed=false;
									ev.joy_button.pressure=0.0;
									if (event.number==5)
										ev.joy_button.button_index=JOY_DPAD_LEFT+(prev_val+1)/2;
									if (event.number==6)
										ev.joy_button.button_index=JOY_DPAD_UP+(prev_val+1)/2;

									input->parse_input_event( ev );
								}
							}

							if (val!=0) {

								ev.joy_button.pressed=true;
								ev.joy_button.pressure=1.0;
								if (event.number==5)
									ev.joy_button.button_index=JOY_DPAD_LEFT+(val+1)/2;
								if (event.number==6)
									ev.joy_button.button_index=JOY_DPAD_UP+(val+1)/2;

								input->parse_input_event( ev );
							}


							dpad_last[axis]=val;

						}
						*/
						//print_line("ev: "+itos(event.number)+" val: "+ rtos((float)event.value / (float)MAX_JOY_AXIS));
						//if (event.number >= JOY_AXIS_MAX)
						//	break;
						//ERR_FAIL_COND(event.number >= JOY_AXIS_MAX);
						ievent.type = InputEvent::JOYSTICK_MOTION;
						ievent.ID = ++event_id;
						ievent.joy_motion.axis = event.number; //_pc_joystick_get_native_axis(event.number);
						ievent.joy_motion.axis_value = (float)event.value / (float)MAX_JOY_AXIS;
						if (event.number < JOY_AXIS_MAX)
							joysticks[i].last_axis[event.number] = event.value;
						input->parse_input_event( ievent );
					//};
					break;

				case JS_EVENT_BUTTON:


					ievent.type = InputEvent::JOYSTICK_BUTTON;
					ievent.ID = ++event_id;
					ievent.joy_button.button_index = event.number; // _pc_joystick_get_native_button(event.number);
					ievent.joy_button.pressed = event.value;
					input->parse_input_event( ievent );
					break;
				};
			};
		};
		if (bytes == 0 || (bytes < 0 && errno != EAGAIN)) {
			close_joystick(i);
		};
	};
	#endif
};