~ubuntu-branches/debian/squeeze/freeciv/squeeze

« back to all changes in this revision

Viewing changes to utility/ftwl/be_x11_ximage.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20100223220902-kiyrmr9i4152cka5
Tags: 2.2.0-1
[ Karl Goetz ]
* Remove civserver files in /etc/ggzd/ (Closes: 523772, 517787)
* Adding ${misc:Depends} to all binary packages (lintian warnings)

[ Clint Adams ]
* New upstream version.
  - Drop data_dsc_use_bindir.diff (binary pathnames have changed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**********************************************************************
2
 
 Freeciv - Copyright (C) 2004 - The Freeciv Project
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; either version 2, or (at your option)
6
 
   any later version.
7
 
 
8
 
   This program is distributed in the hope that it will be useful,
9
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
   GNU General Public License for more details.
12
 
***********************************************************************/
13
 
 
14
 
#ifdef HAVE_CONFIG_H
15
 
#include <config.h>
16
 
#endif
17
 
 
18
 
#include <assert.h>
19
 
#include <errno.h>
20
 
#include <stdio.h>
21
 
 
22
 
#include <X11/Xutil.h>
23
 
#include <X11/Xos.h>
24
 
#include <X11/Xatom.h>
25
 
#include <X11/StringDefs.h>
26
 
#include <X11/keysym.h>
27
 
#include <X11/Shell.h>
28
 
 
29
 
#include "back_end.h"
30
 
#include "be_common_24.h"
31
 
#include "be_common_pixels.h"
32
 
 
33
 
#include "shared.h"
34
 
 
35
 
#include "mem.h"
36
 
#include "netintf.h"
37
 
 
38
 
// fixme
39
 
#include "timing.h"
40
 
#include "widget.h"
41
 
 
42
 
static Display *display;
43
 
static Window window;
44
 
static int screen_number;
45
 
static int display_depth;
46
 
static int x11fd;
47
 
static int other_fd = -1;
48
 
static XImage *root_image;
49
 
static GC gc_plain;
50
 
 
51
 
/*************************************************************************
52
 
  Initialize video mode and window.
53
 
*************************************************************************/
54
 
void be_init(const struct ct_size *screen_size, bool fullscreen)
55
 
{
56
 
  XGCValues values;
57
 
 
58
 
  _Xdebug = 0;
59
 
  display = XOpenDisplay(NULL);
60
 
  assert(display);
61
 
 
62
 
  screen_number = DefaultScreen(display);
63
 
  display_depth = DefaultDepth(display, screen_number);
64
 
  x11fd = ConnectionNumber(display);
65
 
 
66
 
  window =
67
 
      XCreateSimpleWindow(display, XDefaultRootWindow(display), 200, 200,
68
 
                          screen_size->width, screen_size->height, 0, 0,
69
 
                          WhitePixel(display, screen_number));
70
 
  XSelectInput(display, window,
71
 
               ExposureMask | PointerMotionMask | ButtonPressMask |
72
 
               ButtonReleaseMask | KeyPressMask);
73
 
 
74
 
  {
75
 
    Pixmap dummy_mask = XCreatePixmap(display, window, 1, 1, 1);
76
 
 
77
 
    values.graphics_exposures = False;
78
 
    values.foreground = BlackPixel(display, screen_number);
79
 
 
80
 
    values.graphics_exposures = False;
81
 
    gc_plain = XCreateGC(display, window, GCGraphicsExposures, &values);
82
 
 
83
 
    XFreePixmap(display, dummy_mask);
84
 
  }
85
 
 
86
 
  /* pop this window up on the screen */
87
 
  XMapRaised(display, window);
88
 
 
89
 
  root_image =
90
 
      XCreateImage(display, DefaultVisual(display, screen_number),
91
 
                   display_depth, ZPixmap, 0, NULL, screen_size->width,
92
 
                   screen_size->height, 32, 0);
93
 
  root_image->data =
94
 
      fc_malloc(root_image->bytes_per_line * root_image->height);
95
 
}
96
 
 
97
 
/*************************************************************************
98
 
  ...
99
 
*************************************************************************/
100
 
static bool copy_event(struct be_event *event, XEvent * xevent)
101
 
{
102
 
  switch (xevent->type) {
103
 
  case NoExpose:
104
 
  case GraphicsExpose:
105
 
    return FALSE;
106
 
  case Expose:
107
 
    {
108
 
      XExposeEvent *xev = &xevent->xexpose;
109
 
 
110
 
      if (xev->count > 0) {
111
 
        return FALSE;
112
 
      }
113
 
      event->type = BE_EXPOSE;
114
 
    }
115
 
    break;
116
 
  case MotionNotify:
117
 
    {
118
 
      XMotionEvent *xev = &xevent->xmotion;
119
 
 
120
 
      event->type = BE_MOUSE_MOTION;
121
 
      event->position.x = xev->x;
122
 
      event->position.y = xev->y;
123
 
    }
124
 
    break;
125
 
  case ButtonPress:
126
 
  case ButtonRelease:
127
 
    {
128
 
      XButtonEvent *xev = &xevent->xbutton;
129
 
 
130
 
#if 0
131
 
      printf("pos=(%d,%d) button=0x%x state=0x%x\n", xev->x, xev->y,
132
 
             xev->button, xev->state);
133
 
#endif
134
 
      event->type =
135
 
          xevent->type == ButtonPress ? BE_MOUSE_PRESSED : BE_MOUSE_RELEASED;
136
 
      event->position.x = xev->x;
137
 
      event->position.y = xev->y;
138
 
      switch (xev->button) {
139
 
      case 1:
140
 
        event->button = BE_MB_LEFT;
141
 
        break;
142
 
      case 2:
143
 
        event->button = BE_MB_MIDDLE;
144
 
        break;
145
 
      case 3:
146
 
        event->button = BE_MB_RIGHT;
147
 
        break;
148
 
      default:
149
 
        assert(0);
150
 
      }
151
 
    }
152
 
    break;
153
 
  case KeyPress:
154
 
    {
155
 
      XKeyEvent *xev = &xevent->xkey;
156
 
      XKeyEvent copy_xev = *xev;
157
 
      char string[10];
158
 
      KeySym key;
159
 
      struct be_key *k = &event->key;
160
 
      int chars;
161
 
 
162
 
      /* Mod2Mask is NumLock */
163
 
      copy_xev.state = copy_xev.state & (ShiftMask | Mod2Mask);
164
 
      chars = XLookupString(&copy_xev, string, sizeof(string), &key, NULL);
165
 
 
166
 
      if (0)
167
 
        printf("chars=%d string='%s' key=%ld cursor=%d\n", chars, string,
168
 
               key, IsCursorKey(key));
169
 
      k->shift = (xev->state & ShiftMask);
170
 
      k->control = (xev->state & ControlMask);
171
 
      k->alt = (xev->state & Mod1Mask);
172
 
 
173
 
#define T(x,b)                  \
174
 
    } else if (key == x) {      \
175
 
      k->type = b
176
 
          
177
 
      if (FALSE) {
178
 
        T(XK_BackSpace, BE_KEY_BACKSPACE);
179
 
        T(XK_Return, BE_KEY_RETURN);
180
 
        T(XK_KP_Enter, BE_KEY_ENTER);
181
 
        T(XK_Delete, BE_KEY_DELETE);
182
 
        T(XK_Left, BE_KEY_LEFT);
183
 
        T(XK_Right, BE_KEY_RIGHT);
184
 
        T(XK_Up, BE_KEY_UP);
185
 
        T(XK_Down, BE_KEY_DOWN);
186
 
        T(XK_Escape, BE_KEY_ESCAPE);
187
 
        T(XK_Print, BE_KEY_PRINT);
188
 
        T(XK_space, BE_KEY_SPACE);
189
 
        T(XK_KP_0,BE_KEY_KP_0);
190
 
        T(XK_KP_1,BE_KEY_KP_1);
191
 
        T(XK_KP_2,BE_KEY_KP_2);
192
 
        T(XK_KP_3,BE_KEY_KP_3);
193
 
        T(XK_KP_4,BE_KEY_KP_4);
194
 
        T(XK_KP_5,BE_KEY_KP_5);
195
 
        T(XK_KP_6,BE_KEY_KP_6);
196
 
        T(XK_KP_7,BE_KEY_KP_7);
197
 
        T(XK_KP_8,BE_KEY_KP_8);
198
 
        T(XK_KP_9,BE_KEY_KP_9);
199
 
      } else if (chars == 1 && string[0] > ' ' && string[0] <= '~') {
200
 
        k->type = BE_KEY_NORMAL;
201
 
        k->key = string[0];
202
 
        k->shift = FALSE;
203
 
      } else {
204
 
        printf
205
 
            ("WARNING: BE-X11: unconverted KeyPress: chars=%d string='%s' key=0x%lx\n",
206
 
             chars, string, key);
207
 
        return FALSE;
208
 
      }
209
 
      event->type = BE_KEY_PRESSED;
210
 
      event->position.x = xev->x;
211
 
      event->position.y = xev->y;
212
 
    }
213
 
    break;
214
 
  default:
215
 
    printf("got event %d\n", xevent->type);
216
 
    assert(0);
217
 
  }
218
 
  return TRUE;
219
 
}
220
 
 
221
 
/*************************************************************************
222
 
  ...
223
 
*************************************************************************/
224
 
void be_next_non_blocking_event(struct be_event *event)
225
 
{
226
 
  XEvent xevent;
227
 
 
228
 
restart:
229
 
  event->type = BE_NO_EVENT;
230
 
 
231
 
  if (XCheckMaskEvent(display, -1 /*all events */ , &xevent)) {
232
 
    if (copy_event(event, &xevent)) {
233
 
      return;
234
 
    } else {
235
 
      /* discard event */
236
 
      goto restart;
237
 
    }
238
 
  }
239
 
}
240
 
 
241
 
/*************************************************************************
242
 
  ...
243
 
*************************************************************************/
244
 
void be_next_blocking_event(struct be_event *event, struct timeval *timeout)
245
 
{
246
 
  fd_set readfds, exceptfds;
247
 
  int ret, highest = x11fd;
248
 
 
249
 
restart:
250
 
  event->type = BE_NO_EVENT;
251
 
 
252
 
  /* No event available: block on input socket until one is */
253
 
  FD_ZERO(&readfds);
254
 
  FD_SET(x11fd, &readfds);
255
 
 
256
 
  FD_ZERO(&exceptfds);
257
 
 
258
 
  if (other_fd != -1) {
259
 
    FD_SET(other_fd, &readfds);
260
 
    FD_SET(other_fd, &exceptfds);
261
 
    if (other_fd > highest) {
262
 
      highest = other_fd;
263
 
    }
264
 
  }
265
 
 
266
 
  ret = my_select(highest + 1, &readfds, NULL, &exceptfds, timeout);
267
 
  if (ret == 0) {
268
 
    // timed out
269
 
    event->type = BE_TIMEOUT;
270
 
  } else if (ret > 0) {
271
 
    if (other_fd != -1 && (FD_ISSET(other_fd, &readfds) ||
272
 
                           FD_ISSET(other_fd, &exceptfds))) {
273
 
      event->type = BE_DATA_OTHER_FD;
274
 
      event->socket = other_fd;
275
 
    }
276
 
    /* 
277
 
     * New data on the x11 fd. return with BE_NO_EVENT and let the
278
 
     * caller handle it. 
279
 
     */
280
 
  } else if (errno == EINTR) {
281
 
    goto restart;
282
 
  } else {
283
 
    assert(0);
284
 
  }
285
 
}
286
 
 
287
 
/*************************************************************************
288
 
  ...
289
 
*************************************************************************/
290
 
void be_add_net_input(int sock)
291
 
{
292
 
  other_fd = sock;
293
 
}
294
 
 
295
 
/*************************************************************************
296
 
  ...
297
 
*************************************************************************/
298
 
void be_remove_net_input(void)
299
 
{
300
 
  other_fd = -1;
301
 
}
302
 
 
303
 
/*************************************************************************
304
 
  ...
305
 
*************************************************************************/
306
 
void be_screen_get_size(struct ct_size *size)
307
 
{
308
 
  XWindowAttributes window_attributes;
309
 
 
310
 
  XGetWindowAttributes(display, window, &window_attributes);
311
 
 
312
 
  size->width = window_attributes.width;
313
 
  size->height = window_attributes.height;
314
 
}
315
 
 
316
 
#define COMP_565_RED(x)         ((((x)>>3)&0x1f)<<11)
317
 
#define COMP_565_GREEN(x)       ((((x)>>2)&0x3f)<< 5)
318
 
#define COMP_565_BLUE(x)        ((((x)>>3)&0x1f)<< 0)
319
 
 
320
 
/*************************************************************************
321
 
  ...
322
 
*************************************************************************/
323
 
static void fill_ximage_from_image_565(XImage * ximage,
324
 
                                       const struct image *image)
325
 
{
326
 
  int x, y;
327
 
  unsigned short *pdest = (unsigned short *) ximage->data;
328
 
  int extra_per_line = ximage->bytes_per_line / 2 - ximage->width;
329
 
 
330
 
  for (y = 0; y < ximage->height; y++) {
331
 
    for (x = 0; x < ximage->width; x++) {
332
 
      unsigned char *psrc = IMAGE_GET_ADDRESS(image, x, y);
333
 
      unsigned short new_value =
334
 
          (COMP_565_RED(psrc[0]) | COMP_565_GREEN(psrc[1]) |
335
 
           COMP_565_BLUE(psrc[2]));
336
 
      *pdest = new_value;
337
 
      pdest++;
338
 
    }
339
 
    pdest += extra_per_line;
340
 
  }
341
 
}
342
 
 
343
 
/*************************************************************************
344
 
  ...
345
 
*************************************************************************/
346
 
#define COMP_555_RED(x)         ((((x)>>3)&0x1f)<<10)
347
 
#define COMP_555_GREEN(x)       ((((x)>>3)&0x1f)<< 5)
348
 
#define COMP_555_BLUE(x)        ((((x)>>3)&0x1f)<< 0)
349
 
static void fill_ximage_from_image_555(XImage * ximage,
350
 
                                       const struct image *image)
351
 
{
352
 
  int x, y;
353
 
  unsigned short *pdest = (unsigned short *) ximage->data;
354
 
  int extra_per_line = ximage->bytes_per_line / 2 - ximage->width;
355
 
 
356
 
  for (y = 0; y < ximage->height; y++) {
357
 
    for (x = 0; x < ximage->width; x++) {
358
 
      unsigned char *psrc = IMAGE_GET_ADDRESS(image, x, y);
359
 
      unsigned short new_value =
360
 
          (COMP_555_RED(psrc[0]) | COMP_555_GREEN(psrc[1]) |
361
 
           COMP_555_BLUE(psrc[2]));
362
 
      *pdest = new_value;
363
 
      pdest++;
364
 
    }
365
 
    pdest += extra_per_line;
366
 
  }
367
 
}
368
 
 
369
 
/*************************************************************************
370
 
  ...
371
 
*************************************************************************/
372
 
static void fill_ximage_from_image_8888(XImage * ximage,
373
 
                                        const struct image *image)
374
 
{
375
 
  int x, y;
376
 
  unsigned char *pdest = (unsigned char *) ximage->data;
377
 
  int extra_per_line = ximage->bytes_per_line - ximage->width*4;
378
 
 
379
 
  for (y = 0; y < ximage->height; y++) {
380
 
    for (x = 0; x < ximage->width; x++) {
381
 
      unsigned char *psrc = IMAGE_GET_ADDRESS(image, x, y);
382
 
 
383
 
      pdest[0] = psrc[2];
384
 
      pdest[1] = psrc[1];
385
 
      pdest[2] = psrc[0];
386
 
      pdest += 4;
387
 
    }
388
 
    pdest += extra_per_line;
389
 
  }
390
 
}
391
 
 
392
 
/*************************************************************************
393
 
  ...
394
 
*************************************************************************/
395
 
void be_copy_osda_to_screen(struct osda *src)
396
 
{
397
 
  assert(root_image->width == src->image->width &&
398
 
         root_image->height == src->image->height);
399
 
 
400
 
  if (root_image->red_mask == 0xf800 &&
401
 
      root_image->green_mask == 0x7e0 && root_image->blue_mask == 0x1f &&
402
 
      root_image->depth == 16 && root_image->bits_per_pixel == 16
403
 
      && root_image->byte_order == LSBFirst) {
404
 
    fill_ximage_from_image_565(root_image, src->image);
405
 
  } else if (root_image->red_mask == 0x7c00 &&
406
 
             root_image->green_mask == 0x3e0 && root_image->blue_mask == 0x1f
407
 
             && root_image->depth == 15 && root_image->bits_per_pixel == 16
408
 
             && root_image->byte_order == LSBFirst) {
409
 
    fill_ximage_from_image_555(root_image, src->image);
410
 
  } else if (root_image->red_mask == 0xff0000 &&
411
 
             root_image->green_mask == 0xff00
412
 
             && root_image->blue_mask == 0xff && root_image->depth == 24
413
 
             && root_image->bits_per_pixel == 32
414
 
             && root_image->byte_order == LSBFirst) {
415
 
    fill_ximage_from_image_8888(root_image, src->image);
416
 
  } else {
417
 
    fprintf(stderr, "ERROR: unknown screen format: red=0x%lx, "
418
 
            "green=0x%lx, blue=0x%lx depth=%d bpp=%d "
419
 
            "byte_order=%d (LSB=%d MSB=%d)\n",
420
 
            root_image->red_mask, root_image->green_mask,
421
 
            root_image->blue_mask, root_image->depth,
422
 
            root_image->bits_per_pixel, root_image->byte_order, LSBFirst,
423
 
            MSBFirst);
424
 
    assert(0);
425
 
  }
426
 
 
427
 
  XPutImage(display, window, gc_plain, root_image, 0, 0, 0, 0,
428
 
            root_image->width, root_image->height);
429
 
  XFlush(display);
430
 
}
431
 
 
432
 
/*************************************************************************
433
 
  ...
434
 
*************************************************************************/
435
 
bool be_supports_fullscreen(void)
436
 
{
437
 
    return FALSE;
438
 
}