This is gui_motif.c in view mode; [Download] [Up]
/* vi:set ts=4 sw=4: * * VIM - Vi IMproved by Bram Moolenaar * GUI/Motif support by Robert Webb * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. */ #include <Xm/Form.h> #include <Xm/RowColumn.h> #include <Xm/PushB.h> #include <Xm/CascadeB.h> #include <Xm/ScrollBar.h> #include <Xm/MenuShell.h> #if (XmVersion >= 1002) # include <Xm/RepType.h> #endif #include <X11/keysym.h> #include <X11/Xatom.h> #include <X11/StringDefs.h> #include "vim.h" #include "globals.h" #include "proto.h" #include "option.h" extern Widget vimShell; static Widget vimForm; static Widget textArea; static Widget menuBar; /* * Call-back routines. */ static void scroll_cb(w, client_data, call_data) Widget w; XtPointer client_data, call_data; { GuiScrollbar *sb; int value, dragging; sb = gui_find_scrollbar((long)client_data); value = ((XmScrollBarCallbackStruct *)call_data)->value; dragging = (((XmScrollBarCallbackStruct *)call_data)->reason == XmCR_DRAG); gui_drag_scrollbar(sb, value, dragging); } /* * End of call-back routines */ /* * Create all the motif widgets necessary. */ void gui_x11_create_widgets() { #if 0 Dimension n; #endif /* * Start out by adding the configured border width into the border offset */ gui.border_offset = gui.border_width; /* * Install the tearOffModel resource converter. */ #if (XmVersion >= 1002) XmRepTypeInstallTearOffModelConverter(); #endif XtInitializeWidgetClass(xmFormWidgetClass); XtInitializeWidgetClass(xmRowColumnWidgetClass); XtInitializeWidgetClass(xmPrimitiveWidgetClass); XtInitializeWidgetClass(xmCascadeButtonWidgetClass); XtInitializeWidgetClass(xmMenuShellWidgetClass); XtInitializeWidgetClass(xmPushButtonWidgetClass); XtInitializeWidgetClass(xmScrollBarWidgetClass); vimForm = XtVaCreateManagedWidget("vimForm", xmFormWidgetClass, vimShell, XmNborderWidth, 0, XmNhighlightThickness, 0, XmNshadowThickness, 0, XmNmarginWidth, 0, XmNmarginHeight, 0, XmNresizePolicy, XmRESIZE_ANY, XmNforeground, gui.menu_fg_pixel, XmNbackground, gui.menu_bg_pixel, NULL); textArea = XtVaCreateManagedWidget("textArea", xmPrimitiveWidgetClass, vimForm, XmNbackground, gui.back_pixel, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_OPPOSITE_FORM, XmNbottomAttachment, XmATTACH_OPPOSITE_FORM, /* * These take some control away from the user, but avoids making them * add resources to get a decent looking setup. */ XmNborderWidth, 0, XmNhighlightThickness, 0, XmNshadowThickness, 0, NULL); #if 0 /* nobody knows why these are here, since XmNhighlightThickness and XmNshadowThickness are set to 0 above. Keep them around, in case somebody complains */ /* * If there are highlight or shadow borders, add their widths to our * border offset so we don't draw over them. */ XtVaGetValues(textArea, XmNhighlightThickness, &n, NULL); gui.border_offset += n; XtVaGetValues(textArea, XmNshadowThickness, &n, NULL); gui.border_offset += n; #endif menuBar = XtVaCreateManagedWidget("menuBar", xmRowColumnWidgetClass, vimForm, #if (XmVersion >= 1002) XmNtearOffModel, XmTEAR_OFF_ENABLED, #endif XmNrowColumnType, XmMENU_BAR, XmNforeground, gui.menu_fg_pixel, XmNbackground, gui.menu_bg_pixel, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_OPPOSITE_FORM, XmNrightOffset, 0, /* Always stick to rigth hand side */ NULL); /* * Callbacks for textArea, vimForm, and vimShell. */ XtAddEventHandler(textArea, VisibilityChangeMask, FALSE, gui_x11_visibility_cb, (XtPointer)0); XtAddEventHandler(textArea, ExposureMask, FALSE, gui_x11_expose_cb, (XtPointer)0); XtAddEventHandler(vimForm, StructureNotifyMask, FALSE, gui_x11_resize_window_cb, (XtPointer)0); XtAddEventHandler(vimShell, FocusChangeMask, FALSE, gui_x11_focus_change_cb, (XtPointer)0); XtAddEventHandler(textArea, KeyPressMask, FALSE, gui_x11_key_hit_cb, (XtPointer)0); XtAddEventHandler(textArea, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, FALSE, gui_x11_mouse_cb, (XtPointer)0); } void gui_mch_set_text_area_pos(x, y, w, h) int x; int y; int w; int h; { XtVaSetValues(textArea, XmNleftOffset, x, XmNtopOffset, y, XmNrightOffset, -x - w, XmNbottomOffset, -y - h, NULL); } /* * Menu stuff. */ void gui_mch_enable_menu(flag) int flag; { if (flag) XtManageChild(menuBar); else XtUnmanageChild(menuBar); } void gui_mch_set_menu_pos(x, y, w, h) int x; int y; int w; int h; { XtVaSetValues(menuBar, XmNleftOffset, x, XmNtopOffset, y, XmNbottomOffset, -y - h, NULL); } void gui_mch_add_menu(menu, parent) GuiMenu *menu; GuiMenu *parent; { Dimension height, margin; #if (XmVersion >= 1002) Widget widget; XmString label = XmStringCreate((char *)menu->name, XmFONTLIST_DEFAULT_TAG); #else XmString label = XmStringCreate((char *)menu->name, XmSTRING_DEFAULT_CHARSET); #endif Widget shell; menu->id = XtVaCreateWidget("subMenu", xmCascadeButtonWidgetClass, (parent == NULL) ? menuBar : parent->submenu_id, XmNlabelString, label, XmNforeground, gui.menu_fg_pixel, XmNbackground, gui.menu_bg_pixel, NULL); /* XtFree((char *)label); makes Lesstif crash */ shell = XtVaCreateWidget("subMenuShell", xmMenuShellWidgetClass, menu->id, XmNwidth, 1, XmNheight, 1, XmNforeground, gui.menu_fg_pixel, XmNbackground, gui.menu_bg_pixel, NULL); menu->submenu_id = XtVaCreateWidget("rowColumnMenu", xmRowColumnWidgetClass, shell, XmNrowColumnType, XmMENU_PULLDOWN, #if (XmVersion >= 1002) XmNtearOffModel, XmTEAR_OFF_ENABLED, #endif NULL); #if (XmVersion >= 1002) /* Set the colors for the tear off widget */ if ((widget = XmGetTearOffControl(menu->submenu_id)) != (Widget)NULL) XtVaSetValues(widget, XmNforeground, gui.menu_fg_pixel, XmNbackground, gui.menu_bg_pixel, NULL); #endif XtVaSetValues(menu->id, XmNsubMenuId, menu->submenu_id, NULL); /* * The "Help" menu is a special case, and should be placed at the far right * hand side of the menu-bar. */ if (parent == NULL && STRCMP((char *)menu->name, "Help") == 0) XtVaSetValues(menuBar, XmNmenuHelpWidget, menu->id, NULL); if (parent == NULL) { /* * When we add a top-level item to the menu bar, we can figure out how * high the menu bar should be. */ XtVaGetValues(menuBar, XmNmarginHeight, &margin, NULL); XtVaGetValues(menu->id, XmNheight, &height, NULL); gui.menu_height = height + 2 * margin; } } void gui_mch_add_menu_item(menu, parent) GuiMenu *menu; GuiMenu *parent; { #if (XmVersion >= 1002) XmString label = XmStringCreate((char *)menu->name, XmFONTLIST_DEFAULT_TAG); #else XmString label = XmStringCreate((char *)menu->name, XmSTRING_DEFAULT_CHARSET); #endif menu->submenu_id = (Widget)0; menu->id = XtVaCreateWidget("subMenu", xmPushButtonWidgetClass, parent->submenu_id, XmNlabelString, label, XmNforeground, gui.menu_fg_pixel, XmNbackground, gui.menu_bg_pixel, NULL); /* XtFree((char *)label); makes Lesstif crash */ XtAddCallback(menu->id, XmNactivateCallback, gui_x11_menu_cb, (XtPointer)menu); } /* * Destroy the machine specific menu widget. */ void gui_mch_destroy_menu(menu) GuiMenu *menu; { Widget parent; if (menu->submenu_id != (Widget)0) { XtDestroyWidget(menu->submenu_id); menu->submenu_id = (Widget)0; } if (menu->id != (Widget)0) { /* * This is a hack to stop LessTif from crashing when a menu's last * child is destroyed. We check to see if this is the last child and if * so, don't delete it. The parent will be deleted soon anyway, and it * will delete it's children like all good widgets do. */ parent = XtParent(menu->id); if (parent != menuBar) { int num_children; XtVaGetValues(parent, XtNnumChildren, &num_children, NULL); if (num_children > 1) XtDestroyWidget(menu->id); } else XtDestroyWidget(menu->id); menu->id = (Widget)0; } } /* * Scrollbar stuff. */ void gui_mch_set_scrollbar_thumb(sb, val, size, max) GuiScrollbar *sb; int val; int size; int max; { XtVaSetValues(sb->id, XmNvalue, val, XmNsliderSize, size, XmNpageIncrement, (size > 2 ? size - 2 : 1), XmNmaximum, max + 1, /* Motif has max one past the end */ NULL); } void gui_mch_set_scrollbar_pos(sb, x, y, w, h) GuiScrollbar *sb; int x; int y; int w; int h; { XtVaSetValues(sb->id, XmNleftOffset, x, XmNtopOffset, y, XmNrightOffset, -x - w, XmNbottomOffset, -y - h, NULL); } void gui_mch_create_scrollbar(sb, orient) GuiScrollbar *sb; int orient; /* SBAR_VERT or SBAR_HORIZ */ { sb->id = XtVaCreateManagedWidget("scrollBar", xmScrollBarWidgetClass, vimForm, XmNshadowThickness, 1, XmNminimum, 0, XmNorientation, (orient == SBAR_VERT) ? XmVERTICAL : XmHORIZONTAL, XmNforeground, gui.scroll_fg_pixel, XmNbackground, gui.scroll_fg_pixel, XmNtroughColor, gui.scroll_bg_pixel, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_OPPOSITE_FORM, XmNbottomAttachment, XmATTACH_OPPOSITE_FORM, NULL); XtAddCallback(sb->id, XmNvalueChangedCallback, scroll_cb, (XtPointer)sb->ident); XtAddCallback(sb->id, XmNdragCallback, scroll_cb, (XtPointer)sb->ident); } void gui_mch_destroy_scrollbar(sb) GuiScrollbar *sb; { XtDestroyWidget(sb->id); } /* * Miscellaneous stuff: */ Window gui_x11_get_wid() { return(XtWindow(textArea)); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.