00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 # include <config.h>
00023 #endif
00024
00025 #if defined(USE_EXULTSTUDIO) && !defined(WIN32)
00026
00027 #include <iostream>
00028 #include <X11/X.h>
00029 #include <X11/Xlib.h>
00030 #include <X11/Xatom.h>
00031 #include "xdrag.h"
00032 #include "u7drag.h"
00033
00034 using std::cout;
00035 using std::endl;
00036
00037
00038
00039
00040
00041 static void Get_window_coords
00042 (
00043 Display *display,
00044 Window win,
00045 int &sx, int& sy
00046 )
00047 {
00048 Window root, parent;
00049 Window *children;
00050 unsigned int nchildren;
00051 XQueryTree(display, win, &root, &parent, &children, &nchildren);
00052 if (children)
00053 XFree(children);
00054 if (parent && parent != root)
00055 Get_window_coords(display, parent, sx, sy);
00056 else
00057 sx = sy = 0;
00058 XWindowAttributes atts;
00059 XGetWindowAttributes(display, win, &atts);
00060 sx += atts.x;
00061 sy += atts.y;
00062 }
00063
00064
00065
00066
00067
00068 Xdnd::Xdnd
00069 (
00070 Display *d,
00071 Window xw,
00072 Window xgw,
00073 Move_shape_handler_fun movefun,
00074 Move_combo_handler_fun movecmbfun,
00075 Drop_shape_handler_fun shapefun,
00076 Drop_chunk_handler_fun cfun,
00077 Drop_combo_handler_fun cmbfun
00078 ) : display(d), xwmwin(xw), xgamewin(xgw),
00079 num_types(0), lastx(-1), lasty(-1),
00080 file(-1), shape(-1), frame(-1), chunknum(-1),
00081 combo_cnt(-1), combo(0), combo_xtiles(0), combo_ytiles(0),
00082 data_valid(false), move_shape_handler(movefun),
00083 move_combo_handler(movecmbfun),
00084 shape_handler(shapefun), chunk_handler(cfun),
00085 combo_handler(cmbfun)
00086 {
00087 shapeid_atom = XInternAtom(display, U7_TARGET_SHAPEID_NAME, 0);
00088 chunkid_atom = XInternAtom(display, U7_TARGET_CHUNKID_NAME, 0);
00089 comboid_atom = XInternAtom(display, U7_TARGET_COMBOID_NAME, 0);
00090
00091 xdnd_aware = XInternAtom(display, "XdndAware", 0);
00092 xdnd_enter = XInternAtom(display, "XdndEnter", 0);
00093 xdnd_leave = XInternAtom(display, "XdndLeave", 0);
00094 xdnd_position = XInternAtom(display, "XdndPosition", 0);
00095 xdnd_drop = XInternAtom(display, "XdndDrop", 0);
00096 xdnd_status = XInternAtom(display, "XdndStatus", 0);
00097 xdnd_copy = XInternAtom(display, "XdndActionCopy", 0);
00098 xdnd_ask = XInternAtom(display, "XdndActionAsk", 0);
00099 xdnd_typelist = XInternAtom(display, "XdndTypeList", 0);
00100 xdnd_selection = XInternAtom(display, "XdndSelection", 0);
00101 xdnd_version = 3;
00102
00103 if (xwmwin)
00104 XChangeProperty(display, xwmwin, xdnd_aware, XA_ATOM, 32,
00105 PropModeReplace, reinterpret_cast<unsigned char *>(
00106 &xdnd_version), 1);
00107 }
00108
00109
00110
00111
00112
00113 Xdnd::~Xdnd
00114 (
00115 )
00116 {
00117 delete combo;
00118 }
00119
00120
00121
00122
00123
00124 void Xdnd::client_msg
00125 (
00126 XClientMessageEvent& cev
00127 )
00128 {
00129 cout << "Xwin client msg. received." << endl;
00130 char *nm = XGetAtomName(display, cev.message_type);
00131 if (nm)
00132 cout << "Type = " << nm << endl;
00133 XEvent xev;
00134 xev.xclient.type = ClientMessage;
00135 Window drag_win = cev.data.l[0];
00136 xev.xclient.format = 32;
00137 xev.xclient.window = drag_win;
00138 xev.xclient.data.l[0] = xwmwin;
00139 if (cev.message_type == xdnd_enter)
00140 {
00141 data_valid = false;
00142 if (cev.data.l[1]&1)
00143 {
00144 Atom type;
00145 int format;
00146 unsigned long nitems, after;
00147 Atom *data;
00148 XGetWindowProperty(display, drag_win,
00149 xdnd_typelist, 0, 65536,
00150 false, XA_ATOM, &type, &format, &nitems,
00151 &after, reinterpret_cast<unsigned char **>(
00152 &data));
00153 if (format != 32 || type != XA_ATOM)
00154 return;
00155 if (nitems > max_types)
00156 nitems = max_types;
00157 for (num_types = 0; num_types < nitems; num_types++)
00158 drag_types[num_types] = data[num_types];
00159 }
00160 else
00161 {
00162 num_types = 0;
00163 for (int i = 0; i < 3; i++)
00164 if (cev.data.l[2+i])
00165 drag_types[num_types++] =
00166 cev.data.l[2+i];
00167 cout << "num_types = " << num_types << endl;
00168 }
00169
00170 Get_window_coords(display, xgamewin, winx, winy);
00171 }
00172 else if (cev.message_type == xdnd_position)
00173 {
00174 int i;
00175 for (i = 0; i < num_types; i++)
00176 if (drag_types[i] == shapeid_atom ||
00177 drag_types[i] == chunkid_atom ||
00178 drag_types[i] == comboid_atom)
00179 break;
00180 xev.xclient.message_type = xdnd_status;
00181
00182 xev.xclient.data.l[1] = i < num_types ? 3 : 0;
00183
00184 xev.xclient.data.l[2] = 0;
00185 xev.xclient.data.l[3] = 0;
00186 xev.xclient.data.l[4] = xdnd_copy;
00187 XSendEvent(display, drag_win, false, 0, &xev);
00188
00189 int x = ((cev.data.l[2]>>16)&0xffff) - winx;
00190 int y = (cev.data.l[2]&0xffff) - winy;
00191
00192 unsigned long time = 0;
00193 if (i == num_types)
00194 return;
00195 if (!data_valid)
00196 XConvertSelection(display, xdnd_selection,
00197 drag_types[i], xdnd_selection, xwmwin, time);
00198 else if (file == U7_SHAPE_SHAPES)
00199 (*move_shape_handler)(shape, frame, x,y,
00200 lastx, lasty, true);
00201 else if (combo_cnt > 0)
00202 (*move_combo_handler)(combo_xtiles, combo_ytiles,
00203 combo_tiles_right, combo_tiles_below,
00204 x, y, lastx, lasty, true);
00205 lastx = x;
00206 lasty = y;
00207 }
00208 else if (cev.message_type == xdnd_leave)
00209 {
00210 num_types = 0;
00211
00212 (*move_shape_handler)(-1, -1, 0, 0, lastx, lasty, true);
00213 data_valid = false;
00214 }
00215 else if (cev.message_type == xdnd_drop)
00216 {
00217 int i;
00218 for (i = 0; i < num_types; i++)
00219 if (drag_types[i] == shapeid_atom ||
00220 drag_types[i] == chunkid_atom ||
00221 drag_types[i] == comboid_atom)
00222 break;
00223 bool okay = data_valid && i < num_types;
00224 num_types = 0;
00225 if (!okay)
00226 return;
00227 if (shape >= 0)
00228 {
00229 if (file == U7_SHAPE_SHAPES)
00230
00231 (*shape_handler)(shape, frame, lastx,lasty, 0);
00232 }
00233 else if (chunknum >= 0)
00234 (*chunk_handler)(chunknum, lastx, lasty, 0);
00235 else if (combo_cnt >= 0 && combo)
00236 (*combo_handler)(combo_cnt, combo, lastx, lasty, 0);
00237
00238 data_valid = false;
00239 }
00240 }
00241
00242
00243
00244
00245
00246 void Xdnd::select_msg
00247 (
00248 XSelectionEvent& sev
00249 )
00250 {
00251 cout << "SelectionEvent received with target type: " <<
00252 XGetAtomName(display, sev.target) << endl;
00253 if (sev.selection != xdnd_selection ||
00254 (sev.target != shapeid_atom && sev.target != chunkid_atom &&
00255 sev.target != comboid_atom) ||
00256 sev.property == None)
00257 return;
00258 cout << "HERE" << endl;
00259 file = shape = frame = -1;
00260 chunknum = -1;
00261 combo_cnt = -1;
00262 combo_xtiles = combo_ytiles = 0;
00263 delete combo;
00264 combo = 0;
00265 Atom type = None;
00266 int format;
00267 unsigned long nitems, after;
00268 unsigned char *data;
00269 if (XGetWindowProperty(display, sev.requestor, sev.property,
00270 0, 65000, False, AnyPropertyType,
00271 &type, &format, &nitems, &after, &data) != Success)
00272 {
00273 cout << "Error in getting selection" << endl;
00274 return;
00275 }
00276 if (sev.target == shapeid_atom)
00277 {
00278
00279 Get_u7_shapeid(data, file, shape, frame);
00280 data_valid = true;
00281 }
00282 else if (sev.target == chunkid_atom)
00283 {
00284 Get_u7_chunkid(data, chunknum);
00285 data_valid = true;
00286 }
00287 else if (sev.target == comboid_atom)
00288 {
00289 Get_u7_comboid(data, combo_xtiles, combo_ytiles,
00290 combo_tiles_right, combo_tiles_below, combo_cnt, combo);
00291 cout << "Combo: xtiles=" << combo_xtiles << ", ytiles=" << combo_ytiles <<
00292 ", tiles_right=" << combo_tiles_right << ", tiles_below=" <<
00293 combo_tiles_below << endl;
00294 data_valid = true;
00295 }
00296 XFree(data);
00297 }
00298
00299
00300 #endif
00301
00302