forked from 0ad/0ad
212 lines
6.3 KiB
C++
Executable File
212 lines
6.3 KiB
C++
Executable File
// X Window System-specific code
|
|
// Copyright (c) 2004 Jan Wassenberg
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License as
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful, but
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// General Public License for more details.
|
|
//
|
|
// Contact info:
|
|
// Jan.Wassenberg@stud.uni-karlsruhe.de
|
|
// http://www.stud.uni-karlsruhe.de/~urkt/
|
|
|
|
#include "precompiled.h"
|
|
|
|
#ifdef HAVE_X
|
|
|
|
#include <Xlib.h>
|
|
#include <stdlib.h>
|
|
#include <Xatom.h>
|
|
|
|
#include "lib.h"
|
|
#include "debug.h"
|
|
#include "detect.h"
|
|
|
|
#include <algorithm>
|
|
|
|
// useful for choosing a video mode. not called by detect().
|
|
// if we fail, outputs are unchanged (assumed initialized to defaults)
|
|
int get_cur_vmode(int* xres, int* yres, int* bpp, int* freq)
|
|
{
|
|
Display* disp = XOpenDisplay(0);
|
|
if(!disp)
|
|
return -1;
|
|
|
|
int screen = XDefaultScreen(disp);
|
|
|
|
/* 2004-07-13
|
|
NOTE: The XDisplayWidth/Height functions don't actually return the current
|
|
display mode - they return the size of the root window. This means that
|
|
users with "Virtual Desktops" bigger than what their monitors/graphics
|
|
card can handle will have to set their 0AD screen resolution manually.
|
|
|
|
There's supposed to be an X extension that can give you the actual display
|
|
mode, probably including refresh rate info etc, but it's not worth
|
|
researching and implementing that at this stage.
|
|
*/
|
|
|
|
if(xres)
|
|
*xres = XDisplayWidth (disp, screen);
|
|
if(yres)
|
|
*yres = XDisplayHeight(disp, screen);
|
|
if(bpp)
|
|
*bpp = XDefaultDepth(disp, screen);
|
|
if(freq)
|
|
*freq = 0;
|
|
XCloseDisplay(disp);
|
|
return 0;
|
|
}
|
|
|
|
|
|
// useful for determining aspect ratio. not called by detect().
|
|
// if we fail, outputs are unchanged (assumed initialized to defaults)
|
|
int get_monitor_size(int& width_mm, int& height_mm)
|
|
{
|
|
Display* disp = XOpenDisplay(0);
|
|
if(!disp)
|
|
return -1;
|
|
|
|
int screen = XDefaultScreen(disp);
|
|
|
|
width_mm=XDisplayWidthMM(disp, screen);
|
|
height_mm=XDisplayHeightMM(disp, screen);
|
|
|
|
XCloseDisplay(disp);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Oh, boy, this is heavy stuff...
|
|
|
|
<User-End Stuff - Definitions and Conventions>
|
|
http://www.freedesktop.org/standards/clipboards-spec/clipboards.txt
|
|
<Technical, API stuff>
|
|
http://www.mail-archive.com/xfree86@xfree86.org/msg15594.html
|
|
http://michael.toren.net/mirrors/doc/X-copy+paste.txt
|
|
http://devdocs.wesnoth.org/clipboard_8cpp-source.html
|
|
http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html
|
|
http://www.jwz.org/doc/x-cut-and-paste.html
|
|
|
|
The basic run-down on X Selection Handling:
|
|
* One window owns the "current selection" at any one time
|
|
* Accessing the Selection (i.e. "paste"), Step-by-step
|
|
* Ask the X server for the current selection owner
|
|
* Ask the selection owner window to convert the selection into a format
|
|
we can understand (XA_STRING - Latin-1 string - for now)
|
|
* The converted result is stored as a property of the *selection owner*
|
|
window. It is possible to specify the current application window as the
|
|
target - but that'd require some X message handling... easier to skip that..
|
|
* The final step is to acquire the property value of the selection owner
|
|
window
|
|
|
|
Notes:
|
|
An "Atom" is a server-side object that represents a string by an index into some
|
|
kind of table or something. Pretty much like a handle that refers to one unique
|
|
string. Atoms are used here to refer to property names and value formats.
|
|
|
|
Expansions:
|
|
* Implement UTF-8 format support (should be interresting for international users)
|
|
|
|
*/
|
|
wchar_t *clipboard_get()
|
|
{
|
|
Display *disp=XOpenDisplay(NULL);
|
|
if (!disp)
|
|
return NULL;
|
|
|
|
// We use CLIPBOARD as the default, since the CLIPBOARD semantics are much
|
|
// closer to windows semantics.
|
|
Atom selSource=XInternAtom(disp, "CLIPBOARD", False);
|
|
|
|
Window selOwner=XGetSelectionOwner(disp, selSource);
|
|
if (selOwner == None)
|
|
{
|
|
// However, since many apps don't use CLIPBOARD, but use PRIMARY instead
|
|
// we use XA_PRIMARY as a fallback clipboard. This is true for xterm,
|
|
// for example.
|
|
selSource=XA_PRIMARY;
|
|
selOwner=XGetSelectionOwner(disp, selSource);
|
|
}
|
|
if (selOwner != None) {
|
|
Atom pty=XInternAtom(disp, "SelectionPropertyTemp", False);
|
|
XConvertSelection(disp, selSource, XA_STRING, pty, selOwner, CurrentTime);
|
|
XFlush(disp);
|
|
|
|
Atom type;
|
|
int format=0, result=0;
|
|
unsigned long len=0, bytes_left=0, dummy=0;
|
|
unsigned char *data=NULL;
|
|
|
|
// Get the length of the property and some attributes
|
|
// bytes_left will contain the length of the selection
|
|
result = XGetWindowProperty (disp, selOwner, pty,
|
|
0, 0, // offset - len
|
|
0, // Delete 0==FALSE
|
|
AnyPropertyType,//flag
|
|
&type, // return type
|
|
&format, // return format
|
|
&len, &bytes_left,
|
|
&data);
|
|
if (result != Success)
|
|
debug_printf("clipboard_get: result: %d type:%d len:%d format:%d bytes_left:%d\n",
|
|
result, (int)type, len, format, bytes_left);
|
|
if (result == Success && bytes_left > 0)
|
|
{
|
|
result = XGetWindowProperty (disp, selOwner,
|
|
pty, 0, bytes_left, 0,
|
|
AnyPropertyType, &type, &format,
|
|
&len, &dummy, &data);
|
|
|
|
if (result == Success)
|
|
{
|
|
debug_printf("clipboard_get: XGetWindowProperty succeeded, returning data\n");
|
|
debug_printf("clipboard_get: data was: \"%s\", type was %d, XA_STRING atom is %d\n", data, type, XA_STRING);
|
|
|
|
if (type == XA_STRING) //Latin-1: Just copy into low byte of wchar_t
|
|
{
|
|
wchar_t *ret=(wchar_t *)malloc((bytes_left+1)*sizeof(wchar_t));
|
|
std::copy(data, data+bytes_left, ret);
|
|
ret[bytes_left]=0;
|
|
return ret;
|
|
}
|
|
// TODO: Handle UTF8 strings
|
|
}
|
|
else
|
|
{
|
|
debug_printf("clipboard_get: XGetWindowProperty failed!\n");
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int clipboard_free(wchar_t *clip_buf)
|
|
{
|
|
free(clip_buf);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Setting the Selection (i.e. "copy")
|
|
* Would require overriding the SDL X event handler to receive other apps'
|
|
requests for the selection buffer
|
|
* Step-by-step:
|
|
* Store the selection text in a local buffer
|
|
* Tell the X server that we want to own the selection
|
|
* Listen for Selection events and respond to them as appropriate
|
|
*/
|
|
int clipboard_set(const wchar_t *clip_str)
|
|
{
|
|
// Not Implemented, see comment before clipboard_get, above
|
|
return -1;
|
|
}
|
|
|
|
#endif // #ifdef HAVE_X
|