diff options
| author | Eli Zaretskii | 2013-09-29 21:38:56 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-09-29 21:38:56 +0300 |
| commit | 0afa0aabd833fff2e8da06e24da6c4bab7aadec3 (patch) | |
| tree | 9420b06009efbb982e29d0fc2da77079d1cc5fd4 /src/xmenu.c | |
| parent | 0fe3602a281b967ab1709da511c88f763a86e62a (diff) | |
| download | emacs-0afa0aabd833fff2e8da06e24da6c4bab7aadec3.tar.gz emacs-0afa0aabd833fff2e8da06e24da6c4bab7aadec3.zip | |
x-popup-dialog fixed, almost.
Diffstat (limited to 'src/xmenu.c')
| -rw-r--r-- | src/xmenu.c | 184 |
1 files changed, 35 insertions, 149 deletions
diff --git a/src/xmenu.c b/src/xmenu.c index 054a52e7760..fe0e229ef20 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -192,149 +192,6 @@ mouse_position_for_popup (struct frame *f, int *x, int *y) | |||
| 192 | 192 | ||
| 193 | #endif /* HAVE_X_WINDOWS */ | 193 | #endif /* HAVE_X_WINDOWS */ |
| 194 | 194 | ||
| 195 | #ifdef HAVE_MENUS | ||
| 196 | |||
| 197 | DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0, | ||
| 198 | doc: /* Pop up a dialog box and return user's selection. | ||
| 199 | POSITION specifies which frame to use. | ||
| 200 | This is normally a mouse button event or a window or frame. | ||
| 201 | If POSITION is t, it means to use the frame the mouse is on. | ||
| 202 | The dialog box appears in the middle of the specified frame. | ||
| 203 | |||
| 204 | CONTENTS specifies the alternatives to display in the dialog box. | ||
| 205 | It is a list of the form (DIALOG ITEM1 ITEM2...). | ||
| 206 | Each ITEM is a cons cell (STRING . VALUE). | ||
| 207 | The return value is VALUE from the chosen item. | ||
| 208 | |||
| 209 | An ITEM may also be just a string--that makes a nonselectable item. | ||
| 210 | An ITEM may also be nil--that means to put all preceding items | ||
| 211 | on the left of the dialog box and all following items on the right. | ||
| 212 | \(By default, approximately half appear on each side.) | ||
| 213 | |||
| 214 | If HEADER is non-nil, the frame title for the box is "Information", | ||
| 215 | otherwise it is "Question". | ||
| 216 | |||
| 217 | If the user gets rid of the dialog box without making a valid choice, | ||
| 218 | for instance using the window manager, then this produces a quit and | ||
| 219 | `x-popup-dialog' does not return. */) | ||
| 220 | (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | ||
| 221 | { | ||
| 222 | struct frame *f = NULL; | ||
| 223 | Lisp_Object window; | ||
| 224 | |||
| 225 | /* Decode the first argument: find the window or frame to use. */ | ||
| 226 | if (EQ (position, Qt) | ||
| 227 | || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) | ||
| 228 | || EQ (XCAR (position), Qtool_bar)))) | ||
| 229 | { | ||
| 230 | #if 0 /* Using the frame the mouse is on may not be right. */ | ||
| 231 | /* Use the mouse's current position. */ | ||
| 232 | struct frame *new_f = SELECTED_FRAME (); | ||
| 233 | Lisp_Object bar_window; | ||
| 234 | enum scroll_bar_part part; | ||
| 235 | Time time; | ||
| 236 | Lisp_Object x, y; | ||
| 237 | |||
| 238 | (*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y, &time); | ||
| 239 | |||
| 240 | if (new_f != 0) | ||
| 241 | XSETFRAME (window, new_f); | ||
| 242 | else | ||
| 243 | window = selected_window; | ||
| 244 | #endif | ||
| 245 | window = selected_window; | ||
| 246 | } | ||
| 247 | else if (CONSP (position)) | ||
| 248 | { | ||
| 249 | Lisp_Object tem = XCAR (position); | ||
| 250 | if (CONSP (tem)) | ||
| 251 | window = Fcar (XCDR (position)); | ||
| 252 | else | ||
| 253 | { | ||
| 254 | tem = Fcar (XCDR (position)); /* EVENT_START (position) */ | ||
| 255 | window = Fcar (tem); /* POSN_WINDOW (tem) */ | ||
| 256 | } | ||
| 257 | } | ||
| 258 | else if (WINDOWP (position) || FRAMEP (position)) | ||
| 259 | window = position; | ||
| 260 | else | ||
| 261 | window = Qnil; | ||
| 262 | |||
| 263 | /* Decode where to put the menu. */ | ||
| 264 | |||
| 265 | if (FRAMEP (window)) | ||
| 266 | f = XFRAME (window); | ||
| 267 | else if (WINDOWP (window)) | ||
| 268 | { | ||
| 269 | CHECK_LIVE_WINDOW (window); | ||
| 270 | f = XFRAME (WINDOW_FRAME (XWINDOW (window))); | ||
| 271 | } | ||
| 272 | else | ||
| 273 | /* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME, | ||
| 274 | but I don't want to make one now. */ | ||
| 275 | CHECK_WINDOW (window); | ||
| 276 | |||
| 277 | check_window_system (f); | ||
| 278 | |||
| 279 | /* Force a redisplay before showing the dialog. If a frame is created | ||
| 280 | just before showing the dialog, its contents may not have been fully | ||
| 281 | drawn, as this depends on timing of events from the X server. Redisplay | ||
| 282 | is not done when a dialog is shown. If redisplay could be done in the | ||
| 283 | X event loop (i.e. the X event loop does not run in a signal handler) | ||
| 284 | this would not be needed. | ||
| 285 | |||
| 286 | Do this before creating the widget value that points to Lisp | ||
| 287 | string contents, because Fredisplay may GC and relocate them. */ | ||
| 288 | Fredisplay (Qt); | ||
| 289 | |||
| 290 | #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) | ||
| 291 | /* Display a menu with these alternatives | ||
| 292 | in the middle of frame F. */ | ||
| 293 | { | ||
| 294 | Lisp_Object x, y, frame, newpos; | ||
| 295 | XSETFRAME (frame, f); | ||
| 296 | XSETINT (x, FRAME_PIXEL_WIDTH (f) / 2); | ||
| 297 | XSETINT (y, FRAME_PIXEL_HEIGHT (f) / 2); | ||
| 298 | newpos = list2 (list2 (x, y), frame); | ||
| 299 | |||
| 300 | return Fx_popup_menu (newpos, | ||
| 301 | list2 (Fcar (contents), contents)); | ||
| 302 | } | ||
| 303 | #else | ||
| 304 | { | ||
| 305 | Lisp_Object title; | ||
| 306 | const char *error_name; | ||
| 307 | Lisp_Object selection; | ||
| 308 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); | ||
| 309 | |||
| 310 | /* Decode the dialog items from what was specified. */ | ||
| 311 | title = Fcar (contents); | ||
| 312 | CHECK_STRING (title); | ||
| 313 | record_unwind_protect_void (unuse_menu_items); | ||
| 314 | |||
| 315 | if (NILP (Fcar (Fcdr (contents)))) | ||
| 316 | /* No buttons specified, add an "Ok" button so users can pop down | ||
| 317 | the dialog. Also, the lesstif/motif version crashes if there are | ||
| 318 | no buttons. */ | ||
| 319 | contents = list2 (title, Fcons (build_string ("Ok"), Qt)); | ||
| 320 | |||
| 321 | list_of_panes (list1 (contents)); | ||
| 322 | |||
| 323 | /* Display them in a dialog box. */ | ||
| 324 | block_input (); | ||
| 325 | selection = xdialog_show (f, 0, title, header, &error_name); | ||
| 326 | unblock_input (); | ||
| 327 | |||
| 328 | unbind_to (specpdl_count, Qnil); | ||
| 329 | discard_menu_items (); | ||
| 330 | |||
| 331 | if (error_name) error ("%s", error_name); | ||
| 332 | return selection; | ||
| 333 | } | ||
| 334 | #endif | ||
| 335 | } | ||
| 336 | |||
| 337 | |||
| 338 | #ifndef MSDOS | 195 | #ifndef MSDOS |
| 339 | 196 | ||
| 340 | #if defined USE_GTK || defined USE_MOTIF | 197 | #if defined USE_GTK || defined USE_MOTIF |
| @@ -2170,6 +2027,41 @@ xdialog_show (struct frame *f, | |||
| 2170 | return Qnil; | 2027 | return Qnil; |
| 2171 | } | 2028 | } |
| 2172 | 2029 | ||
| 2030 | Lisp_Object | ||
| 2031 | xw_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents) | ||
| 2032 | { | ||
| 2033 | Lisp_Object title; | ||
| 2034 | const char *error_name; | ||
| 2035 | Lisp_Object selection; | ||
| 2036 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); | ||
| 2037 | |||
| 2038 | check_window_system (f); | ||
| 2039 | |||
| 2040 | /* Decode the dialog items from what was specified. */ | ||
| 2041 | title = Fcar (contents); | ||
| 2042 | CHECK_STRING (title); | ||
| 2043 | record_unwind_protect_void (unuse_menu_items); | ||
| 2044 | |||
| 2045 | if (NILP (Fcar (Fcdr (contents)))) | ||
| 2046 | /* No buttons specified, add an "Ok" button so users can pop down | ||
| 2047 | the dialog. Also, the lesstif/motif version crashes if there are | ||
| 2048 | no buttons. */ | ||
| 2049 | contents = list2 (title, Fcons (build_string ("Ok"), Qt)); | ||
| 2050 | |||
| 2051 | list_of_panes (list1 (contents)); | ||
| 2052 | |||
| 2053 | /* Display them in a dialog box. */ | ||
| 2054 | block_input (); | ||
| 2055 | selection = xdialog_show (f, 0, title, header, &error_name); | ||
| 2056 | unblock_input (); | ||
| 2057 | |||
| 2058 | unbind_to (specpdl_count, Qnil); | ||
| 2059 | discard_menu_items (); | ||
| 2060 | |||
| 2061 | if (error_name) error ("%s", error_name); | ||
| 2062 | return selection; | ||
| 2063 | } | ||
| 2064 | |||
| 2173 | #else /* not USE_X_TOOLKIT && not USE_GTK */ | 2065 | #else /* not USE_X_TOOLKIT && not USE_GTK */ |
| 2174 | 2066 | ||
| 2175 | /* The frame of the last activated non-toolkit menu bar. | 2067 | /* The frame of the last activated non-toolkit menu bar. |
| @@ -2531,8 +2423,6 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 2531 | 2423 | ||
| 2532 | #endif /* not USE_X_TOOLKIT */ | 2424 | #endif /* not USE_X_TOOLKIT */ |
| 2533 | 2425 | ||
| 2534 | #endif /* HAVE_MENUS */ | ||
| 2535 | |||
| 2536 | #ifndef MSDOS | 2426 | #ifndef MSDOS |
| 2537 | /* Detect if a dialog or menu has been posted. MSDOS has its own | 2427 | /* Detect if a dialog or menu has been posted. MSDOS has its own |
| 2538 | implementation on msdos.c. */ | 2428 | implementation on msdos.c. */ |
| @@ -2574,8 +2464,4 @@ syms_of_xmenu (void) | |||
| 2574 | Ffset (intern_c_string ("accelerate-menu"), | 2464 | Ffset (intern_c_string ("accelerate-menu"), |
| 2575 | intern_c_string (Sx_menu_bar_open_internal.symbol_name)); | 2465 | intern_c_string (Sx_menu_bar_open_internal.symbol_name)); |
| 2576 | #endif | 2466 | #endif |
| 2577 | |||
| 2578 | #ifdef HAVE_MENUS | ||
| 2579 | defsubr (&Sx_popup_dialog); | ||
| 2580 | #endif | ||
| 2581 | } | 2467 | } |