• R/O
  • HTTP
  • SSH
  • HTTPS

hengband: Commit

変愚蛮怒のメインリポジトリです


Commit MetaInfo

Revisiondc0b6f3887ac59530c30edb0f63525ec5ecfa84b (tree)
Time2003-09-17 00:16:40
Authormogami <mogami@0568...>
Commitermogami

Log Message

マウスによるコピー&ペーストで漢字が使えなかったので、使えるようにした。
漢字はCOMPOUND_TEXTという形式にする必要があった。

Change Summary

Incremental Difference

--- a/src/main-x11.c
+++ b/src/main-x11.c
@@ -2133,23 +2133,152 @@ static void copy_x11_end(const Time time)
21332133 }
21342134 }
21352135
2136+
2137+static Atom xa_targets, xa_timestamp, xa_text, xa_compound_text;
2138+
2139+/*
2140+ * Set the required variable atoms at start-up to avoid errors later.
2141+ */
2142+static void set_atoms(void)
2143+{
2144+ xa_targets = XInternAtom(DPY, "TARGETS", False);
2145+ xa_timestamp = XInternAtom(DPY, "TIMESTAMP", False);
2146+ xa_text = XInternAtom(DPY, "TEXT", False);
2147+ xa_compound_text = XInternAtom(DPY, "COMPOUND_TEXT", False);
2148+}
2149+
2150+
2151+static Atom request_target = 0;
2152+
21362153 /*
21372154 * Send a message to request that the PRIMARY buffer be sent here.
21382155 */
2139-static void paste_x11_request(const Time time)
2156+static void paste_x11_request(Atom target, const Time time)
21402157 {
2158+ /*
2159+ * It's from some sample programs on the web.
2160+ * What does it mean? -- XXX
2161+ */
2162+ Atom property = XInternAtom(DPY, "__COPY_TEXT", False);
2163+
21412164 /* Check the owner. */
2142- if (XGetSelectionOwner(Metadpy->dpy, XA_PRIMARY) == None)
2165+ if (XGetSelectionOwner(DPY, XA_PRIMARY) == None)
21432166 {
21442167 /* No selection. */
21452168 /* bell("No selection found."); */
21462169 return;
21472170 }
21482171
2149- /* Request the event as a STRING. */
2150- XConvertSelection(DPY, XA_PRIMARY, XA_STRING, XA_STRING, WIN, time);
2172+ request_target = target;
2173+
2174+ /* Request the event */
2175+ XConvertSelection(DPY, XA_PRIMARY, target, property, WIN, time);
21512176 }
21522177
2178+
2179+/*
2180+ * Add the contents of the PRIMARY buffer to the input queue.
2181+ *
2182+ * Hack - This doesn't use the "time" of the event, and so accepts anything a
2183+ * client tries to send it.
2184+ */
2185+static void paste_x11_accept(const XSelectionEvent *ptr)
2186+{
2187+ unsigned long left;
2188+ const long offset = 0;
2189+ const long length = 32000;
2190+ XTextProperty xtextproperty;
2191+ errr err = 0;
2192+
2193+ /*
2194+ * It's from some sample programs on the web.
2195+ * What does it mean? -- XXX
2196+ */
2197+ Atom property = XInternAtom(DPY, "__COPY_TEXT", False);
2198+
2199+
2200+ /* Failure. */
2201+ if (ptr->property == None)
2202+ {
2203+ if (request_target == xa_compound_text)
2204+ {
2205+ /* Re-request as STRING */
2206+ paste_x11_request(XA_STRING, ptr->time);
2207+ }
2208+ else
2209+ {
2210+ request_target = 0;
2211+ plog("Paste failure (remote client could not send).");
2212+ }
2213+ return;
2214+ }
2215+
2216+ if (ptr->selection != XA_PRIMARY)
2217+ {
2218+ plog("Paste failure (remote client did not send primary selection).");
2219+ return;
2220+ }
2221+
2222+ if (ptr->target != request_target)
2223+ {
2224+ plog("Paste failure (selection in unknown format).");
2225+ return;
2226+ }
2227+
2228+ /* Get text */
2229+ if (XGetWindowProperty(Metadpy->dpy, Infowin->win, property, offset,
2230+ length, TRUE, request_target,
2231+ &xtextproperty.encoding,
2232+ &xtextproperty.format,
2233+ &xtextproperty.nitems,
2234+ &left,
2235+ &xtextproperty.value)
2236+ != Success)
2237+ {
2238+ /* Failure */
2239+ return;
2240+ }
2241+
2242+ if (request_target == xa_compound_text)
2243+ {
2244+ char **list;
2245+ int count;
2246+
2247+ XmbTextPropertyToTextList(DPY, &xtextproperty, &list, &count);
2248+
2249+ if (list)
2250+ {
2251+ int i;
2252+
2253+ for (i = 0; i < count; i++)
2254+ {
2255+ /* Paste the text. */
2256+ err = type_string(list[i], 0);
2257+
2258+ if (err) break;
2259+ }
2260+
2261+ /* Free the string */
2262+ XFreeStringList(list);
2263+ }
2264+ }
2265+ else /* if (request_target == XA_STRING) */
2266+ {
2267+ /* Paste the text. */
2268+ err = type_string((char *)xtextproperty.value, xtextproperty.nitems);
2269+ }
2270+
2271+ /* Free the data pasted. */
2272+ XFree(xtextproperty.value);
2273+
2274+ /* No room. */
2275+ if (err)
2276+ {
2277+ plog("Paste failure (too much text selected).");
2278+ }
2279+}
2280+
2281+
21532282 /*
21542283 * Add a character to a string in preparation for sending it to another
21552284 * client as a STRING.
@@ -2157,24 +2286,17 @@ static void paste_x11_request(const Time time)
21572286 * receiving this format (although the standard specifies a restricted set).
21582287 * Strings do not have a colour.
21592288 */
2160-static int add_char_string(char *buf, byte a, char c)
2161-{
2162- (void)a;
2163-
2164- *buf = c;
2165- return 1;
2166-}
2167-
2168-static bool paste_x11_send_text(XSelectionRequestEvent *rq, int (*add)(char *, byte, char))
2289+static bool paste_x11_send_text(XSelectionRequestEvent *rq)
21692290 {
21702291 char buf[1024];
2292+ char *list[1000];
21712293 co_ord max, min;
2172- int x,y,l;
2294+ int x,y,l,n;
21732295 byte a;
21742296 char c;
21752297
21762298 /* Too old, or incorrect call. */
2177- if (rq->time < s_ptr->time || !add) return FALSE;
2299+ if (rq->time < s_ptr->time) return FALSE;
21782300
21792301 /* Work out which way around to paste. */
21802302 sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->cur);
@@ -2189,47 +2311,102 @@ static bool paste_x11_send_text(XSelectionRequestEvent *rq, int (*add)(char *, b
21892311 /* Delete the old value of the property. */
21902312 XDeleteProperty(DPY, rq->requestor, rq->property);
21912313
2192- for (y = 0; y < Term->hgt; y++)
2314+ for (n = 0, y = 0; y < Term->hgt; y++)
21932315 {
2316+ int kanji = 0;
2317+
21942318 if (y < min.y) continue;
21952319 if (y > max.y) break;
21962320
2197- for (x = l = 0; x < Term->wid; x++)
2321+ for (l = 0, x = 0; x < Term->wid; x++)
21982322 {
2199- if (x < min.x) continue;
22002323 if (x > max.x) break;
22012324
22022325 /* Find the character. */
22032326 Term_what(x, y, &a, &c);
22042327
2328+ if (1 == kanji) kanji = 2;
2329+ else if (iskanji(c)) kanji = 1;
2330+ else kanji = 0;
2331+
2332+ if (x < min.x) continue;
2333+
2334+ /*
2335+ * A single kanji character was divided in two...
2336+ * Delete the garbage.
2337+ */
2338+ if ((2 == kanji && x == min.x) ||
2339+ (1 == kanji && x == max.x))
2340+ c = ' ';
2341+
22052342 /* Add it. */
2206- l += (*add)(buf+l, a, c);
2343+ buf[l] = c;
2344+ l++;
22072345 }
22082346
2209-#if 0
2210- /* Terminate all but the last line in an appropriate way. */
2211- if (y != max.y) l += (*add)(buf+l, TERM_WHITE, '\n');
2212-#else
2213- /* Terminate all line unless single line message. */
2214- if (min.y != max.y) l += (*add)(buf+l, TERM_WHITE, '\n');
2215-#endif
2347+ /* Terminate all line unless it's single line. */
2348+ if (min.y != max.y)
2349+ {
2350+ buf[l] = '\n';
2351+ l++;
2352+ }
2353+
2354+ /* End of string */
2355+ buf[l] = '\0';
22162356
2217- /* Send the (non-empty) string. */
2218- XChangeProperty(DPY, rq->requestor, rq->property, rq->target, 8,
2219- PropModeAppend, (byte*)buf, l);
2357+ list[n++] = (char *)string_make(buf);
22202358 }
2221- return TRUE;
2222-}
22232359
2224-static Atom xa_targets, xa_timestamp;
2360+ /* End of the list */
2361+ list[n] = NULL;
22252362
2226-/*
2227- * Set the required variable atoms at start-up to avoid errors later.
2228- */
2229-static void set_atoms(void)
2230-{
2231- xa_targets = XInternAtom(DPY, "TARGETS", False);
2232- xa_timestamp = XInternAtom(DPY, "TIMESTAMP", False);
2363+
2364+ if (rq->target == XA_STRING)
2365+ {
2366+ for (n = 0; list[n]; n++)
2367+ {
2368+ /* Send the (non-empty) string. */
2369+ XChangeProperty(DPY, rq->requestor, rq->property, rq->target, 8,
2370+ PropModeAppend, (unsigned char *)list[n], strlen(list[n]));
2371+ }
2372+ }
2373+
2374+ else if (rq->target == xa_text ||
2375+ rq->target == xa_compound_text)
2376+ {
2377+ XTextProperty text_prop;
2378+ XICCEncodingStyle style;
2379+
2380+ if (rq->target == xa_text)
2381+ style = XStdICCTextStyle;
2382+ else /* if (rq->target == xa_compound_text) */
2383+ style = XCompoundTextStyle;
2384+
2385+ if (Success ==
2386+ XmbTextListToTextProperty(DPY, list, n, style, &text_prop))
2387+ {
2388+ /* Send the compound text */
2389+ XChangeProperty(DPY,
2390+ rq->requestor,
2391+ rq->property,
2392+ text_prop.encoding,
2393+ text_prop.format,
2394+ PropModeAppend,
2395+ text_prop.value,
2396+ text_prop.nitems);
2397+
2398+ /* Free the data. */
2399+ XFree(text_prop.value);
2400+ }
2401+ }
2402+
2403+ /* Free the list of strings */
2404+ for (n = 0; list[n]; n++)
2405+ {
2406+ string_free(list[n]);
2407+ }
2408+
2409+ return TRUE;
22332410 }
22342411
22352412 /*
@@ -2253,16 +2430,20 @@ static void paste_x11_send(XSelectionRequestEvent *rq)
22532430 * Note that this currently rejects MULTIPLE targets.
22542431 */
22552432
2256- if (rq->target == XA_STRING)
2433+ if (rq->target == XA_STRING ||
2434+ rq->target == xa_text ||
2435+ rq->target == xa_compound_text)
22572436 {
2258- if (!paste_x11_send_text(rq, add_char_string))
2437+ if (!paste_x11_send_text(rq))
22592438 ptr->property = None;
22602439 }
22612440 else if (rq->target == xa_targets)
22622441 {
2263- Atom target_list[2];
2442+ Atom target_list[4];
22642443 target_list[0] = XA_STRING;
2265- target_list[1] = xa_targets;
2444+ target_list[1] = xa_text;
2445+ target_list[2] = xa_compound_text;
2446+ target_list[3] = xa_targets;
22662447 XChangeProperty(DPY, rq->requestor, rq->property, rq->target,
22672448 (8 * sizeof(target_list[0])), PropModeReplace,
22682449 (unsigned char *)target_list,
@@ -2283,76 +2464,6 @@ static void paste_x11_send(XSelectionRequestEvent *rq)
22832464 XSendEvent(DPY, rq->requestor, FALSE, NoEventMask, &event);
22842465 }
22852466
2286-/*
2287- * Add the contents of the PRIMARY buffer to the input queue.
2288- *
2289- * Hack - This doesn't use the "time" of the event, and so accepts anything a
2290- * client tries to send it.
2291- */
2292-static void paste_x11_accept(const XSelectionEvent *ptr)
2293-{
2294- unsigned long offset, left;
2295-
2296- /* Failure. */
2297- if (ptr->property == None)
2298- {
2299- /* bell("Paste failure (remote client could not send)."); */
2300- return;
2301- }
2302-
2303- if (ptr->selection != XA_PRIMARY)
2304- {
2305- /* bell("Paste failure (remote client did not send primary selection)."); */
2306- return;
2307- }
2308-
2309- if (ptr->target != XA_STRING)
2310- {
2311- /* bell("Paste failure (selection in unknown format)."); */
2312- return;
2313- }
2314-
2315- for (offset = 0; ; offset += left)
2316- {
2317- errr err;
2318-
2319- /* A pointer for the pasted information. */
2320- unsigned char *data;
2321-
2322- Atom type;
2323- int fmt;
2324- unsigned long nitems;
2325-
2326- /* Set data to the string, and catch errors. */
2327- if (XGetWindowProperty(Metadpy->dpy, Infowin->win, XA_STRING, offset,
2328- 32767, TRUE, XA_STRING, &type, &fmt, &nitems, &left, &data)
2329- != Success) break;
2330-
2331- /* Paste the text. */
2332- err = type_string((char*)data, nitems);
2333-
2334- /* Free the data pasted. */
2335- XFree(data);
2336-
2337- /* No room. */
2338- if (err == PARSE_ERROR_OUT_OF_MEMORY)
2339- {
2340- /* bell("Paste failure (too much text selected)."); */
2341- break;
2342- }
2343- /* Paranoia? - strange errors. */
2344- else if (err)
2345- {
2346- break;
2347- }
2348-
2349- /* Pasted everything. */
2350- if (!left) return;
2351- }
2352-
2353- /* An error has occurred, so free the last bit of data before returning. */
2354- XFree(data);
2355-}
23562467
23572468 /*
23582469 * Handle various events conditional on presses of a mouse button.
@@ -2365,7 +2476,7 @@ static void handle_button(Time time, int x, int y, int button,
23652476
23662477 if (press && button == 1) copy_x11_start(x, y);
23672478 if (!press && button == 1) copy_x11_end(time);
2368- if (!press && button == 2) paste_x11_request(time);
2479+ if (!press && button == 2) paste_x11_request(xa_compound_text, time);
23692480 }
23702481
23712482
Show on old repository browser