This commit is contained in:
Camilla Berglund 2014-01-22 01:34:44 +01:00
parent 5ed23e593c
commit 58db8622bd
5 changed files with 36 additions and 43 deletions

View File

@ -40,10 +40,10 @@ void _glfwInitGammaRamp(void)
{ {
if (_glfw.x11.randr.available) if (_glfw.x11.randr.available)
{ {
XRRScreenResources* rr = XRRGetScreenResources(_glfw.x11.display, XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
_glfw.x11.root); _glfw.x11.root);
if (!rr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, rr->crtcs[0])) if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
{ {
// This is probably older Nvidia RandR with broken gamma support // This is probably older Nvidia RandR with broken gamma support
// Flag it as useless and fall back to Xf86VidMode, if available // Flag it as useless and fall back to Xf86VidMode, if available
@ -52,7 +52,7 @@ void _glfwInitGammaRamp(void)
_glfw.x11.randr.gammaBroken = GL_TRUE; _glfw.x11.randr.gammaBroken = GL_TRUE;
} }
XRRFreeScreenResources(rr); XRRFreeScreenResources(sr);
} }
} }

View File

@ -539,7 +539,7 @@ static GLboolean initExtensions(void)
_glfw.x11.SAVE_TARGETS = _glfw.x11.SAVE_TARGETS =
XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);
// Find or create drag and drop atoms // Find Xdnd (drag and drop) atoms, if available
_glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True); _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True);
_glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True); _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True);
_glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True); _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True);

View File

@ -119,7 +119,7 @@ typedef struct _GLFWlibraryX11
Atom NET_ACTIVE_WINDOW; Atom NET_ACTIVE_WINDOW;
Atom MOTIF_WM_HINTS; Atom MOTIF_WM_HINTS;
// Atoms for Xdnd // Xdnd (drag and drop) atoms
Atom XdndAware; Atom XdndAware;
Atom XdndEnter; Atom XdndEnter;
Atom XdndPosition; Atom XdndPosition;
@ -130,11 +130,7 @@ typedef struct _GLFWlibraryX11
Atom XdndFinished; Atom XdndFinished;
Atom XdndSelection; Atom XdndSelection;
struct { // Selection (clipboard) atoms
Window sourceWindow;
} xdnd;
// Selection atoms
Atom TARGETS; Atom TARGETS;
Atom MULTIPLE; Atom MULTIPLE;
Atom CLIPBOARD; Atom CLIPBOARD;
@ -205,6 +201,10 @@ typedef struct _GLFWlibraryX11
char* string; char* string;
} selection; } selection;
struct {
Window source;
} xdnd;
struct { struct {
int present; int present;
int fd; int fd;

View File

@ -854,38 +854,36 @@ static struct codepair {
// Convert X11 KeySym to Unicode // Convert X11 KeySym to Unicode
// //
long _glfwKeySym2Unicode( KeySym keysym ) long _glfwKeySym2Unicode(KeySym keysym)
{ {
int min = 0; int min = 0;
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
int mid; int mid;
/* First check for Latin-1 characters (1:1 mapping) */ // First check for Latin-1 characters (1:1 mapping)
if( (keysym >= 0x0020 && keysym <= 0x007e) || if ((keysym >= 0x0020 && keysym <= 0x007e) ||
(keysym >= 0x00a0 && keysym <= 0x00ff) ) (keysym >= 0x00a0 && keysym <= 0x00ff))
{ return keysym; {
return keysym;
} }
/* Also check for directly encoded 24-bit UCS characters */ // Also check for directly encoded 24-bit UCS characters
if( (keysym & 0xff000000) == 0x01000000 ) if ((keysym & 0xff000000) == 0x01000000)
return keysym & 0x00ffffff; return keysym & 0x00ffffff;
/* Binary search in table */ // Binary search in table
while( max >= min ) while (max >= min)
{ {
mid = (min + max) / 2; mid = (min + max) / 2;
if( keysymtab[mid].keysym < keysym ) if (keysymtab[mid].keysym < keysym)
min = mid + 1; min = mid + 1;
else if( keysymtab[mid].keysym > keysym ) else if (keysymtab[mid].keysym > keysym)
max = mid - 1; max = mid - 1;
else else
{
/* Found it! */
return keysymtab[mid].ucs; return keysymtab[mid].ucs;
}
} }
/* No matching Unicode value found */ // No matching Unicode value found
return -1; return -1;
} }

View File

@ -353,8 +353,7 @@ static GLboolean createWindow(_GLFWwindow* window,
if (_glfw.x11.XdndAware) if (_glfw.x11.XdndAware)
{ {
// Announce support for XDND version 5 and below // Announce support for Xdnd (drag and drop)
const Atom version = 5; const Atom version = 5;
XChangeProperty(_glfw.x11.display, window->x11.handle, XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.XdndAware, XA_ATOM, 32, _glfw.x11.XdndAware, XA_ATOM, 32,
@ -762,15 +761,14 @@ static void processEvent(XEvent *event)
} }
else if (event->xclient.message_type == _glfw.x11.XdndEnter) else if (event->xclient.message_type == _glfw.x11.XdndEnter)
{ {
// Xdnd Enter: the drag&drop event has started in the window, we // A drag operation has entered the window
// could be getting the type and possible conversions here but // TODO: Check if UTF-8 string is supported by the source
// since we use always string conversion we don't need it
} }
else if (event->xclient.message_type == _glfw.x11.XdndDrop) else if (event->xclient.message_type == _glfw.x11.XdndDrop)
{ {
// Xdnd Drop: The drag&drop event has finished dropping on // The drag operation has finished dropping on
// the window, ask to convert the selection // the window, ask to convert it to a UTF-8 string
_glfw.x11.xdnd.sourceWindow = event->xclient.data.l[0]; _glfw.x11.xdnd.source = event->xclient.data.l[0];
XConvertSelection(_glfw.x11.display, XConvertSelection(_glfw.x11.display,
_glfw.x11.XdndSelection, _glfw.x11.XdndSelection,
_glfw.x11.UTF8_STRING, _glfw.x11.UTF8_STRING,
@ -779,8 +777,7 @@ static void processEvent(XEvent *event)
} }
else if (event->xclient.message_type == _glfw.x11.XdndPosition) else if (event->xclient.message_type == _glfw.x11.XdndPosition)
{ {
// Xdnd Position: get coordinates of the mouse inside the window // The drag operation has moved over the window
// and update the mouse position
const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF; const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF;
const int absY = (event->xclient.data.l[2]) & 0xFFFF; const int absY = (event->xclient.data.l[2]) & 0xFFFF;
int x, y; int x, y;
@ -788,7 +785,7 @@ static void processEvent(XEvent *event)
_glfwPlatformGetWindowPos(window, &x, &y); _glfwPlatformGetWindowPos(window, &x, &y);
_glfwInputCursorMotion(window, absX - x, absY - y); _glfwInputCursorMotion(window, absX - x, absY - y);
// Xdnd: reply with an XDND status message // Reply that we are ready to copy the dragged data
XEvent reply; XEvent reply;
memset(&reply, 0, sizeof(reply)); memset(&reply, 0, sizeof(reply));
@ -800,7 +797,7 @@ static void processEvent(XEvent *event)
reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle
reply.xclient.data.l[2] = 0; // Specify an empty rectangle reply.xclient.data.l[2] = 0; // Specify an empty rectangle
reply.xclient.data.l[3] = 0; reply.xclient.data.l[3] = 0;
reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy; // We only accept copying reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy;
XSendEvent(_glfw.x11.display, window->x11.handle, XSendEvent(_glfw.x11.display, window->x11.handle,
False, NoEventMask, &reply); False, NoEventMask, &reply);
@ -814,10 +811,8 @@ static void processEvent(XEvent *event)
{ {
if (event->xselection.property) if (event->xselection.property)
{ {
// Xdnd: got a selection notification from the conversion // The converted data from the drag operation has arrived
// we asked for, get the data and finish the d&d event
char* data; char* data;
const int result = _glfwGetWindowProperty(event->xselection.requestor, const int result = _glfwGetWindowProperty(event->xselection.requestor,
event->xselection.property, event->xselection.property,
event->xselection.target, event->xselection.target,
@ -841,15 +836,15 @@ static void processEvent(XEvent *event)
memset(&reply, 0, sizeof(reply)); memset(&reply, 0, sizeof(reply));
reply.type = ClientMessage; reply.type = ClientMessage;
reply.xclient.window = _glfw.x11.xdnd.sourceWindow; reply.xclient.window = _glfw.x11.xdnd.source;
reply.xclient.message_type = _glfw.x11.XdndFinished; reply.xclient.message_type = _glfw.x11.XdndFinished;
reply.xclient.format = 32; reply.xclient.format = 32;
reply.xclient.data.l[0] = window->x11.handle; reply.xclient.data.l[0] = window->x11.handle;
reply.xclient.data.l[1] = result; reply.xclient.data.l[1] = result;
reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy; // We only ever copy reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy;
// Reply that all is well // Reply that all is well
XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,
False, NoEventMask, &reply); False, NoEventMask, &reply);
XFlush(_glfw.x11.display); XFlush(_glfw.x11.display);
} }