Mercurial > hg > xemacs-beta
comparison src/frame-x.c @ 197:acd284d43ca1 r20-3b25
Import from CVS: tag r20-3b25
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:00:02 +0200 |
parents | ecf6ba7b0a10 |
children | e45d5e7c476e |
comparison
equal
deleted
inserted
replaced
196:58e0786448ca | 197:acd284d43ca1 |
---|---|
48 #include "events.h" | 48 #include "events.h" |
49 #include "extents.h" | 49 #include "extents.h" |
50 #include "faces.h" | 50 #include "faces.h" |
51 #include "frame.h" | 51 #include "frame.h" |
52 #include "window.h" | 52 #include "window.h" |
53 | |
54 #ifdef HAVE_OFFIX_DND | |
55 #include "offix.h" | |
56 #include "events-mod.h" | |
57 #endif | |
53 | 58 |
54 /* Default properties to use when creating frames. */ | 59 /* Default properties to use when creating frames. */ |
55 Lisp_Object Vdefault_x_frame_plist; | 60 Lisp_Object Vdefault_x_frame_plist; |
56 | 61 |
57 Lisp_Object Qwindow_id; | 62 Lisp_Object Qwindow_id; |
318 classhint.res_name = frame_name; | 323 classhint.res_name = frame_name; |
319 classhint.res_class = app_class; | 324 classhint.res_class = app_class; |
320 XSetClassHint (dpy, XtWindow (shell), &classhint); | 325 XSetClassHint (dpy, XtWindow (shell), &classhint); |
321 } | 326 } |
322 | 327 |
328 #ifndef HAVE_SESSION | |
323 static void | 329 static void |
324 x_wm_maybe_store_wm_command (struct frame *f) | 330 x_wm_maybe_store_wm_command (struct frame *f) |
325 { | 331 { |
326 Widget w = FRAME_X_SHELL_WIDGET (f); | 332 Widget w = FRAME_X_SHELL_WIDGET (f); |
327 struct device *d = XDEVICE (FRAME_DEVICE (f)); | 333 struct device *d = XDEVICE (FRAME_DEVICE (f)); |
364 rest = XCDR (rest); | 370 rest = XCDR (rest); |
365 if (NILP (rest)) | 371 if (NILP (rest)) |
366 return; | 372 return; |
367 f = XFRAME (XCAR (rest)); | 373 f = XFRAME (XCAR (rest)); |
368 | 374 |
369 #ifndef HAVE_SESSION | |
370 x_wm_maybe_store_wm_command (f); | 375 x_wm_maybe_store_wm_command (f); |
371 #endif /* HAVE_SESSION */ | 376 |
372 | 377 } |
373 } | 378 } |
374 } | 379 #endif /* !HAVE_SESSION */ |
375 | 380 |
376 static int | 381 static int |
377 x_frame_iconified_p (struct frame *f) | 382 x_frame_iconified_p (struct frame *f) |
378 { | 383 { |
379 Atom actual_type; | 384 Atom actual_type; |
1164 return; | 1169 return; |
1165 } | 1170 } |
1166 #endif /* HAVE_CDE */ | 1171 #endif /* HAVE_CDE */ |
1167 | 1172 |
1168 #ifdef HAVE_OFFIX_DND | 1173 #ifdef HAVE_OFFIX_DND |
1169 #include <OffiX/DragAndDrop.h> | |
1170 | |
1171 void | |
1172 x_offix_drop_event_handler (Widget widget, XtPointer data, XEvent *event, | |
1173 Boolean *b) | |
1174 { | |
1175 int i, len, Type; | |
1176 unsigned char *Data; | |
1177 unsigned long Size; | |
1178 | |
1179 Lisp_Object path = Qnil; | |
1180 Lisp_Object frame = Qnil; | |
1181 Lisp_Object dnd_data = Qnil; | |
1182 Lisp_Object dnd_type = Qnil; | |
1183 | |
1184 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | |
1185 | |
1186 if (!DndIsDropMessage(event)) /* the better way */ | |
1187 { | |
1188 #if 0 | |
1189 stderr_out("DndDropHandler: pseudo drop received (ignore me!)\n"); | |
1190 #endif | |
1191 return; | |
1192 } | |
1193 | |
1194 Type = DndDataType (event); | |
1195 DndGetData (&Data, &Size); | |
1196 | |
1197 GCPRO4 (path, frame, dnd_data, dnd_type); | |
1198 | |
1199 frame = make_frame ((struct frame *) data); | |
1200 #if 0 | |
1201 stderr_out("DndDropHandler: valid drop received (T%d S%u)\n",Type,Size); | |
1202 #endif | |
1203 switch (Type) | |
1204 { | |
1205 case DndFiles: | |
1206 while (*Data) | |
1207 { | |
1208 len = strlen ((char*) Data); | |
1209 path = make_ext_string ((char*) Data, len, FORMAT_FILENAME); | |
1210 va_run_hook_with_args (Qdrag_and_drop_functions, 2, frame, path); | |
1211 Data += len+1; | |
1212 } | |
1213 break; | |
1214 case DndFile: | |
1215 path = make_ext_string ((char*) Data, strlen(Data), FORMAT_FILENAME); | |
1216 va_run_hook_with_args (Qdrag_and_drop_functions, 2, frame, path); | |
1217 break; | |
1218 case DndText: | |
1219 dnd_data = make_ext_string ((char *) Data, strlen(Data), FORMAT_FILENAME); | |
1220 va_run_hook_with_args (Qdrag_and_drop_functions, 3, frame, path, dnd_data); | |
1221 break; | |
1222 case DndDir: | |
1223 case DndLink: | |
1224 case DndExe: | |
1225 case DndURL: | |
1226 case DndMIME: | |
1227 dnd_type = make_int (Type); | |
1228 dnd_data = make_ext_string ((char*) Data, strlen(Data), FORMAT_FILENAME); | |
1229 va_run_hook_with_args (Qdrag_and_drop_functions, 4, | |
1230 frame, path, dnd_data, dnd_type); | |
1231 break; | |
1232 default: /* Unknown, RawData and any other type */ | |
1233 dnd_type = make_int (Type); | |
1234 dnd_data = make_ext_string ((char*) Data, Size, FORMAT_BINARY); | |
1235 va_run_hook_with_args (Qdrag_and_drop_functions, 4, | |
1236 frame, path, dnd_data, dnd_type); | |
1237 break; | |
1238 } | |
1239 | |
1240 UNGCPRO; | |
1241 return; | |
1242 } | |
1243 | 1174 |
1244 DEFUN ("offix-start-drag-internal", Foffix_start_drag_internal, 2, 3, 0, /* | 1175 DEFUN ("offix-start-drag-internal", Foffix_start_drag_internal, 2, 3, 0, /* |
1245 First arg is the event that started the drag, | 1176 First arg is the event that started the drag, |
1246 second arg should be some string. | 1177 second arg should be some string, and the third |
1178 is the type of the data (this should be an int). | |
1179 The type defaults to DndText (4). | |
1247 Start a OffiX drag from a buffer. | 1180 Start a OffiX drag from a buffer. |
1248 For now this will only drag as DndText. | |
1249 This fun is heavily stolen from the CDE Dnd stuff. | |
1250 */ | 1181 */ |
1251 (event, data, dtyp)) | 1182 (event, data, dtyp)) |
1252 { | 1183 { |
1253 if (EVENTP(event) && STRINGP (data)) | 1184 if (EVENTP(event)) |
1254 { | 1185 { |
1255 struct frame *f = decode_x_frame (Fselected_frame (Qnil)); | 1186 struct frame *f = decode_x_frame (Fselected_frame (Qnil)); |
1256 XEvent x_event; | 1187 XEvent x_event; |
1257 Widget wid = FRAME_X_TEXT_WIDGET (f); | 1188 Widget wid = FRAME_X_TEXT_WIDGET (f); |
1258 Display *display = XtDisplayOfObject (wid); | 1189 Display *display = XtDisplayOfObject (wid); |
1259 Window root_window, child_window; | 1190 struct device *d = get_device_from_display (display); |
1260 int root_x, root_y, win_x, win_y; | 1191 struct x_device *xd = DEVICE_X_DATA (d); |
1261 unsigned int keys_and_buttons; | 1192 unsigned int modifier = 0, state = 0; |
1262 char *dnd_data; | 1193 char *dnd_data = NULL; |
1263 unsigned long dnd_len; | 1194 unsigned long dnd_len = 0; |
1264 int dnd_typ; | 1195 int dnd_typ = DndText, dnd_dealloc = 0; |
1265 struct Lisp_Event *lisp_event = XEVENT(event); | 1196 struct Lisp_Event *lisp_event = XEVENT(event); |
1266 | 1197 |
1267 /* only drag if this is really a press */ | 1198 /* only drag if this is really a press */ |
1268 if (EVENT_TYPE(lisp_event) != button_press_event) | 1199 if (EVENT_TYPE(lisp_event) != button_press_event) |
1269 return Qnil; | 1200 return Qnil; |
1270 | 1201 |
1271 /* and whats with MULE data ??? */ | 1202 /* get the desired type */ |
1272 dnd_data = XSTRING_DATA (data); | |
1273 dnd_len = XSTRING_LENGTH (data) + 1; /* the f*cking zero */ | |
1274 | |
1275 /* set the type */ | |
1276 if (!NILP (dtyp) && INTP (dtyp)) | 1203 if (!NILP (dtyp) && INTP (dtyp)) |
1277 dnd_typ = XINT (dtyp); | 1204 dnd_typ = XINT (dtyp); |
1205 | |
1206 if (dnd_typ == DndFiles) | |
1207 { | |
1208 Lisp_Object run = data; | |
1209 int len = 0; | |
1210 | |
1211 if (NILP ( Flistp (data))) | |
1212 return Qnil; | |
1213 | |
1214 /* construct the data from a list of files */ | |
1215 dnd_len = 1; | |
1216 dnd_data = (char *) xmalloc (1); | |
1217 *dnd_data = 0; | |
1218 while (!NILP (run)) | |
1219 { | |
1220 if (!STRINGP (XCAR (run))) | |
1221 { | |
1222 xfree (dnd_data); | |
1223 return Qnil; | |
1224 } | |
1225 len = XSTRING_LENGTH (XCAR (run)) + 1; | |
1226 dnd_data = xrealloc (dnd_data, dnd_len + len); | |
1227 strcpy (dnd_data + dnd_len - 1, XSTRING_DATA (XCAR (run))); | |
1228 dnd_len += len; | |
1229 run = XCDR (run); | |
1230 } | |
1231 | |
1232 dnd_data[dnd_len - 1] = 0; /* the list-ending zero */ | |
1233 dnd_dealloc = 1; | |
1234 | |
1235 } | |
1278 else | 1236 else |
1279 dnd_typ = DndText; /* the default */ | 1237 { |
1238 if (!STRINGP (data)) | |
1239 return Qnil; | |
1240 | |
1241 /* and whats with MULE data ??? */ | |
1242 dnd_data = XSTRING_DATA (data); | |
1243 dnd_len = XSTRING_LENGTH (data) + 1; /* the zero */ | |
1244 | |
1245 } | |
1280 | 1246 |
1281 /* | 1247 /* |
1282 * Eek - XEmacs doesn't keep the old X event around so we have to | 1248 * Eek - XEmacs doesn't keep the old X event around so we have to |
1283 * build a dummy event. This is a truly gross hack. (from CDE) | 1249 * build a dummy event. This is a truly gross hack. (from CDE) |
1284 * | 1250 * but it works... |
1285 * Perhaps there is some way to hand back the lisp event object? | |
1286 * Best way: hand through x-event in all Lisp_Events | |
1287 */ | 1251 */ |
1288 | 1252 |
1289 x_event.xbutton.type = ButtonPress; | 1253 x_event.xbutton.type = ButtonPress; |
1290 x_event.xbutton.send_event = False; | 1254 x_event.xbutton.send_event = False; |
1291 x_event.xbutton.display = XtDisplayOfObject(wid); | 1255 x_event.xbutton.display = XtDisplayOfObject(wid); |
1295 x_event.xbutton.time = lisp_event->timestamp; | 1259 x_event.xbutton.time = lisp_event->timestamp; |
1296 x_event.xbutton.x = lisp_event->event.button.x; | 1260 x_event.xbutton.x = lisp_event->event.button.x; |
1297 x_event.xbutton.y = lisp_event->event.button.y; | 1261 x_event.xbutton.y = lisp_event->event.button.y; |
1298 x_event.xbutton.x_root = lisp_event->event.button.x; /* this is wrong */ | 1262 x_event.xbutton.x_root = lisp_event->event.button.x; /* this is wrong */ |
1299 x_event.xbutton.y_root = lisp_event->event.button.y; | 1263 x_event.xbutton.y_root = lisp_event->event.button.y; |
1300 x_event.xbutton.state = 0; /* calc state from modifier */ | 1264 |
1265 modifier = lisp_event->event.button.modifiers; | |
1266 if (modifier && MOD_SHIFT) state |= ShiftMask; | |
1267 if (modifier && MOD_CONTROL) state |= ControlMask; | |
1268 if (modifier && MOD_META) state |= xd->MetaMask; | |
1269 if (modifier && MOD_SUPER) state |= xd->SuperMask; | |
1270 if (modifier && MOD_HYPER) state |= xd->HyperMask; | |
1271 if (modifier && MOD_ALT) state |= xd->AltMask; | |
1272 state |= (Button1Mask << (lisp_event->event.button.button-1)); | |
1273 | |
1274 x_event.xbutton.state = state; | |
1301 x_event.xbutton.button = lisp_event->event.button.button; | 1275 x_event.xbutton.button = lisp_event->event.button.button; |
1302 x_event.xkey.same_screen = True; | 1276 x_event.xkey.same_screen = True; |
1303 | 1277 |
1304 DndSetData(dnd_typ, dnd_data, dnd_len); | 1278 DndSetData(dnd_typ, dnd_data, dnd_len); |
1279 if (dnd_dealloc) | |
1280 xfree (dnd_data); | |
1305 | 1281 |
1306 if (DndHandleDragging(wid, &x_event)) | 1282 if (DndHandleDragging(wid, &x_event)) |
1307 return Qt; | 1283 return Qt; |
1308 } | 1284 } |
1309 return Qnil; | 1285 return Qnil; |
2005 DtNtextIsBuffer, True, | 1981 DtNtextIsBuffer, True, |
2006 DtNpreserveRegistration, False, | 1982 DtNpreserveRegistration, False, |
2007 NULL); | 1983 NULL); |
2008 } | 1984 } |
2009 #endif /* HAVE_CDE */ | 1985 #endif /* HAVE_CDE */ |
2010 | |
2011 #ifdef HAVE_OFFIX_DND | |
2012 { | |
2013 DndInitialize (FRAME_X_SHELL_WIDGET (f)); | |
2014 DndRegisterDropWidget (FRAME_X_TEXT_WIDGET (f), | |
2015 x_offix_drop_event_handler, | |
2016 (XtPointer) f); | |
2017 | |
2018 } | |
2019 #endif | |
2020 | 1986 |
2021 /* Do a stupid property change to force the server to generate a | 1987 /* Do a stupid property change to force the server to generate a |
2022 propertyNotify event so that the event_stream server timestamp will | 1988 propertyNotify event so that the event_stream server timestamp will |
2023 be initialized to something relevant to the time we created the window. | 1989 be initialized to something relevant to the time we created the window. |
2024 */ | 1990 */ |