~ubuntu-branches/ubuntu/karmic/libxcb/karmic

« back to all changes in this revision

Viewing changes to src/xcb_util.c

  • Committer: Bazaar Package Importer
  • Author(s): Jamey Sharp
  • Date: 2007-11-24 14:59:42 UTC
  • mto: (2.1.2 squeeze) (1.1.4 upstream)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20071124145942-o35xehku11z1vu4u
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
    return ((y + (y >> 3)) & 030707070707) % 077;
56
56
}
57
57
 
58
 
int xcb_parse_display(const char *name, char **host, int *displayp, int *screenp)
 
58
static int _xcb_parse_display(const char *name, char **host, char **protocol,
 
59
                      int *displayp, int *screenp)
59
60
{
60
61
    int len, display, screen;
61
 
    char *colon, *dot, *end;
 
62
    char *slash, *colon, *dot, *end;
62
63
    if(!name || !*name)
63
64
        name = getenv("DISPLAY");
64
65
    if(!name)
65
66
        return 0;
 
67
    slash = strrchr(name, '/');
 
68
    if (slash) {
 
69
        len = slash - name;
 
70
        if (protocol) {
 
71
            *protocol = malloc(len + 1);
 
72
            if(!*protocol)
 
73
                return 0;
 
74
            memcpy(*protocol, name, len);
 
75
            (*protocol)[len] = '\0';
 
76
        }
 
77
        name = slash + 1;
 
78
    } else
 
79
        if (protocol)
 
80
            *protocol = NULL;
 
81
 
66
82
    colon = strrchr(name, ':');
67
83
    if(!colon)
68
84
        return 0;
96
112
    return 1;
97
113
}
98
114
 
99
 
static int _xcb_open_tcp(char *host, const unsigned short port);
100
 
static int _xcb_open_unix(const char *file);
 
115
int xcb_parse_display(const char *name, char **host, int *displayp,
 
116
                             int *screenp)
 
117
{
 
118
    return _xcb_parse_display(name, host, NULL, displayp, screenp);
 
119
}
 
120
 
 
121
static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port);
 
122
static int _xcb_open_unix(char *protocol, const char *file);
101
123
#ifdef DNETCONN
102
 
static int _xcb_open_decnet(const char *host, const unsigned short port);
 
124
static int _xcb_open_decnet(const char *host, char *protocol, const unsigned short port);
103
125
#endif
104
126
 
105
 
static int _xcb_open(char *host, const int display)
 
127
static int _xcb_open(char *host, char *protocol, const int display)
106
128
{
107
129
    int fd;
 
130
    static const char base[] = "/tmp/.X11-unix/X";
 
131
    char file[sizeof(base) + 20];
108
132
 
109
133
    if(*host)
110
134
    {
111
135
#ifdef DNETCONN
112
 
        /* DECnet displays have two colons, so xcb_parse_display will have left
113
 
           one at the end.  However, an IPv6 address can end with *two* colons,
114
 
           so only treat this as a DECnet display if host ends with exactly one
115
 
           colon. */
 
136
        /* DECnet displays have two colons, so _xcb_parse_display will have
 
137
           left one at the end.  However, an IPv6 address can end with *two*
 
138
           colons, so only treat this as a DECnet display if host ends with
 
139
           exactly one colon. */
116
140
        char *colon = strchr(host, ':');
117
141
        if(colon && *(colon+1) == '\0')
118
142
        {
119
143
            *colon = '\0';
120
 
            fd = _xcb_open_decnet(host, display);
 
144
            return _xcb_open_decnet(host, protocol, display);
121
145
        }
122
146
        else
123
147
#endif
124
 
        {
125
 
            /* display specifies TCP */
126
 
            unsigned short port = X_TCP_PORT + display;
127
 
            fd = _xcb_open_tcp(host, port);
128
 
        }
129
 
    }
130
 
    else
131
 
    {
132
 
        /* display specifies Unix socket */
133
 
        static const char base[] = "/tmp/.X11-unix/X";
134
 
        char file[sizeof(base) + 20];
135
 
        snprintf(file, sizeof(file), "%s%d", base, display);
136
 
        fd = _xcb_open_unix(file);
137
 
    }
 
148
            if (protocol
 
149
                || strcmp("unix",host)) { /* follow the old unix: rule */
 
150
 
 
151
                /* display specifies TCP */
 
152
                unsigned short port = X_TCP_PORT + display;
 
153
                return _xcb_open_tcp(host, protocol, port);
 
154
            }
 
155
    }
 
