mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
Refactored Unix Window implementation.
This commit is contained in:
parent
b758f9a1dd
commit
b2b35d0a43
@ -217,11 +217,10 @@ endif()
|
||||
# build the list of external libraries to link
|
||||
if(SFML_OS_WINDOWS)
|
||||
list(APPEND WINDOW_EXT_LIBS winmm gdi32)
|
||||
elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD)
|
||||
elseif(SFML_OS_LINUX)
|
||||
list(APPEND WINDOW_EXT_LIBS ${LIBXCB_LIBRARIES} ${UDEV_LIBRARIES})
|
||||
if(SFML_OS_FREEBSD)
|
||||
list(APPEND WINDOW_EXT_LIBS usbhid)
|
||||
endif()
|
||||
elseif(SFML_OS_FREEBSD)
|
||||
list(APPEND WINDOW_EXT_LIBS ${LIBXCB_LIBRARIES} usbhid)
|
||||
elseif(SFML_OS_MACOSX)
|
||||
list(APPEND WINDOW_EXT_LIBS "-framework Foundation -framework AppKit -framework IOKit -framework Carbon")
|
||||
elseif(SFML_OS_IOS)
|
||||
|
@ -101,6 +101,23 @@ xcb_screen_t* XCBScreenOfDisplay(xcb_connection_t* connection, int screen_nbr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
xcb_screen_t* XCBDefaultScreen(xcb_connection_t* connection)
|
||||
{
|
||||
assert(connection == XGetXCBConnection(sharedDisplay));
|
||||
return XCBScreenOfDisplay(connection, XDefaultScreen(sharedDisplay));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
xcb_window_t XCBDefaultRootWindow(xcb_connection_t* connection)
|
||||
{
|
||||
assert(connection == XGetXCBConnection(sharedDisplay));
|
||||
xcb_screen_t* screen = XCBScreenOfDisplay(connection, XDefaultScreen(sharedDisplay));
|
||||
if (screen)
|
||||
return screen->root;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
@ -60,7 +60,7 @@ xcb_connection_t* OpenConnection();
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Release a reference to the shared display
|
||||
///
|
||||
/// \param Display to release
|
||||
/// \param display Display to release
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void CloseDisplay(Display* display);
|
||||
@ -68,7 +68,7 @@ void CloseDisplay(Display* display);
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Release a reference to the shared display
|
||||
///
|
||||
/// \param Connection of display to release
|
||||
/// \param connection Connection of display to release
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void CloseConnection(xcb_connection_t* connection);
|
||||
@ -76,13 +76,34 @@ void CloseConnection(xcb_connection_t* connection);
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get screen of a display by index (equivalent to XScreenOfDisplay)
|
||||
///
|
||||
/// \param The index of the screen
|
||||
/// \param connection Connection of display
|
||||
/// \param screen_nbr The index of the screen
|
||||
///
|
||||
/// \return Pointer to the screen
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
xcb_screen_t* XCBScreenOfDisplay(xcb_connection_t* connection, int screen_nbr);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get default screen of a display (equivalent to XDefaultScreen)
|
||||
///
|
||||
/// \param connection Connection of display
|
||||
///
|
||||
/// \return Pointer to the default screen of the display
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
xcb_screen_t* XCBDefaultScreen(xcb_connection_t* connection);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get default root window of a display (equivalent to XDefaultRootWindow)
|
||||
///
|
||||
/// \param connection Connection of display
|
||||
///
|
||||
/// \return Root window of the display
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
xcb_window_t XCBDefaultRootWindow(xcb_connection_t* connection);
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
@ -189,16 +189,15 @@ void InputImpl::setVirtualKeyboardVisible(bool /*visible*/)
|
||||
bool InputImpl::isMouseButtonPressed(Mouse::Button button)
|
||||
{
|
||||
// Open a connection with the X server
|
||||
Display* display = OpenDisplay();
|
||||
xcb_connection_t* connection = XGetXCBConnection(display);
|
||||
xcb_connection_t* connection = OpenConnection();
|
||||
|
||||
// Get pointer mask
|
||||
xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply(connection, xcb_query_pointer(connection, XDefaultRootWindow(display)), NULL);
|
||||
xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply(connection, xcb_query_pointer(connection, XCBDefaultRootWindow(connection)), NULL);
|
||||
uint16_t mask = pointer->mask;
|
||||
free(pointer);
|
||||
|
||||
// Close the connection with the X server
|
||||
CloseDisplay(display);
|
||||
CloseConnection(connection);
|
||||
|
||||
switch (button)
|
||||
{
|
||||
@ -216,13 +215,12 @@ bool InputImpl::isMouseButtonPressed(Mouse::Button button)
|
||||
Vector2i InputImpl::getMousePosition()
|
||||
{
|
||||
// Open a connection with the X server
|
||||
Display* display = OpenDisplay();
|
||||
xcb_connection_t* connection = XGetXCBConnection(display);
|
||||
xcb_connection_t* connection = OpenConnection();
|
||||
|
||||
xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply(connection, xcb_query_pointer(connection, XDefaultRootWindow(display)), NULL);
|
||||
xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply(connection, xcb_query_pointer(connection, XCBDefaultRootWindow(connection)), NULL);
|
||||
|
||||
// Close the connection with the X server
|
||||
CloseDisplay(display);
|
||||
CloseConnection(connection);
|
||||
|
||||
// Prepare result.
|
||||
Vector2i result(pointer->root_x, pointer->root_y);
|
||||
@ -263,14 +261,13 @@ Vector2i InputImpl::getMousePosition(const Window& relativeTo)
|
||||
void InputImpl::setMousePosition(const Vector2i& position)
|
||||
{
|
||||
// Open a connection with the X server
|
||||
Display* display = OpenDisplay();
|
||||
xcb_connection_t* connection = XGetXCBConnection(display);
|
||||
xcb_connection_t* connection = OpenConnection();
|
||||
|
||||
xcb_warp_pointer(connection, None, XDefaultRootWindow(display), 0, 0, 0, 0, position.x, position.y);
|
||||
xcb_warp_pointer(connection, None, XCBDefaultRootWindow(connection), 0, 0, 0, 0, position.x, position.y);
|
||||
xcb_flush(connection);
|
||||
|
||||
// Close the connection with the X server
|
||||
CloseDisplay(display);
|
||||
CloseConnection(connection);
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,72 +42,80 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
||||
std::vector<VideoMode> modes;
|
||||
|
||||
// Open a connection with the X server
|
||||
Display* display = OpenDisplay();
|
||||
xcb_connection_t* connection = XGetXCBConnection(display);
|
||||
xcb_connection_t* connection = OpenConnection();
|
||||
|
||||
if (display)
|
||||
// Retrieve the default screen
|
||||
xcb_screen_t* screen = XCBDefaultScreen(connection);
|
||||
|
||||
// Check if the XRandR extension is present
|
||||
static const std::string RANDR = "RANDR";
|
||||
xcb_query_extension_reply_t* randr_ext = xcb_query_extension_reply(
|
||||
connection,
|
||||
xcb_query_extension(
|
||||
connection,
|
||||
RANDR.size(),
|
||||
RANDR.c_str()
|
||||
),
|
||||
NULL
|
||||
);
|
||||
|
||||
if (randr_ext->present)
|
||||
{
|
||||
// Check if the XRandR extension is present
|
||||
xcb_query_extension_cookie_t cookie = xcb_query_extension(connection, 5, "RANDR");
|
||||
// Get the current configuration
|
||||
xcb_generic_error_t* error;
|
||||
xcb_randr_get_screen_info_reply_t* config = xcb_randr_get_screen_info_reply(
|
||||
connection,
|
||||
xcb_randr_get_screen_info(
|
||||
connection,
|
||||
screen->root
|
||||
),
|
||||
&error
|
||||
);
|
||||
|
||||
// Retrieve the default screen
|
||||
xcb_screen_t* screen = XCBScreenOfDisplay(connection, DefaultScreen(display));
|
||||
|
||||
// Check if the XRandR extension is present
|
||||
xcb_query_extension_reply_t* randr_ext = xcb_query_extension_reply(connection, cookie, NULL);
|
||||
if (randr_ext->present)
|
||||
if (!error)
|
||||
{
|
||||
// Get the current configuration
|
||||
xcb_generic_error_t* errors;
|
||||
xcb_randr_get_screen_info_reply_t* config = xcb_randr_get_screen_info_reply(
|
||||
connection, xcb_randr_get_screen_info(connection, screen->root), &errors);
|
||||
if (! errors)
|
||||
// Get the available screen sizes
|
||||
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config);
|
||||
if (sizes && (config->nSizes > 0))
|
||||
{
|
||||
// Get the available screen sizes
|
||||
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config);
|
||||
if (sizes && (config->nSizes > 0))
|
||||
// Get the list of supported depths
|
||||
xcb_depth_iterator_t iter = xcb_screen_allowed_depths_iterator(screen);
|
||||
// Combine depths and sizes to fill the array of supported modes
|
||||
for (; iter.rem; xcb_depth_next(&iter))
|
||||
{
|
||||
// Get the list of supported depths
|
||||
xcb_depth_iterator_t iter = xcb_screen_allowed_depths_iterator(screen);
|
||||
// Combine depths and sizes to fill the array of supported modes
|
||||
for (; iter.rem; xcb_depth_next(&iter))
|
||||
for (int j = 0; j < config->nSizes; ++j)
|
||||
{
|
||||
for (int j = 0; j < config->nSizes; ++j)
|
||||
{
|
||||
// Convert to VideoMode
|
||||
VideoMode mode(sizes[j].width, sizes[j].height, iter.data->depth);
|
||||
// Convert to VideoMode
|
||||
VideoMode mode(sizes[j].width, sizes[j].height, iter.data->depth);
|
||||
|
||||
// Add it only if it is not already in the array
|
||||
if (std::find(modes.begin(), modes.end(), mode) == modes.end())
|
||||
modes.push_back(mode);
|
||||
}
|
||||
// Add it only if it is not already in the array
|
||||
if (std::find(modes.begin(), modes.end(), mode) == modes.end())
|
||||
modes.push_back(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to get the screen configuration
|
||||
err() << "Failed to retrieve the screen configuration while trying to get the supported video modes" << std::endl;
|
||||
}
|
||||
// Free the configuration instance
|
||||
free(errors);
|
||||
free(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
// XRandr extension is not supported: we cannot get the video modes
|
||||
err() << "Failed to use the XRandR extension while trying to get the supported video modes" << std::endl;
|
||||
// Failed to get the screen configuration
|
||||
err() << "Failed to retrieve the screen configuration while trying to get the supported video modes" << std::endl;
|
||||
}
|
||||
free(randr_ext);
|
||||
// Close the connection with the X server
|
||||
CloseDisplay(display);
|
||||
|
||||
// Free the configuration instance
|
||||
free(error);
|
||||
free(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We couldn't connect to the X server
|
||||
err() << "Failed to connect to the X server while trying to get the supported video modes" << std::endl;
|
||||
// XRandr extension is not supported: we cannot get the video modes
|
||||
err() << "Failed to use the XRandR extension while trying to get the supported video modes" << std::endl;
|
||||
}
|
||||
|
||||
free(randr_ext);
|
||||
|
||||
// Close the connection with the X server
|
||||
CloseConnection(connection);
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
@ -118,59 +126,68 @@ VideoMode VideoModeImpl::getDesktopMode()
|
||||
VideoMode desktopMode;
|
||||
|
||||
// Open a connection with the X server
|
||||
Display* display = OpenDisplay();
|
||||
xcb_connection_t* connection = XGetXCBConnection(display);
|
||||
if (display)
|
||||
xcb_connection_t* connection = OpenConnection();
|
||||
|
||||
// Retrieve the default screen
|
||||
xcb_screen_t* screen = XCBDefaultScreen(connection);
|
||||
|
||||
// Check if the XRandR extension is present
|
||||
static const std::string RANDR = "RANDR";
|
||||
xcb_query_extension_reply_t* randr_ext = xcb_query_extension_reply(
|
||||
connection,
|
||||
xcb_query_extension(
|
||||
connection,
|
||||
RANDR.size(),
|
||||
RANDR.c_str()
|
||||
),
|
||||
NULL
|
||||
);
|
||||
|
||||
if (randr_ext->present)
|
||||
{
|
||||
xcb_query_extension_cookie_t cookie = xcb_query_extension(connection, 5, "RANDR");
|
||||
// Retrieve the default screen
|
||||
xcb_screen_t* screen = XCBScreenOfDisplay(connection, DefaultScreen(display));
|
||||
// Get the current configuration
|
||||
xcb_generic_error_t* error;
|
||||
xcb_randr_get_screen_info_reply_t* config = xcb_randr_get_screen_info_reply(
|
||||
connection,
|
||||
xcb_randr_get_screen_info(
|
||||
connection,
|
||||
screen->root
|
||||
),
|
||||
&error
|
||||
);
|
||||
|
||||
// Check if the XRandR extension is present
|
||||
xcb_query_extension_reply_t* randr_ext = xcb_query_extension_reply(connection, cookie, NULL);
|
||||
if (randr_ext->present)
|
||||
if (!error)
|
||||
{
|
||||
// Get the current configuration
|
||||
xcb_generic_error_t* errors;
|
||||
xcb_randr_get_screen_info_reply_t* config =
|
||||
xcb_randr_get_screen_info_reply(
|
||||
connection, xcb_randr_get_screen_info(connection, screen->root), &errors);
|
||||
if (! errors)
|
||||
{
|
||||
// Get the current video mode
|
||||
xcb_randr_mode_t currentMode = config->sizeID;
|
||||
// Get the current video mode
|
||||
xcb_randr_mode_t currentMode = config->sizeID;
|
||||
|
||||
// Get the available screen sizes
|
||||
int nbSizes = xcb_randr_get_screen_info_sizes_length(config);
|
||||
xcb_randr_screen_size_t* sizes= xcb_randr_get_screen_info_sizes(config);
|
||||
if (sizes && (nbSizes > 0))
|
||||
desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, screen->root_depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to get the screen configuration
|
||||
err() << "Failed to retrieve the screen configuration while trying to get the desktop video modes" << std::endl;
|
||||
}
|
||||
// Free the configuration instance
|
||||
free(errors);
|
||||
free(config);
|
||||
// Get the available screen sizes
|
||||
int nbSizes = xcb_randr_get_screen_info_sizes_length(config);
|
||||
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config);
|
||||
if (sizes && (nbSizes > 0))
|
||||
desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, screen->root_depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// XRandr extension is not supported: we cannot get the video modes
|
||||
err() << "Failed to use the XRandR extension while trying to get the desktop video modes" << std::endl;
|
||||
// Failed to get the screen configuration
|
||||
err() << "Failed to retrieve the screen configuration while trying to get the desktop video modes" << std::endl;
|
||||
}
|
||||
|
||||
free(randr_ext);
|
||||
// Close the connection with the X server
|
||||
CloseDisplay(display);
|
||||
// Free the configuration instance
|
||||
free(error);
|
||||
free(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We couldn't connect to the X server
|
||||
err() << "Failed to connect to the X server while trying to get the desktop video modes" << std::endl;
|
||||
// XRandr extension is not supported: we cannot get the video modes
|
||||
err() << "Failed to use the XRandR extension while trying to get the desktop video modes" << std::endl;
|
||||
}
|
||||
|
||||
free(randr_ext);
|
||||
|
||||
// Close the connection with the X server
|
||||
CloseConnection(connection);
|
||||
|
||||
return desktopMode;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include <xcb/xcb_image.h>
|
||||
#include <xcb/xcb_util.h>
|
||||
#include <xcb/randr.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include <cstring>
|
||||
@ -65,18 +67,22 @@ namespace
|
||||
EnterWindowMask | LeaveWindowMask;
|
||||
|
||||
// Find the name of the current executable
|
||||
void findExecutableName(char* buffer, std::size_t bufferSize)
|
||||
std::string findExecutableName()
|
||||
{
|
||||
//Default fallback name
|
||||
const char* executableName = "sfml";
|
||||
std::size_t length = readlink("/proc/self/exe", buffer, bufferSize);
|
||||
if ((length > 0) && (length < bufferSize))
|
||||
{
|
||||
// Remove the path to keep the executable name only
|
||||
buffer[length] = '\0';
|
||||
executableName = basename(buffer);
|
||||
struct stat linkStat;
|
||||
if (!lstat("/proc/self/exe", &linkStat)) {
|
||||
std::vector<char> buffer(0, linkStat.st_size + 1);
|
||||
std::size_t length = readlink("/proc/self/exe", &buffer[0], buffer.size());
|
||||
if ((length > 0) && (length < buffer.size()))
|
||||
{
|
||||
// Remove the path to keep the executable name only
|
||||
buffer[length] = '\0';
|
||||
return basename(&buffer[0]);
|
||||
}
|
||||
}
|
||||
std::memmove(buffer, executableName, std::strlen(executableName) + 1);
|
||||
|
||||
//Default fallback name
|
||||
return "sfml";
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +106,6 @@ m_useSizeHints(false)
|
||||
{
|
||||
// Open a connection with the X server
|
||||
m_display = OpenDisplay();
|
||||
XSetEventQueueOwner(m_display, XCBOwnsEventQueue);
|
||||
m_connection = XGetXCBConnection(m_display);
|
||||
|
||||
if (!m_connection)
|
||||
@ -109,10 +114,8 @@ m_useSizeHints(false)
|
||||
return;
|
||||
}
|
||||
|
||||
// Get connection info.
|
||||
const xcb_setup_t* setup = xcb_get_setup(m_connection);
|
||||
xcb_screen_iterator_t screenIter = xcb_setup_roots_iterator(setup);
|
||||
m_screen = screenIter.data;
|
||||
m_screen = XCBDefaultScreen(m_connection);
|
||||
XSetEventQueueOwner(m_display, XCBOwnsEventQueue);
|
||||
|
||||
// Save the window handle
|
||||
m_window = handle;
|
||||
@ -122,10 +125,12 @@ m_useSizeHints(false)
|
||||
// Make sure the window is listening to all the required events
|
||||
const uint32_t value_list[] = {static_cast<uint32_t>(eventMask)};
|
||||
|
||||
xcb_change_window_attributes(m_connection,
|
||||
m_window,
|
||||
XCB_CW_EVENT_MASK,
|
||||
value_list);
|
||||
xcb_change_window_attributes(
|
||||
m_connection,
|
||||
m_window,
|
||||
XCB_CW_EVENT_MASK,
|
||||
value_list
|
||||
);
|
||||
|
||||
// Do some common initializations
|
||||
initialize();
|
||||
@ -148,32 +153,21 @@ m_useSizeHints(false)
|
||||
{
|
||||
// Open a connection with the X server
|
||||
m_display = OpenDisplay();
|
||||
XSetEventQueueOwner(m_display, XCBOwnsEventQueue);
|
||||
m_connection = XGetXCBConnection(m_display);
|
||||
|
||||
if (!m_connection)
|
||||
{
|
||||
err() << "Failed cast Display object to an XCB connection object" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get connection info.
|
||||
const xcb_setup_t* setup = xcb_get_setup(m_connection);
|
||||
xcb_screen_iterator_t screenIter = xcb_setup_roots_iterator(setup);
|
||||
m_screen = screenIter.data;
|
||||
m_screen = XCBDefaultScreen(m_connection);
|
||||
XSetEventQueueOwner(m_display, XCBOwnsEventQueue);
|
||||
|
||||
// Compute position and size
|
||||
int left, top;
|
||||
bool fullscreen = (style & Style::Fullscreen) != 0;
|
||||
if (!fullscreen)
|
||||
{
|
||||
left = (m_screen->width_in_pixels - mode.width) / 2;
|
||||
top = (m_screen->height_in_pixels - mode.height) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
left = 0;
|
||||
top = 0;
|
||||
}
|
||||
int left = fullscreen ? 0 : (m_screen->width_in_pixels - mode.width) / 2;
|
||||
int top = fullscreen ? 0 : (m_screen->height_in_pixels - mode.height) / 2;
|
||||
int width = mode.width;
|
||||
int height = mode.height;
|
||||
|
||||
@ -187,20 +181,23 @@ m_useSizeHints(false)
|
||||
// Create the window
|
||||
m_window = xcb_generate_id(m_connection);
|
||||
|
||||
xcb_void_cookie_t cookie = xcb_create_window_checked(
|
||||
m_connection,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
m_window,
|
||||
m_screen->root,
|
||||
left, top,
|
||||
width, height,
|
||||
0,
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
XCB_CW_EVENT_MASK | XCB_CW_OVERRIDE_REDIRECT,
|
||||
value_list);
|
||||
xcb_generic_error_t* errptr = xcb_request_check(
|
||||
m_connection,
|
||||
xcb_create_window_checked(
|
||||
m_connection,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
m_window,
|
||||
m_screen->root,
|
||||
left, top,
|
||||
width, height,
|
||||
0,
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||
XCB_COPY_FROM_PARENT,
|
||||
XCB_CW_EVENT_MASK | XCB_CW_OVERRIDE_REDIRECT,
|
||||
value_list
|
||||
)
|
||||
);
|
||||
|
||||
xcb_generic_error_t* errptr = xcb_request_check(m_connection, cookie);
|
||||
bool createWindowFailed = (errptr != NULL);
|
||||
free(errptr);
|
||||
|
||||
@ -213,19 +210,18 @@ m_useSizeHints(false)
|
||||
// Set the window's name
|
||||
setTitle(title);
|
||||
|
||||
// Set the window's style (tell the windows manager to change our window's decorations and functions according to the requested style)
|
||||
// Set the window's style (tell the window manager to change our window's decorations and functions according to the requested style)
|
||||
if (!fullscreen)
|
||||
{
|
||||
static const std::string MOTIF_WM_HINTS = "_MOTIF_WM_HINTS";
|
||||
xcb_intern_atom_cookie_t hintsAtomRequest = xcb_intern_atom(
|
||||
m_connection,
|
||||
0,
|
||||
MOTIF_WM_HINTS.size(),
|
||||
MOTIF_WM_HINTS.c_str()
|
||||
);
|
||||
xcb_intern_atom_reply_t* hintsAtomReply = xcb_intern_atom_reply(
|
||||
m_connection,
|
||||
hintsAtomRequest,
|
||||
xcb_intern_atom(
|
||||
m_connection,
|
||||
0,
|
||||
MOTIF_WM_HINTS.size(),
|
||||
MOTIF_WM_HINTS.c_str()
|
||||
),
|
||||
NULL
|
||||
);
|
||||
|
||||
@ -279,9 +275,16 @@ m_useSizeHints(false)
|
||||
hints.functions |= MWM_FUNC_CLOSE;
|
||||
}
|
||||
|
||||
const unsigned char* ptr = reinterpret_cast<const unsigned char*>(&hints);
|
||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_window,
|
||||
hintsAtomReply->atom, XCB_ATOM_WM_HINTS, 32, 5, ptr);
|
||||
xcb_change_property(
|
||||
m_connection,
|
||||
XCB_PROP_MODE_REPLACE,
|
||||
m_window,
|
||||
hintsAtomReply->atom,
|
||||
XCB_ATOM_WM_HINTS,
|
||||
sizeof(hints.flags) * 8,
|
||||
sizeof(hints) / sizeof(hints.flags),
|
||||
reinterpret_cast<const unsigned char*>(&hints)
|
||||
);
|
||||
|
||||
free(hintsAtomReply);
|
||||
}
|
||||
@ -299,9 +302,8 @@ m_useSizeHints(false)
|
||||
}
|
||||
|
||||
// Set the window's WM class (this can be used by window managers)
|
||||
char windowClass[512];
|
||||
findExecutableName(windowClass, sizeof(windowClass));
|
||||
xcb_icccm_set_wm_class_checked(m_connection, m_window, std::strlen(windowClass), windowClass);
|
||||
std::string windowClass = findExecutableName();
|
||||
xcb_icccm_set_wm_class_checked(m_connection, m_window, windowClass.size(), windowClass.c_str());
|
||||
|
||||
// Do some common initializations
|
||||
initialize();
|
||||
@ -309,8 +311,26 @@ m_useSizeHints(false)
|
||||
// In fullscreen mode, we must grab keyboard and mouse inputs
|
||||
if (fullscreen)
|
||||
{
|
||||
xcb_grab_pointer(m_connection, True, m_window, 0, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, m_window, XCB_NONE, XCB_CURRENT_TIME);
|
||||
xcb_grab_keyboard(m_connection, True, m_window, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
|
||||
xcb_grab_pointer(
|
||||
m_connection,
|
||||
True,
|
||||
m_window,
|
||||
0,
|
||||
XCB_GRAB_MODE_ASYNC,
|
||||
XCB_GRAB_MODE_ASYNC,
|
||||
m_window,
|
||||
XCB_NONE,
|
||||
XCB_CURRENT_TIME
|
||||
);
|
||||
|
||||
xcb_grab_keyboard(
|
||||
m_connection,
|
||||
True,
|
||||
m_window,
|
||||
XCB_CURRENT_TIME,
|
||||
XCB_GRAB_MODE_ASYNC,
|
||||
XCB_GRAB_MODE_ASYNC
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,7 +442,6 @@ Vector2i WindowImplX11::getPosition() const
|
||||
{
|
||||
::Window topLevelWindow = m_window;
|
||||
::Window nextWindow = topLevelWindow;
|
||||
xcb_query_tree_cookie_t treeCookie;
|
||||
xcb_query_tree_reply_t* treeReply = NULL;
|
||||
|
||||
// Get "top level" window, i.e. the window with the root window as its parent.
|
||||
@ -430,14 +449,19 @@ Vector2i WindowImplX11::getPosition() const
|
||||
{
|
||||
topLevelWindow = nextWindow;
|
||||
|
||||
treeCookie = xcb_query_tree(m_connection, topLevelWindow);
|
||||
treeReply = xcb_query_tree_reply(m_connection, treeCookie, NULL);
|
||||
treeReply = xcb_query_tree_reply(m_connection, xcb_query_tree(m_connection, topLevelWindow), NULL);
|
||||
nextWindow = treeReply->parent;
|
||||
free(treeReply);
|
||||
}
|
||||
|
||||
xcb_get_geometry_cookie_t geometryCookie = xcb_get_geometry(m_connection, topLevelWindow);
|
||||
xcb_get_geometry_reply_t* geometryReply = xcb_get_geometry_reply(m_connection, geometryCookie, NULL);
|
||||
xcb_get_geometry_reply_t* geometryReply = xcb_get_geometry_reply(
|
||||
m_connection,
|
||||
xcb_get_geometry(
|
||||
m_connection,
|
||||
topLevelWindow
|
||||
),
|
||||
NULL
|
||||
);
|
||||
sf::Vector2i result(geometryReply->x, geometryReply->y);
|
||||
free(geometryReply);
|
||||
|
||||
@ -480,9 +504,12 @@ void WindowImplX11::setSize(const Vector2u& size)
|
||||
}
|
||||
|
||||
uint32_t values[] = {size.x, size.y};
|
||||
xcb_configure_window(m_connection, m_window,
|
||||
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||
values);
|
||||
xcb_configure_window(
|
||||
m_connection,
|
||||
m_window,
|
||||
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||
values
|
||||
);
|
||||
xcb_flush(m_connection);
|
||||
}
|
||||
|
||||
@ -497,9 +524,16 @@ void WindowImplX11::setTitle(const String& title)
|
||||
std::back_inserter( utf8String )
|
||||
);
|
||||
|
||||
xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_window,
|
||||
XCB_ATOM_WM_NAME, XCB_ATOM_STRING,
|
||||
8, utf8String.length(), utf8String.c_str());
|
||||
xcb_change_property(
|
||||
m_connection,
|
||||
XCB_PROP_MODE_REPLACE,
|
||||
m_window,
|
||||
XCB_ATOM_WM_NAME,
|
||||
XCB_ATOM_STRING,
|
||||
sizeof(std::basic_string<sf::Uint8>::value_type) * 8,
|
||||
utf8String.length(),
|
||||
utf8String.c_str()
|
||||
);
|
||||
xcb_flush(m_connection);
|
||||
}
|
||||
|
||||
@ -519,17 +553,38 @@ void WindowImplX11::setIcon(unsigned int width, unsigned int height, const Uint8
|
||||
|
||||
// Create the icon pixmap
|
||||
xcb_pixmap_t iconPixmap = xcb_generate_id(m_connection);
|
||||
xcb_create_pixmap(m_connection, m_screen->root_depth, iconPixmap, m_screen->root,
|
||||
width, height);
|
||||
xcb_create_pixmap(
|
||||
m_connection,
|
||||
m_screen->root_depth,
|
||||
iconPixmap,
|
||||
m_screen->root,
|
||||
width,
|
||||
height
|
||||
);
|
||||
|
||||
xcb_gcontext_t iconGC = xcb_generate_id(m_connection);
|
||||
xcb_create_gc(m_connection, iconGC, iconPixmap, 0, NULL);
|
||||
xcb_void_cookie_t cookie = xcb_put_image_checked(
|
||||
m_connection, XCB_IMAGE_FORMAT_Z_PIXMAP, iconPixmap, iconGC,
|
||||
width, height, 0, 0, 0, m_screen->root_depth, sizeof(iconPixels), iconPixels);
|
||||
|
||||
xcb_generic_error_t* errptr = xcb_request_check(
|
||||
m_connection,
|
||||
xcb_put_image_checked(
|
||||
m_connection,
|
||||
XCB_IMAGE_FORMAT_Z_PIXMAP,
|
||||
iconPixmap,
|
||||
iconGC,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
m_screen->root_depth,
|
||||
sizeof(iconPixels),
|
||||
iconPixels
|
||||
)
|
||||
);
|
||||
|
||||
xcb_free_gc(m_connection, iconGC);
|
||||
|
||||
xcb_generic_error_t* errptr = xcb_request_check(m_connection, cookie);
|
||||
if (errptr)
|
||||
{
|
||||
err() << "Failed to set the window's icon: Error code " << static_cast<int>(errptr->error_code) << std::endl;
|
||||
@ -554,7 +609,18 @@ void WindowImplX11::setIcon(unsigned int width, unsigned int height, const Uint8
|
||||
}
|
||||
}
|
||||
}
|
||||
xcb_pixmap_t maskPixmap = xcb_create_pixmap_from_bitmap_data(m_connection, m_window, (Uint8*)&maskPixels[0], width, height, 1, 0, 1, NULL);
|
||||
|
||||
xcb_pixmap_t maskPixmap = xcb_create_pixmap_from_bitmap_data(
|
||||
m_connection,
|
||||
m_window,
|
||||
reinterpret_cast<uint8_t*>(&maskPixels[0]),
|
||||
width,
|
||||
height,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
NULL
|
||||
);
|
||||
|
||||
// Send our new icon to the window through the WMHints
|
||||
xcb_icccm_wm_hints_t hints;
|
||||
@ -613,10 +679,14 @@ void WindowImplX11::requestFocus()
|
||||
|
||||
// Check if window is viewable (not on other desktop, ...)
|
||||
// TODO: Check also if minimized
|
||||
xcb_get_window_attributes_cookie_t attribCookie = xcb_get_window_attributes(m_connection, m_window);
|
||||
xcb_get_window_attributes_reply_t* attributes = xcb_get_window_attributes_reply(m_connection,
|
||||
attribCookie,
|
||||
NULL);
|
||||
xcb_get_window_attributes_reply_t* attributes = xcb_get_window_attributes_reply(
|
||||
m_connection,
|
||||
xcb_get_window_attributes(
|
||||
m_connection,
|
||||
m_window
|
||||
),
|
||||
NULL
|
||||
);
|
||||
if (!attributes)
|
||||
{
|
||||
sf::err() << "Failed to check if window is viewable while requesting focus" << std::endl;
|
||||
@ -637,9 +707,16 @@ void WindowImplX11::requestFocus()
|
||||
else
|
||||
{
|
||||
// Get current WM hints.
|
||||
xcb_get_property_cookie_t hintsCookie = xcb_icccm_get_wm_hints_unchecked(m_connection, m_window);
|
||||
xcb_icccm_wm_hints_t hints;
|
||||
xcb_icccm_get_wm_hints_reply(m_connection, hintsCookie, &hints, NULL);
|
||||
xcb_icccm_get_wm_hints_reply(
|
||||
m_connection,
|
||||
xcb_icccm_get_wm_hints_unchecked(
|
||||
m_connection,
|
||||
m_window
|
||||
),
|
||||
&hints,
|
||||
NULL
|
||||
);
|
||||
|
||||
// Even if no hints were returned, we can simply set the proper flags we need and go on. This is
|
||||
// different from Xlib where XAllocWMHints() has to be called.
|
||||
@ -652,13 +729,18 @@ void WindowImplX11::requestFocus()
|
||||
////////////////////////////////////////////////////////////
|
||||
bool WindowImplX11::hasFocus() const
|
||||
{
|
||||
xcb_get_input_focus_cookie_t cookie = xcb_get_input_focus_unchecked(m_connection);
|
||||
xcb_get_input_focus_reply_t* reply = xcb_get_input_focus_reply(m_connection, cookie, NULL);
|
||||
xcb_get_input_focus_reply_t* reply = xcb_get_input_focus_reply(
|
||||
m_connection,
|
||||
xcb_get_input_focus_unchecked(
|
||||
m_connection
|
||||
),
|
||||
NULL
|
||||
);
|
||||
|
||||
bool focussed = (reply->focus == m_window);
|
||||
bool focused = (reply->focus == m_window);
|
||||
free(reply);
|
||||
|
||||
return focussed;
|
||||
return focused;
|
||||
}
|
||||
|
||||
|
||||
@ -666,17 +748,31 @@ bool WindowImplX11::hasFocus() const
|
||||
void WindowImplX11::switchToFullscreen(const VideoMode& mode)
|
||||
{
|
||||
// Check if the XRandR extension is present
|
||||
xcb_query_extension_reply_t* randr_ext =
|
||||
xcb_query_extension_reply(m_connection, xcb_query_extension(m_connection, 5, "RANDR"), NULL);
|
||||
static const std::string RANDR = "RANDR";
|
||||
xcb_query_extension_reply_t* randr_ext = xcb_query_extension_reply(
|
||||
m_connection,
|
||||
xcb_query_extension(
|
||||
m_connection,
|
||||
RANDR.size(),
|
||||
RANDR.c_str()
|
||||
),
|
||||
NULL
|
||||
);
|
||||
|
||||
if (randr_ext->present)
|
||||
{
|
||||
// Get the current configuration
|
||||
xcb_generic_error_t* errors;
|
||||
xcb_randr_get_screen_info_reply_t* config =
|
||||
xcb_randr_get_screen_info_reply(m_connection,
|
||||
xcb_randr_get_screen_info(m_connection, m_screen->root),
|
||||
&errors);
|
||||
if (! errors)
|
||||
xcb_generic_error_t* error;
|
||||
xcb_randr_get_screen_info_reply_t* config = xcb_randr_get_screen_info_reply(
|
||||
m_connection,
|
||||
xcb_randr_get_screen_info(
|
||||
m_connection,
|
||||
m_screen->root
|
||||
),
|
||||
&error
|
||||
);
|
||||
|
||||
if (!error)
|
||||
{
|
||||
// Save the current video mode before we switch to fullscreen
|
||||
m_oldVideoMode = config->sizeID;
|
||||
@ -688,14 +784,19 @@ void WindowImplX11::switchToFullscreen(const VideoMode& mode)
|
||||
// Search a matching size
|
||||
for (int i = 0; i < config->nSizes; ++i)
|
||||
{
|
||||
if ((sizes[i].width == static_cast<int>(mode.width)) && (sizes[i].height == static_cast<int>(mode.height)))
|
||||
if ((sizes[i].width == static_cast<int>(mode.width)) &&
|
||||
(sizes[i].height == static_cast<int>(mode.height)))
|
||||
{
|
||||
// Switch to fullscreen mode
|
||||
xcb_randr_set_screen_config(m_connection,
|
||||
m_screen->root,
|
||||
config->timestamp,
|
||||
config->config_timestamp,
|
||||
i, config->rotation, config->rate);
|
||||
xcb_randr_set_screen_config(
|
||||
m_connection,
|
||||
m_screen->root,
|
||||
config->timestamp,
|
||||
config->config_timestamp,
|
||||
i,
|
||||
config->rotation,
|
||||
config->rate
|
||||
);
|
||||
|
||||
// Set "this" as the current fullscreen window
|
||||
fullscreenWindow = this;
|
||||
@ -709,14 +810,17 @@ void WindowImplX11::switchToFullscreen(const VideoMode& mode)
|
||||
// Failed to get the screen configuration
|
||||
err() << "Failed to get the current screen configuration for fullscreen mode, switching to window mode" << std::endl;
|
||||
}
|
||||
free(errors);
|
||||
|
||||
// Free the configuration instance
|
||||
free(error);
|
||||
free(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
// XRandr extension is not supported: we cannot use fullscreen mode
|
||||
// XRandR extension is not supported: we cannot use fullscreen mode
|
||||
err() << "Fullscreen is not supported, switching to window mode" << std::endl;
|
||||
}
|
||||
|
||||
free(randr_ext);
|
||||
}
|
||||
|
||||
@ -726,30 +830,26 @@ void WindowImplX11::initialize()
|
||||
{
|
||||
// Get the atoms for registering the close event
|
||||
static const std::string WM_DELETE_WINDOW_NAME = "WM_DELETE_WINDOW";
|
||||
|
||||
xcb_intern_atom_cookie_t deleteWindowAtomRequest = xcb_intern_atom(
|
||||
m_connection,
|
||||
0,
|
||||
WM_DELETE_WINDOW_NAME.size(),
|
||||
WM_DELETE_WINDOW_NAME.c_str()
|
||||
);
|
||||
xcb_intern_atom_reply_t* deleteWindowAtomReply = xcb_intern_atom_reply(
|
||||
m_connection,
|
||||
deleteWindowAtomRequest,
|
||||
xcb_intern_atom(
|
||||
m_connection,
|
||||
0,
|
||||
WM_DELETE_WINDOW_NAME.size(),
|
||||
WM_DELETE_WINDOW_NAME.c_str()
|
||||
),
|
||||
NULL
|
||||
);
|
||||
|
||||
static const std::string WM_PROTOCOLS_NAME = "WM_PROTOCOLS";
|
||||
|
||||
xcb_intern_atom_cookie_t protocolsAtomRequest = xcb_intern_atom(
|
||||
m_connection,
|
||||
0,
|
||||
WM_PROTOCOLS_NAME.size(),
|
||||
WM_PROTOCOLS_NAME.c_str()
|
||||
);
|
||||
xcb_intern_atom_reply_t* protocolsAtomReply = xcb_intern_atom_reply(
|
||||
m_connection,
|
||||
protocolsAtomRequest,
|
||||
xcb_intern_atom(
|
||||
m_connection,
|
||||
0,
|
||||
WM_PROTOCOLS_NAME.size(),
|
||||
WM_PROTOCOLS_NAME.c_str()
|
||||
),
|
||||
NULL
|
||||
);
|
||||
|
||||
@ -776,18 +876,25 @@ void WindowImplX11::initialize()
|
||||
|
||||
// Create the input context
|
||||
m_inputMethod = XOpenIM(m_display, NULL, NULL, NULL);
|
||||
|
||||
if (m_inputMethod)
|
||||
{
|
||||
m_inputContext = XCreateIC(m_inputMethod,
|
||||
XNClientWindow, m_window,
|
||||
XNFocusWindow, m_window,
|
||||
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
||||
(void*)NULL);
|
||||
m_inputContext = XCreateIC(
|
||||
m_inputMethod,
|
||||
XNClientWindow,
|
||||
m_window,
|
||||
XNFocusWindow,
|
||||
m_window,
|
||||
XNInputStyle,
|
||||
XIMPreeditNothing | XIMStatusNothing,
|
||||
reinterpret_cast<void*>(NULL)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_inputContext = NULL;
|
||||
}
|
||||
|
||||
if (!m_inputContext)
|
||||
err() << "Failed to create input context for window -- TextEntered event won't be able to return unicode" << std::endl;
|
||||
|
||||
@ -815,10 +922,16 @@ void WindowImplX11::createHiddenCursor()
|
||||
xcb_create_pixmap(m_connection, 1, cursorPixmap, m_window, 1, 1);
|
||||
|
||||
// Create the cursor, using the pixmap as both the shape and the mask of the cursor
|
||||
xcb_create_cursor(m_connection, m_hiddenCursor, cursorPixmap, cursorPixmap,
|
||||
0, 0, 0, // Fore color
|
||||
0, 0, 0, // Back color
|
||||
0, 0);
|
||||
xcb_create_cursor(
|
||||
m_connection,
|
||||
m_hiddenCursor,
|
||||
cursorPixmap,
|
||||
cursorPixmap,
|
||||
0, 0, 0, // Foreground RGB color
|
||||
0, 0, 0, // Background RGB color
|
||||
0, // X
|
||||
0 // Y
|
||||
);
|
||||
|
||||
// We don't need the pixmap any longer, free it
|
||||
xcb_free_pixmap(m_connection, cursorPixmap);
|
||||
@ -832,23 +945,33 @@ void WindowImplX11::cleanup()
|
||||
if (fullscreenWindow == this)
|
||||
{
|
||||
// Get current screen info
|
||||
xcb_generic_error_t* errors;
|
||||
xcb_generic_error_t* error;
|
||||
xcb_randr_get_screen_info_reply_t* config = xcb_randr_get_screen_info_reply(
|
||||
m_connection, xcb_randr_get_screen_info(m_connection, m_screen->root), &errors);
|
||||
if (!errors)
|
||||
m_connection,
|
||||
xcb_randr_get_screen_info(
|
||||
m_connection,
|
||||
m_screen->root
|
||||
),
|
||||
&error
|
||||
);
|
||||
|
||||
if (!error)
|
||||
{
|
||||
// Reset the video mode
|
||||
xcb_randr_set_screen_config(m_connection,
|
||||
m_screen->root,
|
||||
CurrentTime,
|
||||
config->config_timestamp,
|
||||
m_oldVideoMode,
|
||||
config->rotation, config->rate);
|
||||
|
||||
// Free the configuration instance
|
||||
free(config);
|
||||
xcb_randr_set_screen_config(
|
||||
m_connection,
|
||||
m_screen->root,
|
||||
CurrentTime,
|
||||
config->config_timestamp,
|
||||
m_oldVideoMode,
|
||||
config->rotation,
|
||||
config->rate
|
||||
);
|
||||
}
|
||||
free(errors);
|
||||
|
||||
// Free the configuration instance
|
||||
free(error);
|
||||
free(config);
|
||||
|
||||
// Reset the fullscreen window
|
||||
fullscreenWindow = NULL;
|
||||
@ -885,9 +1008,16 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent)
|
||||
pushEvent(event);
|
||||
|
||||
// If the window has been previously marked urgent (notification) as a result of a focus request, undo that
|
||||
xcb_get_property_cookie_t hintsCookie = xcb_icccm_get_wm_hints_unchecked(m_connection, m_window);
|
||||
xcb_icccm_wm_hints_t hints;
|
||||
xcb_icccm_get_wm_hints_reply(m_connection, hintsCookie, &hints, NULL);
|
||||
xcb_icccm_get_wm_hints_reply(
|
||||
m_connection,
|
||||
xcb_icccm_get_wm_hints_unchecked(
|
||||
m_connection,
|
||||
m_window
|
||||
),
|
||||
&hints,
|
||||
NULL
|
||||
);
|
||||
|
||||
// Remove urgency (notification) flag from hints
|
||||
hints.flags &= ~XUrgencyHint;
|
||||
@ -949,8 +1079,8 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent)
|
||||
XEvent fake_event;
|
||||
fake_event.type = KeyPress;
|
||||
fake_event.xany.display = m_display;
|
||||
fake_event.xany.window = e->event;
|
||||
fake_event.xkey.state = e->state;
|
||||
fake_event.xany.window = e->event;
|
||||
fake_event.xkey.state = e->state;
|
||||
fake_event.xkey.keycode = e->detail;
|
||||
|
||||
XLookupString(&fake_event.xkey, buffer, sizeof(buffer), &symbol, &keyboard);
|
||||
@ -974,7 +1104,16 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent)
|
||||
{
|
||||
Status status;
|
||||
Uint8 keyBuffer[16];
|
||||
int length = Xutf8LookupString(m_inputContext, &fake_event.xkey, reinterpret_cast<char*>(keyBuffer), sizeof(keyBuffer), NULL, &status);
|
||||
|
||||
int length = Xutf8LookupString(
|
||||
m_inputContext,
|
||||
&fake_event.xkey,
|
||||
reinterpret_cast<char*>(keyBuffer),
|
||||
sizeof(keyBuffer),
|
||||
NULL,
|
||||
&status
|
||||
);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
Uint32 unicode = 0;
|
||||
@ -1019,7 +1158,7 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent)
|
||||
// has to be converted to an XEvent
|
||||
XKeyEvent fake_event;
|
||||
fake_event.display = m_display;
|
||||
fake_event.state = e->state;
|
||||
fake_event.state = e->state;
|
||||
fake_event.keycode = e->detail;
|
||||
XLookupString(&fake_event, buffer, 32, &symbol, NULL);
|
||||
|
||||
@ -1043,8 +1182,11 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent)
|
||||
|
||||
// XXX: Why button 8 and 9?
|
||||
xcb_button_t button = e->detail;
|
||||
if ((button == XCB_BUTTON_INDEX_1) || (button == XCB_BUTTON_INDEX_2)
|
||||
|| (button == XCB_BUTTON_INDEX_3) || (button == 8) || (button == 9))
|
||||
if ((button == XCB_BUTTON_INDEX_1) ||
|
||||
(button == XCB_BUTTON_INDEX_2) ||
|
||||
(button == XCB_BUTTON_INDEX_3) ||
|
||||
(button == 8) ||
|
||||
(button == 9))
|
||||
{
|
||||
Event event;
|
||||
event.type = Event::MouseButtonPressed;
|
||||
@ -1069,8 +1211,11 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent)
|
||||
xcb_button_release_event_t* e = reinterpret_cast<xcb_button_press_event_t*>(windowEvent);
|
||||
|
||||
xcb_button_t button = e->detail;
|
||||
if ((button == XCB_BUTTON_INDEX_1) || (button == XCB_BUTTON_INDEX_2)
|
||||
|| (button == XCB_BUTTON_INDEX_3) || (button == 8) || (button == 9))
|
||||
if ((button == XCB_BUTTON_INDEX_1) ||
|
||||
(button == XCB_BUTTON_INDEX_2) ||
|
||||
(button == XCB_BUTTON_INDEX_3) ||
|
||||
(button == 8) ||
|
||||
(button == 9))
|
||||
{
|
||||
Event event;
|
||||
event.type = Event::MouseButtonReleased;
|
||||
|
Loading…
Reference in New Issue
Block a user