lwlib-Xlw.c 7.23 KB
Newer Older
Richard M. Stallman's avatar
Richard M. Stallman committed
1 2
/* The lwlib interface to "xlwmenu" menus.
   Copyright (C) 1992 Lucid, Inc.
Dave Love's avatar
Dave Love committed
3
   Copyright (C) 1994, 2000, 2001 Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
4 5 6

This file is part of the Lucid Widget Library.

7
The Lucid Widget Library is free software; you can redistribute it and/or
Richard M. Stallman's avatar
Richard M. Stallman committed
8 9 10 11 12
modify it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

The Lucid Widget Library is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
Richard M. Stallman's avatar
Richard M. Stallman committed
14 15 16 17 18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING.  If not, write to
19 20
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */
Richard M. Stallman's avatar
Richard M. Stallman committed
21

22 23 24 25
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Dave Love's avatar
Dave Love committed
26
#include "lisp.h"
Richard M. Stallman's avatar
Richard M. Stallman committed
27

Richard M. Stallman's avatar
Richard M. Stallman committed
28 29 30 31 32 33 34 35
#include "lwlib-Xlw.h"
#include <X11/StringDefs.h>
#include <X11/IntrinsicP.h>
#include <X11/ObjectP.h>
#include <X11/CompositeP.h>
#include <X11/Shell.h>
#include "xlwmenu.h"

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
#if 0

#include <stdio.h>

/* Print the complete X resource name of widget WIDGET to stderr.
   This is sometimes handy to have available.  */

void
x_print_complete_resource_name (widget)
     Widget widget;
{
  int i;
  String names[100];

  for (i = 0; i < 100 && widget != NULL; ++i)
    {
      names[i] = XtName (widget);
      widget = XtParent (widget);
    }

  for (--i; i >= 1; --i)
    fprintf (stderr, "%s.", names[i]);
  fprintf (stderr, "%s\n", names[0]);
}

#endif /* 0 */


Richard M. Stallman's avatar
Richard M. Stallman committed
64
/* Menu callbacks */
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84

/* Callback XtNhighlightCallback for Lucid menus.  W is the menu
   widget, CLIENT_DATA contains a pointer to the widget_instance
   for the menu, CALL_DATA contains a pointer to the widget_value
   structure for the highlighted menu item.  The latter may be null
   if there isn't any highlighted menu item.  */

static void
highlight_hook (w, client_data, call_data)
     Widget w;
     XtPointer client_data;
     XtPointer call_data;
{
  widget_instance *instance = (widget_instance *) client_data;

  if (instance->info->highlight_cb
      && !w->core.being_destroyed)
    instance->info->highlight_cb (w, instance->info->id, call_data);
}

Richard M. Stallman's avatar
Richard M. Stallman committed
85
static void
86 87 88 89
pre_hook (w, client_data, call_data)
     Widget w;
     XtPointer client_data;
     XtPointer call_data;
Richard M. Stallman's avatar
Richard M. Stallman committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103
{
  widget_instance* instance = (widget_instance*)client_data;
  widget_value* val;

  if (w->core.being_destroyed)
    return;

  val = lw_get_widget_value_for_widget (instance, w);
  if (instance->info->pre_activate_cb)
    instance->info->pre_activate_cb (w, instance->info->id,
				     val ? val->call_data : NULL);
}

static void
104 105 106 107
pick_hook (w, client_data, call_data)
     Widget w;
     XtPointer client_data;
     XtPointer call_data;
Richard M. Stallman's avatar
Richard M. Stallman committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
{
  widget_instance* instance = (widget_instance*)client_data;
  widget_value* contents_val = (widget_value*)call_data;
  widget_value* widget_val;
  XtPointer widget_arg;

  if (w->core.being_destroyed)
    return;

  if (instance->info->selection_cb && contents_val && contents_val->enabled
      && !contents_val->contents)
    instance->info->selection_cb (w, instance->info->id,
				  contents_val->call_data);

  widget_val = lw_get_widget_value_for_widget (instance, w);
  widget_arg = widget_val ? widget_val->call_data : NULL;
  if (instance->info->post_activate_cb)
    instance->info->post_activate_cb (w, instance->info->id, widget_arg);

}

/* creation functions */
Fred Pierresteguy's avatar
Fred Pierresteguy committed
130

Richard M. Stallman's avatar
Richard M. Stallman committed
131
static Widget
132 133
xlw_create_menubar (instance)
     widget_instance* instance;
Richard M. Stallman's avatar
Richard M. Stallman committed
134
{
Fred Pierresteguy's avatar
Fred Pierresteguy committed
135
  Widget widget;
Paul Reilly's avatar
Paul Reilly committed
136
  Arg al[5];
137
  int ac = 0;
Fred Pierresteguy's avatar
Fred Pierresteguy committed
138

139
  XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
Paul Reilly's avatar
Paul Reilly committed
140 141 142 143 144
#ifdef emacs
  XtSetArg (al[ac], XtNshowGrip, 0); ac++;
  XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
  XtSetArg (al[ac], XtNallowResize, 1); ac++;
#endif
Fred Pierresteguy's avatar
Fred Pierresteguy committed
145

146 147
  /* This used to use XtVaCreateWidget, but an old Xt version
     has a bug in XtVaCreateWidget that frees instance->info->name.  */
148
  widget
149 150
    = XtCreateWidget (instance->info->name, xlwMenuWidgetClass,
		      instance->parent, al, ac);
Fred Pierresteguy's avatar
Fred Pierresteguy committed
151

Richard M. Stallman's avatar
Richard M. Stallman committed
152 153
  XtAddCallback (widget, XtNopen, pre_hook, (XtPointer)instance);
  XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
154 155
  XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
		 (XtPointer)instance);
