|
Atrinik Client 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00034 #include <global.h> 00035 #include <SDL_syswm.h> 00036 00037 #if defined(HAVE_X11) 00038 #include <X11/Xlib.h> 00039 #include <X11/Xatom.h> 00040 00041 #ifdef HAVE_X11_XMU 00042 # include <X11/Xmu/Atoms.h> 00043 #endif 00044 00045 static Display *SDL_Display = NULL; 00046 static Window SDL_Window; 00047 #elif defined(WIN32) 00048 static HWND SDL_Window = NULL; 00049 #endif 00050 00051 #if defined(HAVE_X11) 00052 static int clipboard_filter(const SDL_Event *event) 00053 { 00054 /* Post all non-window manager specific events */ 00055 if (event->type != SDL_SYSWMEVENT) 00056 { 00057 return 1; 00058 } 00059 00060 /* Handle window-manager specific clipboard events. */ 00061 switch (event->syswm.msg->event.xevent.type) 00062 { 00063 /* Copy the selection from XA_CUT_BUFFER0 to the requested property. */ 00064 case SelectionRequest: 00065 { 00066 XSelectionRequestEvent *req; 00067 XEvent sevent; 00068 int seln_format; 00069 unsigned long nbytes, overflow; 00070 unsigned char *seln_data; 00071 00072 req = &event->syswm.msg->event.xevent.xselectionrequest; 00073 sevent.xselection.type = SelectionNotify; 00074 sevent.xselection.display = req->display; 00075 sevent.xselection.selection = req->selection; 00076 sevent.xselection.target = None; 00077 sevent.xselection.property = None; 00078 sevent.xselection.requestor = req->requestor; 00079 sevent.xselection.time = req->time; 00080 00081 if (XGetWindowProperty(SDL_Display, DefaultRootWindow(SDL_Display), XA_CUT_BUFFER0, 0, INT_MAX / 4, False, req->target, &sevent.xselection.target, &seln_format, &nbytes, &overflow, &seln_data) == Success) 00082 { 00083 if (sevent.xselection.target == req->target) 00084 { 00085 if (sevent.xselection.target == XA_STRING) 00086 { 00087 if (seln_data[nbytes - 1] == '\0') 00088 { 00089 nbytes--; 00090 } 00091 } 00092 00093 XChangeProperty(SDL_Display, req->requestor, req->property, sevent.xselection.target, seln_format, PropModeReplace, seln_data, nbytes); 00094 sevent.xselection.property = req->property; 00095 } 00096 00097 XFree(seln_data); 00098 } 00099 00100 XSendEvent(SDL_Display, req->requestor, False, 0, &sevent); 00101 XSync(SDL_Display, False); 00102 } 00103 00104 break; 00105 } 00106 00107 /* Post the event for X11 clipboard reading above. */ 00108 return 1; 00109 } 00110 #endif 00111 00115 int clipboard_init() 00116 { 00117 SDL_SysWMinfo info; 00118 00119 /* Grab the window manager specific information. */ 00120 SDL_VERSION(&info.version); 00121 00122 if (SDL_GetWMInfo(&info)) 00123 { 00124 /* Save the information for later use. */ 00125 #if defined(HAVE_X11) 00126 if (info.subsystem == SDL_SYSWM_X11) 00127 { 00128 SDL_Display = info.info.x11.display; 00129 SDL_Window = info.info.x11.window; 00130 00131 /* Enable the special window hook events. */ 00132 SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); 00133 SDL_SetEventFilter(clipboard_filter); 00134 00135 return 1; 00136 } 00137 else 00138 { 00139 LOG(llevBug, "SDL is not running on X11 display.\n"); 00140 return 0; 00141 } 00142 00143 #elif defined(WIN32) 00144 SDL_Window = info.window; 00145 return 1; 00146 00147 #else 00148 return 0; 00149 00150 #endif 00151 } 00152 00153 return 0; 00154 } 00155 00160 int clipboard_set(const char *str) 00161 { 00162 #if defined(HAVE_X11) 00163 if (!SDL_Display) 00164 { 00165 return 0; 00166 } 00167 00168 XChangeProperty(SDL_Display, DefaultRootWindow(SDL_Display), XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, (unsigned const char *) str, strlen(str)); 00169 00170 if (XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window) 00171 { 00172 XSetSelectionOwner(SDL_Display, XA_PRIMARY, SDL_Window, CurrentTime); 00173 } 00174 00175 #ifdef HAVE_X11_XMU 00176 if (XGetSelectionOwner(SDL_Display, XA_CLIPBOARD(SDL_Display)) != SDL_Window) 00177 { 00178 XSetSelectionOwner(SDL_Display, XA_CLIPBOARD(SDL_Display), SDL_Window, CurrentTime); 00179 } 00180 #endif 00181 00182 if (getenv("KDE_FULL_SESSION")) 00183 { 00184 char buf[4096 * 4]; 00185 00186 snprintf(buf, sizeof(buf), "dbus-send --type=method_call --dest=org.kde.klipper /klipper org.kde.klipper.klipper.setClipboardContents string:\"%s\"", str); 00187 00188 if (system(buf) != 0) 00189 { 00190 return 0; 00191 } 00192 } 00193 00194 return 1; 00195 #elif defined(WIN32) 00196 if (!SDL_Window) 00197 { 00198 return 0; 00199 } 00200 00201 if (OpenClipboard(SDL_Window)) 00202 { 00203 SIZE_T i, size; 00204 HANDLE hMem; 00205 00206 /* Find out the size of the data. */ 00207 for (size = 0, i = 0; str[i] != '\0'; i++, size++) 00208 { 00209 if (str[i] == '\n' && (i == 0 || str[i - 1] != '\r')) 00210 { 00211 /* We're going to insert a carriage return. */ 00212 size++; 00213 } 00214 } 00215 00216 size += 1; 00217 00218 hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size); 00219 00220 if (hMem) 00221 { 00222 LPTSTR dst = (LPTSTR) GlobalLock(hMem); 00223 00224 /* Copy the text over, adding carriage returns as necessary. */ 00225 for (i = 0; str[i] != '\0'; i++) 00226 { 00227 if (str[i] == '\n' && (i == 0 || str[i - 1] != '\r')) 00228 { 00229 *dst++ = '\r'; 00230 } 00231 00232 *dst++ = str[i]; 00233 } 00234 00235 *dst = '\0'; 00236 GlobalUnlock(hMem); 00237 00238 EmptyClipboard(); 00239 00240 if (!SetClipboardData(CF_TEXT, hMem)) 00241 { 00242 CloseClipboard(); 00243 return 0; 00244 } 00245 } 00246 00247 CloseClipboard(); 00248 } 00249 00250 return 1; 00251 #else 00252 (void) str; 00253 return 0; 00254 #endif 00255 } 00256 00261 char *clipboard_get() 00262 { 00263 char *result; 00264 #if defined(HAVE_X11) 00265 Window owner; 00266 Atom selection, seln_type; 00267 int seln_format; 00268 unsigned long nbytes, overflow; 00269 char *src; 00270 00271 if (!SDL_Display) 00272 { 00273 return NULL; 00274 } 00275 00276 owner = XGetSelectionOwner(SDL_Display, XA_PRIMARY); 00277 result = NULL; 00278 00279 if (owner == None || owner == SDL_Window) 00280 { 00281 owner = DefaultRootWindow(SDL_Display); 00282 selection = XA_CUT_BUFFER0; 00283 } 00284 else 00285 { 00286 int selection_response = 0; 00287 SDL_Event event; 00288 00289 owner = SDL_Window; 00290 selection = XInternAtom(SDL_Display, "SDL_SELECTION", False); 00291 XConvertSelection(SDL_Display, XA_PRIMARY, XA_STRING, selection, owner, CurrentTime); 00292 00293 while (!selection_response) 00294 { 00295 SDL_WaitEvent(&event); 00296 00297 if (event.type == SDL_SYSWMEVENT) 00298 { 00299 XEvent xevent = event.syswm.msg->event.xevent; 00300 00301 if ((xevent.type == SelectionNotify) && (xevent.xselection.requestor == owner)) 00302 { 00303 selection_response = 1; 00304 } 00305 } 00306 } 00307 } 00308 00309 if (XGetWindowProperty(SDL_Display, owner, selection, 0, INT_MAX / 4, False, XA_STRING, &seln_type, &seln_format, &nbytes, &overflow, (unsigned char **) &src) == Success) 00310 { 00311 if (seln_type == XA_STRING) 00312 { 00313 result = strdup(src); 00314 } 00315 00316 XFree(src); 00317 } 00318 #elif defined(WIN32) 00319 if (!SDL_Window) 00320 { 00321 return NULL; 00322 } 00323 00324 if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(SDL_Window)) 00325 { 00326 HANDLE hMem; 00327 char *src; 00328 00329 hMem = GetClipboardData(CF_TEXT); 00330 00331 if (hMem) 00332 { 00333 src = (char *) GlobalLock(hMem); 00334 result = strdup(src); 00335 GlobalUnlock(hMem); 00336 } 00337 00338 CloseClipboard(); 00339 } 00340 #else 00341 result = NULL; 00342 #endif 00343 00344 return result; 00345 }
1.7.4