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(¬ifier);
}
XAtom4::~XAtom4() {
game->remove_notifier(¬ifier);
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() {}
|