156
 
 
157
    /* display specifies Unix socket */
 
158
    snprintf(file, sizeof(file), "%s%d", base, display);
 
159
    return  _xcb_open_unix(protocol, file);
 
160
 
138
161
 
139
162
    return fd;
140
163
}
141
164
 
142
165
#ifdef DNETCONN
143
 
static int _xcb_open_decnet(const char *host, const unsigned short port)
 
166
static int _xcb_open_decnet(const char *host, const char *protocol, const unsigned short port)
144
167
{
145
168
    int fd;
146
169
    struct sockaddr_dn addr;
149
172
 
150
173
    if(!nodeaddr)
151
174
        return -1;
 
175
    if (protocol && strcmp("dnet",protocol))
 
176
        return -1;
152
177
    addr.sdn_family = AF_DECnet;
153
178
 
154
179
    addr.sdn_add.a_len = nodeaddr->n_length;
173
198
}
174
199
#endif
175
200
 
176
 
static int _xcb_open_tcp(char *host, const unsigned short port)
 
201
static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port)
177
202
{
178
203
    int fd = -1;
179
 
    struct addrinfo hints = { AI_ADDRCONFIG
 
204
    struct addrinfo hints = { 0
 
205
#ifdef AI_ADDRCONFIG
 
206
                              | AI_ADDRCONFIG
 
207
#endif
180
208
#ifdef AI_NUMERICSERV
181
209
                              | AI_NUMERICSERV
182
210
#endif
184
212
    char service[6]; /* "65535" with the trailing '\0' */
185
213
    struct addrinfo *results, *addr;
186
214
    char *bracket;
187
 
    
 
215
 
 
216
    if (protocol && strcmp("tcp",protocol))
 
217
        return -1;
 
218
 
188
219
    /* Allow IPv6 addresses enclosed in brackets. */
189
220
    if(host[0] == '[' && (bracket = strrchr(host, ']')) && bracket[1] == '\0')
190
221
    {
210
241
    return fd;
211
242
}
212
243
 
213
 
static int _xcb_open_unix(const char *file)
 
244
static int _xcb_open_unix(char *protocol, const char *file)
214
245
{
215
246
    int fd;
216
247
    struct sockaddr_un addr = { AF_UNIX };
 
248
 
 
249
    if (protocol && strcmp("unix",protocol))
 
250
        return -1;
 
251
 
217
252
    strcpy(addr.sun_path, file);
218
253
 
219
254
    fd = socket(AF_UNIX, SOCK_STREAM, 0);
228
263
{
229
264
    int fd, display = 0;
230
265
    char *host;
 
266
    char *protocol;
231
267
    xcb_connection_t *c;
232
268
    xcb_auth_info_t auth;
233
269
 
234
 
    if(!xcb_parse_display(displayname, &host, &display, screenp))
 
270
    if(!_xcb_parse_display(displayname, &host, &protocol, &display, screenp))
235
271
        return (xcb_connection_t *) &error_connection;
236
 
    fd = _xcb_open(host, display);
 
272
    fd = _xcb_open(host, protocol, display);
237
273
    free(host);
238
274
    if(fd == -1)
239
275
        return (xcb_connection_t *) &error_connection;
253
289
{
254
290
    int fd, display = 0;
255
291
    char *host;
 
292
    char *protocol;
256
293
 
257
 
    if(!xcb_parse_display(displayname, &host, &display, screenp))
 
294
    if(!_xcb_parse_display(displayname, &host, &protocol, &display, screenp))
258
295
        return (xcb_connection_t *) &error_connection;
259
 
    fd = _xcb_open(host, display);
 
296
    fd = _xcb_open(host, protocol, display);
260
297
    free(host);
261
298
    if(fd == -1)
262
299
        return (xcb_connection_t *) &error_connection;