comparison src/frame-x.c @ 288:e11d67e05968 r21-0b42

Import from CVS: tag r21-0b42
author cvs
date Mon, 13 Aug 2007 10:35:54 +0200
parents 57709be46d1b
children c9fe270a4101
comparison
equal deleted inserted replaced
287:13a0bd77a29d 288:e11d67e05968
55 #include "dragdrop.h" 55 #include "dragdrop.h"
56 #endif 56 #endif
57 57
58 #ifdef HAVE_OFFIX_DND 58 #ifdef HAVE_OFFIX_DND
59 #include "offix.h" 59 #include "offix.h"
60 #endif
61 #if defined (HAVE_OFFIX_DND) || defined (HAVE_CDE)
60 #include "events-mod.h" 62 #include "events-mod.h"
61 #endif 63 #endif
62 64
63 /* Default properties to use when creating frames. */ 65 /* Default properties to use when creating frames. */
64 Lisp_Object Vdefault_x_frame_plist; 66 Lisp_Object Vdefault_x_frame_plist;
988 XtPointer callData) 990 XtPointer callData)
989 { 991 {
990 DtDndConvertCallbackStruct *convertInfo = 992 DtDndConvertCallbackStruct *convertInfo =
991 (DtDndConvertCallbackStruct *) callData; 993 (DtDndConvertCallbackStruct *) callData;
992 char *textdata = (char *) clientData; 994 char *textdata = (char *) clientData;
995 char *textptr = NULL;
996 int i;
993 997
994 if(convertInfo == NULL) 998 if(convertInfo == NULL)
995 { 999 {
996 return; 1000 return;
997 } 1001 }
998 1002
999 if((convertInfo->dragData->protocol != DtDND_BUFFER_TRANSFER) || 1003 if((convertInfo->dragData->protocol != DtDND_BUFFER_TRANSFER
1004 && convertInfo->dragData->protocol != DtDND_FILENAME_TRANSFER) ||
1000 (convertInfo->reason != DtCR_DND_CONVERT_DATA)) 1005 (convertInfo->reason != DtCR_DND_CONVERT_DATA))
1001 { 1006 {
1002 return; 1007 return;
1003 } 1008 }
1004 1009
1005 convertInfo->dragData->data.buffers[0].bp = XtNewString(textdata); 1010 for (textptr=textdata, i=0;
1006 convertInfo->dragData->data.buffers[0].size = strlen(textdata); 1011 i<convertInfo->dragData->numItems;
1007 convertInfo->dragData->data.buffers[0].name = NULL; 1012 textptr+=strlen(textptr)+1, i++)
1008 convertInfo->dragData->numItems = 1; 1013 {
1014 if (convertInfo->dragData->protocol == DtDND_BUFFER_TRANSFER)
1015 {
1016 convertInfo->dragData->data.buffers[i].bp = XtNewString(textptr);
1017 convertInfo->dragData->data.buffers[i].size = strlen(textptr);
1018 convertInfo->dragData->data.buffers[i].name = NULL;
1019 }
1020 else
1021 {
1022 convertInfo->dragData->data.files[i] = XtNewString(textptr);
1023 }
1024 }
1025
1009 convertInfo->status = DtDND_SUCCESS; 1026 convertInfo->status = DtDND_SUCCESS;
1010 } 1027 }
1011 1028
1012 1029
1013 static XtCallbackRec dnd_convert_cb_rec[2]; 1030 static XtCallbackRec dnd_convert_cb_rec[2];
1023 CurrentDragWidget = NULL; 1040 CurrentDragWidget = NULL;
1024 } 1041 }
1025 return arg; 1042 return arg;
1026 } 1043 }
1027 1044
1028 DEFUN ("cde-start-drag-internal", Fcde_start_drag_internal, 1, 1, 0, /* 1045 DEFUN ("cde-start-drag-internal", Fcde_start_drag_internal, 3, 3, 0, /*
1029 Start a CDE drag from a buffer. 1046 Start a CDE drag from a buffer.
1047 First argument is the event that started the drag (must be a
1048 button-press-event),
1049 second arg defines if the data should be treated as a buffer or
1050 a filename transfer (set to nil for buffer transfer),
1051 and the third argument is a list of data strings.
1052 WARNING: can only handle plain/text and file: transfers!
1030 */ 1053 */
1031 (text)) 1054 (event, dragtype, dragdata))
1032 { 1055 {
1033 if (STRINGP (text)) 1056 if (EVENTP (event))
1034 { 1057 {
1035 struct frame *f = decode_x_frame (Fselected_frame (Qnil)); 1058 struct frame *f = decode_x_frame (Fselected_frame (Qnil));
1036 XEvent event; 1059 XEvent x_event;
1037 Widget Wuh = FRAME_X_TEXT_WIDGET (f); 1060 Widget wid = FRAME_X_TEXT_WIDGET (f);
1061 Display *display = XtDisplayOfObject (wid);
1062 struct device *d = get_device_from_display (display);
1063 struct x_device *xd = DEVICE_X_DATA (d);
1064 unsigned int modifier = 0, state = 0;
1038 char *Ctext; 1065 char *Ctext;
1039 Display *display = XtDisplayOfObject (Wuh); 1066 int numItems = 0, textlen = 0, pos = 0;
1040 Window root_window, child_window; 1067 struct Lisp_Event *lisp_event = XEVENT(event);
1041 int root_x, root_y, win_x, win_y; 1068 Lisp_Object item = Qnil;
1042 unsigned int keys_and_buttons; 1069 struct gcpro gcpro1;
1043 1070
1044 if (XQueryPointer (display, RootWindow (display, DefaultScreen (display)), 1071 /* only drag if this is really a press */
1045 &root_window, &child_window, &root_x, &root_y, 1072 if (EVENT_TYPE(lisp_event) != button_press_event
1046 &win_x, &win_y, &keys_and_buttons) == False) 1073 || !LISTP(dragdata))
1047 return Qnil; 1074 return Qnil;
1048 1075
1049 Ctext = xstrdup ((char *) XSTRING_DATA (text)); 1076 GCPRO1 (item);
1050 1077
1051 /* 1078 /*
1052 * Eek - XEmacs doesn't keep the old X event around so we have to 1079 * not so cross hack that converts a emacs event back to a XEvent
1053 * build a dummy event. This is a truly gross hack.
1054 */ 1080 */
1055 1081
1056 event.xbutton.type = ButtonPress; 1082 x_event.xbutton.type = ButtonPress;
1057 event.xbutton.send_event = False; 1083 x_event.xbutton.send_event = False;
1058 event.xbutton.display = XtDisplayOfObject(Wuh); 1084 x_event.xbutton.display = XtDisplayOfObject(wid);
1059 event.xbutton.window = XtWindowOfObject(Wuh); 1085 x_event.xbutton.window = XtWindowOfObject(wid);
1060 event.xbutton.root = XRootWindow(event.xkey.display, 0); 1086 x_event.xbutton.root = XRootWindow(x_event.xkey.display, 0);
1061 event.xbutton.subwindow = 0; 1087 x_event.xbutton.subwindow = 0;
1062 event.xbutton.time = 0; 1088 x_event.xbutton.time = lisp_event->timestamp;
1063 event.xbutton.x = win_x; 1089 x_event.xbutton.x = lisp_event->event.button.x;
1064 event.xbutton.y = win_y; 1090 x_event.xbutton.y = lisp_event->event.button.y;
1065 event.xbutton.x_root = root_x; 1091 x_event.xbutton.x_root = lisp_event->event.button.x; /* this is wrong */
1066 event.xbutton.y_root = root_y; 1092 x_event.xbutton.y_root = lisp_event->event.button.y;
1067 event.xbutton.state = 0; 1093
1068 event.xbutton.button = 1; 1094 modifier = lisp_event->event.button.modifiers;
1069 event.xkey.same_screen = True; 1095 if (modifier & MOD_SHIFT) state |= ShiftMask;
1070 1096 if (modifier & MOD_CONTROL) state |= ControlMask;
1071 dnd_convert_cb_rec[0].callback = x_cde_convert_callback; 1097 if (modifier & MOD_META) state |= xd->MetaMask;
1072 dnd_convert_cb_rec[0].closure = (XtPointer) Ctext; 1098 if (modifier & MOD_SUPER) state |= xd->SuperMask;
1073 dnd_convert_cb_rec[1].callback = NULL; 1099 if (modifier & MOD_HYPER) state |= xd->HyperMask;
1074 dnd_convert_cb_rec[1].closure = NULL; 1100 if (modifier & MOD_ALT) state |= xd->AltMask;
1075 1101 state |= Button1Mask << (lisp_event->event.button.button-1);
1076 dnd_destroy_cb_rec[0].callback = x_cde_destroy_callback; 1102
1077 dnd_destroy_cb_rec[0].closure = (XtPointer) Ctext; 1103 x_event.xbutton.state = state;
1078 dnd_destroy_cb_rec[1].callback = NULL; 1104 x_event.xbutton.button = lisp_event->event.button.button;
1079 dnd_destroy_cb_rec[1].closure = NULL; 1105 x_event.xkey.same_screen = True;
1080 1106
1081 CurrentDragWidget = 1107 /* convert data strings into a big string */
1082 DtDndDragStart (Wuh, &event, DtDND_BUFFER_TRANSFER, 1, XmDROP_COPY, 1108 item = dragdata;
1083 dnd_convert_cb_rec, 1109 while (!NILP (item))
1084 dnd_destroy_cb_rec, 1110 {
1085 NULL, 0); 1111 if (!STRINGP (XCAR (item)))
1086 return Qt; 1112 {
1087 } 1113 numItems=0;
1114 break;
1115 }
1116 textlen += XSTRING_LENGTH (XCAR (item)) + 1;
1117 numItems++;
1118 item = XCDR (item);
1119 }
1120
1121 if (numItems)
1122 {
1123 /*
1124 * concatenate all strings given to one large string, with
1125 * \0 as separator. List is ended by \0.
1126 */
1127 Ctext = (char *)xmalloc (textlen+1);
1128 Ctext[0] = 0;
1129
1130 item = dragdata;
1131 while (!NILP (item))
1132 {
1133 if (!STRINGP (XCAR (item)))
1134 {
1135 numItems=0;
1136 xfree(Ctext);
1137 Ctext=NULL;
1138 break;
1139 }
1140 strcpy (Ctext+pos, (CONST char *)XSTRING_DATA (XCAR (item)));
1141 pos += XSTRING_LENGTH (XCAR (item)) + 1;
1142 item = XCDR (item);
1143 }
1144 Ctext[pos] = 0;
1145
1146 dnd_convert_cb_rec[0].callback = x_cde_convert_callback;
1147 dnd_convert_cb_rec[0].closure = (XtPointer) Ctext;
1148 dnd_convert_cb_rec[1].callback = NULL;
1149 dnd_convert_cb_rec[1].closure = NULL;
1150
1151 dnd_destroy_cb_rec[0].callback = x_cde_destroy_callback;
1152 dnd_destroy_cb_rec[0].closure = (XtPointer) Ctext;
1153 dnd_destroy_cb_rec[1].callback = NULL;
1154 dnd_destroy_cb_rec[1].closure = NULL;
1155
1156 CurrentDragWidget =
1157 DtDndDragStart (wid, &x_event,
1158 (NILP(dragtype)?DtDND_BUFFER_TRANSFER:DtDND_FILENAME_TRANSFER),
1159 numItems,
1160 XmDROP_COPY,
1161 dnd_convert_cb_rec,
1162 dnd_destroy_cb_rec,
1163 NULL, 0);
1164 }
1165
1166 UNGCPRO;
1167
1168 return numItems?Qt:Qnil;
1169 }
1170
1088 return Qnil; 1171 return Qnil;
1089 } 1172 }
1090 1173
1091 static void 1174 static void
1092 x_cde_transfer_callback (Widget widget, XtPointer clientData, 1175 x_cde_transfer_callback (Widget widget, XtPointer clientData,
1176 #endif /* HAVE_CDE */ 1259 #endif /* HAVE_CDE */
1177 1260
1178 #ifdef HAVE_OFFIX_DND 1261 #ifdef HAVE_OFFIX_DND
1179 1262
1180 DEFUN ("offix-start-drag-internal", Foffix_start_drag_internal, 2, 3, 0, /* 1263 DEFUN ("offix-start-drag-internal", Foffix_start_drag_internal, 2, 3, 0, /*
1264 Start a OffiX drag from a buffer.
1181 First arg is the event that started the drag, 1265 First arg is the event that started the drag,
1182 second arg should be some string, and the third 1266 second arg should be some string, and the third
1183 is the type of the data (this should be an int). 1267 is the type of the data (this should be an int).
1184 The type defaults to DndText (4). 1268 The type defaults to DndText (4).
1185 Start a OffiX drag from a buffer.
1186 */ 1269 */
1187 (event, data, dtyp)) 1270 (event, data, dtyp))
1188 { 1271 {
1189 if (EVENTP(event)) 1272 if (EVENTP(event))
1190 { 1273 {
1248 dnd_len = XSTRING_LENGTH (data) + 1; /* the zero */ 1331 dnd_len = XSTRING_LENGTH (data) + 1; /* the zero */
1249 1332
1250 } 1333 }
1251 1334
1252 /* 1335 /*
1253 * Eek - XEmacs doesn't keep the old X event around so we have to 1336 * not so cross hack that converts a emacs event back to a XEvent
1254 * build a dummy event. This is a truly gross hack. (from CDE)
1255 * but it works...
1256 */ 1337 */
1257 1338
1258 x_event.xbutton.type = ButtonPress; 1339 x_event.xbutton.type = ButtonPress;
1259 x_event.xbutton.send_event = False; 1340 x_event.xbutton.send_event = False;
1260 x_event.xbutton.display = XtDisplayOfObject(wid); 1341 x_event.xbutton.display = XtDisplayOfObject(wid);