Guest User

Untitled

a guest
Jan 22nd, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.50 KB | None | 0 0
  1. #ifndef STAND_ALONE_GAME //maks
  2.  
  3. /* Handle clipboard text and data in arbitrary formats */
  4.  
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include <limits.h>
  8. #include <stdlib.h> //maks
  9.  
  10. #include "SDL.h"
  11. #include "SDL_syswm.h"
  12.  
  13. #include "scrap.h"
  14.  
  15. #include "../../gameEngine/dlmalloc.h" //maks
  16.  
  17. /* Miscellaneous defines */
  18. #define PUBLIC
  19. #define PRIVATE static
  20.  
  21. /* Determine what type of clipboard we are using */
  22. #if defined(__unix__) && !defined(__QNXNTO__)
  23. #define X11_SCRAP
  24. #elif defined(__MACOSX__)
  25. #define X11_SCRAP
  26. #elif defined(WIN32)
  27. #define WIN_SCRAP
  28. #elif defined(__QNXNTO__)
  29. #define QNX_SCRAP
  30. #else
  31. #error Unknown window manager for clipboard handling
  32. #endif /* scrap type */
  33.  
  34. /* System dependent data types */
  35. #if defined(X11_SCRAP)
  36. /* * */
  37. typedef Atom scrap_type;
  38.  
  39. #elif defined(WIN_SCRAP)
  40. /* * */
  41. typedef UINT scrap_type;
  42.  
  43. #elif defined(QNX_SCRAP)
  44. /* * */
  45. typedef uint32_t scrap_type;
  46. #define Ph_CL_TEXT T('T', 'E', 'X', 'T')
  47.  
  48. #endif /* scrap type */
  49.  
  50. /* System dependent variables */
  51. #if defined(X11_SCRAP)
  52. /* * */
  53. static Display *SDL_Display;
  54. #if __APPLE
  55. #define SDL_Window SDl_Window //AKR
  56. #endif
  57. static Window SDL_Window;
  58. static void (*Lock_Display)(void);
  59. static void (*Unlock_Display)(void);
  60.  
  61. #elif defined(WIN_SCRAP)
  62. /* * */
  63. static HWND SDL_Window;
  64.  
  65. #elif defined(QNX_SCRAP)
  66. /* * */
  67. static unsigned short InputGroup;
  68.  
  69. #endif /* scrap type */
  70.  
  71. #define FORMAT_PREFIX "SDL_scrap_0x"
  72.  
  73. PRIVATE scrap_type
  74. convert_format(int type)
  75. {
  76. switch (type)
  77. {
  78.  
  79. case T('T', 'E', 'X', 'T'):
  80. #if defined(X11_SCRAP)
  81. /* * */
  82. return XA_STRING;
  83.  
  84. #elif defined(WIN_SCRAP)
  85. /* * */
  86. return CF_TEXT;
  87.  
  88. #elif defined(QNX_SCRAP)
  89. /* * */
  90. return Ph_CL_TEXT;
  91.  
  92. #endif /* scrap type */
  93.  
  94. default:
  95. {
  96. char format[sizeof(FORMAT_PREFIX)+8+1];
  97.  
  98. sprintf(format, "%s%08lx", FORMAT_PREFIX, (unsigned long)type);
  99.  
  100. #if defined(X11_SCRAP)
  101. /* * */
  102. return XInternAtom(SDL_Display, format, False);
  103.  
  104. #elif defined(WIN_SCRAP)
  105. /* * */
  106. return RegisterClipboardFormat(format);
  107.  
  108. #endif /* scrap type */
  109. }
  110. }
  111. }
  112.  
  113. /* Convert internal data to scrap format */
  114. PRIVATE int
  115. convert_data(int type, char *dst, const char *src, int srclen) //maks
  116. {
  117. int dstlen;
  118.  
  119. dstlen = 0;
  120. switch (type)
  121. {
  122. case T('T', 'E', 'X', 'T'):
  123. if ( dst )
  124. {
  125. while ( --srclen >= 0 )
  126. {
  127. #if defined(__unix__)
  128. if ( *src == '\r' )
  129. {
  130. *dst++ = '\n';
  131. ++dstlen;
  132. }
  133. else
  134. #elif defined(WIN32)
  135. if ( *src == '\r' )
  136. {
  137. *dst++ = '\r';
  138. ++dstlen;
  139. *dst++ = '\n';
  140. ++dstlen;
  141. }
  142. else
  143. #endif
  144. {
  145. *dst++ = *src;
  146. ++dstlen;
  147. }
  148. ++src;
  149. }
  150. *dst = '\0';
  151. ++dstlen;
  152. }
  153. else
  154. {
  155. while ( --srclen >= 0 )
  156. {
  157. #if defined(__unix__)
  158. if ( *src == '\r' )
  159. {
  160. ++dstlen;
  161. }
  162. else
  163. #elif defined(WIN32)
  164. if ( *src == '\r' )
  165. {
  166. ++dstlen;
  167. ++dstlen;
  168. }
  169. else
  170. #endif
  171. {
  172. ++dstlen;
  173. }
  174. ++src;
  175. }
  176. ++dstlen;
  177. }
  178. break;
  179.  
  180. default:
  181. if ( dst )
  182. {
  183. *(int *)dst = srclen;
  184. dst += sizeof(int);
  185. memcpy(dst, src, srclen);
  186. }
  187. dstlen = sizeof(int)+srclen;
  188. break;
  189. }
  190. return(dstlen);
  191. }
  192.  
  193. /* Convert scrap data to internal format */
  194. PRIVATE int
  195. convert_scrap(int type, char *dst, char *src, int srclen)
  196. {
  197. int dstlen;
  198.  
  199. dstlen = 0;
  200. switch (type)
  201. {
  202. case T('T', 'E', 'X', 'T'):
  203. {
  204. if ( srclen == 0 )
  205. srclen = strlen(src);
  206. if ( dst )
  207. {
  208. while ( --srclen >= 0 )
  209. {
  210. #if defined(WIN32)
  211. if ( *src == '\r' )
  212. /* drop extraneous '\r' */;
  213. else
  214. #endif
  215. if ( *src == '\n' )
  216. {
  217. *dst++ = '\r';
  218. ++dstlen;
  219. }
  220. else
  221. {
  222. *dst++ = *src;
  223. ++dstlen;
  224. }
  225. ++src;
  226. }
  227. *dst = '\0';
  228. ++dstlen;
  229. }
  230. else
  231. {
  232. while ( --srclen >= 0 )
  233. {
  234. #if defined(WIN32)
  235. if ( *src == '\r' )
  236. /* drop extraneous '\r' */;
  237. else
  238. #endif
  239. ++dstlen;
  240. ++src;
  241. }
  242. ++dstlen;
  243. }
  244. }
  245. break;
  246.  
  247. default:
  248. dstlen = *(int *)src;
  249. if ( dst )
  250. {
  251. if ( srclen == 0 )
  252. memcpy(dst, src+sizeof(int), dstlen);
  253. else
  254. memcpy(dst, src+sizeof(int), srclen-sizeof(int));
  255. }
  256. break;
  257. }
  258. return dstlen;
  259. }
  260.  
  261. #if defined(X11_SCRAP)
  262. /* The system message filter function -- handle clipboard messages */
  263. PRIVATE int clipboard_filter(const SDL_Event *event);
  264. #endif
  265.  
  266. PUBLIC int
  267. init_scrap(void)
  268. {
  269. SDL_SysWMinfo info;
  270. int retval;
  271.  
  272. /* Grab the window manager specific information */
  273. retval = -1;
  274. //SDL_SetError("SDL is not running on known window manager"); //maks
  275.  
  276. SDL_VERSION(&info.version);
  277. if ( SDL_GetWMInfo(&info) )
  278. {
  279. /* Save the information for later use */
  280. #if defined(X11_SCRAP) || defined (__MACOSX__)
  281. /* * */
  282. if ( info.subsystem == SDL_SYSWM_X11 )
  283. {
  284. SDL_Display = info.info.x11.display;
  285. SDL_Window = info.info.x11.window;
  286. Lock_Display = info.info.x11.lock_func;
  287. Unlock_Display = info.info.x11.unlock_func;
  288.  
  289. /* Enable the special window hook events */
  290. SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
  291. #if (SDL_VERSION_ATLEAST(1, 3, 0)) //AKR, TODO: remove this when all projects use the SDL 13
  292. SDL_SetEventFilter(clipboard_filter,NULL);
  293. #else
  294. SDL_SetEventFilter(clipboard_filter);
  295. #endif
  296.  
  297. retval = 0;
  298. }
  299. else
  300. {
  301. //SDL_SetError("SDL is not running on X11"); //maks
  302. }
  303.  
  304. #elif defined(WIN_SCRAP)
  305. /* * */
  306. SDL_Window = info.window;
  307. retval = 0;
  308.  
  309. #elif defined(QNX_SCRAP)
  310. /* * */
  311. InputGroup=PhInputGroup(NULL);
  312. retval = 0;
  313.  
  314. #endif /* scrap type */
  315. }
  316. return(retval);
  317. }
  318.  
  319. PUBLIC int
  320. lost_scrap(void)
  321. {
  322. int retval;
  323.  
  324. #if defined(X11_SCRAP)
  325. /* * */
  326. Lock_Display();
  327. #ifdef __MACOSX__ // AKR, because of APPSTORE doesnt support X11
  328. return 0; //AKR - appstore
  329. #elif
  330. retval = ( XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window );
  331. #endif
  332. Unlock_Display();
  333.  
  334. #elif defined(WIN_SCRAP)
  335. /* * */
  336. retval = ( GetClipboardOwner() != SDL_Window );
  337.  
  338. #elif defined(QNX_SCRAP)
  339. /* * */
  340. retval = ( PhInputGroup(NULL) != InputGroup );
  341.  
  342. #endif /* scrap type */
  343.  
  344. return(retval);
  345. }
  346.  
  347. PUBLIC void
  348. put_scrap(int type, int srclen, const char *src) //maks
  349. {
  350. scrap_type format;
  351. int dstlen;
  352. char *dst;
  353.  
  354. format = convert_format(type);
  355. dstlen = convert_data(type, NULL, src, srclen);
  356.  
  357. #if defined(X11_SCRAP)
  358. /* * */
  359. dst = (char *)malloc(dstlen);
  360. #ifndef __MACOSX__ // AKR, because of APPSTORE doesnt support X11
  361. if ( dst != NULL )
  362. {
  363. Lock_Display();
  364. convert_data(type, dst, src, srclen);
  365. XChangeProperty(SDL_Display, DefaultRootWindow(SDL_Display),
  366. XA_CUT_BUFFER0, format, 8, PropModeReplace, dst, dstlen);
  367. free(dst);
  368. if ( lost_scrap() )
  369. XSetSelectionOwner(SDL_Display, XA_PRIMARY, SDL_Window, CurrentTime);
  370. Unlock_Display();
  371. }
  372. #endif
  373. #elif defined(WIN_SCRAP)
  374. /* * */
  375. if ( OpenClipboard(SDL_Window) )
  376. {
  377. HANDLE hMem;
  378.  
  379. hMem = GlobalAlloc((GMEM_MOVEABLE|GMEM_DDESHARE), dstlen);
  380. if ( hMem != NULL )
  381. {
  382. dst = (char *)GlobalLock(hMem);
  383. convert_data(type, dst, src, srclen);
  384. GlobalUnlock(hMem);
  385. EmptyClipboard();
  386. SetClipboardData(format, hMem);
  387. }
  388. CloseClipboard();
  389. }
  390.  
  391. #elif defined(QNX_SCRAP)
  392. /* * */
  393. #if (_NTO_VERSION < 620) /* before 6.2.0 releases */
  394. {
  395. PhClipHeader clheader={Ph_CLIPBOARD_TYPE_TEXT, 0, NULL};
  396. int* cldata;
  397. int status;
  398.  
  399. dst = (char *)malloc(dstlen+4);
  400. if (dst != NULL)
  401. {
  402. cldata=(int*)dst;
  403. *cldata=type;
  404. convert_data(type, dst+4, src, srclen);
  405. clheader.data=dst;
  406. if (dstlen>65535)
  407. {
  408. clheader.length=65535; /* maximum photon clipboard size :( */
  409. }
  410. else
  411. {
  412. clheader.length=dstlen+4;
  413. }
  414. status=PhClipboardCopy(InputGroup, 1, &clheader);
  415. if (status==-1)
  416. {
  417. fprintf(stderr, "Photon: copy to clipboard was failed !\n");
  418. }
  419. free(dst);
  420. }
  421. }
  422. #else /* 6.2.0 and 6.2.1 and future releases */
  423. {
  424. PhClipboardHdr clheader={Ph_CLIPBOARD_TYPE_TEXT, 0, NULL};
  425. int* cldata;
  426. int status;
  427.  
  428. dst = (char *)malloc(dstlen+4);
  429. if (dst != NULL)
  430. {
  431. cldata=(int*)dst;
  432. *cldata=type;
  433. convert_data(type, dst+4, src, srclen);
  434. clheader.data=dst;
  435. clheader.length=dstlen+4;
  436. status=PhClipboardWrite(InputGroup, 1, &clheader);
  437. if (status==-1)
  438. {
  439. fprintf(stderr, "Photon: copy to clipboard was failed !\n");
  440. }
  441. free(dst);
  442. }
  443. }
  444. #endif
  445. #endif /* scrap type */
  446. }
  447.  
  448. PUBLIC void
  449. get_scrap(int type, int *dstlen, char **dst)
  450. {
  451. scrap_type format;
  452.  
  453. *dstlen = 0;
  454. format = convert_format(type);
  455.  
  456. #if defined(X11_SCRAP)
  457. /* * */
  458. {
  459. Window owner;
  460. Atom selection;
  461. Atom seln_type;
  462. int seln_format;
  463. unsigned long nbytes;
  464. unsigned long overflow;
  465. char *src;
  466.  
  467. Lock_Display();
  468. #ifdef __MACOSX__ // AKR, because of APPSTORE doesnt support X11
  469. owner=NULL;
  470. #elif
  471. owner = XGetSelectionOwner(SDL_Display, XA_PRIMARY);
  472. #endif
  473. Unlock_Display();
  474. if ( (owner == None) || (owner == SDL_Window) )
  475. {
  476. owner = DefaultRootWindow(SDL_Display);
  477. selection = XA_CUT_BUFFER0;
  478. }
  479. else
  480. {
  481. int selection_response = 0;
  482. SDL_Event event;
  483.  
  484. owner = SDL_Window;
  485. Lock_Display();
  486. selection = XInternAtom(SDL_Display, "SDL_SELECTION", False);
  487. #ifndef __MACOSX__ // AKR, because of APPSTORE doesnt support X11
  488. XConvertSelection(SDL_Display, XA_PRIMARY, format,
  489. selection, owner, CurrentTime);
  490. #endif
  491. Unlock_Display();
  492. while ( ! selection_response )
  493. {
  494. SDL_WaitEvent(&event);
  495. if ( event.type == SDL_SYSWMEVENT )
  496. {
  497. XEvent xevent = event.syswm.msg->event.xevent;
  498.  
  499. if ( (xevent.type == SelectionNotify) &&
  500. (xevent.xselection.requestor == owner) )
  501. selection_response = 1;
  502. }
  503. }
  504. }
  505. #ifndef __MACOSX__ // AKR, because of APPSTORE doesnt support X11
  506.  
  507. Lock_Display();
  508. if ( XGetWindowProperty(SDL_Display, owner, selection, 0, INT_MAX/4,
  509. False, format, &seln_type, &seln_format,
  510. &nbytes, &overflow, (unsigned char **)&src) == Success )
  511. {
  512. if ( seln_type == format )
  513. {
  514. *dstlen = convert_scrap(type, NULL, src, nbytes);
  515. *dst = (char *)realloc(*dst, *dstlen);
  516. if ( *dst == NULL )
  517. *dstlen = 0;
  518. else
  519. convert_scrap(type, *dst, src, nbytes);
  520. }
  521. XFree(src);
  522. }
  523. #endif
  524.  
  525. }
  526.  
  527. Unlock_Display();
  528. #elif defined(WIN_SCRAP)
  529. /* * */
  530. if ( IsClipboardFormatAvailable(format) && OpenClipboard(SDL_Window) )
  531. {
  532. HANDLE hMem;
  533. char *src;
  534.  
  535. hMem = GetClipboardData(format);
  536. if ( hMem != NULL )
  537. {
  538. src = (char *)GlobalLock(hMem);
  539. *dstlen = convert_scrap(type, NULL, src, 0);
  540. *dst = (char *)realloc(*dst, *dstlen);
  541. if ( *dst == NULL )
  542. *dstlen = 0;
  543. else
  544. convert_scrap(type, *dst, src, 0);
  545. GlobalUnlock(hMem);
  546. }
  547. CloseClipboard();
  548. }
  549. #elif defined(QNX_SCRAP)
  550. /* * */
  551. #if (_NTO_VERSION < 620) /* before 6.2.0 releases */
  552. {
  553. void* clhandle;
  554. PhClipHeader* clheader;
  555. int* cldata;
  556.  
  557. clhandle=PhClipboardPasteStart(InputGroup);
  558. if (clhandle!=NULL)
  559. {
  560. clheader=PhClipboardPasteType(clhandle, Ph_CLIPBOARD_TYPE_TEXT);
  561. if (clheader!=NULL)
  562. {
  563. cldata=clheader->data;
  564. if ((clheader->length>4) && (*cldata==type))
  565. {
  566. *dstlen = convert_scrap(type, NULL, (char*)clheader->data+4, clheader->length-4);
  567. *dst = (char *)realloc(*dst, *dstlen);
  568. if (*dst == NULL)
  569. {
  570. *dstlen = 0;
  571. }
  572. else
  573. {
  574. convert_scrap(type, *dst, (char*)clheader->data+4, clheader->length-4);
  575. }
  576. }
  577. }
  578. PhClipboardPasteFinish(clhandle);
  579. }
  580. }
  581. #else /* 6.2.0 and 6.2.1 and future releases */
  582. {
  583. void* clhandle;
  584. PhClipboardHdr* clheader;
  585. int* cldata;
  586.  
  587. clheader=PhClipboardRead(InputGroup, Ph_CLIPBOARD_TYPE_TEXT);
  588. if (clheader!=NULL)
  589. {
  590. cldata=clheader->data;
  591. if ((clheader->length>4) && (*cldata==type))
  592. {
  593. *dstlen = convert_scrap(type, NULL, (char*)clheader->data+4, clheader->length-4);
  594. *dst = (char *)realloc(*dst, *dstlen);
  595. if (*dst == NULL)
  596. {
  597. *dstlen = 0;
  598. }
  599. else
  600. {
  601. convert_scrap(type, *dst, (char*)clheader->data+4, clheader->length-4);
  602. }
  603. }
  604. }
  605. }
  606. #endif
  607. #endif /* scrap type */
  608. }
  609.  
  610. #if defined(X11_SCRAP)
  611. PRIVATE int clipboard_filter(const SDL_Event *event)
  612. {
  613. /* Post all non-window manager specific events */
  614. if (event==NULL || event->type != SDL_SYSWMEVENT ) { //AKR sometimes NULL arrives
  615. return(1);
  616. }
  617.  
  618. /* Handle window-manager specific clipboard events */
  619. switch (event->syswm.msg->event.xevent.type) {
  620. /* Copy the selection from XA_CUT_BUFFER0 to the requested property */
  621. case SelectionRequest: {
  622. XSelectionRequestEvent *req;
  623. XEvent sevent;
  624. int seln_format;
  625. unsigned long nbytes;
  626. unsigned long overflow;
  627. unsigned char *seln_data;
  628.  
  629. req = &event->syswm.msg->event.xevent.xselectionrequest;
  630. sevent.xselection.type = SelectionNotify;
  631. sevent.xselection.display = req->display;
  632. sevent.xselection.selection = req->selection;
  633. sevent.xselection.target = None;
  634. sevent.xselection.property = None;
  635. sevent.xselection.requestor = req->requestor;
  636. sevent.xselection.time = req->time;
  637. #ifndef __MACOSX__ // AKR, because of APPSTORE doesnt support X11
  638. if ( XGetWindowProperty(SDL_Display, DefaultRootWindow(SDL_Display),
  639. XA_CUT_BUFFER0, 0, INT_MAX/4, False, req->target,
  640. &sevent.xselection.target, &seln_format,
  641. &nbytes, &overflow, &seln_data) == Success )
  642. {
  643. if ( sevent.xselection.target == req->target )
  644. {
  645. if ( sevent.xselection.target == XA_STRING )
  646. {
  647. if ( seln_data[nbytes-1] == '\0' )
  648. --nbytes;
  649. }
  650. XChangeProperty(SDL_Display, req->requestor, req->property,
  651. sevent.xselection.target, seln_format, PropModeReplace,
  652. seln_data, nbytes);
  653. sevent.xselection.property = req->property;
  654. }
  655. XFree(seln_data);
  656. }
  657. XSendEvent(SDL_Display,req->requestor,False,0,&sevent);
  658. XSync(SDL_Display, False);
  659. #endif
  660. }
  661. break;
  662. }
  663.  
  664. /* Post the event for X11 clipboard reading above */
  665. return(1);
  666. }
  667. #endif /* X11_SCRAP */
  668.  
  669. #endif //#ifndef STAND_ALONE_GAME
Add Comment
Please, Sign In to add comment