Richard M. Stallman's avatar
Richard M. Stallman committed
156 157 158 159
  return widget;
}

static Widget
160 161
xlw_create_popup_menu (instance)
     widget_instance* instance;
Richard M. Stallman's avatar
Richard M. Stallman committed
162
{
163 164 165
  Widget popup_shell
    = XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
			  instance->parent, NULL, 0);
166

Fred Pierresteguy's avatar
Fred Pierresteguy committed
167
  Widget widget;
168 169
  Arg al[2];
  int ac = 0;
Fred Pierresteguy's avatar
Fred Pierresteguy committed
170

171 172
  XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
  XtSetArg (al[ac], XtNhorizontal, False); ac++;
Fred Pierresteguy's avatar
Fred Pierresteguy committed
173

174 175
  /* This used to use XtVaManagedCreateWidget, but an old Xt version
     has a bug in XtVaManagedCreateWidget that frees instance->info->name.  */
176
  widget
177 178
    = XtCreateManagedWidget ("popup", xlwMenuWidgetClass,
			     popup_shell, al, ac);
Fred Pierresteguy's avatar
Fred Pierresteguy committed
179

Richard M. Stallman's avatar
Richard M. Stallman committed
180
  XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
181 182
  XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
		 (XtPointer)instance);
Richard M. Stallman's avatar
Richard M. Stallman committed
183 184 185
  return popup_shell;
}

186
widget_creation_entry
Richard M. Stallman's avatar
Richard M. Stallman committed
187 188 189 190 191 192 193 194
xlw_creation_table [] =
{
  {"menubar", xlw_create_menubar},
  {"popup", xlw_create_popup_menu},
  {NULL, NULL}
};

Boolean
195 196
lw_lucid_widget_p (widget)
     Widget widget;
Richard M. Stallman's avatar
Richard M. Stallman committed
197 198
{
  WidgetClass the_class = XtClass (widget);
199

Richard M. Stallman's avatar
Richard M. Stallman committed
200 201 202
  if (the_class == xlwMenuWidgetClass)
    return True;
  if (the_class == overrideShellWidgetClass)
203 204
    return (XtClass (((CompositeWidget)widget)->composite.children [0])
	    == xlwMenuWidgetClass);
Richard M. Stallman's avatar
Richard M. Stallman committed
205 206 207 208
  return False;
}

void
Dave Love's avatar
Dave Love committed
209 210 211 212
#ifdef PROTOTYPES
xlw_update_one_widget (widget_instance* instance, Widget widget,
		       widget_value* val, Boolean deep_p)
#else
213 214 215 216 217
xlw_update_one_widget (instance, widget, val, deep_p)
     widget_instance* instance;
     Widget widget;
     widget_value* val;
     Boolean deep_p;
Dave Love's avatar
Dave Love committed
218
#endif
Richard M. Stallman's avatar
Richard M. Stallman committed
219
{
220
  Arg al[1];
Richard M. Stallman's avatar
Richard M. Stallman committed
221

222 223 224 225 226
  /* This used to use XtVaSetValues, but some old Xt versions
     that have a bug in XtVaCreateWidget might have it here too.  */
  XtSetArg (al[0], XtNmenu, instance->info->val);

  XtSetValues (widget, al, 1);
Richard M. Stallman's avatar
Richard M. Stallman committed
227 228 229
}

void
230 231 232 233
xlw_update_one_value (instance, widget, val)
     widget_instance* instance;
     Widget widget;
     widget_value* val;
Richard M. Stallman's avatar
Richard M. Stallman committed
234 235 236 237 238
{
  return;
}

void
Dave Love's avatar
Dave Love committed
239 240 241
#ifdef PROTOTYPES
xlw_pop_instance (widget_instance* instance, Boolean up)
#else
242 243 244
xlw_pop_instance (instance, up)
     widget_instance* instance;
     Boolean up;
Dave Love's avatar
Dave Love committed
245
#endif
Richard M. Stallman's avatar
Richard M. Stallman committed
246 247 248 249
{
}

void
250
xlw_popup_menu (widget, event)
251
     Widget widget;
252
     XEvent *event;
Richard M. Stallman's avatar
Richard M. Stallman committed
253 254 255 256 257 258 259 260 261
{
  XButtonPressedEvent dummy;
  XlwMenuWidget mw;

  if (!XtIsShell (widget))
    return;

  mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];

262
  if (event)
263
    pop_up_menu (mw, (XButtonPressedEvent*) event);
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
  else
    {
      dummy.type = ButtonPress;
      dummy.serial = 0;
      dummy.send_event = 0;
      dummy.display = XtDisplay (widget);
      dummy.window = XtWindow (XtParent (widget));
      dummy.time = CurrentTime;
      dummy.button = 0;
      XQueryPointer (dummy.display, dummy.window, &dummy.root,
		     &dummy.subwindow, &dummy.x_root, &dummy.y_root,
		     &dummy.x, &dummy.y, &dummy.state);

      pop_up_menu (mw, &dummy);
    }
Richard M. Stallman's avatar
Richard M. Stallman committed
279 280 281 282
}

/* Destruction of instances */
void
283 284
xlw_destroy_instance (instance)
     widget_instance* instance;
Richard M. Stallman's avatar
Richard M. Stallman committed
285 286 287 288 289
{
  if (instance->widget)
    XtDestroyWidget (instance->widget);
}