diff -r 6b3b7803e05d code/ryzom/client/src/events_listener.cpp
--- a/code/ryzom/client/src/events_listener.cpp	Mon May 17 15:27:56 2010 +0200
+++ b/code/ryzom/client/src/events_listener.cpp	Wed May 19 00:38:24 2010 +0200
@@ -145,11 +145,16 @@
 	// Event from the Mouse (ANGLE)
 	if(event == EventGDMouseMove)
 	{
+#ifdef NL_OS_WINDOWS
 		CGDMouseMove* mouseEvent=(CGDMouseMove*)&event;
 		// Mouse acceleration
 		sint dX = mouseEvent->X;
 		sint dY = ClientCfg.FreeLookInverted ? -mouseEvent->Y : mouseEvent->Y;
 		updateFreeLookPos((float) dX, (float) dY);
+#else
+		// just to make sure that there is no game device implementation un unix
+		nlerror("not expecting EventGDMouseMove on unix");
+#endif
 	}
 	// Event from the Mouse (MOVE)
 	else if(event == EventMouseMoveId)
diff -r 6b3b7803e05d code/ryzom/client/src/input.cpp
--- a/code/ryzom/client/src/input.cpp	Mon May 17 15:27:56 2010 +0200
+++ b/code/ryzom/client/src/input.cpp	Wed May 19 00:38:24 2010 +0200
@@ -65,6 +65,11 @@
 // mask for mouse buttons that are known to be down
 uint							DownMouseButtons = 0;
 
+#ifdef NL_OS_UNIX
+// on X11, store whether the mouse was captured or not
+bool							MouseCapture = false;
+#endif
+
 //////////////
 // FUNCTION //
 //////////////
@@ -244,6 +249,13 @@
 		}
 		UpdateMouse ();
 	}
+	
+#ifdef NL_OS_UNIX
+	// on X11 the mouse needs to get pulled into the middle each update, else
+	// the cursor would reach the border of the window / desktop 
+	// and freelook would hang
+	Driver->setMousePos(0.5f, 0.5f);
+#endif
 }
 
 //*********************************************************************************
@@ -360,24 +372,28 @@
 	HWND drvWnd = (HWND) Driver->getDisplay();
 	if (!drvWnd) return;
 	SetCapture(drvWnd);
+#else
+	// on X11, set driver mouse capture on and store it locally as well
+	Driver->setCapture(MouseCapture = true);
 #endif
 }
 
 //*********************************************************************************
 void ReleaseSystemCursor()
 {
+	if (!IsSystemCursorCaptured()) return;
 #ifdef NL_OS_WINDOWS
-	if (IsSystemCursorCaptured())
+	// if hardware mouse and not in client area, then force to update its aspect by updating its pos
+	if (!IsSystemCursorInClientArea())
 	{
-		// if hardware mouse and not in client area, then force to update its aspect by updating its pos
-		if (!IsSystemCursorInClientArea())
-		{
-			// force update
-			ShowCursor(FALSE);
-			ShowCursor(TRUE);
-		}
-		ReleaseCapture();
+		// force update
+		ShowCursor(FALSE);
+		ShowCursor(TRUE);
 	}
+	ReleaseCapture();
+#else
+	// on X11, set driver mouse capture off and store it locally as well
+	Driver->setCapture(MouseCapture = false);
 #endif
 }
 
@@ -388,7 +404,7 @@
 #ifdef NL_OS_WINDOWS
 	return GetCapture() == (HWND) Driver->getDisplay();
 #else
-	return false;
+	return MouseCapture;
 #endif
 }
 
diff -r 6b3b7803e05d code/ryzom/client/src/motion/user_controls.cpp
--- a/code/ryzom/client/src/motion/user_controls.cpp	Mon May 17 15:27:56 2010 +0200
+++ b/code/ryzom/client/src/motion/user_controls.cpp	Wed May 19 00:38:24 2010 +0200
@@ -431,6 +431,11 @@
 	// The mouse may still "StandardMove" ie through a CEventMouseMove
 	// This can happens cause DirectInputDisabled, or because of the "Rotation Anti-Lag system"
 	// which start to rotate before the mouse is hid and message mode passed to RawMode
+	// 
+	// If we are not on Windows; on X11 there is always StandardMove/CEventMouseMove.
+	// Currently, there is only a direct input IMouseDevice, not available on X11.
+
+#ifdef NL_OS_WINDOWS
 	extern IMouseDevice				*MouseDevice;
 	if (MouseDevice)
 	{
@@ -446,6 +451,35 @@
 			EventsListener.updateFreeLookPos(dmpx, dmpy);
 		}
 	}
+#else
+	// On X11, do the thing without IMouseDevice implementation
+	if( EventsListener.getMousePosX() != _LastFrameMousePosX ||
+		EventsListener.getMousePosY() != _LastFrameMousePosY )
+	{
+		float	dmpx, dmpy;
+		
+		// On X11 in free look mode, the mouse is pulled back to (0.5, 0.5) 
+		// every update to prevent reaching a border and get stuck.
+		if(IsMouseFreeLook()) 
+		{
+			dmpx = EventsListener.getMousePosX() - 0.5;
+			dmpy = EventsListener.getMousePosY() - 0.5;
+		}
+		else 
+		{
+			dmpx = EventsListener.getMousePosX() - _LastFrameMousePosX;
+			dmpy = EventsListener.getMousePosY() - _LastFrameMousePosY;
+		}
+		
+		// TODO: read desktop mouse speed value on X11 / implement X11MouseDevice
+		dmpx *= 450.0f; 
+		dmpy *= 450.0f;
+
+		if(ClientCfg.FreeLookInverted) dmpy = -dmpy;
+		// update free look
+		EventsListener.updateFreeLookPos(dmpx, dmpy);
+	}
+#endif
 
 	// If the mouse move on the axis X, with a CGDMouseMove
 	if(EventsListener.isMouseAngleX())
