Mercurial > hg > xemacs-beta
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); |