77 #define _CLIPBOARD_HELPER_C 80 #include "pixmap_helper.h" 86 #define MIN_EVENT_LOOP_SLEEP_PERIOD 100 87 #define MAX_EVENT_LOOP_SLEEP_PERIOD 100000 90 typedef struct _ClipboardTask_
92 volatile struct _ClipboardTask_ *pNext;
112 typedef struct _ClipboardData_
114 struct _ClipboardData_ *pNext;
132 static volatile int bClipboardQuitFlag = 0;
133 static volatile CLIPBOARD_TASK *
volatile pCBTHead = NULL;
134 static CLIPBOARD_DATA *pCBDHead = NULL;
138 static void * ClipboardThreadProc(
void *);
148 unsigned long long ullTick;
164 WBDebugPrint(
"TEMPORARY: %s took %llu ticks)\n", __FUNCTION__, ullTick);
170 static char *pGlobalDisplayNameForClipboardInit = NULL;
182 if(!szDisplayName || !*szDisplayName)
184 szDisplayName =
":0.0";
188 pGlobalDisplayNameForClipboardInit =
WBCopyString(szDisplayName);
190 if(!pGlobalDisplayNameForClipboardInit)
192 WB_ERROR_PRINT(
"ERROR: in %s - NULL display name\n",__FUNCTION__);
201 WB_ERROR_PRINT(
"ERROR: in %s - Unable to create mutex\n",__FUNCTION__);
213 bClipboardQuitFlag = 1;
218 hClipboardThread =
WBThreadCreate(ClipboardThreadProc, pGlobalDisplayNameForClipboardInit);
233 int iDelayPeriod = MIN_EVENT_LOOP_SLEEP_PERIOD;
236 bClipboardQuitFlag > 0)
240 if(iDelayPeriod < MAX_EVENT_LOOP_SLEEP_PERIOD)
242 iDelayPeriod += (iDelayPeriod >> 1);
246 iDelayPeriod = MAX_EVENT_LOOP_SLEEP_PERIOD;
250 if(pGlobalDisplayNameForClipboardInit)
252 WBFree(pGlobalDisplayNameForClipboardInit);
253 pGlobalDisplayNameForClipboardInit = NULL;
267 WB_DEBUG_PRINT(DebugLevel_Light | DebugSubSystem_Init,
"INFO: %s - Clipboard Thread started\n",__FUNCTION__);
277 WB_ERROR_PRINT(
"ERROR: invalid 'pDisplay' in WBExitClipboardSystem\n");
283 bClipboardQuitFlag = 1;
289 WB_ERROR_PRINT(
"ERROR: in %s - hClipboardThread == INVALID_HANDLE_VALUE\n",__FUNCTION__);
300 volatile CLIPBOARD_TASK *pT = pCBTHead;
301 pCBTHead = pCBTHead->pNext;
308 WB_ERROR_PRINT(
"WARNING: %s - non-null 'clipboard task' being deleted (%p), ref count %d\n",
309 __FUNCTION__, pT, pT->nRefCount);
324 CLIPBOARD_DATA *pD = pCBDHead;
325 pCBDHead = pCBDHead->pNext;
338 WB_DEBUG_PRINT(DebugLevel_Light | DebugSubSystem_Init,
"INFO: %s - Clipboard Thread ended\n",__FUNCTION__);
344 static Bool __ClipboardThreadEventPredicate(Display *pDisplay, XEvent *pEvent, XPointer arg)
347 (pEvent->type == SelectionNotify ||
348 pEvent->type == SelectionClear ||
349 pEvent->type == SelectionRequest))
363 void CleanupDoneList(CLIPBOARD_TASK **ppDoneList)
375 *ppDoneList = (CLIPBOARD_TASK *)pT->pNext;
383 if(!pT->fType && pT->pData)
396 void AddNewItemToRunList(CLIPBOARD_TASK **ppRunList)
398 CLIPBOARD_TASK *pT, *pT2;
401 pT = (CLIPBOARD_TASK *)pCBTHead;
405 pCBTHead = pT->pNext;
419 *ppRunList = (CLIPBOARD_TASK *)pT;
427 pT2 = (CLIPBOARD_TASK *)pT2->pNext;
440 void * ClipboardThreadProc(
void *pParam)
442 unsigned long long ullTick;
443 int iLen, iFactor, iDelayPeriod;
444 const char *pDisplayName = (
const char *)pParam;
445 Display *pDisplay = NULL;
446 volatile CLIPBOARD_TASK *pT;
447 CLIPBOARD_TASK *pT2, *pT3;
448 CLIPBOARD_TASK *pRunList = NULL;
449 CLIPBOARD_TASK *pDoneList = NULL;
450 CLIPBOARD_DATA *pD, *pD2;
451 Window wWindow = None;
458 #ifdef X_HAVE_UTF8_STRING 460 #endif // X_HAVE_UTF8_STRING 473 pDisplay = XOpenDisplay(pDisplayName);
477 WB_ERROR_PRINT(
"%s - can't open display %s\n", __FUNCTION__, pDisplayName);
479 bClipboardQuitFlag = -1;
484 aINCR = XInternAtom(pDisplay,
"INCR", False);
485 aWBCLIP = XInternAtom(pDisplay,
"WB_CLIP", False);
486 aCLIPBOARD = XInternAtom(pDisplay,
"CLIPBOARD", False);
487 aTEXT = XInternAtom(pDisplay,
"TEXT", False);
488 aC_STRING = XInternAtom(pDisplay,
"C_STRING", False);
490 aTARGETS = XInternAtom(pDisplay,
"TARGETS", False);
491 aMULTIPLE = XInternAtom(pDisplay,
"MULTIPLE", False);
492 aTIMESTAMP = XInternAtom(pDisplay,
"TIMESTAMP", False);
493 aPIXEL = XInternAtom(pDisplay,
"PIXEL", False);
495 #ifdef X_HAVE_UTF8_STRING 496 aUTF8_STRING = XInternAtom(pDisplay,
"UTF8_STRING", False);
497 #endif // X_HAVE_UTF8_STRING 499 aNULL = XInternAtom(pDisplay,
"NULL", False);
515 #ifdef X_HAVE_UTF8_STRING
526 " aCOMPOUND_TEXT=%d\n" 531 #ifdef X_HAVE_UTF8_STRING
534 " aNULL=%d\n", __FUNCTION__,
537 #ifdef X_HAVE_UTF8_STRING
542 bClipboardQuitFlag = -1;
548 wWindow = XCreateSimpleWindow(pDisplay, DefaultRootWindow(pDisplay), 0, 0, 1, 1, 0, 0, 0);
552 bClipboardQuitFlag = -1;
554 WB_ERROR_PRINT(
"%s - can't create simple window\n", __FUNCTION__);
559 XSelectInput(pDisplay, wWindow, PropertyChangeMask);
565 bClipboardQuitFlag = 0;
573 WB_DEBUG_PRINT(DebugLevel_Light | DebugSubSystem_Init,
"INFO: %s - Clipboard Thread initialization complete\n",__FUNCTION__);
574 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_Init,
"CLIPBOARD THREAD STARTUP took %llu ticks\n", ullTick);
580 iDelayPeriod = MIN_EVENT_LOOP_SLEEP_PERIOD;
582 while(!bClipboardQuitFlag)
595 CleanupDoneList(&pDoneList);
598 AddNewItemToRunList(&pRunList);
613 int bDoneAndSignal = 0;
629 else if(pT->fType == 0)
640 aSelection = pT->aSelection;
641 if(aSelection == None)
643 wOwn = XGetSelectionOwner(pDisplay, XA_PRIMARY);
647 aSelection = XA_PRIMARY;
651 wOwn = XGetSelectionOwner(pDisplay,
aCLIPBOARD);
661 pT->aSelection = aSelection;
666 wOwn = XGetSelectionOwner(pDisplay, aSelection);
669 if(aSelection != XA_PRIMARY && aSelection !=
aCLIPBOARD)
672 WB_ERROR_PRINT(
"TEMPORARY: %s - selection = %d \"%s\" owner = %u (%08xH)\n",
673 __FUNCTION__, (
int)aSelection, p1, (
int)wOwn, (
int)wOwn);
693 while(pD && pD->aSelection != aSelection)
704 if(pD->aSelection == None &&
705 (aSelection == XA_PRIMARY ||
717 if(pD->nFormat == 16)
721 else if(pD->nFormat == 32)
730 iLen = iFactor * pD->cbLength;
732 pT->pData =
WBAlloc(iLen + iFactor);
736 memcpy(pT->pData, pD->aData, iLen);
738 pT->cbLength = pD->cbLength;
739 pT->nFormat = pD->nFormat;
751 WB_ERROR_PRINT(
"TEMPORARY: %s - clipboard data is NULL\n", __FUNCTION__);
753 goto null_data_me_own;
759 WB_ERROR_PRINT(
"TEMPORARY: %s - return NULL clipboard data, owned by me\n", __FUNCTION__);
780 WB_ERROR_PRINT(
"TEMPORARY: %s line %d - unable to lock mutex\n", __FUNCTION__, __LINE__);
786 else if(wOwn == None)
804 XConvertSelection(pDisplay, aSelection, pT->aType,
806 wWindow, CurrentTime);
816 else if(pT->fState == 1)
830 else if(pT->fType == 1)
852 if(pD->aSelection == pT->aSelection)
868 if(pD->aSelection == None &&
869 (pT->aSelection == XA_PRIMARY ||
875 if(pT->aSelection == None &&
876 (pD->aSelection == XA_PRIMARY ||
891 pD2->pNext = pD->pNext;
895 pCBDHead = pD->pNext;
903 if(!pT->pData || !pT->cbLength)
905 if(XGetSelectionOwner(pDisplay, pT->aSelection) == wWindow)
909 if(pT->aSelection == None)
911 XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime);
912 XSetSelectionOwner(pDisplay,
aCLIPBOARD, None, CurrentTime);
916 XSetSelectionOwner(pDisplay, pT->aSelection, None, CurrentTime);
926 if(pT->nFormat == 16)
928 iTrueLen = pT->cbLength * 2;
930 else if(pT->nFormat == 32)
932 iTrueLen = pT->cbLength * 4;
936 iTrueLen = pT->cbLength;
939 pD = (CLIPBOARD_DATA *)
WBAlloc(
sizeof(*pD) + 2 + iTrueLen);
945 XSetSelectionOwner(pDisplay, pT->aSelection, None, CurrentTime);
947 WB_ERROR_PRINT(
"%s - not enough memory for clipboard data - empty clipboard assignment\n", __FUNCTION__);
951 memcpy(pD->aData, pT->pData, iTrueLen);
953 pD->aSelection = pT->aSelection;
954 pD->aType = pT->aType;
955 pD->nFormat = pT->nFormat;
956 pD->cbLength = pT->cbLength;
960 if(pD->aSelection != None)
964 XSetSelectionOwner(pDisplay, pD->aSelection, wWindow, CurrentTime);
971 XSetSelectionOwner(pDisplay, XA_PRIMARY, wWindow, CurrentTime);
972 XSetSelectionOwner(pDisplay,
aCLIPBOARD, wWindow, CurrentTime);
1000 WB_ERROR_PRINT(
"TEMPORARY: %s - walking clipboard data\n", __FUNCTION__);
1006 if(pD->nFormat == 16)
1008 iLen = 2 * pD->cbLength;
1010 else if(pD->nFormat == 32)
1012 iLen = 4 * pD->cbLength;
1016 iLen = pD->cbLength;
1028 WBDebugPrint(
" length: %d (%d)\n", pD->cbLength, iLen);
1034 memcpy(p1, pD->aData, iLen);
1078 pT2->pNext = pT->pNext;
1082 pRunList = (CLIPBOARD_TASK *)pT->pNext;
1091 pDoneList = (CLIPBOARD_TASK *)pT;
1099 pT3 = (CLIPBOARD_TASK *)pT3->pNext;
1119 pT = pRunList->pNext;
1135 pT2 = (CLIPBOARD_TASK *)pT;
1142 if(bClipboardQuitFlag)
1154 memset(&evt, 0,
sizeof(evt));
1158 while(XEventsQueued(pDisplay, QueuedAlready) > 0)
1163 XNextEvent(pDisplay, &evt);
1165 if(evt.type == SelectionClear ||
1166 evt.type == SelectionRequest ||
1167 evt.type == SelectionNotify)
1169 WB_ERROR_PRINT(
"TEMPORARY: %s line %d - selection event found\n", __FUNCTION__, __LINE__);
1175 WB_ERROR_PRINT(
"TEMPORARY: %s line %d - unrecognized event (ignoring)\n", __FUNCTION__, __LINE__);
1182 if(evt.type == SelectionClear ||
1183 evt.type == SelectionRequest ||
1184 evt.type == SelectionNotify)
1187 unsigned long nItems, cbLeft;
1188 unsigned char *pBuf;
1222 if(evt.type == SelectionClear)
1230 Window wOwn = XGetSelectionOwner(pDisplay, evt.xselectionclear.selection);
1234 if(evt.xselectionclear.selection ==
aCLIPBOARD ||
1235 evt.xselectionclear.selection == XA_PRIMARY)
1237 XSetSelectionOwner(pDisplay, XA_PRIMARY,
1244 XSetSelectionOwner(pDisplay, evt.xselectionclear.selection,
1256 if(pD->aSelection == evt.xselectionclear.selection ||
1257 (pD->aSelection == None &&
1258 (evt.xselectionclear.selection == XA_PRIMARY ||
1259 evt.xselectionclear.selection ==
aCLIPBOARD)))
1264 pCBDHead = pD->pNext;
1268 pD2->pNext = pD->pNext;
1285 else if(evt.type == SelectionRequest)
1293 while(pD && pD->aSelection != evt.xselectionrequest.selection)
1304 if(pD->aSelection == None &&
1305 (evt.xselectionrequest.selection == XA_PRIMARY ||
1306 evt.xselectionrequest.selection ==
aCLIPBOARD))
1317 if(evt.xselectionrequest.target ==
aTARGETS)
1322 aT[1] = pD ? pD->aType : XA_STRING;
1324 XChangeProperty(pDisplay, evt.xselectionrequest.requestor,
1325 evt.xselectionrequest.property,
1326 XA_ATOM, 32, PropModeReplace,
1327 (
void *)aT,
sizeof(aT)/
sizeof(aT[0]));
1329 WB_ERROR_PRINT(
"TEMPORARY: %s - sending TARGETS XChangeProperty\n", __FUNCTION__);
1332 (evt.xselectionrequest.target == pD->aType ||
1333 (evt.xselectionrequest.target == XA_STRING && pD->aType ==
aUTF8_STRING) ||
1334 (evt.xselectionrequest.target ==
aUTF8_STRING && pD->aType == XA_STRING)))
1336 int nE = pD->cbLength;
1338 if(pD->nFormat == 16)
1342 else if(pD->nFormat == 32)
1352 XChangeProperty(pDisplay, evt.xselectionrequest.requestor,
1353 evt.xselectionrequest.property,
1354 pD->aType, pD->nFormat, PropModeReplace,
1355 (
unsigned char *)pD->aData, nE);
1361 WB_ERROR_PRINT(
"TEMPORARY: %s - sent XChangeProperty\n", __FUNCTION__);
1367 XChangeProperty(pDisplay, evt.xselectionrequest.requestor,
1368 evt.xselectionrequest.property,
1369 None, 0, PropModeReplace,
1372 WB_ERROR_PRINT(
"%s - sending 'None' for XChangeProperty\n", __FUNCTION__);
1383 memset(&evt2, 0,
sizeof(evt2));
1385 evt2.xselection.type = SelectionNotify;
1386 evt2.xselection.display = evt.xselectionrequest.display;
1387 evt2.xselection.requestor = evt.xselectionrequest.requestor;
1388 evt2.xselection.property = evt.xselectionrequest.property;
1389 evt2.xselection.selection = evt.xselectionrequest.selection;
1390 evt2.xselection.target = evt.xselectionrequest.target;
1391 evt2.xselection.time = evt.xselectionrequest.time;
1393 XFlush(evt2.xselection.display);
1396 XSendEvent(evt2.xselection.display, evt.xselectionrequest.requestor,
1398 XFlush(evt2.xselection.display);
1400 WB_ERROR_PRINT(
"TEMPORARY: %s - reply message sent\n", __FUNCTION__);
1402 else if(evt.type == SelectionNotify)
1408 int bDoneAndSignal = 0;
1416 WB_ERROR_PRINT(
"TEMPORARY: %s line %d - event loop for SelectionNotify\n", __FUNCTION__, __LINE__);
1419 && pT->aSelection == evt.xselection.selection
1420 && pT->aType == evt.xselection.target
1421 && (pT->aProp == evt.xselection.property ||
1422 evt.xselection.property == None))
1426 if(evt.xselection.property == None)
1428 #ifdef X_HAVE_UTF8_STRING 1433 pT->aType = XA_STRING;
1436 XConvertSelection(pDisplay, pT->aSelection, pT->aType,
1438 wWindow, CurrentTime);
1441 #endif // X_HAVE_UTF8_STRING 1445 WB_ERROR_PRINT(
"ERROR: %s line %d - Unable to do conversion\n", __FUNCTION__, __LINE__);
1452 else if(pT->fState == 1)
1456 if(!XGetWindowProperty(pDisplay, wWindow, pT->aProp, 0, 0, False,
1457 AnyPropertyType, &aType, &iFormat, &nItems, &cbLeft, &pBuf))
1470 XDeleteProperty(pDisplay, wWindow, pT->aProp);
1482 pT->cbLength = cbLeft / 2;
1484 else if(iFormat == 32)
1486 pT->cbLength = cbLeft / 4;
1490 pT->cbLength = cbLeft;
1493 if(!XGetWindowProperty(pDisplay, wWindow, pT->aProp, 0, pT->cbLength, False,
1494 AnyPropertyType, &aType, &iFormat, &nItems, &cbLeft, &pBuf) &&
1497 pT->nFormat = iFormat;
1500 if(nItems != pT->cbLength)
1502 WB_ERROR_PRINT(
"WARNING: %s - nItems %ld does not match calculated length %d\n",
1503 __FUNCTION__, nItems, pT->cbLength);
1506 pT->pData =
WBAlloc(iLen + 4);
1510 memcpy(pT->pData, pBuf, iLen);
1511 ((
char *)pT->pData)[iLen] = 0;
1516 pT->cbLength = iLen + 1;
1525 WB_ERROR_PRINT(
"ERROR: %s line %d - Unable to allocate pointer\n", __FUNCTION__, __LINE__);
1534 WB_ERROR_PRINT(
"ERROR: %s line %d - Unable to get window property\n", __FUNCTION__, __LINE__);
1543 XDeleteProperty(pDisplay, wWindow, pT->aProp);
1549 WB_ERROR_PRINT(
"ERROR: %s line %d - Unable to get window property\n", __FUNCTION__, __LINE__);
1556 else if(pT->fState == 2)
1558 WB_ERROR_PRINT(
"WARNING: %s - INCREMENTAL not supported (yet)\n", __FUNCTION__);
1577 WB_ERROR_PRINT(
"TEMPORARY: %s line %d - put thingy in done list, signal caller\n", __FUNCTION__, __LINE__);
1583 pT2->pNext = pT->pNext;
1587 pRunList = (CLIPBOARD_TASK *)pT->pNext;
1596 pDoneList = (CLIPBOARD_TASK *)pT;
1604 pT3 = (CLIPBOARD_TASK *)pT3->pNext;
1617 WB_ERROR_PRINT(
"TEMPORARY: %s line %d - signaled caller\n", __FUNCTION__, __LINE__);
1626 pT = pRunList->pNext;
1637 pT2 = (CLIPBOARD_TASK *)pT;
1646 if(bClipboardQuitFlag)
1656 XEventsQueued(pDisplay, QueuedAlready) <= 0)
1658 static unsigned long long ullLastTime = 0;
1659 unsigned long long ullTemp;
1670 if((ullTemp - ullLastTime) > 50000)
1672 ullLastTime = ullTemp;
1675 XSync(pDisplay, False);
1681 if(iDelayPeriod < MAX_EVENT_LOOP_SLEEP_PERIOD)
1683 iDelayPeriod += (iDelayPeriod >> 1);
1687 iDelayPeriod = MAX_EVENT_LOOP_SLEEP_PERIOD;
1692 iDelayPeriod = MIN_EVENT_LOOP_SLEEP_PERIOD;
1697 "INFO: %s line %d - exit from main thread loop\n", __FUNCTION__, __LINE__);
1706 WB_ERROR_PRINT(
"ERROR: %s - Clipboard Thread can't lock mutex on exit\n",__FUNCTION__);
1712 pDoneList = (CLIPBOARD_TASK *)pT->pNext;
1718 if(!pT->fType && pT->pData)
1733 pRunList = (CLIPBOARD_TASK *)pT->pNext;
1741 if(!pT->fType && pT->pData)
1756 pCBTHead = pT->pNext;
1773 XSync(pDisplay, False);
1782 CLIPBOARD_DATA *pD = pCBDHead;
1783 pCBDHead = pCBDHead->pNext;
1785 if(pDisplay && wWindow != None)
1787 if(pD->aSelection != None &&
1788 XGetSelectionOwner(pDisplay, pD->aSelection) == wWindow)
1790 XSetSelectionOwner(pDisplay, pD->aSelection, None, CurrentTime);
1792 else if(pD->aSelection == None)
1794 if(XGetSelectionOwner(pDisplay,
aCLIPBOARD) == wWindow)
1796 XSetSelectionOwner(pDisplay,
aCLIPBOARD, None, CurrentTime);
1798 else if(XGetSelectionOwner(pDisplay, XA_PRIMARY) == wWindow)
1800 XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime);
1822 XDestroyWindow(pDisplay, wWindow);
1829 XSync(pDisplay, FALSE);
1830 XCloseDisplay(pDisplay);
1835 "INFO: %s - Clipboard Thread exit complete\n",__FUNCTION__);
1849 int WBSetClipboardData(Display *pDisplay, Atom aType,
int iFormat,
const void *pData,
unsigned long nData)
1856 void *
WBGetSelectionData(Display *pDisplay, Atom aSelection, Atom *paType,
int *piFormat,
unsigned long *pnData)
1859 volatile CLIPBOARD_TASK *pT, *pTask;
1873 iFormat = *piFormat;
1888 pTask = (CLIPBOARD_TASK *)
WBAlloc(
sizeof(*pTask));
1891 WB_ERROR_PRINT(
"%s - can't create 'CLIPBOARD_TASK' for clipboard task\n", __FUNCTION__);
1896 memset((
void *)pTask, 0,
sizeof(*pTask));
1899 pTask->pData = NULL;
1900 pTask->cbLength = 0;
1901 pTask->aSelection = aSelection;
1902 pTask->aType = aType;
1903 pTask->nFormat = iFormat;
1904 pTask->nRefCount = 1;
1905 pTask->pNext = NULL;
1910 WB_ERROR_PRINT(
"%s - can't create 'cond' for clipboard task\n", __FUNCTION__);
1919 WB_ERROR_PRINT(
"%s - can't lock mutex for clipboard task\n", __FUNCTION__);
1928 while(pT && pT->pNext)
1950 pRval = pTask->pData;
1951 pTask->pData = NULL;
1955 *paType = pTask->aType;
1960 *piFormat = pTask->nFormat;
1965 *pnData = pTask->cbLength;
1973 WB_ERROR_PRINT(
"ERROR: %s - clipboard task %p has non-NULL 'pNext' on return (%p), refcount = %d\n",
1974 __FUNCTION__, pTask, pTask->pNext, pTask->nRefCount);
1976 else if(pTask->nRefCount < 1 || pTask->nRefCount > 2)
1978 WB_ERROR_PRINT(
"ERROR: %s - clipboard task %p has wrong refcount %d\n",
1979 __FUNCTION__, pTask, pTask->nRefCount);
1983 WB_ERROR_PRINT(
"TEMPORARY: %s - returning NULL\n", __FUNCTION__);
1994 WB_ERROR_PRINT(
"%s - %s error waiting on cond,mutex for completion\n", __FUNCTION__,
1995 (
const char *)(iErr > 0 ?
"timeout" :
"unknown"));
2002 while(pT && pT->pNext)
2004 if(pT->pNext == pTask)
2006 pT->pNext = pTask->pNext;
2030 pTask->pData = NULL;
2061 int WBSetSelectionData(Display *pDisplay, Atom aSelection, Atom aType,
int iFormat,
const void *pData,
unsigned long nData)
2064 volatile CLIPBOARD_TASK *pT, *pTask;
2073 pTask = (CLIPBOARD_TASK *)
WBAlloc(
sizeof(*pTask));
2076 WB_ERROR_PRINT(
"%s - can't create 'CLIPBOARD_TASK' for clipboard task\n", __FUNCTION__);
2081 memset((
void *)pTask, 0,
sizeof(*pTask));
2084 pTask->pData = (
void *)pData;
2085 pTask->cbLength = nData;
2086 pTask->aSelection = aSelection;
2087 pTask->aType = aType;
2088 pTask->nFormat = iFormat;
2089 pTask->nRefCount = 1;
2090 pTask->pNext = NULL;
2095 WB_ERROR_PRINT(
"%s - can't create 'cond' for clipboard task\n", __FUNCTION__);
2105 WB_ERROR_PRINT(
"%s - can't lock mutex for clipboard task\n", __FUNCTION__);
2115 while(pT && pT->pNext)
2134 WB_ERROR_PRINT(
"%s - error waiting on cond,mutex for completionk\n", __FUNCTION__);
2138 while(pT && pT->pNext)
2140 if(pT->pNext == pTask)
2142 pT->pNext = pTask->pNext;
Atom aCOMPOUND_TEXT
COMPOUND_TEXT Atom for the clipboard.
'window helper' main header file for the X11workbench Toolkit API
#define WB_DEBUG_PRINT(L,...)
Preferred method of implementing conditional debug output.
Utilities for copying and drawing text, determining text extents, and so on.
int WBMutexUnlock(WB_MUTEX *pMtx)
Unlock a previously locked mutex.
Atom aMULTIPLE
MULTIPLE Atom for the clipboard.
void * WBThreadWait(WB_THREAD hThread)
Wait for a specified threat to exit.
int __StartInitClipboardSystem(Display *pDisplay, const char *szDisplayName)
initializes clipboard sub-system
Atom aINCR
INCR Atom for the clipboard.
const char * GetStartupDisplayName(void)
returns character name of the display to be opened and passed to WBInit
unsigned int WBInterlockedIncrement(volatile unsigned int *pValue)
Interlocked 'atomic' increment of an unsigned integer.
int WBSetSelectionData(Display *pDisplay, Atom aSelection, Atom aType, int iFormat, const void *pData, unsigned long nData)
Get clipboard data of requested type.
static __inline__ Display * WBGetDefaultDisplay(void)
Returns the default Display.
'configuration helper' main header file for the X11 Work Bench Toolkit API
unsigned int WBInterlockedExchange(volatile unsigned int *pValue, unsigned int nNewVal)
Interlocked 'atomic' exchange of an unsigned integer with a specified value.
Atom aTIMESTAMP
TIMESTAMP Atom for the clipboard.
int WBSetClipboardData(Display *pDisplay, Atom aType, int iFormat, const void *pData, unsigned long nData)
Get clipboard data of requested type.
Atom aPIXEL
PIXEL Atom for the clipboard.
WB_THREAD WBThreadCreate(void *(*function)(void *), void *pParam)
Create a new thread, returning its WB_THREAD identifier.
void * WBAlloc(int nSize)
High performance memory sub-allocator 'allocate'.
int WBCondSignal(WB_COND *pCond)
Signal a condition (event)
#define END_XCALL_DEBUG_WRAPPER
wrapper macro for calls into the X11 library. This macro follows the call(s)
#define WB_ERROR_PRINT(...)
Preferred method of implementing an 'error level' debug message for all subsystems.
void WBFree(void *pBuf)
High performance memory sub-allocator 'free'.
unsigned int WBInterlockedDecrement(volatile unsigned int *pValue)
Interlocked 'atomic' decrement of an unsigned integer.
void * WBGetSelectionData(Display *pDisplay, Atom aSelection, Atom *paType, int *piFormat, unsigned long *pnData)
Get clipboard data of requested type.
Atom aCLIPBOARD
CLIPBOARD Atom for the clipboard.
A 'C++'-like object for managing text, that can be overridden for custom behavior.
void WBDebugDumpEvent(XEvent *pEvent)
dumps the contents of an XEvent
int WBMutexCreate(WB_MUTEX *pMtx)
Create a lockable mutex.
int WBMutexLock(WB_MUTEX *pMtx, int nTimeout)
Wait for and lock a mutex, blocking until it is available.
int WBThreadRunning(WB_THREAD hThread)
Determine whether a thread is running (can be suspended)
int WBInitClipboardSystem(Display *pDisplay, const char *szDisplayName)
initializes clipboard sub-system
Atom aTARGETS
TARGETS Atom for the clipboard.
void WBMutexFree(WB_MUTEX *pMtx)
Free a lockable mutex.
#define BEGIN_XCALL_DEBUG_WRAPPER
wrapper macro for calls into the X11 library. This macro precedes the call(s)
void WBDebugPrint(const char *pFmt,...) __attribute__((format(printf
conditional debug message output
char * WBCopyString(const char *pSrc)
A simple utility that returns a WBAlloc() copy of a 0-byte terminated string.
Atom aNULL
NULL Atom for the clipboard.
int WBCondWaitMutex(WB_COND *pCond, WB_MUTEX *pMtx, int nTimeout)
Wait for a signal on a condition (event)
void * WBGetClipboardData(Display *pDisplay, Atom *paType, int *piFormat, unsigned long *pnData)
Get clipboard data of requested type.
Atom aTEXT
TEXT Atom for the clipboard.
Atom aC_STRING
C_STRING Atom for the clipboard.
int __FinishInitClipboardSystem(Display *pDisplay, const char *szDisplayName)
initializes clipboard sub-system
unsigned int WBInterlockedRead(volatile unsigned int *pValue)
Interlocked 'atomic' read of an unsigned integer.
int WBCondCreate(WB_COND *pCond)
Create a signallable condition.
void WBExitClipboardSystem(Display *pDisplay)
Shut down the clipboard sub-system.
Atom aUTF8_STRING
UTF8_STRING Atom for the clipboard.
void WBCondFree(WB_COND *pCond)
Free a signallable condition.