1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
#define NHASH (1<<5)
#define HASHMASK (NHASH-1)
typedef struct Kbdbuf Kbdbuf;
typedef struct Mousebuf Mousebuf;
typedef struct Tagbuf Tagbuf;
typedef struct Client Client;
typedef struct DImage DImage;
typedef struct DScreen DScreen;
typedef struct CScreen CScreen;
typedef struct FChar FChar;
typedef struct Refresh Refresh;
typedef struct Refx Refx;
typedef struct DName DName;
struct Kbdbuf
{
Rune r[256];
int ri;
int wi;
int stall;
int alting;
Rune k[10];
int nk;
};
struct Mousebuf
{
Mouse m[256];
Mouse last;
int ri;
int wi;
int stall;
int resized;
};
struct Tagbuf
{
int t[256];
int ri;
int wi;
};
struct Client
{
int rfd;
// wfdlk protects writes to wfd, which can be issued from either
// the RPC thread or the graphics thread.
QLock wfdlk;
int wfd;
uchar* mbuf;
int nmbuf;
char* wsysid;
// drawlk protects the draw data structures.
// It can be acquired by an RPC thread or a graphics thread
// but must not be held on one thread while waiting for the other.
QLock drawlk;
/*Ref r;*/
DImage* dimage[NHASH];
CScreen* cscreen;
Refresh* refresh;
Rendez refrend;
uchar* readdata;
int nreaddata;
int busy;
int clientid;
int slot;
int refreshme;
int infoid;
int op;
int displaydpi;
int forcedpi;
int waste;
Rectangle flushrect;
Memimage *screenimage;
DScreen* dscreen;
int nname;
DName* name;
int namevers;
// Only accessed/modified by the graphics thread.
const void* view;
// eventlk protects the keyboard and mouse events.
QLock eventlk;
Kbdbuf kbd;
Mousebuf mouse;
Tagbuf kbdtags;
Tagbuf mousetags;
Rectangle mouserect;
};
struct Refresh
{
DImage* dimage;
Rectangle r;
Refresh* next;
};
struct Refx
{
Client* client;
DImage* dimage;
};
struct DName
{
char *name;
Client *client;
DImage* dimage;
int vers;
};
struct FChar
{
int minx; /* left edge of bits */
int maxx; /* right edge of bits */
uchar miny; /* first non-zero scan-line */
uchar maxy; /* last non-zero scan-line + 1 */
schar left; /* offset of baseline */
uchar width; /* width of baseline */
};
/*
* Reference counts in DImages:
* one per open by original client
* one per screen image or fill
* one per image derived from this one by name
*/
struct DImage
{
int id;
int ref;
char *name;
int vers;
Memimage* image;
int ascent;
int nfchar;
FChar* fchar;
DScreen* dscreen; /* 0 if not a window */
DImage* fromname; /* image this one is derived from, by name */
DImage* next;
};
struct CScreen
{
DScreen* dscreen;
CScreen* next;
};
struct DScreen
{
int id;
int public;
int ref;
DImage *dimage;
DImage *dfill;
Memscreen* screen;
Client* owner;
DScreen* next;
};
// For the most part, the graphics driver-specific code in files
// like mac-screen.m runs in the graphics library's main thread,
// while the RPC service code in srv.c runs on the RPC service thread.
// The exceptions in each file, which are called by the other,
// are marked with special prefixes: gfx_* indicates code that
// is in srv.c but nonetheless runs on the main graphics thread,
// while rpc_* indicates code that is in, say, mac-screen.m but
// nonetheless runs on the RPC service thread.
//
// The gfx_* and rpc_* calls typically synchronize with the other
// code in the file by acquiring a lock (or running a callback on the
// target thread, which amounts to the same thing).
// To avoid deadlock, callers of those routines must not hold any locks.
// gfx_* routines are called on the graphics thread,
// invoked from graphics driver callbacks to do RPC work.
// No locks are held on entry.
void gfx_abortcompose(Client*);
void gfx_keystroke(Client*, int);
void gfx_main(void);
void gfx_mousetrack(Client*, int, int, int, uint);
void gfx_replacescreenimage(Client*, Memimage*);
void gfx_started(void);
// rpc_* routines are called on the RPC thread,
// invoked by the RPC server code to do graphics work.
// No locks are held on entry.
Memimage *rpc_attach(Client*, char*, char*);
char* rpc_getsnarf(void);
void rpc_putsnarf(char*);
void rpc_resizeimg(Client*);
void rpc_resizewindow(Client*, Rectangle);
void rpc_serve(Client*);
void rpc_setcursor(Client*, Cursor*, Cursor2*);
void rpc_setlabel(Client*, char*);
void rpc_setmouse(Client*, Point);
void rpc_shutdown(void);
void rpc_topwin(Client*);
void rpc_main(void);
void rpc_bouncemouse(Client*, Mouse);
void rpc_flush(Client*, Rectangle);
// rpc_gfxdrawlock and rpc_gfxdrawunlock
// are called around drawing operations to lock and unlock
// access to the graphics display, for systems where the
// individual memdraw operations use the graphics display (X11, not macOS).
void rpc_gfxdrawlock(void);
void rpc_gfxdrawunlock(void);
// draw* routines are called on the RPC thread,
// invoked by the RPC server to do pixel pushing.
// No locks are held on entry.
int draw_dataread(Client*, void*, int);
int draw_datawrite(Client*, void*, int);
void draw_initdisplaymemimage(Client*, Memimage*);
// utility routines
int latin1(Rune*, int);
int mouseswap(int);
int parsewinsize(char*, Rectangle*, int*);
extern Client *client0; // set in single-client mode
|