Mercurial > vim
annotate src/if_xcmdsrv.c @ 33591:288da62613ba v9.0.2040
patch 9.0.2040: trim(): hard to use default mask
Commit: https://github.com/vim/vim/commit/6e6386716f9494ae86027c6d34f657fd03dfec42
Author: Illia Bobyr <illia.bobyr@gmail.com>
Date: Tue Oct 17 11:09:45 2023 +0200
patch 9.0.2040: trim(): hard to use default mask
Problem: trim(): hard to use default mask
Solution: Use default 'mask' when it is v:none
The default 'mask' value is pretty complex, as it includes many
characters. Yet, if one needs to specify the trimming direction, the
third argument, 'trim()' currently requires the 'mask' value to be
provided explicitly.
'v:none' is already used to mean "use the default argument value" in
user defined functions. See |none-function_argument| in help.
closes: #13363
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Illia Bobyr <illia.bobyr@gmail.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 17 Oct 2023 11:15:09 +0200 |
parents | 27c9212d10aa |
children | 1629cc65d78d |
rev | line source |
---|---|
10042
4aead6a9b7a9
commit https://github.com/vim/vim/commit/edf3f97ae2af024708ebb4ac614227327033ca47
Christian Brabandt <cb@256bit.org>
parents:
8732
diff
changeset
|
1 /* vi:set ts=8 sts=4 sw=4 noet: |
7 | 2 * |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * X command server by Flemming Madsen | |
5 * | |
6 * Do ":help uganda" in Vim to read copying and usage conditions. | |
7 * Do ":help credits" in Vim to see a list of people who contributed. | |
8 * See README.txt for an overview of the Vim source code. | |
9 * | |
10 * if_xcmdsrv.c: Functions for passing commands through an X11 display. | |
11 * | |
12 */ | |
13 | |
14 #include "vim.h" | |
15 #include "version.h" | |
16 | |
17 #if defined(FEAT_CLIENTSERVER) || defined(PROTO) | |
18 | |
19 # ifdef FEAT_X11 | |
20 # include <X11/Intrinsic.h> | |
21 # include <X11/Xatom.h> | |
22 # endif | |
23 | |
24 /* | |
1121 | 25 * This file provides procedures that implement the command server |
26 * functionality of Vim when in contact with an X11 server. | |
7 | 27 * |
28 * Adapted from TCL/TK's send command in tkSend.c of the tk 3.6 distribution. | |
29 * Adapted for use in Vim by Flemming Madsen. Protocol changed to that of tk 4 | |
30 */ | |
31 | |
32 /* | |
33 * Copyright (c) 1989-1993 The Regents of the University of California. | |
34 * All rights reserved. | |
35 * | |
36 * Permission is hereby granted, without written agreement and without | |
37 * license or royalty fees, to use, copy, modify, and distribute this | |
38 * software and its documentation for any purpose, provided that the | |
39 * above copyright notice and the following two paragraphs appear in | |
40 * all copies of this software. | |
41 * | |
42 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR | |
43 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT | |
44 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF | |
45 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
46 * | |
47 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, | |
48 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | |
49 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | |
50 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO | |
51 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
52 */ | |
53 | |
54 | |
55 /* | |
56 * When a result is being awaited from a sent command, one of | |
57 * the following structures is present on a list of all outstanding | |
58 * sent commands. The information in the structure is used to | |
59 * process the result when it arrives. You're probably wondering | |
60 * how there could ever be multiple outstanding sent commands. | |
61 * This could happen if Vim instances invoke each other recursively. | |
62 * It's unlikely, but possible. | |
63 */ | |
64 | |
65 typedef struct PendingCommand | |
66 { | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
67 int serial; // Serial number expected in result. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
68 int code; // Result Code. 0 is OK |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
69 char_u *result; // String result for command (malloc'ed). |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
70 // NULL means command still pending. |
7 | 71 struct PendingCommand *nextPtr; |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
72 // Next in list of all outstanding commands. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
73 // NULL means end of list. |
7 | 74 } PendingCommand; |
75 | |
76 static PendingCommand *pendingCommands = NULL; | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
77 // List of all commands currently |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
78 // being waited for. |
7 | 79 |
80 /* | |
81 * The information below is used for communication between processes | |
82 * during "send" commands. Each process keeps a private window, never | |
83 * even mapped, with one property, "Comm". When a command is sent to | |
84 * an interpreter, the command is appended to the comm property of the | |
85 * communication window associated with the interp's process. Similarly, | |
86 * when a result is returned from a sent command, it is also appended | |
87 * to the comm property. | |
88 * | |
89 * Each command and each result takes the form of ASCII text. For a | |
90 * command, the text consists of a nul character followed by several | |
39 | 91 * nul-terminated ASCII strings. The first string consists of a |
92 * single letter: | |
93 * "c" for an expression | |
94 * "k" for keystrokes | |
95 * "r" for reply | |
96 * "n" for notification. | |
97 * Subsequent strings have the form "option value" where the following options | |
98 * are supported: | |
7 | 99 * |
100 * -r commWindow serial | |
101 * | |
102 * This option means that a response should be sent to the window | |
103 * whose X identifier is "commWindow" (in hex), and the response should | |
104 * be identified with the serial number given by "serial" (in decimal). | |
105 * If this option isn't specified then the send is asynchronous and | |
106 * no response is sent. | |
107 * | |
108 * -n name | |
109 * "Name" gives the name of the application for which the command is | |
110 * intended. This option must be present. | |
111 * | |
39 | 112 * -E encoding |
113 * Encoding name used for the text. This is the 'encoding' of the | |
114 * sender. The receiver may want to do conversion to his 'encoding'. | |
115 * | |
7 | 116 * -s script |
117 * "Script" is the script to be executed. This option must be | |
118 * present. Taken as a series of keystrokes in a "k" command where | |
119 * <Key>'s are expanded | |
120 * | |
121 * The options may appear in any order. The -n and -s options must be | |
122 * present, but -r may be omitted for asynchronous RPCs. For compatibility | |
123 * with future releases that may add new features, there may be additional | |
124 * options present; as long as they start with a "-" character, they will | |
125 * be ignored. | |
126 * | |
127 * A result also consists of a zero character followed by several null- | |
128 * terminated ASCII strings. The first string consists of the single | |
129 * letter "r". Subsequent strings have the form "option value" where | |
130 * the following options are supported: | |
131 * | |
132 * -s serial | |
133 * Identifies the command for which this is the result. It is the | |
134 * same as the "serial" field from the -s option in the command. This | |
135 * option must be present. | |
136 * | |
137 * -r result | |
138 * "Result" is the result string for the script, which may be either | |
139 * a result or an error message. If this field is omitted then it | |
140 * defaults to an empty string. | |
141 * | |
142 * -c code | |
143 * 0: for OK. This is the default. | |
144 * 1: for error: Result is the last error | |
145 * | |
146 * -i errorInfo | |
147 * -e errorCode | |
148 * Not applicable for Vim | |
149 * | |
150 * Options may appear in any order, and only the -s option must be | |
151 * present. As with commands, there may be additional options besides | |
152 * these; unknown options are ignored. | |
153 */ | |
154 | |
155 /* | |
156 * Maximum size property that can be read at one time by | |
157 * this module: | |
158 */ | |
159 | |
160 #define MAX_PROP_WORDS 100000 | |
161 | |
162 struct ServerReply | |
163 { | |
164 Window id; | |
165 garray_T strings; | |
166 }; | |
167 static garray_T serverReply = { 0, 0, 0, 0, 0 }; | |
168 enum ServerReplyOp { SROP_Find, SROP_Add, SROP_Delete }; | |
169 | |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
170 typedef int (*EndCond)(void *); |
7 | 171 |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
172 struct x_cmdqueue |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
173 { |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
174 char_u *propInfo; |
7123
077ae8b63e15
commit https://github.com/vim/vim/commit/b8603882b1679385b287f14c527fa61eee60a9dd
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
175 long_u len; |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
176 struct x_cmdqueue *next; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
177 struct x_cmdqueue *prev; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
178 }; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
179 |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
180 typedef struct x_cmdqueue x_queue_T; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
181 |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
182 // dummy node, header for circular queue |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
183 static x_queue_T head = {NULL, 0, NULL, NULL}; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
184 |
7 | 185 /* |
186 * Forward declarations for procedures defined later in this file: | |
187 */ | |
188 | |
7803
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
189 static Window LookupName(Display *dpy, char_u *name, int delete, char_u **loose); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
190 static int SendInit(Display *dpy); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
191 static int DoRegisterName(Display *dpy, char_u *name); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
192 static void DeleteAnyLingerer(Display *dpy, Window w); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
193 static int GetRegProp(Display *dpy, char_u **regPropp, long_u *numItemsp, int domsg); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
194 static int WaitForPend(void *p); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
195 static int WindowValid(Display *dpy, Window w); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
196 static void ServerWait(Display *dpy, Window w, EndCond endCond, void *endData, int localLoop, int seconds); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
197 static int AppendPropCarefully(Display *display, Window window, Atom property, char_u *value, int length); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
198 static int x_error_check(Display *dpy, XErrorEvent *error_event); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
199 static int IsSerialName(char_u *name); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
200 static void save_in_queue(char_u *buf, long_u len); |
37c929c4a073
commit https://github.com/vim/vim/commit/92b8b2d307e34117f146319872010b0ccc9d2713
Christian Brabandt <cb@256bit.org>
parents:
7172
diff
changeset
|
201 static void server_parse_message(Display *dpy, char_u *propInfo, long_u numItems); |
7 | 202 |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
203 // Private variables for the "server" functionality |
7 | 204 static Atom registryProperty = None; |
205 static Atom vimProperty = None; | |
206 static int got_x_error = FALSE; | |
207 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
208 static char_u *empty_prop = (char_u *)""; // empty GetRegProp() result |
7 | 209 |
210 /* | |
211 * Associate an ASCII name with Vim. Try real hard to get a unique one. | |
212 * Returns FAIL or OK. | |
213 */ | |
214 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
215 serverRegisterName( |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
216 Display *dpy, // display to register with |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
217 char_u *name) // the name that will be used as a base |
7 | 218 { |
219 int i; | |
220 int res; | |
221 char_u *p = NULL; | |
222 | |
223 res = DoRegisterName(dpy, name); | |
31702
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
224 if (res >= 0) |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
225 return OK; |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
226 |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
227 i = 1; |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
228 do |
7 | 229 { |
31702
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
230 if (res < -1 || i >= 1000) |
7 | 231 { |
31702
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
232 msg_attr(_("Unable to register a command server name"), |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
233 HL_ATTR(HLF_W)); |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
234 return FAIL; |
7 | 235 } |
31702
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
236 if (p == NULL) |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
237 p = alloc(STRLEN(name) + 10); |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
238 if (p == NULL) |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
239 { |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
240 res = -10; |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
241 continue; |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
242 } |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
243 sprintf((char *)p, "%s%d", name, i++); |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
244 res = DoRegisterName(dpy, p); |
7 | 245 } |
31702
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
246 while (res < 0) |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
247 ; |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
248 vim_free(p); |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
249 |
7 | 250 return OK; |
251 } | |
252 | |
253 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
254 DoRegisterName(Display *dpy, char_u *name) |
7 | 255 { |
256 Window w; | |
257 XErrorHandler old_handler; | |
258 #define MAX_NAME_LENGTH 100 | |
259 char_u propInfo[MAX_NAME_LENGTH + 20]; | |
260 | |
261 if (commProperty == None) | |
262 { | |
263 if (SendInit(dpy) < 0) | |
264 return -2; | |
265 } | |
266 | |
267 /* | |
268 * Make sure the name is unique, and append info about it to | |
269 * the registry property. It's important to lock the server | |
270 * here to prevent conflicting changes to the registry property. | |
271 * WARNING: Do not step through this while debugging, it will hangup the X | |
272 * server! | |
273 */ | |
274 XGrabServer(dpy); | |
275 w = LookupName(dpy, name, FALSE, NULL); | |
276 if (w != (Window)0) | |
277 { | |
278 Status status; | |
279 int dummyInt; | |
280 unsigned int dummyUns; | |
281 Window dummyWin; | |
282 | |
283 /* | |
284 * The name is currently registered. See if the commWindow | |
285 * associated with the name exists. If not, or if the commWindow | |
286 * is *our* commWindow, then just unregister the old name (this | |
287 * could happen if an application dies without cleaning up the | |
288 * registry). | |
289 */ | |
290 old_handler = XSetErrorHandler(x_error_check); | |
291 status = XGetGeometry(dpy, w, &dummyWin, &dummyInt, &dummyInt, | |
292 &dummyUns, &dummyUns, &dummyUns, &dummyUns); | |
293 (void)XSetErrorHandler(old_handler); | |
294 if (status != Success && w != commWindow) | |
295 { | |
296 XUngrabServer(dpy); | |
297 XFlush(dpy); | |
298 return -1; | |
299 } | |
300 (void)LookupName(dpy, name, /*delete=*/TRUE, NULL); | |
301 } | |
302 sprintf((char *)propInfo, "%x %.*s", (int_u)commWindow, | |
303 MAX_NAME_LENGTH, name); | |
304 old_handler = XSetErrorHandler(x_error_check); | |
305 got_x_error = FALSE; | |
306 XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING, 8, | |
307 PropModeAppend, propInfo, STRLEN(propInfo) + 1); | |
308 XUngrabServer(dpy); | |
309 XSync(dpy, False); | |
310 (void)XSetErrorHandler(old_handler); | |
311 | |
312 if (!got_x_error) | |
313 { | |
314 #ifdef FEAT_EVAL | |
315 set_vim_var_string(VV_SEND_SERVER, name, -1); | |
316 #endif | |
317 serverName = vim_strsave(name); | |
318 need_maketitle = TRUE; | |
319 return 0; | |
320 } | |
321 return -2; | |
322 } | |
323 | |
324 #if defined(FEAT_GUI) || defined(PROTO) | |
325 /* | |
326 * Clean out new ID from registry and set it as comm win. | |
327 * Change any registered window ID. | |
328 */ | |
329 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
330 serverChangeRegisteredWindow( |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
331 Display *dpy, // Display to register with |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
332 Window newwin) // Re-register to this ID |
7 | 333 { |
334 char_u propInfo[MAX_NAME_LENGTH + 20]; | |
335 | |
336 commWindow = newwin; | |
337 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
338 // Always call SendInit() here, to make sure commWindow is marked as a Vim |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
339 // window. |
7 | 340 if (SendInit(dpy) < 0) |
341 return; | |
342 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
343 // WARNING: Do not step through this while debugging, it will hangup the X |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
344 // server! |
7 | 345 XGrabServer(dpy); |
346 DeleteAnyLingerer(dpy, newwin); | |
347 if (serverName != NULL) | |
348 { | |
26771
fc859aea8cec
patch 8.2.3914: various spelling mistakes in comments
Bram Moolenaar <Bram@vim.org>
parents:
26336
diff
changeset
|
349 // Reinsert name if it was already registered |
7 | 350 (void)LookupName(dpy, serverName, /*delete=*/TRUE, NULL); |
351 sprintf((char *)propInfo, "%x %.*s", | |
352 (int_u)newwin, MAX_NAME_LENGTH, serverName); | |
353 XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING, 8, | |
354 PropModeAppend, (char_u *)propInfo, | |
355 STRLEN(propInfo) + 1); | |
356 } | |
357 XUngrabServer(dpy); | |
358 } | |
359 #endif | |
360 | |
361 /* | |
362 * Send to an instance of Vim via the X display. | |
363 * Returns 0 for OK, negative for an error. | |
364 */ | |
365 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
366 serverSendToVim( |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
367 Display *dpy, // Where to send. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
368 char_u *name, // Where to send. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
369 char_u *cmd, // What to send. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
370 char_u **result, // Result of eval'ed expression |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
371 Window *server, // Actual ID of receiving app |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
372 Bool asExpr, // Interpret as keystrokes or expr ? |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
373 int timeout, // seconds to wait or zero |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
374 Bool localLoop, // Throw away everything but result |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
375 int silent) // don't complain about no server |
7 | 376 { |
377 Window w; | |
378 char_u *property; | |
379 int length; | |
380 int res; | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
381 static int serial = 0; // Running count of sent commands. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
382 // Used to give each command a |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
383 // different serial number. |
7 | 384 PendingCommand pending; |
385 char_u *loosename = NULL; | |
386 | |
387 if (result != NULL) | |
388 *result = NULL; | |
389 if (name == NULL || *name == NUL) | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
390 name = (char_u *)"GVIM"; // use a default name |
7 | 391 |
31287
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
392 if (commProperty == None && dpy != NULL && SendInit(dpy) < 0) |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
393 return -1; |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
394 |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
395 #if defined(FEAT_EVAL) |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
396 ch_log(NULL, "serverSendToVim(%s, %s)", name, cmd); |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
397 #endif |
7 | 398 |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
399 // Execute locally if no display or target is ourselves |
7 | 400 if (dpy == NULL || (serverName != NULL && STRICMP(name, serverName) == 0)) |
11177
76fb679a310e
patch 8.0.0475: not enough testing for the client-server feature
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
401 return sendToLocalVim(cmd, asExpr, result); |
7 | 402 |
403 /* | |
404 * Bind the server name to a communication window. | |
405 * | |
406 * Find any survivor with a serialno attached to the name if the | |
407 * original registrant of the wanted name is no longer present. | |
408 * | |
409 * Delete any lingering names from dead editors. | |
410 */ | |
411 while (TRUE) | |
412 { | |
413 w = LookupName(dpy, name, FALSE, &loosename); | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
414 // Check that the window is hot |
7 | 415 if (w != None) |
416 { | |
417 if (!WindowValid(dpy, w)) | |
418 { | |
419 LookupName(dpy, loosename ? loosename : name, | |
420 /*DELETE=*/TRUE, NULL); | |
12399
de1ae9d8ef57
patch 8.0.1079: memory leak when remote_foreground() fails
Christian Brabandt <cb@256bit.org>
parents:
11211
diff
changeset
|
421 vim_free(loosename); |
7 | 422 continue; |
423 } | |
424 } | |
425 break; | |
426 } | |
427 if (w == None) | |
428 { | |
429 if (!silent) | |
26877
06a137af96f8
patch 8.2.3967: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26771
diff
changeset
|
430 semsg(_(e_no_registered_server_named_str), name); |
7 | 431 return -1; |
432 } | |
433 else if (loosename != NULL) | |
434 name = loosename; | |
435 if (server != NULL) | |
436 *server = w; | |
437 | |
438 /* | |
439 * Send the command to target interpreter by appending it to the | |
440 * comm window in the communication window. | |
500 | 441 * Length must be computed exactly! |
7 | 442 */ |
500 | 443 length = STRLEN(name) + STRLEN(p_enc) + STRLEN(cmd) + 14; |
16825
ce04ebdf26b8
patch 8.1.1414: alloc() returning "char_u *" causes a lot of type casts
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
444 property = alloc(length + 30); |
7 | 445 |
39 | 446 sprintf((char *)property, "%c%c%c-n %s%c-E %s%c-s %s", |
447 0, asExpr ? 'c' : 'k', 0, name, 0, p_enc, 0, cmd); | |
7 | 448 if (name == loosename) |
449 vim_free(loosename); | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
450 // Add a back reference to our comm window |
7 | 451 serial++; |
452 sprintf((char *)property + length, "%c-r %x %d", | |
453 0, (int_u)commWindow, serial); | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
454 // Add length of what "-r %x %d" resulted in, skipping the NUL. |
7 | 455 length += STRLEN(property + length + 1) + 1; |
456 | |
457 res = AppendPropCarefully(dpy, w, commProperty, property, length + 1); | |
458 vim_free(property); | |
459 if (res < 0) | |
460 { | |
26893
79c76ca2c53c
patch 8.2.3975: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26883
diff
changeset
|
461 emsg(_(e_failed_to_send_command_to_destination_program)); |
7 | 462 return -1; |
463 } | |
464 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
465 if (!asExpr) // There is no answer for this - Keys are sent async |
7 | 466 return 0; |
467 | |
468 /* | |
469 * Register the fact that we're waiting for a command to | |
470 * complete (this is needed by SendEventProc and by | |
471 * AppendErrorProc to pass back the command's results). | |
472 */ | |
473 pending.serial = serial; | |
474 pending.code = 0; | |
475 pending.result = NULL; | |
476 pending.nextPtr = pendingCommands; | |
477 pendingCommands = &pending; | |
478 | |
11211
71311d899b42
patch 8.0.0492: a failing client-server request can make Vim hang
Christian Brabandt <cb@256bit.org>
parents:
11181
diff
changeset
|
479 ServerWait(dpy, w, WaitForPend, &pending, localLoop, |
71311d899b42
patch 8.0.0492: a failing client-server request can make Vim hang
Christian Brabandt <cb@256bit.org>
parents:
11181
diff
changeset
|
480 timeout > 0 ? timeout : 600); |
7 | 481 |
482 /* | |
483 * Unregister the information about the pending command | |
484 * and return the result. | |
485 */ | |
486 if (pendingCommands == &pending) | |
487 pendingCommands = pending.nextPtr; | |
488 else | |
489 { | |
490 PendingCommand *pcPtr; | |
491 | |
492 for (pcPtr = pendingCommands; pcPtr != NULL; pcPtr = pcPtr->nextPtr) | |
493 if (pcPtr->nextPtr == &pending) | |
494 { | |
495 pcPtr->nextPtr = pending.nextPtr; | |
496 break; | |
497 } | |
498 } | |
31287
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
499 |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
500 #if defined(FEAT_EVAL) |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
501 ch_log(NULL, "serverSendToVim() result: %s", |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
502 pending.result == NULL ? "NULL" : (char *)pending.result); |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
503 #endif |
7 | 504 if (result != NULL) |
505 *result = pending.result; | |
506 else | |
507 vim_free(pending.result); | |
508 | |
509 return pending.code == 0 ? 0 : -1; | |
510 } | |
511 | |
512 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
513 WaitForPend(void *p) |
7 | 514 { |
515 PendingCommand *pending = (PendingCommand *) p; | |
516 return pending->result != NULL; | |
517 } | |
518 | |
519 /* | |
520 * Return TRUE if window "w" exists and has a "Vim" property on it. | |
521 */ | |
522 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
523 WindowValid(Display *dpy, Window w) |
7 | 524 { |
525 XErrorHandler old_handler; | |
526 Atom *plist; | |
527 int numProp; | |
528 int i; | |
529 | |
530 old_handler = XSetErrorHandler(x_error_check); | |
531 got_x_error = 0; | |
532 plist = XListProperties(dpy, w, &numProp); | |
533 XSync(dpy, False); | |
534 XSetErrorHandler(old_handler); | |
535 if (plist == NULL || got_x_error) | |
536 return FALSE; | |
537 | |
538 for (i = 0; i < numProp; i++) | |
539 if (plist[i] == vimProperty) | |
540 { | |
541 XFree(plist); | |
542 return TRUE; | |
543 } | |
544 XFree(plist); | |
545 return FALSE; | |
546 } | |
547 | |
548 /* | |
549 * Enter a loop processing X events & polling chars until we see a result | |
550 */ | |
551 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
552 ServerWait( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
553 Display *dpy, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
554 Window w, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
555 EndCond endCond, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
556 void *endData, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
557 int localLoop, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
558 int seconds) |
7 | 559 { |
560 time_t start; | |
561 time_t now; | |
562 XEvent event; | |
3670 | 563 |
18642
bbea1f108187
patch 8.1.2313: debugging where a delay comes from is not easy
Bram Moolenaar <Bram@vim.org>
parents:
16825
diff
changeset
|
564 #define UI_MSEC_DELAY 53 |
3670 | 565 #define SEND_MSEC_POLL 500 |
28142
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
566 #ifdef HAVE_SELECT |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
567 fd_set fds; |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
568 |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
569 FD_ZERO(&fds); |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
570 FD_SET(ConnectionNumber(dpy), &fds); |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
571 #else |
3670 | 572 struct pollfd fds; |
573 | |
574 fds.fd = ConnectionNumber(dpy); | |
575 fds.events = POLLIN; | |
576 #endif | |
7 | 577 |
578 time(&start); | |
3670 | 579 while (TRUE) |
7 | 580 { |
3670 | 581 while (XCheckWindowEvent(dpy, commWindow, PropertyChangeMask, &event)) |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
582 serverEventProc(dpy, &event, 1); |
8732
29765df3a866
commit https://github.com/vim/vim/commit/1e7885abe8daa793fd9328d0fd6c456214cb467e
Christian Brabandt <cb@256bit.org>
parents:
7823
diff
changeset
|
583 server_parse_messages(); |
3670 | 584 |
585 if (endCond(endData) != 0) | |
586 break; | |
587 if (!WindowValid(dpy, w)) | |
588 break; | |
7 | 589 time(&now); |
590 if (seconds >= 0 && (now - start) >= seconds) | |
591 break; | |
3670 | 592 |
11181
13544aa85dc0
patch 8.0.0477: the client-server test may hang when failing
Christian Brabandt <cb@256bit.org>
parents:
11177
diff
changeset
|
593 #ifdef FEAT_TIMERS |
13544aa85dc0
patch 8.0.0477: the client-server test may hang when failing
Christian Brabandt <cb@256bit.org>
parents:
11177
diff
changeset
|
594 check_due_timer(); |
13544aa85dc0
patch 8.0.0477: the client-server test may hang when failing
Christian Brabandt <cb@256bit.org>
parents:
11177
diff
changeset
|
595 #endif |
13544aa85dc0
patch 8.0.0477: the client-server test may hang when failing
Christian Brabandt <cb@256bit.org>
parents:
11177
diff
changeset
|
596 |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
597 // Just look out for the answer without calling back into Vim |
7 | 598 if (localLoop) |
599 { | |
28142
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
600 #ifdef HAVE_SELECT |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
601 struct timeval tv; |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
602 |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
603 // Set the time every call, select() may change it to the remaining |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
604 // time. |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
605 tv.tv_sec = 0; |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
606 tv.tv_usec = SEND_MSEC_POLL * 1000; |
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
607 if (select(FD_SETSIZE, &fds, NULL, NULL, &tv) < 0) |
7 | 608 break; |
609 #else | |
28142
7dec326adb36
patch 8.2.4595: X11: using --remote-wait may keep the CPU busy
Bram Moolenaar <Bram@vim.org>
parents:
26917
diff
changeset
|
610 if (poll(&fds, 1, SEND_MSEC_POLL) < 0) |
7 | 611 break; |
612 #endif | |
613 } | |
614 else | |
615 { | |
616 if (got_int) | |
617 break; | |
3670 | 618 ui_delay((long)UI_MSEC_DELAY, TRUE); |
7 | 619 ui_breakcheck(); |
620 } | |
621 } | |
622 } | |
623 | |
624 | |
625 /* | |
626 * Fetch a list of all the Vim instance names currently registered for the | |
627 * display. | |
628 * | |
629 * Returns a newline separated list in allocated memory or NULL. | |
630 */ | |
631 char_u * | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
632 serverGetVimNames(Display *dpy) |
7 | 633 { |
634 char_u *regProp; | |
635 char_u *entry; | |
636 char_u *p; | |
637 long_u numItems; | |
638 int_u w; | |
639 garray_T ga; | |
640 | |
641 if (registryProperty == None) | |
642 { | |
643 if (SendInit(dpy) < 0) | |
644 return NULL; | |
645 } | |
646 | |
647 /* | |
648 * Read the registry property. | |
649 */ | |
650 if (GetRegProp(dpy, ®Prop, &numItems, TRUE) == FAIL) | |
651 return NULL; | |
652 | |
653 /* | |
654 * Scan all of the names out of the property. | |
655 */ | |
656 ga_init2(&ga, 1, 100); | |
1880 | 657 for (p = regProp; (long_u)(p - regProp) < numItems; p++) |
7 | 658 { |
659 entry = p; | |
660 while (*p != 0 && !isspace(*p)) | |
661 p++; | |
662 if (*p != 0) | |
663 { | |
664 w = None; | |
665 sscanf((char *)entry, "%x", &w); | |
666 if (WindowValid(dpy, (Window)w)) | |
667 { | |
668 ga_concat(&ga, p + 1); | |
669 ga_concat(&ga, (char_u *)"\n"); | |
670 } | |
671 while (*p != 0) | |
672 p++; | |
673 } | |
674 } | |
675 if (regProp != empty_prop) | |
676 XFree(regProp); | |
21 | 677 ga_append(&ga, NUL); |
7 | 678 return ga.ga_data; |
679 } | |
680 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
681 ///////////////////////////////////////////////////////////// |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
682 // Reply stuff |
7 | 683 |
684 static struct ServerReply * | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
685 ServerReplyFind(Window w, enum ServerReplyOp op) |
7 | 686 { |
687 struct ServerReply *p; | |
688 struct ServerReply e; | |
689 int i; | |
690 | |
691 p = (struct ServerReply *) serverReply.ga_data; | |
692 for (i = 0; i < serverReply.ga_len; i++, p++) | |
693 if (p->id == w) | |
694 break; | |
695 if (i >= serverReply.ga_len) | |
696 p = NULL; | |
697 | |
698 if (p == NULL && op == SROP_Add) | |
699 { | |
700 if (serverReply.ga_growsize == 0) | |
701 ga_init2(&serverReply, sizeof(struct ServerReply), 1); | |
702 if (ga_grow(&serverReply, 1) == OK) | |
703 { | |
704 p = ((struct ServerReply *) serverReply.ga_data) | |
705 + serverReply.ga_len; | |
706 e.id = w; | |
707 ga_init2(&e.strings, 1, 100); | |
1740 | 708 mch_memmove(p, &e, sizeof(e)); |
7 | 709 serverReply.ga_len++; |
710 } | |
711 } | |
712 else if (p != NULL && op == SROP_Delete) | |
713 { | |
714 ga_clear(&p->strings); | |
715 mch_memmove(p, p + 1, (serverReply.ga_len - i - 1) * sizeof(*p)); | |
716 serverReply.ga_len--; | |
717 } | |
718 | |
719 return p; | |
720 } | |
721 | |
722 /* | |
723 * Convert string to windowid. | |
724 * Issue an error if the id is invalid. | |
725 */ | |
726 Window | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
727 serverStrToWin(char_u *str) |
7 | 728 { |
729 unsigned id = None; | |
730 | |
731 sscanf((char *)str, "0x%x", &id); | |
732 if (id == None) | |
26917
d91aea2a612c
patch 8.2.3987: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26893
diff
changeset
|
733 semsg(_(e_invalid_server_id_used_str), str); |
7 | 734 |
735 return (Window)id; | |
736 } | |
737 | |
738 /* | |
39 | 739 * Send a reply string (notification) to client with id "name". |
7 | 740 * Return -1 if the window is invalid. |
741 */ | |
742 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
743 serverSendReply(char_u *name, char_u *str) |
7 | 744 { |
745 char_u *property; | |
746 int length; | |
747 int res; | |
748 Display *dpy = X_DISPLAY; | |
749 Window win = serverStrToWin(name); | |
750 | |
751 if (commProperty == None) | |
752 { | |
753 if (SendInit(dpy) < 0) | |
754 return -2; | |
755 } | |
756 if (!WindowValid(dpy, win)) | |
757 return -1; | |
758 | |
500 | 759 length = STRLEN(p_enc) + STRLEN(str) + 14; |
31702
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
760 if ((property = alloc(length + 30)) == NULL) |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
761 return -1; |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
762 |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
763 sprintf((char *)property, "%cn%c-E %s%c-n %s%c-w %x", |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
764 0, 0, p_enc, 0, str, 0, (unsigned int)commWindow); |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
765 // Add length of what "%x" resulted in. |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
766 length += STRLEN(property + length); |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
767 res = AppendPropCarefully(dpy, win, commProperty, property, length + 1); |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
768 vim_free(property); |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
769 |
27c9212d10aa
patch 9.0.1183: code is indented more than necessary
Bram Moolenaar <Bram@vim.org>
parents:
31287
diff
changeset
|
770 return res; |
7 | 771 } |
772 | |
773 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
774 WaitForReply(void *p) |
7 | 775 { |
776 Window *w = (Window *) p; | |
11177
76fb679a310e
patch 8.0.0475: not enough testing for the client-server feature
Christian Brabandt <cb@256bit.org>
parents:
11158
diff
changeset
|
777 |
7 | 778 return ServerReplyFind(*w, SROP_Find) != NULL; |
779 } | |
780 | |
781 /* | |
782 * Wait for replies from id (win) | |
11211
71311d899b42
patch 8.0.0492: a failing client-server request can make Vim hang
Christian Brabandt <cb@256bit.org>
parents:
11181
diff
changeset
|
783 * When "timeout" is non-zero wait up to this many seconds. |
30325
58fb880f3607
patch 9.0.0498: various small issues
Bram Moolenaar <Bram@vim.org>
parents:
28142
diff
changeset
|
784 * Return 0 and the allocated string in "*str" when a reply is available. |
7 | 785 * Return -1 if the window becomes invalid while waiting. |
786 */ | |
787 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
788 serverReadReply( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
789 Display *dpy, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
790 Window win, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
791 char_u **str, |
11211
71311d899b42
patch 8.0.0492: a failing client-server request can make Vim hang
Christian Brabandt <cb@256bit.org>
parents:
11181
diff
changeset
|
792 int localLoop, |
71311d899b42
patch 8.0.0492: a failing client-server request can make Vim hang
Christian Brabandt <cb@256bit.org>
parents:
11181
diff
changeset
|
793 int timeout) |
7 | 794 { |
795 int len; | |
796 char_u *s; | |
797 struct ServerReply *p; | |
798 | |
11211
71311d899b42
patch 8.0.0492: a failing client-server request can make Vim hang
Christian Brabandt <cb@256bit.org>
parents:
11181
diff
changeset
|
799 ServerWait(dpy, win, WaitForReply, &win, localLoop, |
71311d899b42
patch 8.0.0492: a failing client-server request can make Vim hang
Christian Brabandt <cb@256bit.org>
parents:
11181
diff
changeset
|
800 timeout > 0 ? timeout : -1); |
7 | 801 |
802 if ((p = ServerReplyFind(win, SROP_Find)) != NULL && p->strings.ga_len > 0) | |
803 { | |
804 *str = vim_strsave(p->strings.ga_data); | |
805 len = STRLEN(*str) + 1; | |
806 if (len < p->strings.ga_len) | |
807 { | |
808 s = (char_u *) p->strings.ga_data; | |
809 mch_memmove(s, s + len, p->strings.ga_len - len); | |
810 p->strings.ga_len -= len; | |
811 } | |
812 else | |
813 { | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
814 // Last string read. Remove from list |
7 | 815 ga_clear(&p->strings); |
816 ServerReplyFind(win, SROP_Delete); | |
817 } | |
818 return 0; | |
819 } | |
820 return -1; | |
821 } | |
822 | |
823 /* | |
824 * Check for replies from id (win). | |
825 * Return TRUE and a non-malloc'ed string if there is. Else return FALSE. | |
826 */ | |
827 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
828 serverPeekReply(Display *dpy, Window win, char_u **str) |
7 | 829 { |
830 struct ServerReply *p; | |
831 | |
832 if ((p = ServerReplyFind(win, SROP_Find)) != NULL && p->strings.ga_len > 0) | |
833 { | |
834 if (str != NULL) | |
835 *str = p->strings.ga_data; | |
836 return 1; | |
837 } | |
838 if (!WindowValid(dpy, win)) | |
839 return -1; | |
840 return 0; | |
841 } | |
842 | |
843 | |
844 /* | |
845 * Initialize the communication channels for sending commands and receiving | |
846 * results. | |
847 */ | |
848 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
849 SendInit(Display *dpy) |
7 | 850 { |
851 XErrorHandler old_handler; | |
852 | |
853 /* | |
854 * Create the window used for communication, and set up an | |
855 * event handler for it. | |
856 */ | |
857 old_handler = XSetErrorHandler(x_error_check); | |
858 got_x_error = FALSE; | |
859 | |
860 if (commProperty == None) | |
861 commProperty = XInternAtom(dpy, "Comm", False); | |
862 if (vimProperty == None) | |
863 vimProperty = XInternAtom(dpy, "Vim", False); | |
864 if (registryProperty == None) | |
865 registryProperty = XInternAtom(dpy, "VimRegistry", False); | |
866 | |
867 if (commWindow == None) | |
868 { | |
869 commWindow = XCreateSimpleWindow(dpy, XDefaultRootWindow(dpy), | |
870 getpid(), 0, 10, 10, 0, | |
871 WhitePixel(dpy, DefaultScreen(dpy)), | |
872 WhitePixel(dpy, DefaultScreen(dpy))); | |
873 XSelectInput(dpy, commWindow, PropertyChangeMask); | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
874 // WARNING: Do not step through this while debugging, it will hangup |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
875 // the X server! |
7 | 876 XGrabServer(dpy); |
877 DeleteAnyLingerer(dpy, commWindow); | |
878 XUngrabServer(dpy); | |
879 } | |
880 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
881 // Make window recognizable as a vim window |
7 | 882 XChangeProperty(dpy, commWindow, vimProperty, XA_STRING, |
883 8, PropModeReplace, (char_u *)VIM_VERSION_SHORT, | |
884 (int)STRLEN(VIM_VERSION_SHORT) + 1); | |
885 | |
886 XSync(dpy, False); | |
887 (void)XSetErrorHandler(old_handler); | |
888 | |
889 return got_x_error ? -1 : 0; | |
890 } | |
891 | |
892 /* | |
893 * Given a server name, see if the name exists in the registry for a | |
894 * particular display. | |
895 * | |
896 * If the given name is registered, return the ID of the window associated | |
897 * with the name. If the name isn't registered, then return 0. | |
898 * | |
899 * Side effects: | |
900 * If the registry property is improperly formed, then it is deleted. | |
901 * If "delete" is non-zero, then if the named server is found it is | |
902 * removed from the registry property. | |
903 */ | |
904 static Window | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
905 LookupName( |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
906 Display *dpy, // Display whose registry to check. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
907 char_u *name, // Name of a server. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
908 int delete, // If non-zero, delete info about name. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
909 char_u **loose) // Do another search matching -999 if not found |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
910 // Return result here if a match is found |
7 | 911 { |
912 char_u *regProp, *entry; | |
913 char_u *p; | |
914 long_u numItems; | |
915 int_u returnValue; | |
916 | |
917 /* | |
918 * Read the registry property. | |
919 */ | |
920 if (GetRegProp(dpy, ®Prop, &numItems, FALSE) == FAIL) | |
921 return 0; | |
922 | |
923 /* | |
924 * Scan the property for the desired name. | |
925 */ | |
926 returnValue = (int_u)None; | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
927 entry = NULL; // Not needed, but eliminates compiler warning. |
1880 | 928 for (p = regProp; (long_u)(p - regProp) < numItems; ) |
7 | 929 { |
930 entry = p; | |
931 while (*p != 0 && !isspace(*p)) | |
932 p++; | |
933 if (*p != 0 && STRICMP(name, p + 1) == 0) | |
934 { | |
935 sscanf((char *)entry, "%x", &returnValue); | |
936 break; | |
937 } | |
938 while (*p != 0) | |
939 p++; | |
940 p++; | |
941 } | |
942 | |
943 if (loose != NULL && returnValue == (int_u)None && !IsSerialName(name)) | |
944 { | |
1880 | 945 for (p = regProp; (long_u)(p - regProp) < numItems; ) |
7 | 946 { |
947 entry = p; | |
948 while (*p != 0 && !isspace(*p)) | |
949 p++; | |
950 if (*p != 0 && IsSerialName(p + 1) | |
951 && STRNICMP(name, p + 1, STRLEN(name)) == 0) | |
952 { | |
953 sscanf((char *)entry, "%x", &returnValue); | |
954 *loose = vim_strsave(p + 1); | |
955 break; | |
956 } | |
957 while (*p != 0) | |
958 p++; | |
959 p++; | |
960 } | |
961 } | |
962 | |
963 /* | |
964 * Delete the property, if that is desired (copy down the | |
965 * remainder of the registry property to overlay the deleted | |
966 * info, then rewrite the property). | |
967 */ | |
968 if (delete && returnValue != (int_u)None) | |
969 { | |
970 int count; | |
971 | |
972 while (*p != 0) | |
973 p++; | |
974 p++; | |
975 count = numItems - (p - regProp); | |
976 if (count > 0) | |
1740 | 977 mch_memmove(entry, p, count); |
7 | 978 XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING, |
979 8, PropModeReplace, regProp, | |
980 (int)(numItems - (p - entry))); | |
981 XSync(dpy, False); | |
982 } | |
983 | |
984 if (regProp != empty_prop) | |
985 XFree(regProp); | |
986 return (Window)returnValue; | |
987 } | |
988 | |
989 /* | |
1197 | 990 * Delete any lingering occurrence of window id. We promise that any |
991 * occurrence is not ours since it is not yet put into the registry (by us) | |
7 | 992 * |
993 * This is necessary in the following scenario: | |
994 * 1. There is an old windowid for an exit'ed vim in the registry | |
995 * 2. We get that id for our commWindow but only want to send, not register. | |
996 * 3. The window will mistakenly be regarded valid because of own commWindow | |
997 */ | |
998 static void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
999 DeleteAnyLingerer( |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1000 Display *dpy, // Display whose registry to check. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1001 Window win) // Window to remove |
7 | 1002 { |
1003 char_u *regProp, *entry = NULL; | |
1004 char_u *p; | |
1005 long_u numItems; | |
28 | 1006 int_u wwin; |
7 | 1007 |
1008 /* | |
1009 * Read the registry property. | |
1010 */ | |
1011 if (GetRegProp(dpy, ®Prop, &numItems, FALSE) == FAIL) | |
1012 return; | |
1013 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1014 // Scan the property for the window id. |
1880 | 1015 for (p = regProp; (long_u)(p - regProp) < numItems; ) |
7 | 1016 { |
1017 if (*p != 0) | |
1018 { | |
28 | 1019 sscanf((char *)p, "%x", &wwin); |
1020 if ((Window)wwin == win) | |
7 | 1021 { |
1022 int lastHalf; | |
1023 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1024 // Copy down the remainder to delete entry |
7 | 1025 entry = p; |
1026 while (*p != 0) | |
1027 p++; | |
1028 p++; | |
1029 lastHalf = numItems - (p - regProp); | |
1030 if (lastHalf > 0) | |
1740 | 1031 mch_memmove(entry, p, lastHalf); |
7 | 1032 numItems = (entry - regProp) + lastHalf; |
1033 p = entry; | |
1034 continue; | |
1035 } | |
1036 } | |
1037 while (*p != 0) | |
1038 p++; | |
1039 p++; | |
1040 } | |
1041 | |
1042 if (entry != NULL) | |
1043 { | |
1044 XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, | |
1045 XA_STRING, 8, PropModeReplace, regProp, | |
1046 (int)(p - regProp)); | |
1047 XSync(dpy, False); | |
1048 } | |
1049 | |
1050 if (regProp != empty_prop) | |
1051 XFree(regProp); | |
1052 } | |
1053 | |
1054 /* | |
1055 * Read the registry property. Delete it when it's formatted wrong. | |
1056 * Return the property in "regPropp". "empty_prop" is used when it doesn't | |
1057 * exist yet. | |
1058 * Return OK when successful. | |
1059 */ | |
1060 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1061 GetRegProp( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1062 Display *dpy, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1063 char_u **regPropp, |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1064 long_u *numItemsp, |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1065 int domsg) // When TRUE give error message. |
7 | 1066 { |
1067 int result, actualFormat; | |
1068 long_u bytesAfter; | |
1069 Atom actualType; | |
819 | 1070 XErrorHandler old_handler; |
7 | 1071 |
1072 *regPropp = NULL; | |
819 | 1073 old_handler = XSetErrorHandler(x_error_check); |
1074 got_x_error = FALSE; | |
1075 | |
7 | 1076 result = XGetWindowProperty(dpy, RootWindow(dpy, 0), registryProperty, 0L, |
1077 (long)MAX_PROP_WORDS, False, | |
1078 XA_STRING, &actualType, | |
1079 &actualFormat, numItemsp, &bytesAfter, | |
1080 regPropp); | |
1081 | |
819 | 1082 XSync(dpy, FALSE); |
1083 (void)XSetErrorHandler(old_handler); | |
1084 if (got_x_error) | |
1085 return FAIL; | |
1086 | |
7 | 1087 if (actualType == None) |
1088 { | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1089 // No prop yet. Logically equal to the empty list |
7 | 1090 *numItemsp = 0; |
1091 *regPropp = empty_prop; | |
1092 return OK; | |
1093 } | |
1094 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1095 // If the property is improperly formed, then delete it. |
7 | 1096 if (result != Success || actualFormat != 8 || actualType != XA_STRING) |
1097 { | |
1098 if (*regPropp != NULL) | |
1099 XFree(*regPropp); | |
1100 XDeleteProperty(dpy, RootWindow(dpy, 0), registryProperty); | |
1101 if (domsg) | |
26893
79c76ca2c53c
patch 8.2.3975: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents:
26883
diff
changeset
|
1102 emsg(_(e_vim_instance_registry_property_is_badly_formed_deleted)); |
7 | 1103 return FAIL; |
1104 } | |
1105 return OK; | |
1106 } | |
1107 | |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1108 |
7 | 1109 /* |
1197 | 1110 * This procedure is invoked by the various X event loops throughout Vims when |
7 | 1111 * a property changes on the communication window. This procedure reads the |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1112 * property and enqueues command requests and responses. If immediate is true, |
13353
8412df1479a3
patch 8.0.1550: various small problems in source files
Christian Brabandt <cb@256bit.org>
parents:
12399
diff
changeset
|
1113 * it runs the event immediately instead of enqueuing it. Immediate can cause |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1114 * unintended behavior and should only be used for code that blocks for a |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1115 * response. |
7 | 1116 */ |
1117 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1118 serverEventProc( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1119 Display *dpy, |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1120 XEvent *eventPtr, // Information about event. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1121 int immediate) // Run event immediately. Should mostly be 0. |
7 | 1122 { |
1123 char_u *propInfo; | |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1124 int result, actualFormat; |
7 | 1125 long_u numItems, bytesAfter; |
1126 Atom actualType; | |
1127 | |
1128 if (eventPtr != NULL) | |
1129 { | |
1130 if (eventPtr->xproperty.atom != commProperty | |
1131 || eventPtr->xproperty.state != PropertyNewValue) | |
1132 return; | |
1133 } | |
1134 | |
1135 /* | |
1136 * Read the comm property and delete it. | |
1137 */ | |
1138 propInfo = NULL; | |
1139 result = XGetWindowProperty(dpy, commWindow, commProperty, 0L, | |
1140 (long)MAX_PROP_WORDS, True, | |
1141 XA_STRING, &actualType, | |
1142 &actualFormat, &numItems, &bytesAfter, | |
1143 &propInfo); | |
1144 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1145 // If the property doesn't exist or is improperly formed then ignore it. |
7 | 1146 if (result != Success || actualType != XA_STRING || actualFormat != 8) |
1147 { | |
1148 if (propInfo != NULL) | |
1149 XFree(propInfo); | |
1150 return; | |
1151 } | |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1152 if (immediate) |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1153 server_parse_message(dpy, propInfo, numItems); |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1154 else |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1155 save_in_queue(propInfo, numItems); |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1156 } |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1157 |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1158 /* |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1159 * Saves x clientserver commands in a queue so that they can be called when |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1160 * vim is idle. |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1161 */ |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1162 static void |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1163 save_in_queue(char_u *propInfo, long_u len) |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1164 { |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1165 x_queue_T *node; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1166 |
16825
ce04ebdf26b8
patch 8.1.1414: alloc() returning "char_u *" causes a lot of type casts
Bram Moolenaar <Bram@vim.org>
parents:
16764
diff
changeset
|
1167 node = ALLOC_ONE(x_queue_T); |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1168 if (node == NULL) |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1169 return; // out of memory |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1170 node->propInfo = propInfo; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1171 node->len = len; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1172 |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1173 if (head.next == NULL) // initialize circular queue |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1174 { |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1175 head.next = &head; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1176 head.prev = &head; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1177 } |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1178 |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1179 // insert node at tail of queue |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1180 node->next = &head; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1181 node->prev = head.prev; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1182 head.prev->next = node; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1183 head.prev = node; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1184 } |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1185 |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1186 /* |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1187 * Parses queued clientserver messages. |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1188 */ |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1189 void |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1190 server_parse_messages(void) |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1191 { |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1192 x_queue_T *node; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1193 |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1194 if (!X_DISPLAY) |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1195 return; // cannot happen? |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1196 while (head.next != NULL && head.next != &head) |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1197 { |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1198 node = head.next; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1199 head.next = node->next; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1200 node->next->prev = node->prev; |
7172
ad57f5b5bd6c
commit https://github.com/vim/vim/commit/4e86150ec5b5158da92b28938ea55819dc890a14
Christian Brabandt <cb@256bit.org>
parents:
7123
diff
changeset
|
1201 server_parse_message(X_DISPLAY, node->propInfo, node->len); |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1202 vim_free(node); |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1203 } |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1204 } |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1205 |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1206 /* |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1207 * Returns a non-zero value if there are clientserver messages waiting |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1208 * int the queue. |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1209 */ |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1210 int |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1211 server_waiting(void) |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1212 { |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1213 return head.next != NULL && head.next != &head; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1214 } |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1215 |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1216 /* |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1217 * Prases a single clientserver message. A single message may contain multiple |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1218 * commands. |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1219 * "propInfo" will be freed. |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1220 */ |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1221 static void |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1222 server_parse_message( |
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1223 Display *dpy, |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1224 char_u *propInfo, // A string containing 0 or more X commands |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1225 long_u numItems) // The size of propInfo in bytes. |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1226 { |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1227 char_u *p; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1228 int code; |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1229 char_u *tofree; |
7 | 1230 |
31287
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1231 #if defined(FEAT_EVAL) |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1232 ch_log(NULL, "server_parse_message() numItems: %ld", numItems); |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1233 #endif |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1234 |
7 | 1235 /* |
1236 * Several commands and results could arrive in the property at | |
1237 * one time; each iteration through the outer loop handles a | |
1238 * single command or result. | |
1239 */ | |
1880 | 1240 for (p = propInfo; (long_u)(p - propInfo) < numItems; ) |
7 | 1241 { |
1242 /* | |
1243 * Ignore leading NULs; each command or result starts with a | |
1244 * NUL so that no matter how badly formed a preceding command | |
1245 * is, we'll be able to tell that a new command/result is | |
1246 * starting. | |
1247 */ | |
1248 if (*p == 0) | |
1249 { | |
1250 p++; | |
1251 continue; | |
1252 } | |
1253 | |
31287
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1254 if ((*p == 'c' || *p == 'k') && p[1] == 0) |
7 | 1255 { |
1256 Window resWindow; | |
3668 | 1257 char_u *name, *script, *serial, *end; |
7 | 1258 Bool asKeys = *p == 'k'; |
39 | 1259 char_u *enc; |
7 | 1260 |
1261 /* | |
1262 * This is an incoming command from some other application. | |
1263 * Iterate over all of its options. Stop when we reach | |
1264 * the end of the property or something that doesn't look | |
1265 * like an option. | |
1266 */ | |
1267 p += 2; | |
1268 name = NULL; | |
1269 resWindow = None; | |
1270 serial = (char_u *)""; | |
1271 script = NULL; | |
39 | 1272 enc = NULL; |
1880 | 1273 while ((long_u)(p - propInfo) < numItems && *p == '-') |
7 | 1274 { |
31287
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1275 #if defined(FEAT_EVAL) |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1276 ch_log(NULL, "server_parse_message() item: %c, %s", p[-2], p); |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1277 #endif |
7 | 1278 switch (p[1]) |
1279 { | |
1280 case 'r': | |
1281 end = skipwhite(p + 2); | |
1282 resWindow = 0; | |
1283 while (vim_isxdigit(*end)) | |
1284 { | |
1285 resWindow = 16 * resWindow + (long_u)hex2nr(*end); | |
1286 ++end; | |
1287 } | |
1288 if (end == p + 2 || *end != ' ') | |
1289 resWindow = None; | |
1290 else | |
1291 { | |
1292 p = serial = end + 1; | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1293 clientWindow = resWindow; // Remember in global |
7 | 1294 } |
1295 break; | |
1296 case 'n': | |
1297 if (p[2] == ' ') | |
1298 name = p + 3; | |
1299 break; | |
1300 case 's': | |
1301 if (p[2] == ' ') | |
1302 script = p + 3; | |
1303 break; | |
39 | 1304 case 'E': |
1305 if (p[2] == ' ') | |
1306 enc = p + 3; | |
1307 break; | |
7 | 1308 } |
1309 while (*p != 0) | |
1310 p++; | |
1311 p++; | |
1312 } | |
1313 | |
1314 if (script == NULL || name == NULL) | |
1315 continue; | |
1316 | |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1317 if (serverName != NULL && STRICMP(name, serverName) == 0) |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1318 { |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1319 script = serverConvert(enc, script, &tofree); |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1320 if (asKeys) |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1321 server_to_input_buf(script); |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1322 else |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1323 { |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1324 char_u *res; |
3668 | 1325 |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1326 res = eval_client_expr_to_string(script); |
3668 | 1327 if (resWindow != None) |
1328 { | |
1329 garray_T reply; | |
1330 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1331 // Initialize the result property. |
3668 | 1332 ga_init2(&reply, 1, 100); |
7009 | 1333 (void)ga_grow(&reply, 50 + STRLEN(p_enc)); |
3668 | 1334 sprintf(reply.ga_data, "%cr%c-E %s%c-s %s%c-r ", |
39 | 1335 0, 0, p_enc, 0, serial, 0); |
3668 | 1336 reply.ga_len = 14 + STRLEN(p_enc) + STRLEN(serial); |
1337 | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1338 // Evaluate the expression and return the result. |
3668 | 1339 if (res != NULL) |
1340 ga_concat(&reply, res); | |
1341 else | |
1342 { | |
31287
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1343 ga_concat(&reply, |
fa309d9af73c
patch 9.0.0977: it is not easy to see what client-server commands are doing
Bram Moolenaar <Bram@vim.org>
parents:
30325
diff
changeset
|
1344 (char_u *)_(e_invalid_expression_received)); |
3668 | 1345 ga_append(&reply, 0); |
1346 ga_concat(&reply, (char_u *)"-c 1"); | |
1347 } | |
1348 ga_append(&reply, NUL); | |
1349 (void)AppendPropCarefully(dpy, resWindow, commProperty, | |
1350 reply.ga_data, reply.ga_len); | |
1351 ga_clear(&reply); | |
1352 } | |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1353 vim_free(res); |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1354 } |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1355 vim_free(tofree); |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
7009
diff
changeset
|
1356 } |
7 | 1357 } |
1358 else if (*p == 'r' && p[1] == 0) | |
1359 { | |
39 | 1360 int serial, gotSerial; |
1361 char_u *res; | |
1362 PendingCommand *pcPtr; | |
1363 char_u *enc; | |
7 | 1364 |
1365 /* | |
1366 * This is a reply to some command that we sent out. Iterate | |
1367 * over all of its options. Stop when we reach the end of the | |
1368 * property or something that doesn't look like an option. | |
1369 */ | |
1370 p += 2; | |
1371 gotSerial = 0; | |
1372 res = (char_u *)""; | |
1373 code = 0; | |
39 | 1374 enc = NULL; |
1880 | 1375 while ((long_u)(p - propInfo) < numItems && *p == '-') |
7 | 1376 { |
1377 switch (p[1]) | |
1378 { | |
1379 case 'r': | |
1380 if (p[2] == ' ') | |
1381 res = p + 3; | |
1382 break; | |
39 | 1383 case 'E': |
1384 if (p[2] == ' ') | |
1385 enc = p + 3; | |
1386 break; | |
7 | 1387 case 's': |
1388 if (sscanf((char *)p + 2, " %d", &serial) == 1) | |
1389 gotSerial = 1; | |
1390 break; | |
1391 case 'c': | |
1392 if (sscanf((char *)p + 2, " %d", &code) != 1) | |
1393 code = 0; | |
1394 break; | |
1395 } | |
1396 while (*p != 0) | |
1397 p++; | |
1398 p++; | |
1399 } | |
1400 | |
1401 if (!gotSerial) | |
1402 continue; | |
1403 | |
1404 /* | |
1405 * Give the result information to anyone who's | |
1406 * waiting for it. | |
1407 */ | |
1408 for (pcPtr = pendingCommands; pcPtr != NULL; pcPtr = pcPtr->nextPtr) | |
1409 { | |
1410 if (serial != pcPtr->serial || pcPtr->result != NULL) | |
1411 continue; | |
1412 | |
1413 pcPtr->code = code; | |
7009 | 1414 res = serverConvert(enc, res, &tofree); |
1415 if (tofree == NULL) | |
1416 res = vim_strsave(res); | |
1417 pcPtr->result = res; | |
7 | 1418 break; |
1419 } | |
1420 } | |
1421 else if (*p == 'n' && p[1] == 0) | |
1422 { | |
1423 Window win = 0; | |
1424 unsigned int u; | |
1425 int gotWindow; | |
1426 char_u *str; | |
1427 struct ServerReply *r; | |
39 | 1428 char_u *enc; |
7 | 1429 |
1430 /* | |
10942
e05695e59f6d
patch 8.0.0360: sometimes VimL is used instead of "Vim script"
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1431 * This is a (n)otification. Sent with serverreply_send in Vim |
e05695e59f6d
patch 8.0.0360: sometimes VimL is used instead of "Vim script"
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
1432 * script. Execute any autocommand and save it for later retrieval |
7 | 1433 */ |
1434 p += 2; | |
1435 gotWindow = 0; | |
1436 str = (char_u *)""; | |
39 | 1437 enc = NULL; |
1880 | 1438 while ((long_u)(p - propInfo) < numItems && *p == '-') |
7 | 1439 { |
1440 switch (p[1]) | |
1441 { | |
1442 case 'n': | |
1443 if (p[2] == ' ') | |
1444 str = p + 3; | |
1445 break; | |
39 | 1446 case 'E': |
1447 if (p[2] == ' ') | |
1448 enc = p + 3; | |
1449 break; | |
7 | 1450 case 'w': |
1451 if (sscanf((char *)p + 2, " %x", &u) == 1) | |
1452 { | |
1453 win = u; | |
1454 gotWindow = 1; | |
1455 } | |
1456 break; | |
1457 } | |
1458 while (*p != 0) | |
1459 p++; | |
1460 p++; | |
1461 } | |
1462 | |
1463 if (!gotWindow) | |
1464 continue; | |
39 | 1465 str = serverConvert(enc, str, &tofree); |
7 | 1466 if ((r = ServerReplyFind(win, SROP_Add)) != NULL) |
1467 { | |
1468 ga_concat(&(r->strings), str); | |
21 | 1469 ga_append(&(r->strings), NUL); |
7 | 1470 } |
1698 | 1471 { |
1472 char_u winstr[30]; | |
1473 | |
1474 sprintf((char *)winstr, "0x%x", (unsigned int)win); | |
1475 apply_autocmds(EVENT_REMOTEREPLY, winstr, str, TRUE, curbuf); | |
1476 } | |
39 | 1477 vim_free(tofree); |
7 | 1478 } |
1479 else | |
1480 { | |
1481 /* | |
1482 * Didn't recognize this thing. Just skip through the next | |
1483 * null character and try again. | |
1484 * Even if we get an 'r'(eply) we will throw it away as we | |
1485 * never specify (and thus expect) one | |
1486 */ | |
1487 while (*p != 0) | |
1488 p++; | |
1489 p++; | |
1490 } | |
1491 } | |
1492 XFree(propInfo); | |
1493 } | |
1494 | |
1495 /* | |
1496 * Append a given property to a given window, but set up an X error handler so | |
1497 * that if the append fails this procedure can return an error code rather | |
1498 * than having Xlib panic. | |
1499 * Return: 0 for OK, -1 for error | |
1500 */ | |
1501 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1502 AppendPropCarefully( |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1503 Display *dpy, // Display on which to operate. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1504 Window window, // Window whose property is to be modified. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1505 Atom property, // Name of property. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1506 char_u *value, // Characters to append to property. |
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1507 int length) // How much to append |
7 | 1508 { |
1509 XErrorHandler old_handler; | |
1510 | |
1511 old_handler = XSetErrorHandler(x_error_check); | |
1512 got_x_error = FALSE; | |
1513 XChangeProperty(dpy, window, property, XA_STRING, 8, | |
1514 PropModeAppend, value, length); | |
1515 XSync(dpy, False); | |
1516 (void) XSetErrorHandler(old_handler); | |
1517 return got_x_error ? -1 : 0; | |
1518 } | |
1519 | |
1520 | |
1521 /* | |
1522 * Another X Error handler, just used to check for errors. | |
1523 */ | |
1524 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1525 x_error_check(Display *dpy UNUSED, XErrorEvent *error_event UNUSED) |
7 | 1526 { |
1527 got_x_error = TRUE; | |
1528 return 0; | |
1529 } | |
1530 | |
1531 /* | |
1532 * Check if "str" looks like it had a serial number appended. | |
1533 * Actually just checks if the name ends in a digit. | |
1534 */ | |
1535 static int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7803
diff
changeset
|
1536 IsSerialName(char_u *str) |
7 | 1537 { |
1538 int len = STRLEN(str); | |
1539 | |
1540 return (len > 1 && vim_isdigit(str[len - 1])); | |
1541 } | |
18798
f0f9692d4487
patch 8.1.2387: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents:
18642
diff
changeset
|
1542 #endif // FEAT_CLIENTSERVER |