File: xatom4.cc

package info (click to toggle)
atom4 4.1-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 664 kB
  • ctags: 947
  • sloc: cpp: 4,451; makefile: 52; sh: 45; perl: 6
file content (161 lines) | stat: -rw-r--r-- 3,761 bytes parent folder | download | duplicates (7)
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
/*
 * X11 client for Atom-4
 * Implementation file
 *
 * $Id: xatom4.cc,v 1.29 2003/04/08 09:57:43 hsteoh Exp hsteoh $
 */

#include <stdio.h>			// FOR NOW ONLY
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/xpm.h>

#include "exception.h"
#include "xatom4.h"


#define WIN_WIDTH		640
#define WIN_HEIGHT		480

#define BOARD_X			0	// location of board pane
#define BOARD_Y			0

#define XCELLS			16	// board dimensions
#define YCELLS			16

#define COLOR_CLOSENESS		32768


/*
 *
 * Class XAtom4
 *
 */

void XAtom4::gamestate_notifier::notify_move(atom4 *src, int player,
                                             elist<boardchange> &chg) {
  app->refresh();

  // TBD: print message about player's move

  XFlush(app->conn->display());		// update display now
}

void XAtom4::gamestate_notifier::notify_clear(atom4 *src) {
  app->refresh();
  XFlush(app->conn->display());		// update display now
}

XAtom4::XAtom4(xconnection *xconn, atom4 *gm, int *indicator) :
	appwindow(xconn, "Atom4 X11 Client", "XAtom4",
	          WIN_WIDTH, WIN_HEIGHT, "XAtom4", "XAtom4"),
	conn(xconn), game(gm), exitflag(indicator), notifier(this) {
  Display *disp = conn->display();
  unsigned int score_x;

  eng = new xsprite_engine(conn, win, COLOR_CLOSENESS);
  if (!eng) throw exception("Unable to initialize sprite engine");

  boardpane = new xtriboard(conn, eng, this, game, BOARD_X, BOARD_Y);
  score_x = BOARD_X+boardpane->ext_width();
  scorepane = new xscoreboard(conn, eng, this, game, score_x, 0,
                              WIN_WIDTH-score_x, boardpane->height());

  // Select events we're interested in
  XSelectInput(disp, win, KeyPressMask | KeyReleaseMask |
                          ButtonPressMask | ButtonReleaseMask |
                          PointerMotionMask |
                          ExposureMask |
                          FocusChangeMask);

  // Map sub-windows
  XMapSubwindows(disp, win);

  *exitflag=0;

  // Register game state watcher
  game->add_notifier(&notifier);
}

XAtom4::~XAtom4() {
  game->remove_notifier(&notifier);
  delete scorepane;
  delete boardpane;
}

void XAtom4::refresh() {
  boardpane->refresh();
  scorepane->refresh();
}

void XAtom4::expose(XExposeEvent ev) {
  int x=ev.x, y=ev.y, w=ev.width, h=ev.height;

  // nothing for now
}

void XAtom4::key_press(XKeyPressedEvent ev) {
  KeySym keysym = XLookupKeysym(&ev, 0);
  switch(keysym) {
  case XK_k:	case XK_K:
    game->reset();
    break;
  case XK_n:	case XK_N:
    if (game->round_over()) {
      game->newround();
    }
    break;
  case XK_q:	case XK_Q:
    *exitflag=1;			// signal event loop to quit
    break;
  }
}

void XAtom4::mouse_buttondown(XButtonPressedEvent ev) {
  int x=ev.x, y=ev.y;
  int bx,by;				// board coors

  if (*boardpane==ev.subwindow) {	// Event is on board window
    if (!game->is_local_turn()) return;	// not playing, nothing to do

    if (ev.button==1) {
      boardpane->calc_bcoor(x,y,bx,by);

      if (game->check_legal(bx,by)) {
        boardpane->cursor_off();
        game->move(game->current_player(), bx,by);

        // Update cursor if there's still a next turn
        if (!game->round_over()) {
          boardpane->set_cursor(game->current_tile());
        }
      } else {
        // TODO: print error message
      }
    } // endif(ev.button)
  } else {
    // For now, ignore button events anywhere else
  }
}



/*
 *
 * Class x11ui
 *
 */

x11ui::x11ui(char *xserver, atom4 *game, eventloop *loop, int *exitflag) :
	interface(game),
	conn(xserver,loop),
	game_app(&conn, game, exitflag) {

  // Make sure that all initialization X requests are sent out before we
  // enter event loop; else we might end up in a deadlock.
  XFlush(conn.display());
}

x11ui::~x11ui() {}