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 | |
| parent | 0fe3602a281b967ab1709da511c88f763a86e62a (diff) | |
| download | emacs-0afa0aabd833fff2e8da06e24da6c4bab7aadec3.tar.gz emacs-0afa0aabd833fff2e8da06e24da6c4bab7aadec3.zip | |
x-popup-dialog fixed, almost.
Diffstat (limited to 'src')
| -rw-r--r-- | src/menu.c | 139 | ||||
| -rw-r--r-- | src/nsmenu.m | 31 | ||||
| -rw-r--r-- | src/nsterm.h | 4 | ||||
| -rw-r--r-- | src/w32menu.c | 136 | ||||
| -rw-r--r-- | src/w32term.h | 4 | ||||
| -rw-r--r-- | src/xmenu.c | 184 | ||||
| -rw-r--r-- | src/xterm.h | 4 |
7 files changed, 204 insertions, 298 deletions
diff --git a/src/menu.c b/src/menu.c index 5ca687f3d8a..7c34a9cacd4 100644 --- a/src/menu.c +++ b/src/menu.c | |||
| @@ -1376,6 +1376,141 @@ no quit occurs and `x-popup-menu' returns nil. */) | |||
| 1376 | return selection; | 1376 | return selection; |
| 1377 | } | 1377 | } |
| 1378 | 1378 | ||
| 1379 | #ifdef HAVE_MENUS | ||
| 1380 | |||
| 1381 | DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0, | ||
| 1382 | doc: /* Pop up a dialog box and return user's selection. | ||
| 1383 | POSITION specifies which frame to use. | ||
| 1384 | This is normally a mouse button event or a window or frame. | ||
| 1385 | If POSITION is t, it means to use the frame the mouse is on. | ||
| 1386 | The dialog box appears in the middle of the specified frame. | ||
| 1387 | |||
| 1388 | CONTENTS specifies the alternatives to display in the dialog box. | ||
| 1389 | It is a list of the form (DIALOG ITEM1 ITEM2...). | ||
| 1390 | Each ITEM is a cons cell (STRING . VALUE). | ||
| 1391 | The return value is VALUE from the chosen item. | ||
| 1392 | |||
| 1393 | An ITEM may also be just a string--that makes a nonselectable item. | ||
| 1394 | An ITEM may also be nil--that means to put all preceding items | ||
| 1395 | on the left of the dialog box and all following items on the right. | ||
| 1396 | \(By default, approximately half appear on each side.) | ||
| 1397 | |||
| 1398 | If HEADER is non-nil, the frame title for the box is "Information", | ||
| 1399 | otherwise it is "Question". | ||
| 1400 | |||
| 1401 | If the user gets rid of the dialog box without making a valid choice, | ||
| 1402 | for instance using the window manager, then this produces a quit and | ||
| 1403 | `x-popup-dialog' does not return. */) | ||
| 1404 | (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | ||
| 1405 | { | ||
| 1406 | struct frame *f = NULL; | ||
| 1407 | Lisp_Object window; | ||
| 1408 | |||
| 1409 | /* Decode the first argument: find the window or frame to use. */ | ||
| 1410 | if (EQ (position, Qt) | ||
| 1411 | || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) | ||
| 1412 | || EQ (XCAR (position), Qtool_bar)))) | ||
| 1413 | { | ||
| 1414 | #if 0 /* Using the frame the mouse is on may not be right. */ | ||
| 1415 | /* Use the mouse's current position. */ | ||
| 1416 | struct frame *new_f = SELECTED_FRAME (); | ||
| 1417 | Lisp_Object bar_window; | ||
| 1418 | enum scroll_bar_part part; | ||
| 1419 | Time time; | ||
| 1420 | Lisp_Object x, y; | ||
| 1421 | |||
| 1422 | (*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y, &time); | ||
| 1423 | |||
| 1424 | if (new_f != 0) | ||
| 1425 | XSETFRAME (window, new_f); | ||
| 1426 | else | ||
| 1427 | window = selected_window; | ||
| 1428 | #endif | ||
| 1429 | window = selected_window; | ||
| 1430 | } | ||
| 1431 | else if (CONSP (position)) | ||
| 1432 | { | ||
| 1433 | Lisp_Object tem = XCAR (position); | ||
| 1434 | if (CONSP (tem)) | ||
| 1435 | window = Fcar (XCDR (position)); | ||
| 1436 | else | ||
| 1437 | { | ||
| 1438 | tem = Fcar (XCDR (position)); /* EVENT_START (position) */ | ||
| 1439 | window = Fcar (tem); /* POSN_WINDOW (tem) */ | ||
| 1440 | } | ||
| 1441 | } | ||
| 1442 | else if (WINDOWP (position) || FRAMEP (position)) | ||
| 1443 | window = position; | ||
| 1444 | else | ||
| 1445 | window = Qnil; | ||
| 1446 | |||
| 1447 | /* Decode where to put the menu. */ | ||
| 1448 | |||
| 1449 | if (FRAMEP (window)) | ||
| 1450 | f = XFRAME (window); | ||
| 1451 | else if (WINDOWP (window)) | ||
| 1452 | { | ||
| 1453 | CHECK_LIVE_WINDOW (window); | ||
| 1454 | f = XFRAME (WINDOW_FRAME (XWINDOW (window))); | ||
| 1455 | } | ||
| 1456 | else | ||
| 1457 | /* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME, | ||
| 1458 | but I don't want to make one now. */ | ||
| 1459 | CHECK_WINDOW (window); | ||
| 1460 | |||
| 1461 | /* Force a redisplay before showing the dialog. If a frame is created | ||
| 1462 | just before showing the dialog, its contents may not have been fully | ||
| 1463 | drawn, as this depends on timing of events from the X server. Redisplay | ||
| 1464 | is not done when a dialog is shown. If redisplay could be done in the | ||
| 1465 | X event loop (i.e. the X event loop does not run in a signal handler) | ||
| 1466 | this would not be needed. | ||
| 1467 | |||
| 1468 | Do this before creating the widget value that points to Lisp | ||
| 1469 | string contents, because Fredisplay may GC and relocate them. */ | ||
| 1470 | Fredisplay (Qt); | ||
| 1471 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) | ||
| 1472 | if (FRAME_WINDOW_P (f)) | ||
| 1473 | return xw_popup_dialog (f, header, contents); | ||
| 1474 | else | ||
| 1475 | #endif | ||
| 1476 | #if defined (HAVE_NTGUI) && defined (HAVE_DIALOGS) | ||
| 1477 | if (FRAME_W32_P (f)) | ||
| 1478 | return w32_popup_dialog (f, header, contents); | ||
| 1479 | else | ||
| 1480 | #endif | ||
| 1481 | #ifdef HAVE_NS | ||
| 1482 | if (FRAME_NS_P (f)) | ||
| 1483 | return ns_popup_dialog (position, header, contents); | ||
| 1484 | else | ||
| 1485 | #endif | ||
| 1486 | /* Display a menu with these alternatives | ||
| 1487 | in the middle of frame F. */ | ||
| 1488 | { | ||
| 1489 | Lisp_Object x, y, frame, newpos; | ||
| 1490 | int frame_width, frame_height; | ||
| 1491 | |||
| 1492 | if (FRAME_WINDOW_P (f)) | ||
| 1493 | { | ||
| 1494 | frame_width = FRAME_PIXEL_WIDTH (f); | ||
| 1495 | frame_height = FRAME_PIXEL_HEIGHT (f); | ||
| 1496 | } | ||
| 1497 | else | ||
| 1498 | { | ||
| 1499 | frame_width = FRAME_COLS (f); | ||
| 1500 | frame_height = FRAME_LINES (f); | ||
| 1501 | } | ||
| 1502 | XSETFRAME (frame, f); | ||
| 1503 | XSETINT (x, frame_width / 2); | ||
| 1504 | XSETINT (y, frame_height / 2); | ||
| 1505 | newpos = list2 (list2 (x, y), frame); | ||
| 1506 | |||
| 1507 | return Fx_popup_menu (newpos, | ||
| 1508 | list2 (Fcar (contents), contents)); | ||
| 1509 | } | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | #endif /* HAVE_MENUS */ | ||
| 1513 | |||
| 1379 | void | 1514 | void |
| 1380 | syms_of_menu (void) | 1515 | syms_of_menu (void) |
| 1381 | { | 1516 | { |
| @@ -1384,4 +1519,8 @@ syms_of_menu (void) | |||
| 1384 | menu_items_inuse = Qnil; | 1519 | menu_items_inuse = Qnil; |
| 1385 | 1520 | ||
| 1386 | defsubr (&Sx_popup_menu); | 1521 | defsubr (&Sx_popup_menu); |
| 1522 | |||
| 1523 | #ifdef HAVE_MENUS | ||
| 1524 | defsubr (&Sx_popup_dialog); | ||
| 1525 | #endif | ||
| 1387 | } | 1526 | } |
diff --git a/src/nsmenu.m b/src/nsmenu.m index 3ed1734d222..19f161709d1 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -1452,7 +1452,7 @@ pop_down_menu (void *arg) | |||
| 1452 | 1452 | ||
| 1453 | 1453 | ||
| 1454 | Lisp_Object | 1454 | Lisp_Object |
| 1455 | ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | 1455 | ns_popup_dialog (Lisp_Object position, Lisp_Object header, Lisp_Object contents) |
| 1456 | { | 1456 | { |
| 1457 | id dialog; | 1457 | id dialog; |
| 1458 | Lisp_Object window, tem, title; | 1458 | Lisp_Object window, tem, title; |
| @@ -1919,34 +1919,6 @@ DEFUN ("ns-reset-menu", Fns_reset_menu, Sns_reset_menu, 0, 0, 0, | |||
| 1919 | } | 1919 | } |
| 1920 | 1920 | ||
| 1921 | 1921 | ||
| 1922 | DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0, | ||
| 1923 | doc: /* Pop up a dialog box and return user's selection. | ||
| 1924 | POSITION specifies which frame to use. | ||
| 1925 | This is normally a mouse button event or a window or frame. | ||
| 1926 | If POSITION is t, it means to use the frame the mouse is on. | ||
| 1927 | The dialog box appears in the middle of the specified frame. | ||
| 1928 | |||
| 1929 | CONTENTS specifies the alternatives to display in the dialog box. | ||
| 1930 | It is a list of the form (DIALOG ITEM1 ITEM2...). | ||
| 1931 | Each ITEM is a cons cell (STRING . VALUE). | ||
| 1932 | The return value is VALUE from the chosen item. | ||
| 1933 | |||
| 1934 | An ITEM may also be just a string--that makes a nonselectable item. | ||
| 1935 | An ITEM may also be nil--that means to put all preceding items | ||
| 1936 | on the left of the dialog box and all following items on the right. | ||
| 1937 | \(By default, approximately half appear on each side.) | ||
| 1938 | |||
| 1939 | If HEADER is non-nil, the frame title for the box is "Information", | ||
| 1940 | otherwise it is "Question". | ||
| 1941 | |||
| 1942 | If the user gets rid of the dialog box without making a valid choice, | ||
| 1943 | for instance using the window manager, then this produces a quit and | ||
| 1944 | `x-popup-dialog' does not return. */) | ||
| 1945 | (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | ||
| 1946 | { | ||
| 1947 | return ns_popup_dialog (position, contents, header); | ||
| 1948 | } | ||
| 1949 | |||
| 1950 | DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, | 1922 | DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, |
| 1951 | doc: /* Return t if a menu or popup dialog is active. */) | 1923 | doc: /* Return t if a menu or popup dialog is active. */) |
| 1952 | (void) | 1924 | (void) |
| @@ -1968,7 +1940,6 @@ syms_of_nsmenu (void) | |||
| 1968 | update menus there. */ | 1940 | update menus there. */ |
| 1969 | trackingMenu = 1; | 1941 | trackingMenu = 1; |
| 1970 | #endif | 1942 | #endif |
| 1971 | defsubr (&Sx_popup_dialog); | ||
| 1972 | defsubr (&Sns_reset_menu); | 1943 | defsubr (&Sns_reset_menu); |
| 1973 | defsubr (&Smenu_or_popup_active_p); | 1944 | defsubr (&Smenu_or_popup_active_p); |
| 1974 | 1945 | ||
diff --git a/src/nsterm.h b/src/nsterm.h index 9f7767b312e..198a8867545 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -850,8 +850,8 @@ extern void find_and_call_menu_selection (struct frame *f, | |||
| 850 | extern Lisp_Object find_and_return_menu_selection (struct frame *f, | 850 | extern Lisp_Object find_and_return_menu_selection (struct frame *f, |
| 851 | bool keymaps, | 851 | bool keymaps, |
| 852 | void *client_data); | 852 | void *client_data); |
| 853 | extern Lisp_Object ns_popup_dialog (Lisp_Object position, Lisp_Object contents, | 853 | extern Lisp_Object ns_popup_dialog (Lisp_Object position, Lisp_Object header, |
| 854 | Lisp_Object header); | 854 | Lisp_Object contents); |
| 855 | 855 | ||
| 856 | #define NSAPP_DATA2_RUNASSCRIPT 10 | 856 | #define NSAPP_DATA2_RUNASSCRIPT 10 |
| 857 | extern void ns_run_ascript (void); | 857 | extern void ns_run_ascript (void); |
diff --git a/src/w32menu.c b/src/w32menu.c index ad2eb96495a..6ac02d95a63 100644 --- a/src/w32menu.c +++ b/src/w32menu.c | |||
| @@ -115,129 +115,34 @@ static int fill_in_menu (HMENU, widget_value *); | |||
| 115 | void w32_free_menu_strings (HWND); | 115 | void w32_free_menu_strings (HWND); |
| 116 | 116 | ||
| 117 | #ifdef HAVE_MENUS | 117 | #ifdef HAVE_MENUS |
| 118 | 118 | #ifdef HAVE_DIALOGS | |
| 119 | DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0, | 119 | Lisp_Object |
| 120 | doc: /* Pop up a dialog box and return user's selection. | 120 | w32_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents) |
| 121 | POSITION specifies which frame to use. | ||
| 122 | This is normally a mouse button event or a window or frame. | ||
| 123 | If POSITION is t, it means to use the frame the mouse is on. | ||
| 124 | The dialog box appears in the middle of the specified frame. | ||
| 125 | |||
| 126 | CONTENTS specifies the alternatives to display in the dialog box. | ||
| 127 | It is a list of the form (TITLE ITEM1 ITEM2...). | ||
| 128 | Each ITEM is a cons cell (STRING . VALUE). | ||
| 129 | The return value is VALUE from the chosen item. | ||
| 130 | |||
| 131 | An ITEM may also be just a string--that makes a nonselectable item. | ||
| 132 | An ITEM may also be nil--that means to put all preceding items | ||
| 133 | on the left of the dialog box and all following items on the right. | ||
| 134 | \(By default, approximately half appear on each side.) | ||
| 135 | |||
| 136 | If HEADER is non-nil, the frame title for the box is "Information", | ||
| 137 | otherwise it is "Question". */) | ||
| 138 | (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | ||
| 139 | { | 121 | { |
| 140 | struct frame *f = NULL; | 122 | Lisp_Object title; |
| 141 | Lisp_Object window; | 123 | char *error_name; |
| 142 | 124 | Lisp_Object selection; | |
| 143 | /* Decode the first argument: find the window or frame to use. */ | ||
| 144 | if (EQ (position, Qt) | ||
| 145 | || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) | ||
| 146 | || EQ (XCAR (position), Qtool_bar)))) | ||
| 147 | { | ||
| 148 | #if 0 /* Using the frame the mouse is on may not be right. */ | ||
| 149 | /* Use the mouse's current position. */ | ||
| 150 | struct frame *new_f = SELECTED_FRAME (); | ||
| 151 | Lisp_Object bar_window; | ||
| 152 | enum scroll_bar_part part; | ||
| 153 | Time time; | ||
| 154 | Lisp_Object x, y; | ||
| 155 | |||
| 156 | (*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y, &time); | ||
| 157 | |||
| 158 | if (new_f != 0) | ||
| 159 | XSETFRAME (window, new_f); | ||
| 160 | else | ||
| 161 | window = selected_window; | ||
| 162 | #endif | ||
| 163 | window = selected_window; | ||
| 164 | } | ||
| 165 | else if (CONSP (position)) | ||
| 166 | { | ||
| 167 | Lisp_Object tem = XCAR (position); | ||
| 168 | if (CONSP (tem)) | ||
| 169 | window = Fcar (XCDR (position)); | ||
| 170 | else | ||
| 171 | { | ||
| 172 | tem = Fcar (XCDR (position)); /* EVENT_START (position) */ | ||
| 173 | window = Fcar (tem); /* POSN_WINDOW (tem) */ | ||
| 174 | } | ||
| 175 | } | ||
| 176 | else if (WINDOWP (position) || FRAMEP (position)) | ||
| 177 | window = position; | ||
| 178 | else | ||
| 179 | window = Qnil; | ||
| 180 | |||
| 181 | /* Decode where to put the menu. */ | ||
| 182 | |||
| 183 | if (FRAMEP (window)) | ||
| 184 | f = XFRAME (window); | ||
| 185 | else if (WINDOWP (window)) | ||
| 186 | { | ||
| 187 | CHECK_LIVE_WINDOW (window); | ||
| 188 | f = XFRAME (WINDOW_FRAME (XWINDOW (window))); | ||
| 189 | } | ||
| 190 | else | ||
| 191 | /* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME, | ||
| 192 | but I don't want to make one now. */ | ||
| 193 | CHECK_WINDOW (window); | ||
| 194 | 125 | ||
| 195 | check_window_system (f); | 126 | check_window_system (f); |
| 196 | 127 | ||
| 197 | #ifndef HAVE_DIALOGS | 128 | /* Decode the dialog items from what was specified. */ |
| 198 | 129 | title = Fcar (contents); | |
| 199 | { | 130 | CHECK_STRING (title); |
| 200 | /* Handle simple Yes/No choices as MessageBox popups. */ | ||
| 201 | if (is_simple_dialog (contents)) | ||
| 202 | return simple_dialog_show (f, contents, header); | ||
| 203 | else | ||
| 204 | { | ||
| 205 | /* Display a menu with these alternatives | ||
| 206 | in the middle of frame F. */ | ||
| 207 | Lisp_Object x, y, frame, newpos; | ||
| 208 | XSETFRAME (frame, f); | ||
| 209 | XSETINT (x, FRAME_PIXEL_WIDTH (f) / 2); | ||
| 210 | XSETINT (y, FRAME_PIXEL_HEIGHT (f) / 2); | ||
| 211 | newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil)); | ||
| 212 | return Fx_popup_menu (newpos, | ||
| 213 | Fcons (Fcar (contents), Fcons (contents, Qnil))); | ||
| 214 | } | ||
| 215 | } | ||
| 216 | #else /* HAVE_DIALOGS */ | ||
| 217 | { | ||
| 218 | Lisp_Object title; | ||
| 219 | char *error_name; | ||
| 220 | Lisp_Object selection; | ||
| 221 | |||
| 222 | /* Decode the dialog items from what was specified. */ | ||
| 223 | title = Fcar (contents); | ||
| 224 | CHECK_STRING (title); | ||
| 225 | 131 | ||
| 226 | list_of_panes (Fcons (contents, Qnil)); | 132 | list_of_panes (Fcons (contents, Qnil)); |
| 227 | 133 | ||
| 228 | /* Display them in a dialog box. */ | 134 | /* Display them in a dialog box. */ |
| 229 | block_input (); | 135 | block_input (); |
| 230 | selection = w32_dialog_show (f, 0, title, header, &error_name); | 136 | selection = w32_dialog_show (f, 0, title, header, &error_name); |
| 231 | unblock_input (); | 137 | unblock_input (); |
| 232 | 138 | ||
| 233 | discard_menu_items (); | 139 | discard_menu_items (); |
| 234 | FRAME_DISPLAY_INFO (f)->grabbed = 0; | 140 | FRAME_DISPLAY_INFO (f)->grabbed = 0; |
| 235 | 141 | ||
| 236 | if (error_name) error (error_name); | 142 | if (error_name) error (error_name); |
| 237 | return selection; | 143 | return selection; |
| 238 | } | ||
| 239 | #endif /* HAVE_DIALOGS */ | ||
| 240 | } | 144 | } |
| 145 | #endif /* HAVE_DIALOGS */ | ||
| 241 | 146 | ||
| 242 | /* Activate the menu bar of frame F. | 147 | /* Activate the menu bar of frame F. |
| 243 | This is called from keyboard.c when it gets the | 148 | This is called from keyboard.c when it gets the |
| @@ -1724,9 +1629,6 @@ syms_of_w32menu (void) | |||
| 1724 | DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); | 1629 | DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); |
| 1725 | 1630 | ||
| 1726 | defsubr (&Smenu_or_popup_active_p); | 1631 | defsubr (&Smenu_or_popup_active_p); |
| 1727 | #ifdef HAVE_MENUS | ||
| 1728 | defsubr (&Sx_popup_dialog); | ||
| 1729 | #endif | ||
| 1730 | } | 1632 | } |
| 1731 | 1633 | ||
| 1732 | /* | 1634 | /* |
diff --git a/src/w32term.h b/src/w32term.h index 095ca54e3e8..8244487dfc7 100644 --- a/src/w32term.h +++ b/src/w32term.h | |||
| @@ -798,6 +798,10 @@ typedef char guichar_t; | |||
| 798 | 798 | ||
| 799 | #define GUI_SDATA(x) ((guichar_t*) SDATA (x)) | 799 | #define GUI_SDATA(x) ((guichar_t*) SDATA (x)) |
| 800 | 800 | ||
| 801 | #if defined HAVE_DIALOGS | ||
| 802 | extern Lisp_Object w32_popup_dialog (struct frame *, Lisp_Object, Lisp_Object); | ||
| 803 | #endif | ||
| 804 | |||
| 801 | extern void syms_of_w32term (void); | 805 | extern void syms_of_w32term (void); |
| 802 | extern void syms_of_w32menu (void); | 806 | extern void syms_of_w32menu (void); |
| 803 | extern void syms_of_w32fns (void); | 807 | extern void syms_of_w32fns (void); |
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 | } |
diff --git a/src/xterm.h b/src/xterm.h index 36aa8e52b1c..5ec4851a0e1 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -1035,6 +1035,10 @@ extern void x_free_dpy_colors (Display *, Screen *, Colormap, | |||
| 1035 | 1035 | ||
| 1036 | /* Defined in xmenu.c */ | 1036 | /* Defined in xmenu.c */ |
| 1037 | 1037 | ||
| 1038 | #if defined USE_X_TOOLKIT || defined USE_GTK | ||
| 1039 | extern Lisp_Object xw_popup_dialog (struct frame *, Lisp_Object, Lisp_Object); | ||
| 1040 | #endif | ||
| 1041 | |||
| 1038 | #if defined USE_GTK || defined USE_MOTIF | 1042 | #if defined USE_GTK || defined USE_MOTIF |
| 1039 | extern void x_menu_set_in_use (int); | 1043 | extern void x_menu_set_in_use (int); |
| 1040 | #endif | 1044 | #endif |