void Xutf8SetWMProperties ( Display *dpy, Window w, _Xconst char *windowName, _Xconst char *iconName, char **argv, int argc, XSizeHints *sizeHints, XWMHints *wmHints, XClassHint *classHints) { XTextProperty wname, iname; XTextProperty *wprop = NULL; XTextProperty *iprop = NULL; if (windowName && Xutf8TextListToTextProperty(dpy, (char**)&windowName, 1, XStdICCTextStyle, &wname) >= Success) wprop = &wname; if (iconName && Xutf8TextListToTextProperty(dpy, (char**)&iconName, 1, XStdICCTextStyle, &iname) >= Success) iprop = &iname; XSetWMProperties(dpy, w, wprop, iprop, argv, argc, sizeHints, wmHints, classHints); if (wprop) Xfree((char *)wname.value); if (iprop) Xfree((char *)iname.value); /* Note: The WM_LOCALE_NAME property is set by XSetWMProperties. */ }
void XimCommitString(void* arg, FcitxInputContext* ic, const char* str) { FcitxXimFrontend* xim = (FcitxXimFrontend*) arg; XTextProperty tp; IMCommitStruct cms; FcitxXimIC* ximic = (FcitxXimIC*) ic->privateic; /* avoid Seg fault */ if (!ic) return; /* * I'm not sure whether xim should commit string before preedit done * but this can fix opera's crash in specific input box * quite strange. */ if (GetXimIC(ic)->bPreeditStarted == true) { XimPreeditCallbackDraw(xim, GetXimIC(ic), "", 0); XimPreeditCallbackDone(xim, GetXimIC(ic)); GetXimIC(ic)->bPreeditStarted = false; } Xutf8TextListToTextProperty(xim->display, (char **) &str, 1, XCompoundTextStyle, &tp); memset(&cms, 0, sizeof(IMCommitStruct)); cms.major_code = XIM_COMMIT; cms.icid = ximic->id; cms.connect_id = ximic->connect_id; cms.flag = XimLookupChars; cms.commit_string = (char *) tp.value; IMCommitString(xim->ims, (XPointer) & cms); XFree(tp.value); }
void export_text_xim() { char *text = output_buffer; if (!output_bufferN) return; XTextProperty tp; #if 0 char outbuf[512]; utf8_big5(output_buffer, outbuf); text = outbuf; XmbTextListToTextProperty(dpy, &text, 1, XCompoundTextStyle, &tp); #else Xutf8TextListToTextProperty(dpy, &text, 1, XCompoundTextStyle, &tp); #endif #if DEBUG && 0 dbg("send_utf8_ch: %s\n", text); #endif ((IMCommitStruct*)current_forward_eve)->flag |= XimLookupChars; ((IMCommitStruct*)current_forward_eve)->commit_string = (char *)tp.value; IMCommitString(current_ims, (XPointer)current_forward_eve); clear_output_buffer(); XFree(tp.value); }
static void xdpy_set_window_title_default(ALLEGRO_DISPLAY *display, const char *title) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; { Atom WM_NAME = XInternAtom(system->x11display, "WM_NAME", False); Atom _NET_WM_NAME = XInternAtom(system->x11display, "_NET_WM_NAME", False); char *list[1] = { (char *) title }; XTextProperty property; Xutf8TextListToTextProperty(system->x11display, list, 1, XUTF8StringStyle, &property); XSetTextProperty(system->x11display, glx->window, &property, WM_NAME); XSetTextProperty(system->x11display, glx->window, &property, _NET_WM_NAME); XSetTextProperty(system->x11display, glx->window, &property, XA_WM_NAME); XFree(property.value); } { XClassHint *hint = XAllocClassHint(); if (hint) { ALLEGRO_PATH *exepath = al_get_standard_path(ALLEGRO_EXENAME_PATH); // hint doesn't use a const char*, so we use strdup to create a non const string hint->res_name = strdup(al_get_path_basename(exepath)); hint->res_class = strdup(al_get_path_basename(exepath)); XSetClassHint(system->x11display, glx->window, hint); free(hint->res_name); free(hint->res_class); XFree(hint); al_destroy_path(exepath); } } }
int xu_getstrprop(Window win, Atom atm, char **text) { XTextProperty prop; char **list; int nitems = 0; *text = NULL; XGetTextProperty(X_Dpy, win, &prop, atm); if (!prop.nitems) return (0); if (Xutf8TextPropertyToTextList(X_Dpy, &prop, &list, &nitems) == Success && nitems > 0 && *list) { if (nitems > 1) { XTextProperty prop2; if (Xutf8TextListToTextProperty(X_Dpy, list, nitems, XUTF8StringStyle, &prop2) == Success) { *text = xstrdup((const char *)prop2.value); XFree(prop2.value); } } else { *text = xstrdup(*list); } XFreeStringList(list); } XFree(prop.value); return (nitems); }
int dwbremote_set_property_list(Display *dpy, Window win, Atom atom, char **list, int count) { XTextProperty prop; Xutf8TextListToTextProperty(dpy, list, count, XUTF8StringStyle, &prop); XSetTextProperty(dpy, win, &prop, atom); XFree(prop.value); return 0; }
void ewmh_update_desktop_names() { char** names = g_new(char*, g_tags->len); for (int i = 0; i < g_tags->len; i++) { names[i] = g_array_index(g_tags, HSTag*,i)->name->str; } XTextProperty text_prop; Xutf8TextListToTextProperty(g_display, names, g_tags->len, XUTF8StringStyle, &text_prop); XSetTextProperty(g_display, g_root, &text_prop, g_netatom[NetDesktopNames]); XFree(text_prop.value); g_free(names); }
void ewmh_update_desktop_names() { char** names = g_new(char*, tag_get_count()); for (int i = 0; i < tag_get_count(); i++) { names[i] = get_tag_by_index(i)->name->str; } XTextProperty text_prop; Xutf8TextListToTextProperty(g_display, names, tag_get_count(), XUTF8StringStyle, &text_prop); XSetTextProperty(g_display, g_root, &text_prop, g_netatom[NetDesktopNames]); XFree(text_prop.value); g_free(names); }
void AppX11::setWmName(QWidget *widget, const QString &name) { d->wmName = name.toUtf8(); char *utf8 = d->wmName.data(); auto wid = widget->effectiveWinId(); if (d->connection && d->display) { XTextProperty text; Xutf8TextListToTextProperty(d->display, &utf8, 1, XCompoundTextStyle, &text); XSetWMName(d->display, wid, &text); // xcb_icccm_set_wm_name(d->x.connection, d->x.window, XCB_ATOM_STRING, 8, d->wmName.size(), d->wmName.constData()); const char className[] = "cmplayer\0CMPlayer"; xcb_icccm_set_wm_class(d->connection, wid, sizeof(className), className); } }
void hook_emit(int argc, const char** argv) { static int last_property_number = 0; if (argc <= 0) { // nothing to do return; } XTextProperty text_prop; static char atom_name[STRING_BUF_SIZE]; snprintf(atom_name, STRING_BUF_SIZE, HERBST_HOOK_PROPERTY_FORMAT, last_property_number); Atom atom = ATOM(atom_name); Xutf8TextListToTextProperty(g_display, (char**)argv, argc, XUTF8StringStyle, &text_prop); XSetTextProperty(g_display, g_event_window, &text_prop, atom); XFree(text_prop.value); // set counter for next property last_property_number += 1; last_property_number %= HERBST_HOOK_PROPERTY_COUNT; }
EAPI void ecore_x_icccm_title_set(Ecore_X_Window win, const char *t) { char *list[1]; XTextProperty xprop; int ret; if (!t) return; LOGFN(__FILE__, __LINE__, __FUNCTION__); xprop.value = NULL; #ifdef X_HAVE_UTF8_STRING list[0] = strdup(t); ret = Xutf8TextListToTextProperty(_ecore_x_disp, list, 1, XUTF8StringStyle, &xprop); #else /* ifdef X_HAVE_UTF8_STRING */ list[0] = strdup(t); ret = XmbTextListToTextProperty(_ecore_x_disp, list, 1, XStdICCTextStyle, &xprop); #endif /* ifdef X_HAVE_UTF8_STRING */ if (_ecore_xlib_sync) ecore_x_sync(); if (ret >= Success) { XSetWMName(_ecore_x_disp, win, &xprop); if (_ecore_xlib_sync) ecore_x_sync(); if (xprop.value) XFree(xprop.value); } else if (XStringListToTextProperty(list, 1, &xprop) >= Success) { XSetWMName(_ecore_x_disp, win, &xprop); if (_ecore_xlib_sync) ecore_x_sync(); if (xprop.value) XFree(xprop.value); } free(list[0]); }
/* * Class: sun_awt_X11_XlibWrapper * Method: SetProperty * Signature: (JJJLjava/lang/String;)V */ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_SetProperty (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong atom, jstring jstr) { char *cname; XTextProperty tp; int32_t status; /* In case there are direct support of UTF-8 declared, use UTF-8 strings. */ if (!JNU_IsNull(env, jstr)) { #ifdef X_HAVE_UTF8_STRING cname = (*env)->GetStringUTFChars(env, jstr, JNI_FALSE); #else cname = (char *)JNU_GetStringPlatformChars(env, jstr, NULL); #endif } else { cname = ""; } #ifdef X_HAVE_UTF8_STRING status = Xutf8TextListToTextProperty((Display *)display, &cname, 1, XStdICCTextStyle, &tp); #else status = XmbTextListToTextProperty((Display *)display, &cname, 1, XStdICCTextStyle, &tp); #endif if (status == Success || status > 0) { AWT_CHECK_HAVE_LOCK(); XChangeProperty((Display *)display, window, atom, tp.encoding, tp.format, PropModeReplace, tp.value, tp.nitems); if (tp.value != NULL) { XFree(tp.value); } } if (!JNU_IsNull(env, jstr)) { #ifdef X_HAVE_UTF8_STRING (*env)->ReleaseStringUTFChars(env, jstr, (const char *) cname); #else JNU_ReleaseStringPlatformChars(env, jstr, (const char *) cname); #endif } }
void xim_commit_preedit(XIMHandle* handle, const char* result_str) { IC* ic = icmgr_get_current(); if (ic == NULL) return; XTextProperty tp; IMCommitStruct cs; Xutf8TextListToTextProperty(dpy, (char**) &result_str, 1, XCompoundTextStyle, &tp); memset(&cs, 0, sizeof(IMCommitStruct)); cs.major_code = XIM_COMMIT; cs.icid = ic->icid; cs.connect_id = ic->connect_id; cs.flag = XimLookupChars; cs.commit_string = (char*) tp.value; IMCommitString(handle, (XPointer) &cs); XFree(tp.value); }
void XimCommitString(void* arg, FcitxInputContext* ic, const char* str) { FcitxXimFrontend* xim = (FcitxXimFrontend*) arg; XTextProperty tp; FcitxXimIC* ximic = (FcitxXimIC*) ic->privateic; /* avoid Seg fault */ if (!ic) return; Xutf8TextListToTextProperty(xim->display, (char **) &str, 1, XCompoundTextStyle, &tp); IMCommitStruct* cms = fcitx_utils_new(IMCommitStruct); cms->major_code = XIM_COMMIT; cms->icid = ximic->id; cms->connect_id = ximic->connect_id; cms->flag = XimLookupChars; cms->commit_string = (char *) tp.value; XimPendingCall(xim, XCT_COMMIT, (XPointer) cms); }
static void xdpy_set_window_title(ALLEGRO_DISPLAY *display, const char *title) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; _al_mutex_lock(&system->lock); Atom WM_NAME = XInternAtom(system->x11display, "WM_NAME", False); Atom _NET_WM_NAME = XInternAtom(system->x11display, "_NET_WM_NAME", False); char *list[] = {(void *)title}; XTextProperty property; Xutf8TextListToTextProperty(system->x11display, list, 1, XUTF8StringStyle, &property); XSetTextProperty(system->x11display, glx->window, &property, WM_NAME); XSetTextProperty(system->x11display, glx->window, &property, _NET_WM_NAME); XFree(property.value); XClassHint hint; hint.res_name = strdup(title); // Leak? (below too...) hint.res_class = strdup(title); XSetClassHint(system->x11display, glx->window, &hint); _al_mutex_unlock(&system->lock); }
static void _context_commit_text_cb (IBusInputContext *context, IBusText *text, X11IC *x11ic) { g_assert (IBUS_IS_INPUT_CONTEXT (context)); g_assert (IBUS_IS_TEXT (text)); g_assert (x11ic != NULL); XTextProperty tp; IMCommitStruct cms = {0}; Xutf8TextListToTextProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), (gchar **)&(text->text), 1, XCompoundTextStyle, &tp); cms.major_code = XIM_COMMIT; cms.icid = x11ic->icid; cms.connect_id = x11ic->connect_id; cms.flag = XimLookupChars; cms.commit_string = (gchar *)tp.value; IMCommitString (_xims, (XPointer) & cms); XFree (tp.value); }
static void _xim_preedit_callback_draw (XIMS xims, X11IC *x11ic, const gchar *preedit_string, IBusAttrList *attr_list) { IMPreeditCBStruct pcb; XIMText text; XTextProperty tp; static XIMFeedback *feedback; static gint feedback_len = 0; guint j, i, len; if (preedit_string == NULL) return; len = g_utf8_strlen (preedit_string, -1); if (len + 1 > feedback_len) { feedback_len = (len + 1 + 63) & ~63; if (feedback) { feedback = g_renew (XIMFeedback, feedback, feedback_len); } else { feedback = g_new (XIMFeedback, feedback_len); } } for (i = 0; i < len; i++) { feedback[i] = 0; } if (attr_list != NULL) { for (i = 0;; i++) { XIMFeedback attr = 0; IBusAttribute *ibus_attr = ibus_attr_list_get (attr_list, i); if (ibus_attr == NULL) { break; } switch (ibus_attr->type) { case IBUS_ATTR_TYPE_UNDERLINE: if (ibus_attr->value == IBUS_ATTR_UNDERLINE_SINGLE) { attr = XIMUnderline; } break; case IBUS_ATTR_TYPE_BACKGROUND: { if (ibus_attr->value != 0xffffff) { attr = XIMReverse; } break; } default: continue; } for (j = ibus_attr->start_index; j < ibus_attr->end_index; j++) { feedback[j] |= attr; } } } for (i = 0; i < len; i++) { if (feedback[i] == 0) { feedback[i] = XIMUnderline; } } feedback[len] = 0; pcb.major_code = XIM_PREEDIT_DRAW; pcb.connect_id = x11ic->connect_id; pcb.icid = x11ic->icid; pcb.todo.draw.caret = len; pcb.todo.draw.chg_first = 0; pcb.todo.draw.chg_length = x11ic->onspot_preedit_length; pcb.todo.draw.text = &text; text.feedback = feedback; if (len > 0) { Xutf8TextListToTextProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), (char **)&preedit_string, 1, XCompoundTextStyle, &tp); text.encoding_is_wchar = 0; text.length = strlen ((char*)tp.value); text.string.multi_byte = (char*)tp.value; IMCallCallback (xims, (XPointer) & pcb); XFree (tp.value); } else { text.encoding_is_wchar = 0; text.length = 0; text.string.multi_byte = ""; IMCallCallback (xims, (XPointer) & pcb); len = 0; } x11ic->onspot_preedit_length = len; }
int winClipboardFlushXEvents (HWND hwnd, int iWindow, Display *pDisplay, Bool fUseUnicode) { static Atom atomLocalProperty; static Atom atomCompoundText; static Atom atomUTF8String; static Atom atomTargets; static int generation; if (generation != serverGeneration) { generation = serverGeneration; atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False); atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); atomTargets = XInternAtom (pDisplay, "TARGETS", False); } /* Process all pending events */ while (XPending (pDisplay)) { XTextProperty xtpText = {0}; XEvent event; XSelectionEvent eventSelection; unsigned long ulReturnBytesLeft; char *pszReturnData = NULL; char *pszGlobalData = NULL; int iReturn; HGLOBAL hGlobal = NULL; XICCEncodingStyle xiccesStyle; int iConvertDataLen = 0; char *pszConvertData = NULL; char *pszTextList[2] = {NULL}; int iCount; char **ppszTextList = NULL; wchar_t *pwszUnicodeStr = NULL; int iUnicodeLen = 0; int iReturnDataLen = 0; int i; Bool fAbort = FALSE; Bool fCloseClipboard = FALSE; Bool fSetClipboardData = TRUE; /* Get the next event - will not block because one is ready */ XNextEvent (pDisplay, &event); /* Branch on the event type */ switch (event.type) { /* * SelectionRequest */ case SelectionRequest: { char *pszAtomName = NULL; winDebug("SelectionRequest - target %d\n", event.xselectionrequest.target); pszAtomName = XGetAtomName (pDisplay, event.xselectionrequest.target); winDebug("SelectionRequest - Target atom name %s\n", pszAtomName); XFree (pszAtomName); pszAtomName = NULL; } /* Abort if invalid target type */ if (event.xselectionrequest.target != XA_STRING && event.xselectionrequest.target != atomUTF8String && event.xselectionrequest.target != atomCompoundText && event.xselectionrequest.target != atomTargets) { /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Handle targets type of request */ if (event.xselectionrequest.target == atomTargets) { Atom atomTargetArr[] = {atomTargets, atomCompoundText, atomUTF8String, XA_STRING}; /* Try to change the property */ iReturn = XChangeProperty (pDisplay, event.xselectionrequest.requestor, event.xselectionrequest.property, XA_ATOM, 32, PropModeReplace, (unsigned char *) atomTargetArr, (sizeof (atomTargetArr) / sizeof (atomTargetArr[0]))); if (iReturn == BadAlloc || iReturn == BadAtom || iReturn == BadMatch || iReturn == BadValue || iReturn == BadWindow) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "XChangeProperty failed: %d\n", iReturn); } /* Setup selection notify xevent */ eventSelection.type = SelectionNotify; eventSelection.send_event = True; eventSelection.display = pDisplay; eventSelection.requestor = event.xselectionrequest.requestor; eventSelection.selection = event.xselectionrequest.selection; eventSelection.target = event.xselectionrequest.target; eventSelection.property = event.xselectionrequest.property; eventSelection.time = event.xselectionrequest.time; /* * Notify the requesting window that * the operation has completed */ iReturn = XSendEvent (pDisplay, eventSelection.requestor, False, 0L, (XEvent *) &eventSelection); if (iReturn == BadValue || iReturn == BadWindow) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "XSendEvent () failed\n"); } break; } /* Check that clipboard format is available */ if (fUseUnicode && !IsClipboardFormatAvailable (CF_UNICODETEXT)) { static int count; /* Hack to stop acroread spamming the log */ static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */ if (hwnd != lasthwnd) count = 0; count++; if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not " "available from Win32 clipboard. Aborting %d.\n", count); lasthwnd = hwnd; /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } else if (!fUseUnicode && !IsClipboardFormatAvailable (CF_TEXT)) { ErrorF ("winClipboardFlushXEvents - CF_TEXT is not " "available from Win32 clipboard. Aborting.\n"); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Close clipboard if we have it open already */ if (GetOpenClipboardWindow () == hwnd) { CloseClipboard (); } /* Access the clipboard */ if (!OpenClipboard (hwnd)) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "OpenClipboard () failed: %08lx\n", GetLastError ()); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Indicate that clipboard was opened */ fCloseClipboard = TRUE; /* Setup the string style */ if (event.xselectionrequest.target == XA_STRING) xiccesStyle = XStringStyle; #ifdef X_HAVE_UTF8_STRING else if (event.xselectionrequest.target == atomUTF8String) xiccesStyle = XUTF8StringStyle; #endif else if (event.xselectionrequest.target == atomCompoundText) xiccesStyle = XCompoundTextStyle; else xiccesStyle = XStringStyle; /* * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me */ /* Get a pointer to the clipboard text, in desired format */ if (fUseUnicode) { /* Retrieve clipboard data */ hGlobal = GetClipboardData (CF_UNICODETEXT); } else { /* Retrieve clipboard data */ hGlobal = GetClipboardData (CF_TEXT); } if (!hGlobal) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "GetClipboardData () failed: %08lx\n", GetLastError ()); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } pszGlobalData = (char *) GlobalLock (hGlobal); /* Convert the Unicode string to UTF8 (MBCS) */ if (fUseUnicode) { iConvertDataLen = WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)pszGlobalData, -1, NULL, 0, NULL, NULL); /* NOTE: iConvertDataLen includes space for null terminator */ pszConvertData = (char *) malloc (iConvertDataLen); WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)pszGlobalData, -1, pszConvertData, iConvertDataLen, NULL, NULL); } else { pszConvertData = strdup (pszGlobalData); iConvertDataLen = strlen (pszConvertData) + 1; } /* Convert DOS string to UNIX string */ winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData)); /* Setup our text list */ pszTextList[0] = pszConvertData; pszTextList[1] = NULL; /* Initialize the text property */ xtpText.value = NULL; xtpText.nitems = 0; /* Create the text property from the text list */ if (fUseUnicode) { #ifdef X_HAVE_UTF8_STRING iReturn = Xutf8TextListToTextProperty (pDisplay, pszTextList, 1, xiccesStyle, &xtpText); #endif } else { iReturn = XmbTextListToTextProperty (pDisplay, pszTextList, 1, xiccesStyle, &xtpText); } if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "X*TextListToTextProperty failed: %d\n", iReturn); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Free the converted string */ free (pszConvertData); pszConvertData = NULL; /* Copy the clipboard text to the requesting window */ iReturn = XChangeProperty (pDisplay, event.xselectionrequest.requestor, event.xselectionrequest.property, event.xselectionrequest.target, 8, PropModeReplace, xtpText.value, xtpText.nitems); if (iReturn == BadAlloc || iReturn == BadAtom || iReturn == BadMatch || iReturn == BadValue || iReturn == BadWindow) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "XChangeProperty failed: %d\n", iReturn); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Release the clipboard data */ GlobalUnlock (hGlobal); pszGlobalData = NULL; fCloseClipboard = FALSE; CloseClipboard (); /* Clean up */ XFree (xtpText.value); xtpText.value = NULL; xtpText.nitems = 0; /* Setup selection notify event */ eventSelection.type = SelectionNotify; eventSelection.send_event = True; eventSelection.display = pDisplay; eventSelection.requestor = event.xselectionrequest.requestor; eventSelection.selection = event.xselectionrequest.selection; eventSelection.target = event.xselectionrequest.target; eventSelection.property = event.xselectionrequest.property; eventSelection.time = event.xselectionrequest.time; /* Notify the requesting window that the operation has completed */ iReturn = XSendEvent (pDisplay, eventSelection.requestor, False, 0L, (XEvent *) &eventSelection); if (iReturn == BadValue || iReturn == BadWindow) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "XSendEvent () failed\n"); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } winClipboardFlushXEvents_SelectionRequest_Done: /* Free allocated resources */ if (xtpText.value) { XFree (xtpText.value); xtpText.value = NULL; xtpText.nitems = 0; } free(pszConvertData); if (hGlobal && pszGlobalData) GlobalUnlock (hGlobal); /* * Send a SelectionNotify event to the requesting * client when we abort. */ if (fAbort) { /* Setup selection notify event */ eventSelection.type = SelectionNotify; eventSelection.send_event = True; eventSelection.display = pDisplay; eventSelection.requestor = event.xselectionrequest.requestor; eventSelection.selection = event.xselectionrequest.selection; eventSelection.target = event.xselectionrequest.target; eventSelection.property = None; eventSelection.time = event.xselectionrequest.time; /* Notify the requesting window that the operation is complete */ iReturn = XSendEvent (pDisplay, eventSelection.requestor, False, 0L, (XEvent *) &eventSelection); if (iReturn == BadValue || iReturn == BadWindow) { /* * Should not be a problem if XSendEvent fails because * the client may simply have exited. */ ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "XSendEvent () failed for abort event.\n"); } } /* Close clipboard if it was opened */ if (fCloseClipboard) { fCloseClipboard = FALSE; CloseClipboard (); } break; /* * SelectionNotify */ case SelectionNotify: winDebug ("winClipboardFlushXEvents - SelectionNotify\n"); { char *pszAtomName; pszAtomName = XGetAtomName (pDisplay, event.xselection.selection); winDebug("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", pszAtomName); XFree (pszAtomName); } /* * Request conversion of UTF8 and CompoundText targets. */ if (event.xselection.property == None) { if (event.xselection.target == XA_STRING) { winDebug ("winClipboardFlushXEvents - SelectionNotify - " "XA_STRING\n"); return WIN_XEVENTS_CONVERT; } else if (event.xselection.target == atomUTF8String) { winDebug("winClipboardFlushXEvents - SelectionNotify - " "Requesting conversion of UTF8 target.\n"); XConvertSelection (pDisplay, event.xselection.selection, XA_STRING, atomLocalProperty, iWindow, CurrentTime); /* Process the ConvertSelection event */ XFlush (pDisplay); return WIN_XEVENTS_CONVERT; } #ifdef X_HAVE_UTF8_STRING else if (event.xselection.target == atomCompoundText) { winDebug("winClipboardFlushXEvents - SelectionNotify - " "Requesting conversion of CompoundText target.\n"); XConvertSelection (pDisplay, event.xselection.selection, atomUTF8String, atomLocalProperty, iWindow, CurrentTime); /* Process the ConvertSelection event */ XFlush (pDisplay); return WIN_XEVENTS_CONVERT; } #endif else { ErrorF ("winClipboardFlushXEvents - SelectionNotify - " "Unknown format. Cannot request conversion, " "aborting.\n"); break; } } /* Retrieve the size of the stored data */ iReturn = XGetWindowProperty (pDisplay, iWindow, atomLocalProperty, 0, 0, /* Don't get data, just size */ False, AnyPropertyType, &xtpText.encoding, &xtpText.format, &xtpText.nitems, &ulReturnBytesLeft, &xtpText.value); if (iReturn != Success) { ErrorF ("winClipboardFlushXEvents - SelectionNotify - " "XGetWindowProperty () failed, aborting: %d\n", iReturn); break; } winDebug("SelectionNotify - returned data %d left %d\n", xtpText.nitems, ulReturnBytesLeft); /* Request the selection data */ iReturn = XGetWindowProperty (pDisplay, iWindow, atomLocalProperty, 0, ulReturnBytesLeft, False, AnyPropertyType, &xtpText.encoding, &xtpText.format, &xtpText.nitems, &ulReturnBytesLeft, &xtpText.value); if (iReturn != Success) { ErrorF ("winClipboardFlushXEvents - SelectionNotify - " "XGetWindowProperty () failed, aborting: %d\n", iReturn); break; } { char *pszAtomName = NULL; winDebug("SelectionNotify - returned data %d left %d\n", xtpText.nitems, ulReturnBytesLeft); pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); winDebug("Notify atom name %s\n", pszAtomName); XFree (pszAtomName); pszAtomName = NULL; } if (fUseUnicode) { #ifdef X_HAVE_UTF8_STRING /* Convert the text property to a text list */ iReturn = Xutf8TextPropertyToTextList (pDisplay, &xtpText, &ppszTextList, &iCount); #endif } else { iReturn = XmbTextPropertyToTextList (pDisplay, &xtpText, &ppszTextList, &iCount); } if (iReturn == Success || iReturn > 0) { /* Conversion succeeded or some unconvertible characters */ if (ppszTextList != NULL) { iReturnDataLen = 0; for (i = 0; i < iCount; i++) { iReturnDataLen += strlen(ppszTextList[i]); } pszReturnData = malloc (iReturnDataLen + 1); pszReturnData[0] = '\0'; for (i = 0; i < iCount; i++) { strcat (pszReturnData, ppszTextList[i]); } } else { ErrorF ("winClipboardFlushXEvents - SelectionNotify - " "X*TextPropertyToTextList list_return is NULL.\n"); pszReturnData = malloc (1); pszReturnData[0] = '\0'; } } else { ErrorF ("winClipboardFlushXEvents - SelectionNotify - " "X*TextPropertyToTextList returned: "); switch (iReturn) { case XNoMemory: ErrorF ("XNoMemory\n"); break; case XConverterNotFound: ErrorF ("XConverterNotFound\n"); break; default: ErrorF ("%d", iReturn); break; } pszReturnData = malloc (1); pszReturnData[0] = '\0'; } /* Free the data returned from XGetWindowProperty */ if (ppszTextList) XFreeStringList (ppszTextList); ppszTextList = NULL; XFree (xtpText.value); xtpText.value = NULL; xtpText.nitems = 0; /* Convert the X clipboard string to DOS format */ winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); if (fUseUnicode) { /* Find out how much space needed to convert MBCS to Unicode */ iUnicodeLen = MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, NULL, 0); /* Allocate memory for the Unicode string */ pwszUnicodeStr = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1)); if (!pwszUnicodeStr) { ErrorF ("winClipboardFlushXEvents - SelectionNotify " "malloc failed for pwszUnicodeStr, aborting.\n"); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionNotify_Done; } /* Do the actual conversion */ MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, pwszUnicodeStr, iUnicodeLen); /* Allocate global memory for the X clipboard data */ hGlobal = GlobalAlloc (GMEM_MOVEABLE, sizeof (wchar_t) * (iUnicodeLen + 1)); } else { pszConvertData = strdup (pszReturnData); iConvertDataLen = strlen (pszConvertData) + 1; /* Allocate global memory for the X clipboard data */ hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen); } free (pszReturnData); /* Check that global memory was allocated */ if (!hGlobal) { ErrorF ("winClipboardFlushXEvents - SelectionNotify " "GlobalAlloc failed, aborting: %ld\n", GetLastError ()); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionNotify_Done; } /* Obtain a pointer to the global memory */ pszGlobalData = GlobalLock (hGlobal); if (pszGlobalData == NULL) { ErrorF ("winClipboardFlushXEvents - Could not lock global " "memory for clipboard transfer\n"); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionNotify_Done; } /* Copy the returned string into the global memory */ if (fUseUnicode) { memcpy (pszGlobalData, pwszUnicodeStr, sizeof (wchar_t) * (iUnicodeLen + 1)); free (pwszUnicodeStr); pwszUnicodeStr = NULL; } else { strcpy (pszGlobalData, pszConvertData); free (pszConvertData); pszConvertData = NULL; } /* Release the pointer to the global memory */ GlobalUnlock (hGlobal); pszGlobalData = NULL; /* Push the selection data to the Windows clipboard */ if (fUseUnicode) SetClipboardData (CF_UNICODETEXT, hGlobal); else SetClipboardData (CF_TEXT, hGlobal); /* Flag that SetClipboardData has been called */ fSetClipboardData = FALSE; /* * NOTE: Do not try to free pszGlobalData, it is owned by * Windows after the call to SetClipboardData (). */ winClipboardFlushXEvents_SelectionNotify_Done: /* Free allocated resources */ if (ppszTextList) XFreeStringList (ppszTextList); if (xtpText.value) { XFree (xtpText.value); xtpText.value = NULL; xtpText.nitems = 0; } free(pszConvertData); free(pwszUnicodeStr); if (hGlobal && pszGlobalData) GlobalUnlock (hGlobal); if (fSetClipboardData && g_fUnicodeSupport) SetClipboardData (CF_UNICODETEXT, NULL); if (fSetClipboardData) SetClipboardData (CF_TEXT, NULL); return WIN_XEVENTS_NOTIFY; case SelectionClear: winDebug("SelectionClear - doing nothing\n"); break; case PropertyNotify: break; case MappingNotify: break; default: ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type); break; } } return WIN_XEVENTS_SUCCESS; }
int winClipboardFlushXEvents(HWND hwnd, Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms) { Atom atomClipboard = atoms->atomClipboard; Atom atomLocalProperty = atoms->atomLocalProperty; Atom atomUTF8String = atoms->atomUTF8String; Atom atomCompoundText = atoms->atomCompoundText; Atom atomTargets = atoms->atomTargets; /* Process all pending events */ while (XPending(pDisplay)) { XTextProperty xtpText = { 0 }; XEvent event; XSelectionEvent eventSelection; unsigned long ulReturnBytesLeft; char *pszReturnData = NULL; char *pszGlobalData = NULL; int iReturn; HGLOBAL hGlobal = NULL; XICCEncodingStyle xiccesStyle; char *pszConvertData = NULL; char *pszTextList[2] = { NULL }; int iCount; char **ppszTextList = NULL; wchar_t *pwszUnicodeStr = NULL; Bool fAbort = FALSE; Bool fCloseClipboard = FALSE; Bool fSetClipboardData = TRUE; /* Get the next event - will not block because one is ready */ XNextEvent(pDisplay, &event); /* Branch on the event type */ switch (event.type) { /* * SelectionRequest */ case SelectionRequest: { char *pszAtomName = NULL; winDebug("SelectionRequest - target %ld\n", event.xselectionrequest.target); pszAtomName = XGetAtomName(pDisplay, event.xselectionrequest.target); winDebug("SelectionRequest - Target atom name %s\n", pszAtomName); XFree(pszAtomName); pszAtomName = NULL; } /* Abort if invalid target type */ if (event.xselectionrequest.target != XA_STRING && event.xselectionrequest.target != atomUTF8String && event.xselectionrequest.target != atomCompoundText && event.xselectionrequest.target != atomTargets) { /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Handle targets type of request */ if (event.xselectionrequest.target == atomTargets) { Atom atomTargetArr[] = { atomTargets, atomCompoundText, atomUTF8String, XA_STRING }; /* Try to change the property */ iReturn = XChangeProperty(pDisplay, event.xselectionrequest.requestor, event.xselectionrequest.property, XA_ATOM, 32, PropModeReplace, (unsigned char *) atomTargetArr, ARRAY_SIZE(atomTargetArr)); if (iReturn == BadAlloc || iReturn == BadAtom || iReturn == BadMatch || iReturn == BadValue || iReturn == BadWindow) { ErrorF("winClipboardFlushXEvents - SelectionRequest - " "XChangeProperty failed: %d\n", iReturn); } /* Setup selection notify xevent */ eventSelection.type = SelectionNotify; eventSelection.send_event = True; eventSelection.display = pDisplay; eventSelection.requestor = event.xselectionrequest.requestor; eventSelection.selection = event.xselectionrequest.selection; eventSelection.target = event.xselectionrequest.target; eventSelection.property = event.xselectionrequest.property; eventSelection.time = event.xselectionrequest.time; /* * Notify the requesting window that * the operation has completed */ iReturn = XSendEvent(pDisplay, eventSelection.requestor, False, 0L, (XEvent *) &eventSelection); if (iReturn == BadValue || iReturn == BadWindow) { ErrorF("winClipboardFlushXEvents - SelectionRequest - " "XSendEvent () failed\n"); } break; } /* Close clipboard if we have it open already */ if (GetOpenClipboardWindow() == hwnd) { CloseClipboard(); } /* Access the clipboard */ if (!OpenClipboard(hwnd)) { ErrorF("winClipboardFlushXEvents - SelectionRequest - " "OpenClipboard () failed: %08x\n", (unsigned int)GetLastError()); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Indicate that clipboard was opened */ fCloseClipboard = TRUE; /* Check that clipboard format is available */ if (data->fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) { static int count; /* Hack to stop acroread spamming the log */ static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */ if (hwnd != lasthwnd) count = 0; count++; if (count < 6) ErrorF("winClipboardFlushXEvents - CF_UNICODETEXT is not " "available from Win32 clipboard. Aborting %d.\n", count); lasthwnd = hwnd; /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } else if (!data->fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) { ErrorF("winClipboardFlushXEvents - CF_TEXT is not " "available from Win32 clipboard. Aborting.\n"); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Setup the string style */ if (event.xselectionrequest.target == XA_STRING) xiccesStyle = XStringStyle; #ifdef X_HAVE_UTF8_STRING else if (event.xselectionrequest.target == atomUTF8String) xiccesStyle = XUTF8StringStyle; #endif else if (event.xselectionrequest.target == atomCompoundText) xiccesStyle = XCompoundTextStyle; else xiccesStyle = XStringStyle; /* Get a pointer to the clipboard text, in desired format */ if (data->fUseUnicode) { /* Retrieve clipboard data */ hGlobal = GetClipboardData(CF_UNICODETEXT); } else { /* Retrieve clipboard data */ hGlobal = GetClipboardData(CF_TEXT); } if (!hGlobal) { ErrorF("winClipboardFlushXEvents - SelectionRequest - " "GetClipboardData () failed: %08x\n", (unsigned int)GetLastError()); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } pszGlobalData = (char *) GlobalLock(hGlobal); /* Convert the Unicode string to UTF8 (MBCS) */ if (data->fUseUnicode) { int iConvertDataLen = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) pszGlobalData, -1, NULL, 0, NULL, NULL); /* NOTE: iConvertDataLen includes space for null terminator */ pszConvertData = malloc(iConvertDataLen); WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) pszGlobalData, -1, pszConvertData, iConvertDataLen, NULL, NULL); } else { pszConvertData = strdup(pszGlobalData); } /* Convert DOS string to UNIX string */ winClipboardDOStoUNIX(pszConvertData, strlen(pszConvertData)); /* Setup our text list */ pszTextList[0] = pszConvertData; pszTextList[1] = NULL; /* Initialize the text property */ xtpText.value = NULL; xtpText.nitems = 0; /* Create the text property from the text list */ if (data->fUseUnicode) { #ifdef X_HAVE_UTF8_STRING iReturn = Xutf8TextListToTextProperty(pDisplay, pszTextList, 1, xiccesStyle, &xtpText); #endif } else { iReturn = XmbTextListToTextProperty(pDisplay, pszTextList, 1, xiccesStyle, &xtpText); } if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) { ErrorF("winClipboardFlushXEvents - SelectionRequest - " "X*TextListToTextProperty failed: %d\n", iReturn); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Free the converted string */ free(pszConvertData); pszConvertData = NULL; /* Copy the clipboard text to the requesting window */ iReturn = XChangeProperty(pDisplay, event.xselectionrequest.requestor, event.xselectionrequest.property, event.xselectionrequest.target, 8, PropModeReplace, xtpText.value, xtpText.nitems); if (iReturn == BadAlloc || iReturn == BadAtom || iReturn == BadMatch || iReturn == BadValue || iReturn == BadWindow) { ErrorF("winClipboardFlushXEvents - SelectionRequest - " "XChangeProperty failed: %d\n", iReturn); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Release the clipboard data */ GlobalUnlock(hGlobal); pszGlobalData = NULL; fCloseClipboard = FALSE; CloseClipboard(); /* Clean up */ XFree(xtpText.value); xtpText.value = NULL; xtpText.nitems = 0; /* Setup selection notify event */ eventSelection.type = SelectionNotify; eventSelection.send_event = True; eventSelection.display = pDisplay; eventSelection.requestor = event.xselectionrequest.requestor; eventSelection.selection = event.xselectionrequest.selection; eventSelection.target = event.xselectionrequest.target; eventSelection.property = event.xselectionrequest.property; eventSelection.time = event.xselectionrequest.time; /* Notify the requesting window that the operation has completed */ iReturn = XSendEvent(pDisplay, eventSelection.requestor, False, 0L, (XEvent *) &eventSelection); if (iReturn == BadValue || iReturn == BadWindow) { ErrorF("winClipboardFlushXEvents - SelectionRequest - " "XSendEvent () failed\n"); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionRequest_Done; } winClipboardFlushXEvents_SelectionRequest_Done: /* Free allocated resources */ if (xtpText.value) { XFree(xtpText.value); xtpText.value = NULL; xtpText.nitems = 0; } free(pszConvertData); if (hGlobal && pszGlobalData) GlobalUnlock(hGlobal); /* * Send a SelectionNotify event to the requesting * client when we abort. */ if (fAbort) { /* Setup selection notify event */ eventSelection.type = SelectionNotify; eventSelection.send_event = True; eventSelection.display = pDisplay; eventSelection.requestor = event.xselectionrequest.requestor; eventSelection.selection = event.xselectionrequest.selection; eventSelection.target = event.xselectionrequest.target; eventSelection.property = None; eventSelection.time = event.xselectionrequest.time; /* Notify the requesting window that the operation is complete */ iReturn = XSendEvent(pDisplay, eventSelection.requestor, False, 0L, (XEvent *) &eventSelection); if (iReturn == BadValue || iReturn == BadWindow) { /* * Should not be a problem if XSendEvent fails because * the client may simply have exited. */ ErrorF("winClipboardFlushXEvents - SelectionRequest - " "XSendEvent () failed for abort event.\n"); } } /* Close clipboard if it was opened */ if (fCloseClipboard) { fCloseClipboard = FALSE; CloseClipboard(); } break; /* * SelectionNotify */ case SelectionNotify: winDebug("winClipboardFlushXEvents - SelectionNotify\n"); { char *pszAtomName; pszAtomName = XGetAtomName(pDisplay, event.xselection.selection); winDebug ("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", pszAtomName); XFree(pszAtomName); } /* SelectionNotify with property of None indicates either: (i) Generated by the X server if no owner for the specified selection exists (perhaps it's disappeared on us mid-transaction), or (ii) Sent by the selection owner when the requested selection conversion could not be performed or server errors prevented the conversion data being returned */ if (event.xselection.property == None) { ErrorF("winClipboardFlushXEvents - SelectionNotify - " "Conversion to format %ld refused.\n", event.xselection.target); return WIN_XEVENTS_FAILED; } if (event.xselection.target == atomTargets) { return winClipboardSelectionNotifyTargets(hwnd, iWindow, pDisplay, data, atoms); } /* Retrieve the selection data and delete the property */ iReturn = XGetWindowProperty(pDisplay, iWindow, atomLocalProperty, 0, INT_MAX, True, AnyPropertyType, &xtpText.encoding, &xtpText.format, &xtpText.nitems, &ulReturnBytesLeft, &xtpText.value); if (iReturn != Success) { ErrorF("winClipboardFlushXEvents - SelectionNotify - " "XGetWindowProperty () failed, aborting: %d\n", iReturn); goto winClipboardFlushXEvents_SelectionNotify_Done; } { char *pszAtomName = NULL; winDebug("SelectionNotify - returned data %lu left %lu\n", xtpText.nitems, ulReturnBytesLeft); pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); winDebug("Notify atom name %s\n", pszAtomName); XFree(pszAtomName); pszAtomName = NULL; } if (data->fUseUnicode) { #ifdef X_HAVE_UTF8_STRING /* Convert the text property to a text list */ iReturn = Xutf8TextPropertyToTextList(pDisplay, &xtpText, &ppszTextList, &iCount); #endif } else { iReturn = XmbTextPropertyToTextList(pDisplay, &xtpText, &ppszTextList, &iCount); } if (iReturn == Success || iReturn > 0) { /* Conversion succeeded or some unconvertible characters */ if (ppszTextList != NULL) { int i; int iReturnDataLen = 0; for (i = 0; i < iCount; i++) { iReturnDataLen += strlen(ppszTextList[i]); } pszReturnData = malloc(iReturnDataLen + 1); pszReturnData[0] = '\0'; for (i = 0; i < iCount; i++) { strcat(pszReturnData, ppszTextList[i]); } } else { ErrorF("winClipboardFlushXEvents - SelectionNotify - " "X*TextPropertyToTextList list_return is NULL.\n"); pszReturnData = malloc(1); pszReturnData[0] = '\0'; } } else { ErrorF("winClipboardFlushXEvents - SelectionNotify - " "X*TextPropertyToTextList returned: "); switch (iReturn) { case XNoMemory: ErrorF("XNoMemory\n"); break; case XLocaleNotSupported: ErrorF("XLocaleNotSupported\n"); break; case XConverterNotFound: ErrorF("XConverterNotFound\n"); break; default: ErrorF("%d\n", iReturn); break; } pszReturnData = malloc(1); pszReturnData[0] = '\0'; } /* Free the data returned from XGetWindowProperty */ if (ppszTextList) XFreeStringList(ppszTextList); ppszTextList = NULL; XFree(xtpText.value); xtpText.value = NULL; xtpText.nitems = 0; /* Convert the X clipboard string to DOS format */ winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData)); if (data->fUseUnicode) { /* Find out how much space needed to convert MBCS to Unicode */ int iUnicodeLen = MultiByteToWideChar(CP_UTF8, 0, pszReturnData, -1, NULL, 0); /* NOTE: iUnicodeLen includes space for null terminator */ pwszUnicodeStr = malloc(sizeof(wchar_t) * iUnicodeLen); if (!pwszUnicodeStr) { ErrorF("winClipboardFlushXEvents - SelectionNotify " "malloc failed for pwszUnicodeStr, aborting.\n"); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionNotify_Done; } /* Do the actual conversion */ MultiByteToWideChar(CP_UTF8, 0, pszReturnData, -1, pwszUnicodeStr, iUnicodeLen); /* Allocate global memory for the X clipboard data */ hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * iUnicodeLen); } else { int iConvertDataLen = 0; pszConvertData = strdup(pszReturnData); iConvertDataLen = strlen(pszConvertData) + 1; /* Allocate global memory for the X clipboard data */ hGlobal = GlobalAlloc(GMEM_MOVEABLE, iConvertDataLen); } free(pszReturnData); /* Check that global memory was allocated */ if (!hGlobal) { ErrorF("winClipboardFlushXEvents - SelectionNotify " "GlobalAlloc failed, aborting: %08x\n", (unsigned int)GetLastError()); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionNotify_Done; } /* Obtain a pointer to the global memory */ pszGlobalData = GlobalLock(hGlobal); if (pszGlobalData == NULL) { ErrorF("winClipboardFlushXEvents - Could not lock global " "memory for clipboard transfer\n"); /* Abort */ fAbort = TRUE; goto winClipboardFlushXEvents_SelectionNotify_Done; } /* Copy the returned string into the global memory */ if (data->fUseUnicode) { wcscpy((wchar_t *)pszGlobalData, pwszUnicodeStr); free(pwszUnicodeStr); pwszUnicodeStr = NULL; } else { strcpy(pszGlobalData, pszConvertData); free(pszConvertData); pszConvertData = NULL; } /* Release the pointer to the global memory */ GlobalUnlock(hGlobal); pszGlobalData = NULL; /* Push the selection data to the Windows clipboard */ if (data->fUseUnicode) SetClipboardData(CF_UNICODETEXT, hGlobal); else SetClipboardData(CF_TEXT, hGlobal); /* Flag that SetClipboardData has been called */ fSetClipboardData = FALSE; /* * NOTE: Do not try to free pszGlobalData, it is owned by * Windows after the call to SetClipboardData (). */ winClipboardFlushXEvents_SelectionNotify_Done: /* Free allocated resources */ if (ppszTextList) XFreeStringList(ppszTextList); if (xtpText.value) { XFree(xtpText.value); xtpText.value = NULL; xtpText.nitems = 0; } free(pszConvertData); free(pwszUnicodeStr); if (hGlobal && pszGlobalData) GlobalUnlock(hGlobal); if (fSetClipboardData) { SetClipboardData(CF_UNICODETEXT, NULL); SetClipboardData(CF_TEXT, NULL); } return WIN_XEVENTS_NOTIFY_DATA; case SelectionClear: winDebug("SelectionClear - doing nothing\n"); break; case PropertyNotify: break; case MappingNotify: break; default: if (event.type == XFixesSetSelectionOwnerNotify + xfixes_event_base) { XFixesSelectionNotifyEvent *e = (XFixesSelectionNotifyEvent *) & event; winDebug("winClipboardFlushXEvents - XFixesSetSelectionOwnerNotify\n"); /* Save selection owners for monitored selections, ignore other selections */ if ((e->selection == XA_PRIMARY) && fPrimarySelection) { MonitorSelection(e, CLIP_OWN_PRIMARY); } else if (e->selection == atomClipboard) { MonitorSelection(e, CLIP_OWN_CLIPBOARD); } else break; /* Selection is being disowned */ if (e->owner == None) { winDebug ("winClipboardFlushXEvents - No window, returning.\n"); break; } /* XXX: there are all kinds of wacky edge cases we might need here: - we own windows clipboard, but neither PRIMARY nor CLIPBOARD have an owner, so we should disown it? - root window is taking ownership? */ /* If we are the owner of the most recently owned selection, don't go all recursive :) */ if ((lastOwnedSelectionIndex != CLIP_OWN_NONE) && (s_iOwners[lastOwnedSelectionIndex] == iWindow)) { winDebug("winClipboardFlushXEvents - Ownership changed to us, aborting.\n"); break; } /* Close clipboard if we have it open already (possible? correct??) */ if (GetOpenClipboardWindow() == hwnd) { CloseClipboard(); } /* Access the Windows clipboard */ if (!OpenClipboard(hwnd)) { ErrorF("winClipboardFlushXEvents - OpenClipboard () failed: %08x\n", (int) GetLastError()); break; } /* Take ownership of the Windows clipboard */ if (!EmptyClipboard()) { ErrorF("winClipboardFlushXEvents - EmptyClipboard () failed: %08x\n", (int) GetLastError()); break; } /* Advertise regular text and unicode */ SetClipboardData(CF_UNICODETEXT, NULL); SetClipboardData(CF_TEXT, NULL); /* Release the clipboard */ if (!CloseClipboard()) { ErrorF("winClipboardFlushXEvents - CloseClipboard () failed: %08x\n", (int) GetLastError()); break; } } /* XFixesSelectionWindowDestroyNotifyMask */ /* XFixesSelectionClientCloseNotifyMask */ else { ErrorF("winClipboardFlushXEvents - unexpected event type %d\n", event.type); } break; } } return WIN_XEVENTS_SUCCESS; }
void XimPreeditCallbackDraw(FcitxXimFrontend* xim, FcitxXimIC* ic, const char* preedit_string, int cursorPos) { XTextProperty tp; uint i, len; if (preedit_string == NULL) return; len = fcitx_utf8_strlen(preedit_string); if (len + 1 > xim->feedback_len) { xim->feedback_len = len + 1; if (xim->feedback) { xim->feedback = realloc(xim->feedback, sizeof(XIMFeedback) * xim->feedback_len); } else { xim->feedback = fcitx_utils_malloc0(sizeof(XIMFeedback) * xim->feedback_len); } } FcitxInputState* input = FcitxInstanceGetInputState(xim->owner); FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input); int offset = 0; for (i = 0; i < FcitxMessagesGetMessageCount(clientPreedit) ; i ++) { int type = FcitxMessagesGetClientMessageType(clientPreedit, i); char* str = FcitxMessagesGetMessageString(clientPreedit, i); int j = 0; XIMFeedback fb = 0; if ((type & MSG_NOUNDERLINE) == 0) fb |= XIMUnderline; if (type & MSG_HIGHLIGHT) fb |= XIMReverse; for (; j < fcitx_utf8_strlen(str); j++) { xim->feedback[offset] = fb; offset ++; } } xim->feedback[len] = 0; IMPreeditCBStruct* pcb = fcitx_utils_new(IMPreeditCBStruct); XIMText* text = fcitx_utils_new(XIMText); pcb->major_code = XIM_PREEDIT_DRAW; pcb->connect_id = ic->connect_id; pcb->icid = ic->id; pcb->todo.draw.caret = fcitx_utf8_strnlen(preedit_string, cursorPos); pcb->todo.draw.chg_first = 0; pcb->todo.draw.chg_length = ic->onspot_preedit_length; pcb->todo.draw.text = text; text->feedback = xim->feedback; Xutf8TextListToTextProperty(xim->display, (char **)&preedit_string, 1, XCompoundTextStyle, &tp); text->encoding_is_wchar = 0; text->length = strlen((char*)tp.value); text->string.multi_byte = (char*)tp.value; XimPendingCall(xim, XCT_CALLCALLBACK, (XPointer) pcb); ic->onspot_preedit_length = len; }
void DrawMessageWindow (MessageWindow* messageWindow, char *title, char **msg, int length) { FcitxLightUI* lightui = messageWindow->owner; Display *dpy = lightui->dpy; int i = 0; if (title) { if (messageWindow->title) free(messageWindow->title); messageWindow->title = strdup(title); } else if (!messageWindow->title) return; title = messageWindow->title; FcitxLog(DEBUG, "%s", title); XTextProperty tp; Xutf8TextListToTextProperty(dpy, &title, 1, XUTF8StringStyle, &tp); XSetWMName(dpy, messageWindow->window, &tp); XFree(tp.value); if (msg) { if (messageWindow->msg) { for (i =0 ;i<messageWindow->length; i++) free(messageWindow->msg[i]); free(messageWindow->msg); } messageWindow->length = length; messageWindow->msg = malloc(sizeof(char*) * length); for (i = 0; i < messageWindow->length; i++) messageWindow->msg[i] = strdup(msg[i]); } else { if (!messageWindow->msg) return; } msg = messageWindow->msg; length = messageWindow->length; if (!msg || length == 0) return; messageWindow->height = MESSAGE_WINDOW_MARGIN * 2 + length *(messageWindow->fontSize + MESSAGE_WINDOW_LINESPACE); messageWindow->width = 0; for (i = 0; i< length ;i ++) { int width; if (width > messageWindow->width) messageWindow->width = width; } messageWindow->width += MESSAGE_WINDOW_MARGIN * 2; XResizeWindow(dpy, messageWindow->window, messageWindow->width, messageWindow->height); int x, y; x = MESSAGE_WINDOW_MARGIN; y = MESSAGE_WINDOW_MARGIN; for (i = 0; i< length ;i ++) { y += messageWindow->fontSize + MESSAGE_WINDOW_LINESPACE; } ActivateWindow(dpy, lightui->iScreen, messageWindow->window); }
bool hc_send_command(HCConnection* con, int argc, char* argv[], GString** ret_out, int* ret_status) { if (!hc_create_client_window(con)) { return false; } // check for running window manager instance // TODO // set arguments XTextProperty text_prop; Xutf8TextListToTextProperty(con->display, argv, argc, XUTF8StringStyle, &text_prop); XSetTextProperty(con->display, con->client_window, &text_prop, con->atom_args); XFree(text_prop.value); // get output int command_status = 0; XEvent event; GString* output = NULL; bool output_received = false, status_received = false; while (!output_received || !status_received) { XNextEvent(con->display, &event); if (event.type != PropertyNotify) { // got an event of wrong type continue; } XPropertyEvent* pe = &(event.xproperty); if (pe->window != con->client_window) { // got an event from wrong window continue; } if (!output_received && pe->atom == con->atom_output) { output = window_property_to_g_string(con->display, con->client_window, con->atom_output); if (!output) { fprintf(stderr, "could not get WindowProperty \"%s\"\n", HERBST_IPC_OUTPUT_ATOM); return false; } output_received = true; } else if (!status_received && pe->atom == con->atom_status) { int *value; Atom type; int format; unsigned long items, bytes; if (Success != XGetWindowProperty(con->display, con->client_window, XInternAtom(con->display, HERBST_IPC_STATUS_ATOM, False), 0, 1, False, XA_ATOM, &type, &format, &items, &bytes, (unsigned char**)&value)) { // if could not get window property fprintf(stderr, "could not get WindowProperty \"%s\"\n", HERBST_IPC_STATUS_ATOM); return false; } command_status = *value; XFree(value); status_received = true; } } *ret_status = command_status; *ret_out = output; return true; }