diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 3 | ||||
| -rw-r--r-- | src/w32menu.c | 181 |
2 files changed, 163 insertions, 21 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index f36731450d4..34edb2370b3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | 2008-04-10 Jason Rumney <jasonr@gnu.org> | 1 | 2008-04-10 Jason Rumney <jasonr@gnu.org> |
| 2 | 2 | ||
| 3 | * w32menu.c (is_simple_dialog, simple_dialog_show): New functions. | ||
| 4 | (Fx_popup_dialog): Handle simple yes/no questions as dialogs. | ||
| 5 | |||
| 3 | * w32.c (logon_network_drive): Also logon to remote drives that | 6 | * w32.c (logon_network_drive): Also logon to remote drives that |
| 4 | are mapped to drive letters. | 7 | are mapped to drive letters. |
| 5 | 8 | ||
diff --git a/src/w32menu.c b/src/w32menu.c index f4857eb9d10..1f8561210c1 100644 --- a/src/w32menu.c +++ b/src/w32menu.c | |||
| @@ -168,22 +168,28 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; | |||
| 168 | 168 | ||
| 169 | extern Lisp_Object Qmenu_bar_update_hook; | 169 | extern Lisp_Object Qmenu_bar_update_hook; |
| 170 | 170 | ||
| 171 | void set_frame_menubar (); | 171 | void set_frame_menubar P_ ((FRAME_PTR, int, int)); |
| 172 | 172 | ||
| 173 | static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, | 173 | static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
| 174 | Lisp_Object, Lisp_Object, Lisp_Object, | 174 | Lisp_Object, Lisp_Object, Lisp_Object, |
| 175 | Lisp_Object, Lisp_Object)); | 175 | Lisp_Object, Lisp_Object)); |
| 176 | #ifdef HAVE_DIALOGS | 176 | #ifdef HAVE_DIALOGS |
| 177 | static Lisp_Object w32_dialog_show (); | 177 | static Lisp_Object w32_dialog_show P_ ((FRAME_PTR, int, Lisp_Object, char**)); |
| 178 | #else | ||
| 179 | static int is_simple_dialog P_ ((Lisp_Object)); | ||
| 180 | static Lisp_Object simple_dialog_show P_ ((FRAME_PTR, Lisp_Object, Lisp_Object)); | ||
| 178 | #endif | 181 | #endif |
| 179 | static Lisp_Object w32_menu_show (); | 182 | static Lisp_Object w32_menu_show P_ ((FRAME_PTR, int, int, int, int, |
| 180 | 183 | Lisp_Object, char **)); | |
| 181 | static void keymap_panes (); | 184 | |
| 182 | static void single_keymap_panes (); | 185 | static void keymap_panes P_ ((Lisp_Object *, int, int)); |
| 183 | static void single_menu_item (); | 186 | static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
| 184 | static void list_of_panes (); | 187 | int, int)); |
| 185 | static void list_of_items (); | 188 | static void single_menu_item P_ ((Lisp_Object, Lisp_Object, |
| 186 | void w32_free_menu_strings (HWND); | 189 | Lisp_Object *, int, int)); |
| 190 | static void list_of_panes P_ ((Lisp_Object)); | ||
| 191 | static void list_of_items P_ ((Lisp_Object)); | ||
| 192 | void w32_free_menu_strings P_((HWND)); | ||
| 187 | 193 | ||
| 188 | /* This holds a Lisp vector that holds the results of decoding | 194 | /* This holds a Lisp vector that holds the results of decoding |
| 189 | the keymaps or alist-of-alists that specify a menu. | 195 | the keymaps or alist-of-alists that specify a menu. |
| @@ -928,17 +934,23 @@ otherwise it is "Question". */) | |||
| 928 | CHECK_WINDOW (window); | 934 | CHECK_WINDOW (window); |
| 929 | 935 | ||
| 930 | #ifndef HAVE_DIALOGS | 936 | #ifndef HAVE_DIALOGS |
| 931 | /* Display a menu with these alternatives | 937 | |
| 932 | in the middle of frame F. */ | ||
| 933 | { | 938 | { |
| 934 | Lisp_Object x, y, frame, newpos; | 939 | /* Handle simple Yes/No choices as MessageBox popups. */ |
| 935 | XSETFRAME (frame, f); | 940 | if (is_simple_dialog (contents)) |
| 936 | XSETINT (x, x_pixel_width (f) / 2); | 941 | return simple_dialog_show (f, contents, header); |
| 937 | XSETINT (y, x_pixel_height (f) / 2); | 942 | else |
| 938 | newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil)); | 943 | { |
| 939 | 944 | /* Display a menu with these alternatives | |
| 940 | return Fx_popup_menu (newpos, | 945 | in the middle of frame F. */ |
| 941 | Fcons (Fcar (contents), Fcons (contents, Qnil))); | 946 | Lisp_Object x, y, frame, newpos; |
| 947 | XSETFRAME (frame, f); | ||
| 948 | XSETINT (x, x_pixel_width (f) / 2); | ||
| 949 | XSETINT (y, x_pixel_height (f) / 2); | ||
| 950 | newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil)); | ||
| 951 | return Fx_popup_menu (newpos, | ||
| 952 | Fcons (Fcar (contents), Fcons (contents, Qnil))); | ||
| 953 | } | ||
| 942 | } | 954 | } |
| 943 | #else /* HAVE_DIALOGS */ | 955 | #else /* HAVE_DIALOGS */ |
| 944 | { | 956 | { |
| @@ -2001,6 +2013,29 @@ w32_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 2001 | 2013 | ||
| 2002 | 2014 | ||
| 2003 | #ifdef HAVE_DIALOGS | 2015 | #ifdef HAVE_DIALOGS |
| 2016 | /* TODO: On Windows, there are two ways of defining a dialog. | ||
| 2017 | |||
| 2018 | 1. Create a predefined dialog resource and include it in nt/emacs.rc. | ||
| 2019 | Using this method, we could then set the titles and make unneeded | ||
| 2020 | buttons invisible before displaying the dialog. Everything would | ||
| 2021 | be a fixed size though, so there is a risk that text does not | ||
| 2022 | fit on a button. | ||
| 2023 | 2. Create the dialog template in memory on the fly. This allows us | ||
| 2024 | to size the dialog and buttons dynamically, probably giving more | ||
| 2025 | natural looking results for dialogs with few buttons, and eliminating | ||
| 2026 | the problem of text overflowing the buttons. But the API for this is | ||
| 2027 | quite complex - structures have to be allocated in particular ways, | ||
| 2028 | text content is tacked onto the end of structures in variable length | ||
| 2029 | arrays with further structures tacked on after these, there are | ||
| 2030 | certain alignment requirements for all this, and we have to | ||
| 2031 | measure all the text and convert to "dialog coordinates" to figure | ||
| 2032 | out how big to make everything. | ||
| 2033 | |||
| 2034 | For now, we'll just stick with menus for dialogs that are more | ||
| 2035 | complicated than simple yes/no type questions for which we can use | ||
| 2036 | the MessageBox function. | ||
| 2037 | */ | ||
| 2038 | |||
| 2004 | static char * button_names [] = { | 2039 | static char * button_names [] = { |
| 2005 | "button1", "button2", "button3", "button4", "button5", | 2040 | "button1", "button2", "button3", "button4", "button5", |
| 2006 | "button6", "button7", "button8", "button9", "button10" }; | 2041 | "button6", "button7", "button8", "button9", "button10" }; |
| @@ -2192,7 +2227,111 @@ w32_dialog_show (f, keymaps, title, header, error) | |||
| 2192 | 2227 | ||
| 2193 | return Qnil; | 2228 | return Qnil; |
| 2194 | } | 2229 | } |
| 2195 | #endif /* HAVE_DIALOGS */ | 2230 | #else /* !HAVE_DIALOGS */ |
| 2231 | |||
| 2232 | /* Currently we only handle Yes No dialogs (y-or-n-p and yes-or-no-p) as | ||
| 2233 | simple dialogs. We could handle a few more, but I'm not aware of | ||
| 2234 | anywhere in Emacs that uses the other specific dialog choices that | ||
| 2235 | MessageBox provides. */ | ||
| 2236 | |||
| 2237 | static int is_simple_dialog (contents) | ||
| 2238 | Lisp_Object contents; | ||
| 2239 | { | ||
| 2240 | Lisp_Object options = XCDR (contents); | ||
| 2241 | Lisp_Object name, yes, no, other; | ||
| 2242 | |||
| 2243 | yes = build_string ("Yes"); | ||
| 2244 | no = build_string ("No"); | ||
| 2245 | |||
| 2246 | if (!CONSP (options)) | ||
| 2247 | return 0; | ||
| 2248 | |||
| 2249 | name = XCAR (XCAR (options)); | ||
| 2250 | if (!CONSP (options)) | ||
| 2251 | return 0; | ||
| 2252 | |||
| 2253 | if (!NILP (Fstring_equal (name, yes))) | ||
| 2254 | other = no; | ||
| 2255 | else if (!NILP (Fstring_equal (name, no))) | ||
| 2256 | other = yes; | ||
| 2257 | else | ||
| 2258 | return 0; | ||
| 2259 | |||
| 2260 | options = XCDR (options); | ||
| 2261 | if (!CONSP (options)) | ||
| 2262 | return 0; | ||
| 2263 | |||
| 2264 | name = XCAR (XCAR (options)); | ||
| 2265 | if (NILP (Fstring_equal (name, other))) | ||
| 2266 | return 0; | ||
| 2267 | |||
| 2268 | /* Check there are no more options. */ | ||
| 2269 | options = XCDR (options); | ||
| 2270 | return !(CONSP (options)); | ||
| 2271 | } | ||
| 2272 | |||
| 2273 | static Lisp_Object simple_dialog_show (f, contents, header) | ||
| 2274 | FRAME_PTR f; | ||
| 2275 | Lisp_Object contents, header; | ||
| 2276 | { | ||
| 2277 | int answer; | ||
| 2278 | UINT type; | ||
| 2279 | char *text, *title; | ||
| 2280 | Lisp_Object lispy_answer = Qnil, temp = XCAR (contents); | ||
| 2281 | |||
| 2282 | if (STRINGP (temp)) | ||
| 2283 | text = SDATA (temp); | ||
| 2284 | else | ||
| 2285 | text = ""; | ||
| 2286 | |||
| 2287 | if (NILP (header)) | ||
| 2288 | { | ||
| 2289 | title = "Question"; | ||
| 2290 | type = MB_ICONQUESTION; | ||
| 2291 | } | ||
| 2292 | else | ||
| 2293 | { | ||
| 2294 | title = "Information"; | ||
| 2295 | type = MB_ICONINFORMATION; | ||
| 2296 | } | ||
| 2297 | type |= MB_YESNO; | ||
| 2298 | |||
| 2299 | /* Since we only handle Yes/No dialogs, and we already checked | ||
| 2300 | is_simple_dialog, we don't need to worry about checking contents | ||
| 2301 | to see what type of dialog to use. */ | ||
| 2302 | answer = MessageBox (FRAME_W32_WINDOW (f), text, title, type); | ||
| 2303 | |||
| 2304 | if (answer == IDYES) | ||
| 2305 | lispy_answer = build_string ("Yes"); | ||
| 2306 | else if (answer == IDNO) | ||
| 2307 | lispy_answer = build_string ("No"); | ||
| 2308 | else | ||
| 2309 | Fsignal (Qquit, Qnil); | ||
| 2310 | |||
| 2311 | for (temp = XCDR (contents); CONSP (temp); temp = XCDR (temp)) | ||
| 2312 | { | ||
| 2313 | Lisp_Object item, name, value; | ||
| 2314 | item = XCAR (temp); | ||
| 2315 | if (CONSP (item)) | ||
| 2316 | { | ||
| 2317 | name = XCAR (item); | ||
| 2318 | value = XCDR (item); | ||
| 2319 | } | ||
| 2320 | else | ||
| 2321 | { | ||
| 2322 | name = item; | ||
| 2323 | value = Qnil; | ||
| 2324 | } | ||
| 2325 | |||
| 2326 | if (!NILP (Fstring_equal (name, lispy_answer))) | ||
| 2327 | { | ||
| 2328 | return value; | ||
| 2329 | } | ||
| 2330 | } | ||
| 2331 | Fsignal (Qquit, Qnil); | ||
| 2332 | return Qnil; | ||
| 2333 | } | ||
| 2334 | #endif /* !HAVE_DIALOGS */ | ||
| 2196 | 2335 | ||
| 2197 | 2336 | ||
| 2198 | /* Is this item a separator? */ | 2337 | /* Is this item a separator? */ |