📄 gdkselection-win32.c
字号:
atom = gdk_atom_intern (sFormat, FALSE); data[i++] = atom; } } } if (!has_bmp && (IsClipboardFormatAvailable (CF_BITMAP) || IsClipboardFormatAvailable (CF_DIB))) data[i++] = _image_bmp; if (i > 0) _gdk_selection_property_store (requestor, GDK_SELECTION_TYPE_ATOM, 32, (guchar *) data, i * sizeof (GdkAtom)); else property = GDK_NONE; API_CALL (CloseClipboard, ()); } else if (selection == GDK_SELECTION_CLIPBOARD && (target == GDK_TARGET_STRING || target == _utf8_string)) { /* Converting the CLIPBOARD selection means he wants the * contents of the clipboard. Get the clipboard data, and store * it for later. */ if (!API_CALL (OpenClipboard, (GDK_WINDOW_HWND (requestor)))) return; /* Try various formats. First the simplest, CF_UNICODETEXT. */ if (G_WIN32_IS_NT_BASED () && (hdata = GetClipboardData (CF_UNICODETEXT)) != NULL) { wchar_t *ptr, *wcs, *p, *q; guchar *data; glong length, wclen; if ((ptr = GlobalLock (hdata)) != NULL) { length = GlobalSize (hdata); GDK_NOTE (DND, g_print ("...CF_UNICODETEXT: %ld bytes\n", length)); /* Strip out \r */ wcs = g_new (wchar_t, length / 2 + 1); p = ptr; q = wcs; wclen = 0; while (p < ptr + length / 2) { if (*p != '\r') { *q++ = *p; wclen++; } p++; } data = g_utf16_to_utf8 (wcs, wclen, NULL, NULL, &error); g_free (wcs); if (!data) { g_error_free (error); } else _gdk_selection_property_store (requestor, target, 8, data, strlen (data) + 1); GlobalUnlock (hdata); } } else if ((hdata = GetClipboardData (_cf_utf8_string)) != NULL) { /* UTF8_STRING is a format we store ourselves when necessary */ guchar *ptr; gint length; if ((ptr = GlobalLock (hdata)) != NULL) { length = GlobalSize (hdata); GDK_NOTE (DND, g_print ("...UTF8_STRING: %d bytes: %.10s\n", length, ptr)); _gdk_selection_property_store (requestor, target, 8, g_memdup (ptr, length), length); GlobalUnlock (hdata); } } else if ((hdata = GetClipboardData (CF_TEXT)) != NULL) { /* We must always assume the data can contain non-ASCII * in either the current code page, or if there is CF_LOCALE * data, in that locale's default code page. */ HGLOBAL hlcid; UINT cp = CP_ACP; wchar_t *wcs, *wcs2, *p, *q; guchar *ptr, *data; glong length, wclen, wclen2; if ((ptr = GlobalLock (hdata)) != NULL) { length = GlobalSize (hdata); GDK_NOTE (DND, g_print ("...CF_TEXT: %ld bytes: %.10s\n", length, ptr)); if ((hlcid = GetClipboardData (CF_LOCALE)) != NULL) { gchar buf[10]; LCID *lcidptr = GlobalLock (hlcid); if (GetLocaleInfo (*lcidptr, LOCALE_IDEFAULTANSICODEPAGE, buf, sizeof (buf))) { cp = atoi (buf); GDK_NOTE (DND, g_print ("...CF_LOCALE: %#lx cp:%d\n", *lcidptr, cp)); } GlobalUnlock (hlcid); } wcs = g_new (wchar_t, length + 1); wclen = MultiByteToWideChar (cp, 0, ptr, length, wcs, length + 1); /* Strip out \r */ wcs2 = g_new (wchar_t, wclen); p = wcs; q = wcs2; wclen2 = 0; while (p < wcs + wclen) { if (*p != '\r') { *q++ = *p; wclen2++; } p++; } g_free (wcs); data = g_utf16_to_utf8 (wcs2, wclen2, NULL, &length, &error); g_free (wcs2); if (!data) g_error_free (error); else _gdk_selection_property_store (requestor, target, 8, data, length + 1); GlobalUnlock (hdata); } } else property = GDK_NONE; API_CALL (CloseClipboard, ()); } else if (selection == GDK_SELECTION_CLIPBOARD && target == _image_bmp) { guchar *data; if (!API_CALL (OpenClipboard, (GDK_WINDOW_HWND (requestor)))) return; if ((hdata = GetClipboardData (RegisterClipboardFormat ("image/bmp"))) != NULL) { /* "image/bmp" is the first choice. */ guchar *ptr; if ((ptr = GlobalLock (hdata)) != NULL) { gint length = GlobalSize (hdata); GDK_NOTE (DND, g_print ("...BITMAP (from \"image/bmp\": %d bytes\n", length)); _gdk_selection_property_store (requestor, target, 8, g_memdup (ptr, length), length); GlobalUnlock (hdata); } } else if ((hdata = GetClipboardData (CF_DIB)) != NULL) { /* If there's CF_DIB but not "image/bmp", the clipboard * owner is probably a native Win32 application. */ BITMAPINFOHEADER *ptr; if ((ptr = GlobalLock (hdata)) != NULL) { BITMAPFILEHEADER *hdr; /* Need to add a file header so gdk-pixbuf can load it */ gint length = GlobalSize (hdata) + sizeof (BITMAPFILEHEADER); GDK_NOTE (DND, g_print ("...BITMAP (from CF_DIB): %d bytes\n", length)); data = g_try_malloc (length); if (data) { hdr = (BITMAPFILEHEADER *)data; hdr->bfType = 0x4d42; /* 0x42 = "B" 0x4d = "M" */ /* Compute the size of the entire file. */ hdr->bfSize = (DWORD) (sizeof (BITMAPFILEHEADER) + ptr->biSize + ptr->biClrUsed * sizeof (RGBQUAD) + ptr->biSizeImage); hdr->bfReserved1 = 0; hdr->bfReserved2 = 0; /* Compute the offset to the array of color indices. */ hdr->bfOffBits = (DWORD) sizeof (BITMAPFILEHEADER) + ptr->biSize + ptr->biClrUsed * sizeof (RGBQUAD); /* Copy the data behind it */ memcpy (data + sizeof (BITMAPFILEHEADER), ptr, length - sizeof (BITMAPFILEHEADER)); _gdk_selection_property_store (requestor, target, 8, data, length); } GlobalUnlock (hdata); } } API_CALL (CloseClipboard, ()); } else if (selection == GDK_SELECTION_CLIPBOARD) { const char *targetname = gdk_atom_name (target); UINT fmt = 0; if (!API_CALL (OpenClipboard, (GDK_WINDOW_HWND (requestor)))) return; /* Check if it's available. In fact, we can simply call * GetClipboardData (RegisterClipboardFormat (targetname)), but * the global custom format ID space is limited, * (0xC000~0xFFFF), and we better not waste an format ID if we * are just a requestor. */ for ( ; 0 != (fmt = EnumClipboardFormats (fmt)); ) { char sFormat[80]; if (GetClipboardFormatName (fmt, sFormat, 80) > 0 && strcmp (sFormat, targetname) == 0) { if ((hdata = GetClipboardData (fmt)) != NULL) { /* Simply get it without conversion */ guchar *ptr; gint length; if ((ptr = GlobalLock (hdata)) != NULL) { length = GlobalSize (hdata); GDK_NOTE (DND, g_print ("... %s: %d bytes\n", targetname, length)); _gdk_selection_property_store (requestor, target, 8, g_memdup (ptr, length), length); GlobalUnlock (hdata); break; } } } } API_CALL (CloseClipboard, ()); } else if (selection == _gdk_win32_dropfiles) { /* This means he wants the names of the dropped files. * gdk_dropfiles_filter already has stored the text/uri-list * data temporarily in dropfiles_prop. */ if (dropfiles_prop != NULL) { _gdk_selection_property_store (requestor, selection, dropfiles_prop->format, dropfiles_prop->data, dropfiles_prop->length); g_free (dropfiles_prop); dropfiles_prop = NULL; } } else property = GDK_NONE; /* Generate a selection notify message so that we actually fetch * the data (if property == _gdk_selection_property) or indicating failure * (if property == GDK_NONE). */ generate_selection_notify (requestor, selection, target, property, time);}gintgdk_selection_property_get (GdkWindow *requestor, guchar **data, GdkAtom *ret_type, gint *ret_format){ GdkSelProp *prop; GSList *prop_list; g_return_val_if_fail (requestor != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (requestor), 0); if (GDK_WINDOW_DESTROYED (requestor)) return 0; GDK_NOTE (DND, g_print ("gdk_selection_property_get: %p\n", GDK_WINDOW_HWND (requestor))); prop_list = g_hash_table_lookup (sel_prop_table, GDK_WINDOW_HWND (requestor)); prop = prop_list ? (GdkSelProp *) prop_list->data : NULL; if (prop == NULL) { *data = NULL; return 0; } *data = g_malloc (prop->length + 1); (*data)[prop->length] = '\0'; if (prop->length > 0) memmove (*data, prop->data, prop->length); if (ret_type) *ret_type = prop->type; if (ret_format) *ret_format = prop->format; return prop->length;}void_gdk_selection_property_delete (GdkWindow *window){ GdkSelProp *prop; GSList *prop_list; GDK_NOTE (DND, g_print ("_gdk_selection_property_delete: %p\n", GDK_WINDOW_HWND (window))); prop_list = g_hash_table_lookup (sel_prop_table, GDK_WINDOW_HWND (window)); if (prop_list && (prop = (GdkSelProp *) prop_list->data) != NULL) { g_free (prop->data); prop_list = g_slist_remove (prop_list, prop); g_free (prop); g_hash_table_insert (sel_prop_table, GDK_WINDOW_HWND (window), prop_list); }}voidgdk_selection_send_notify_for_display (GdkDisplay *display, guint32 requestor, GdkAtom selection, GdkAtom target, GdkAtom property, guint32 time){ gchar *sel_name, *tgt_name, *prop_name; g_return_if_fail (display == _gdk_display); GDK_NOTE (DND, (sel_name = gdk_atom_name (selection), tgt_name = gdk_atom_name (target), prop_name = gdk_atom_name (property), g_print ("gdk_selection_send_notify: %#x %#x (%s) %#x (%s) %#x (%s)\n", requestor, (guint) selection, sel_name, (guint) target, tgt_name, (guint) property, prop_name), g_free (sel_name), g_free (tgt_name), g_free (prop_name)));}/* It's hard to say whether implementing this actually is of any use * on the Win32 platform? gtk calls only * gdk_text_property_to_utf8_list_for_display(). */gintgdk_text_property_to_text_list_for_display (GdkDisplay *display, GdkAtom encoding, gint format, const guchar *text, gint length, gchar ***list){ GError *error = NULL; gchar *enc_name; gchar *result; const gchar *charset; const gchar *source_charset = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -