1 /* $TOG: dnd.c /main/12 1998/04/09 11:43:47 mgreess $ */
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company
4 * (c) Copyright 1993, 1994 International Business Machines Corp.
5 * (c) Copyright 1993, 1994 Novell, Inc.
6 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
24 #include <Xm/DragIcon.h>
25 #include <Xm/AtomMgr.h>
26 #include <Xm/ToggleBG.h>
34 #include "group_editor.h"
49 #include "drag_mask_xbm"
51 static Bool lookForButton(Display *, XEvent *, XPointer);
54 extern char *sys_errlist[];
57 extern int drag_load_proc(char*, Calendar *);
58 static char dnd_filename[20];
61 validate_dropped_appt(char *filename, Calendar *c) {
62 Props *p = (Props *)c->properties;
63 Props_pu *pu = (Props_pu *)c->properties_pu;
64 CmDataList *list = CmDataListCreate();
69 if (!filename || *filename == '\0')
72 op = parse_appt_from_file(c->DT_catd, filename, list, p, query_user,
73 (void *)c, c->general->version);
75 for (i = 1; i <= list->count; i++)
76 if (a = (Dtcm_appointment *)CmDataListGetData(list, i))
78 CmDataListDestroy(list, B_FALSE);
90 XtPointer client_data,
93 DtDndDropAnimateCallbackStruct *animateInfo = (DtDndDropAnimateCallbackStruct *)call_data;
99 #if defined(FNS) && defined(FNS_DEMO)
104 c = (Calendar *)client_data;
106 for (i = 0; i < animateInfo->dropData->numItems; i++) {
107 switch(animateInfo->dropData->protocol) {
108 case DtDND_FILENAME_TRANSFER:
109 data = animateInfo->dropData->data.files[i];
111 #if defined(FNS) && defined(FNS_DEMO)
112 if (cmfns_use_fns(c->properties) &&
113 cmfns_name_from_file(data, buf, sizeof(buf)) == 1) {
115 * Looks like an HFS file has been dropped on us.
116 * Get the calendar service associated with the
117 * FNS name and browse it
119 if (cmfns_lookup_calendar(buf,
120 addr_buf, sizeof(addr_buf)) == 1) {
122 switch_it(c, addr_buf, main_win);
127 drag_load_proc(data, c);
129 case DtDND_BUFFER_TRANSFER:
132 * Save data to a file so we can pass it to drag_load_proc().
136 strcpy(filename, "/tmp/cmXXXXXX");
140 if (!dnd_filename[0]){
146 if ((fp = fopen(dnd_filename, "w")) == 0) {
150 data = animateInfo->dropData->data.buffers[0].bp;
151 size = animateInfo->dropData->data.buffers[0].size;
152 fwrite(data, 1, size, fp);
156 drag_load_proc(dnd_filename, c);
158 unlink(dnd_filename);
159 dnd_filename[0] = NULL;
172 XtPointer client_data,
175 Display *display = XtDisplay(w);
176 DtDndDropCallbackStruct *transfer_info = (DtDndDropCallbackStruct *)call_data;
183 #if defined(FNS) && defined(FNS_DEMO)
188 c = (Calendar *)client_data;
190 transfer_info->status = DtDND_SUCCESS;
192 for (i = 0; i < transfer_info->dropData->numItems; i++) {
193 switch(transfer_info->dropData->protocol) {
194 case DtDND_FILENAME_TRANSFER:
195 data = transfer_info->dropData->data.files[i];
197 #if defined(FNS) && defined(FNS_DEMO)
198 if (cmfns_use_fns(c->properties) &&
199 cmfns_name_from_file(data, buf, sizeof(buf)) == 1) {
201 * Looks like an HFS file has been dropped on us.
202 * Get the calendar service associated with the
203 * FNS name and browse it
205 if (cmfns_lookup_calendar(buf,
206 addr_buf, sizeof(addr_buf)) == 1) {
208 switch_it(c, addr_buf, main_win);
214 if (validate_dropped_appt(data, c) == False) {
215 transfer_info->status = DtDND_FAILURE;
218 case DtDND_BUFFER_TRANSFER:
221 * Save data to a file so we can pass it to drag_load_proc().
223 strcpy(dnd_filename, "/tmp/cmXXXXXX");
224 mktemp(dnd_filename);
226 if ((fp = fopen(dnd_filename, "w")) == 0) {
227 transfer_info->status = DtDND_FAILURE;
231 data = transfer_info->dropData->data.buffers[0].bp;
232 size = transfer_info->dropData->data.buffers[0].size;
233 fwrite(data, 1, size, fp);
236 if (validate_dropped_appt(dnd_filename, c) == False) {
237 unlink(dnd_filename);
238 dnd_filename[0] = NULL;
239 transfer_info->status = DtDND_FAILURE;
246 transfer_info->status = DtDND_FAILURE;
255 cm_register_drop_site(
260 XtCallbackRec transfer_cb_rec[] = { {handle_drop_cb, NULL},
262 static XtCallbackRec animateCBRec[] = { {handle_animate_cb, NULL},
264 Display *display = XtDisplayOfObject(w);
267 * The above string "CalendarAppointment" is hard coded to match the type
268 * used in dtdnddemo. In the future we need to use the true
269 * type from the data typing database
272 transfer_cb_rec[0].closure = (XtPointer)c;
273 animateCBRec[0].closure = (XtPointer)c;
275 DtDndVaDropRegister(w, DtDND_FILENAME_TRANSFER | DtDND_BUFFER_TRANSFER,
278 DtNdropAnimateCallback, animateCBRec,
279 DtNtextIsBuffer, True,
285 * Insert the appointment into the calendar.
289 * 0 User overuled. Appointment not inserted.
293 schedule_appt(Calendar *c, Dtcm_appointment *a) {
294 char date_buf[MAXNAMELEN], buf[BUFSIZ], buf2[BUFSIZ];
296 Editor *e = (Editor *)c->editor;
297 ToDo *t = (ToDo *)c->todo;
298 Props *p = (Props *)c->properties;
299 CSA_entry_handle entry;
300 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
301 SeparatorType st = get_int_prop(p, CP_DATESEPARATOR);
305 if (strcmp(c->calname, c->view->current_calendar) != 0) {
307 * Make sure user really meant to insert appointment
308 * into somebody elses calendar.
310 char *ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
311 char *title = XtNewString(catgets(c->DT_catd, 1, 212,
312 "Calendar : Schedule Appointment"));
313 sprintf(buf, "%s", catgets(c->DT_catd, 1, 210, "The appointment will be scheduled in the calendar\nyou are currently browsing. Do you still want to schedule it?"));
314 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 211, "Schedule in"),
315 c->view->current_calendar);
316 answer = dialog_popup(c->frame,
319 BUTTON_IDENT, 1, ident,
320 BUTTON_IDENT, 2, buf2,
329 if (!editor_created(e))
332 XtUnmanageChild(e->base_form_mgr);
333 e->editor_is_up = False;
335 if ((rc = editor_insert(a, &entry, c)) == True) {
337 _csa_iso8601_to_tick(a->time->value->item.string_value, &tick);
338 format_tick(tick, ot, st, date_buf);
339 sprintf(buf, catgets(c->DT_catd, 1, 214,
340 "Appointment scheduled: %s"), date_buf);
341 set_message(c->message_text, buf);
344 set_message(c->message_text, "");
353 XtUnmanageChild(t->frame);
354 t->todo_is_up = False;
356 if (todo_insert(a, &entry, c)) {
358 * No messages displayed on calendar for todo.
363 * No messages displayed on calendar for todo.
371 * Call the routines in file_parse (in libDtCm) to read the appointments!
374 drag_load_proc(char *filename, Calendar *c) {
376 char buf[MAXNAMELEN * 2];
377 CmDataList *list = CmDataListCreate();
378 Props *p = (Props *)c->properties;
379 Props_pu *pu = (Props_pu *)c->properties_pu;
384 if (!filename || *filename == '\0')
387 op = parse_appt_from_file(c->DT_catd, filename, list, p, query_user,
388 (void *)c, c->general->version);
389 if (list->count <= 0) {
391 sprintf(buf, "%s", catgets(c->DT_catd, 1, 842,
392 "The information transferred did not\ncontain any appointments."));
396 case COULD_NOT_OPEN_FILE:
397 msg = XtNewString(catgets(c->DT_catd, 1, 843,
398 "Drag and Drop operation failed."));
399 sprintf(buf, "%s\n%s",
401 catgets(c->DT_catd, 1, 844,
402 "Unable to locate the transferred information."));
407 catgets(c->DT_catd, 1, 218, "Invalid DATE specified"));
410 sprintf(buf, "%s", catgets(c->DT_catd, 1, 219,
411 "Invalid START time specified"));
414 sprintf(buf, "%s", catgets(c->DT_catd, 1, 220,
415 "Invalid END time specified"));
418 sprintf(buf, "%s", catgets(c->DT_catd, 1, 221,
419 "Empty or missing DATE field"));
422 sprintf(buf, "%s", catgets(c->DT_catd, 1, 222,
423 "Empty or missing START field"));
426 sprintf(buf, "%s", catgets(c->DT_catd, 1, 223,
427 "Empty or missing WHAT field"));
429 case REPEAT_FOR_MISMATCH:
430 sprintf(buf, "%s", catgets(c->DT_catd, 1, 224,
431 "REPEAT and FOR field mismatch"));
436 sprintf(buf, "%s", catgets(c->DT_catd, 1, 225,
437 "Schedule appointment was cancelled."));
441 sprintf(buf, "%s", catgets(c->DT_catd, 1, 225,
442 "Schedule appointment was cancelled."));
446 while (op == VALID_APPT && i <= list->count) {
447 extern void scrub_attr_list(Dtcm_appointment *);
449 a = (Dtcm_appointment *)CmDataListGetData(list, i);
453 ret_val = schedule_appt(c, a);
456 sprintf(buf, "%s", catgets(c->DT_catd, 1, 226,
457 "Internal error scheduling appointment."));
458 } else if (ret_val == 0) {
460 sprintf(buf, "%s", catgets(c->DT_catd, 1, 225,
461 "Schedule appointment was cancelled."));
466 for (i = 1; i <= list->count; i++)
467 if (a = (Dtcm_appointment *)CmDataListGetData(list, i))
468 free_appt_struct(&a);
469 CmDataListDestroy(list, B_FALSE);
471 if (op != VALID_APPT) {
472 char *title = XtNewString(catgets(c->DT_catd, 1, 1073,
473 "Calendar : Error - Drag and Drop"));
474 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
475 dialog_popup(c->frame,
478 BUTTON_IDENT, 1, ident,
479 BUTTON_HELP, DND_ERROR_HELP,
480 DIALOG_IMAGE, pu->xm_error_pixmap,
490 /* gets a pointer to the currently selected appointment in the editor.
491 This will need to be changed if we ever allow more than one item
492 to be selected in the editor at a time. */
495 get_appt_struct(DragContext *context) {
496 int *item_list = NULL, item_cnt = 0, answer;
497 char buf[MAXNAMELEN];
499 Calendar *c = context->calendar;
501 CSA_entry_handle entry;
504 pr = (Props_pu *)(c->properties_pu);
506 if (context->editor_type == SingleEditorList)
507 list = ((Editor *) context->editor)->appt_list;
508 else if (context->editor_type == GroupEditorList)
509 list = ((GEditor *) context->editor)->appt_list;
510 else if (context->editor_type == TodoEditorList)
511 list = ((ToDo *) context->editor)->todo_list;
513 if (!XmListGetSelectedPos(list, &item_list, &item_cnt)) {
514 char *title = XtNewString(catgets(c->DT_catd, 1, 230,
515 "Calendar : Error - Drag Appointment"));
516 char *text = XtNewString(catgets(c->DT_catd, 1, 231, "Select an appointment and DRAG again."));
517 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
518 answer = dialog_popup(c->frame,
521 BUTTON_IDENT, 1, ident,
522 BUTTON_HELP, RESELECT_ERROR_HELP,
523 DIALOG_IMAGE, pr->xm_error_pixmap,
532 if (context->editor_type == SingleEditorList)
533 entry = editor_nth_appt((Editor *)context->editor,
535 else if (context->editor_type == GroupEditorList)
536 entry = geditor_nth_appt((GEditor *)context->editor,
537 item_list[0] - 1, &ad);
538 else if (context->editor_type == TodoEditorList)
539 entry = t_nth_appt((ToDo *)context->editor,
544 char *title = XtNewString(catgets(c->DT_catd, 1, 230,
545 "Calendar : Error - Drag Appointment"));
546 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
547 sprintf(buf, "%s", catgets(c->DT_catd, 1, 845,
548 "Drag and Drop operation Failed\nInternal consistency error."));
549 answer = dialog_popup(c->frame,
552 BUTTON_IDENT, 1, ident,
553 DIALOG_IMAGE, pr->xm_error_pixmap,
557 XtFree((XtPointer)item_list);
567 * Fills in data object with calendar appointment string based on which
568 * appointment in the list was under the pointer when the drag started.
573 XtPointer clientData,
576 DtDndConvertCallbackStruct *convertInfo
577 = (DtDndConvertCallbackStruct*)callData;
578 DtDndBuffer *data = &(convertInfo->dragData->data.buffers[0]);
579 DragContext *context = (DragContext *)clientData;
580 Display *display = XtDisplay(dragContext);
582 = XmInternAtom(display, "CalendarAppointment", False);
583 Calendar *c = context->calendar;
585 if (convertInfo->reason != DtCR_DND_CONVERT_DATA)
588 /* REMIND: Need to check convertInfo->reason, handle DELETE, etc */
590 data->bp = XtNewString(context->data);
591 data->size = strlen(data->bp);
592 data->name = XtNewString(catgets(c->DT_catd, 1, 236, "CalendarAppointment"));
598 * Returns a new IconInfo structure with bitmap, mask, width, height,
599 * icon type and name.
602 GetIcon(Calendar *calendar)
605 Display *display = XtDisplay(calendar->frame);
606 Window window = XtWindow(calendar->frame);
607 unsigned char *bitmapData, *bitmapMask;
608 Editor *e = (Editor *) calendar->editor;
609 GEditor *ge = (GEditor *) calendar->geditor;
611 if (e->drag_bitmap == NULL) {
612 e->drag_bitmap = XCreateBitmapFromData(display,
613 window, (char *) drag_xbm_bits,
614 drag_xbm_width, drag_xbm_height);
615 if (e->drag_bitmap == NULL) {
617 printf(catgets(calendar->DT_catd, 1, 237, "XCreateBitmapFromData() failed for bitmap.\n"));
621 ge->drag_bitmap = e->drag_bitmap;
623 if (e->drag_mask == NULL) {
624 e->drag_mask = XCreateBitmapFromData(display,
625 window, (char *) drag_mask_xbm_bits,
626 drag_mask_xbm_width, drag_mask_xbm_height);
627 if (e->drag_mask == NULL) {
628 printf(catgets(calendar->DT_catd, 1, 238, "XCreateBitmapFromData() failed for mask.\n"));
632 ge->drag_mask = e->drag_mask;
639 * Resets drag state to indicate the drag is over. Free memory allocated
645 XtPointer clientData,
648 DragContext *context = (DragContext *) clientData;
653 if ((context->editor_type == SingleEditorList) ||
654 (context->editor_type == SingleEditorIcon))
655 ((Editor *) context->editor)->doing_drag = False;
656 else if ((context->editor_type == TodoEditorList) ||
657 (context->editor_type == TodoEditorIcon))
658 ((ToDo *) context->editor)->doing_drag = False;
659 else if ((context->editor_type == GroupEditorList) ||
660 (context->editor_type == GroupEditorIcon))
661 ((GEditor *) context->editor)->doing_drag = False;
670 CreateDragSourceIcon(
677 int pixmapX, pixmapY;
678 unsigned int pixmapWidth, pixmapHeight, pixmapBorder, pixmapDepth;
682 XGetGeometry (XtDisplayOfObject(widget), pixmap, &rootWindow,
683 &pixmapX, &pixmapY, &pixmapWidth, &pixmapHeight,
684 &pixmapBorder, &pixmapDepth);
686 XtSetArg(args[nn], XmNwidth, pixmapWidth); nn++;
687 XtSetArg(args[nn], XmNheight, pixmapHeight); nn++;
688 XtSetArg(args[nn], XmNmaxWidth, pixmapWidth); nn++;
689 XtSetArg(args[nn], XmNmaxHeight, pixmapHeight); nn++;
690 XtSetArg(args[nn], XmNpixmap, pixmap); nn++;
691 XtSetArg(args[nn], XmNmask, mask); nn++;
692 XtSetArg(args[nn], XmNdepth, pixmapDepth); nn++;
693 dragIcon = XmCreateDragIcon(widget, "sourceIcon", args, nn);
699 TranslationDragStart(
703 Cardinal *num_params)
705 static XtCallbackRec convertCBRec[] = { {ApptConvertCB, NULL},
707 static XtCallbackRec dragFinishCBRec[] = { {DragFinishCB, NULL},
710 Display *display = XtDisplay(widget);
711 DragContext *context = calloc(sizeof(DragContext), 1);
712 Editor *e = (Editor *) calendar->editor;
713 CSA_entry_handle entry;
715 Props *p = (Props *)calendar->properties;
717 context->calendar = calendar;
719 if (((Editor *)calendar->editor)->appt_list == widget) {
720 context->editor_type = SingleEditorList;
721 context->editor = (caddr_t) calendar->editor;
722 } else if (((GEditor *)calendar->geditor)->appt_list == widget) {
723 context->editor_type = GroupEditorList;
724 context->editor = (caddr_t) calendar->geditor;
725 } else if (((ToDo *)calendar->todo)->todo_list == widget) {
726 context->editor_type = TodoEditorList;
727 context->editor = (caddr_t) calendar->todo;
735 if (((entry = get_appt_struct(context)) == (CSA_entry_handle)NULL) ||
736 ((apptstr = parse_appt_to_string(calendar->cal_handle,
738 calendar->general->version))
741 switch (context->editor_type)
743 case SingleEditorList:
744 ((Editor *)context->editor)->doing_drag = False;
747 case GroupEditorList:
748 ((GEditor *)context->editor)->doing_drag = False;
752 ((ToDo *)context->editor)->doing_drag = False;
760 context->data = apptstr;
764 convertCBRec[0].closure = (XtPointer)context;
765 dragFinishCBRec[0].closure = (XtPointer)context;
767 if (e->drag_icon == NULL) {
768 e->drag_icon = CreateDragSourceIcon(widget,
773 if (DtDndVaDragStart(widget, event, DtDND_BUFFER_TRANSFER, 1,
775 convertCBRec, dragFinishCBRec,
776 DtNsourceIcon, e->drag_icon,
779 printf(catgets(calendar->DT_catd, 1, 239,
780 "DragStart returned NULL.\n"));
789 EditorType editor_type)
791 static XtCallbackRec convertCBRec[] = { {ApptConvertCB, NULL},
793 static XtCallbackRec dragFinishCBRec[] = { {DragFinishCB, NULL},
796 Display *display = XtDisplay(widget);
797 DragContext *context = calloc(sizeof(DragContext), 1);
798 Editor *e = (Editor *) calendar->editor;
799 GEditor *ge = (GEditor *) calendar->geditor;
800 ToDo *t = (ToDo *) calendar->todo;
801 Dtcm_appointment *appt;
803 int preDsswFlags, preRfpFlags;
805 context->calendar = calendar;
806 context->editor_type = editor_type;
808 if (editor_type == SingleEditorIcon)
810 context->editor = (caddr_t) e;
811 appt = allocate_appt_struct(appt_write, DATAVER_ARCHIVE, NULL);
812 load_appt_defaults(appt, (Props *) calendar->properties);
813 preDsswFlags = e->dsswFlags;
814 preRfpFlags = e->rfpFlags;
815 if (!dssw_form_flags_to_appt(&e->dssw, appt,
817 now(), &e->dsswFlags) ||
818 !rfp_form_flags_to_appt(&e->rfp, appt,
821 (preDsswFlags != e->dsswFlags) ||
822 (preRfpFlags != e->rfpFlags))
824 e->doing_drag = False;
825 free_appt_struct(&appt);
830 else if (editor_type == GroupEditorIcon)
832 context->editor = (caddr_t) ge;
833 appt = allocate_appt_struct(appt_write, DATAVER_ARCHIVE, NULL);
834 load_appt_defaults(appt, (Props *) calendar->properties);
835 preDsswFlags = ge->dsswFlags;
836 preRfpFlags = ge->rfpFlags;
837 if (!dssw_form_flags_to_appt(&ge->dssw, appt,
839 now(), &ge->dsswFlags) ||
840 !rfp_form_flags_to_appt(&ge->rfp, appt,
843 (preDsswFlags != ge->dsswFlags) ||
844 (preRfpFlags != ge->rfpFlags))
846 ge->doing_drag = False;
847 free_appt_struct(&appt);
852 else if (editor_type == TodoEditorIcon)
854 context->editor = (caddr_t) t;
855 if (t->cal->general->version < DATAVER4)
856 appt = allocate_appt_struct(appt_write, DATAVER_ARCHIVE,
857 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
858 CSA_ENTRY_ATTR_LAST_UPDATE_I,
859 CSA_ENTRY_ATTR_ORGANIZER_I,
860 CSA_ENTRY_ATTR_START_DATE_I,
861 CSA_ENTRY_ATTR_TYPE_I,
862 CSA_ENTRY_ATTR_CLASSIFICATION_I,
863 CSA_ENTRY_ATTR_END_DATE_I,
864 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
865 CSA_ENTRY_ATTR_SUMMARY_I,
866 CSA_ENTRY_ATTR_STATUS_I,
867 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
868 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
869 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
870 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
871 CSA_ENTRY_ATTR_AUDIO_REMINDER_I,
872 CSA_ENTRY_ATTR_FLASHING_REMINDER_I,
873 CSA_ENTRY_ATTR_MAIL_REMINDER_I,
874 CSA_ENTRY_ATTR_POPUP_REMINDER_I,
877 appt = allocate_appt_struct(appt_write,
878 DATAVER_ARCHIVE, NULL);
880 dssw_form_to_todo(&t->dssw, appt, calendar->calname, now());
881 preRfpFlags = t->rfpFlags;
882 if (!rfp_form_flags_to_appt(&t->rfp, appt,
885 (preRfpFlags != t->rfpFlags))
887 t->doing_drag = False;
888 free_appt_struct(&appt);
892 appt->type->value->item.sint32_value = CSA_TYPE_TODO;
893 appt->show_time->value->item.sint32_value = True;
895 XmToggleButtonGadgetGetState(t->completed_toggle);
896 appt->state->value->item.sint32_value =
898 CSA_STATUS_COMPLETED : CSA_X_DT_STATUS_ACTIVE;
905 apptstr = parse_attrs_to_string(appt, (Props *)calendar->properties,
906 attrs_to_string(appt->attrs,
908 free_appt_struct(&appt);
910 context->data = apptstr;
914 convertCBRec[0].closure = (XtPointer)context;
915 dragFinishCBRec[0].closure = (XtPointer)context;
917 if (e->drag_icon == NULL) {
918 e->drag_icon = CreateDragSourceIcon(widget, e->drag_bitmap,
922 if (DtDndVaDragStart(widget, event, DtDND_BUFFER_TRANSFER, 1,
924 convertCBRec, dragFinishCBRec,
925 DtNsourceIcon, e->drag_icon,
929 printf(catgets(calendar->DT_catd, 1, 239,
930 "DragStart returned NULL.\n"));
935 #define ABS_DELTA(x1, x2) (x1 < x2 ? x2 - x1 : x1 - x2)
943 if (event->type == MotionNotify)
945 XEvent *press = (XEvent *)arg;
947 if ((ABS_DELTA(press->xbutton.x_root,
948 event->xmotion.x_root) > DAMPING) ||
949 (ABS_DELTA(press->xbutton.y_root,
950 event->xmotion.y_root) > DAMPING))
953 else if (event->type == ButtonRelease)
963 // Translation implementing Motif 1.2.5 ProcessPress function
965 * Taken from dtmail/dtmail/RoamMenuWindow.C
968 #define SELECTION_ACTION 0
969 #define TRANSFER_ACTION 1
976 Cardinal *num_params)
978 int i, action, cur_item;
979 int *selected_positions, nselected_positions;
982 * This action happens when Button1 is pressed and the Selection
983 * and Transfer are integrated on Button1. It is passed two
984 * parameters: the action to call when the event is a selection,
985 * and the action to call when the event is a transfer.
988 if (*num_params != 2 || !XmIsList(w))
991 action = SELECTION_ACTION;
992 cur_item = XmListYToPos(w, event->xbutton.y);
997 XmNselectedPositions, &selected_positions,
998 XmNselectedPositionCount, &nselected_positions,
1001 for (i=0; i<nselected_positions; i++)
1003 if (cur_item == selected_positions[i])
1006 * The determination of whether this is a transfer drag
1007 * cannot be made until a Motion event comes in. It is
1008 * not a drag as soon as a ButtonUp event happens.
1017 switch (new_event.type)
1020 action = TRANSFER_ACTION;
1023 action = SELECTION_ACTION;
1031 XtCallActionProc(w, params[action], event, params, *num_params);