1 #include "../common/cache.h"
5 #include "../common/menuengine.h"
6 #include "../common/cheetahmenu.h"
9 #include "../common/debug.h"
10 #include "../common/systeminfo.h"
11 #include "../common/exec.h"
13 #define LONGEST_MENU_ITEM 40
16 * Windows-specific Cheetah menu functions
18 struct windows_menu_data
{
25 void reset_platform(void *platform
)
27 /* On Windows, we don't do anything to reset the menu */
31 * menu_item_builder to build a Windows-specific menu separator
33 * Always returns FALSE so the menu engine does not track this item
35 BOOL
build_separator(struct git_data
*data
, const struct menu_item
*item
,
38 struct windows_menu_data
*windows_menu
= platform
;
39 InsertMenu(windows_menu
->menu
, windows_menu
->index
,
40 MF_SEPARATOR
| MF_BYPOSITION
, 0, "");
41 windows_menu
->index
++;
47 * menu_item_builder to build a simple menu item
49 * Explorer's context menu are limited in the number of comands
50 * that they can use, so build_item would:
51 * - do nothing if that limit is reached and return FALSE to
52 * instruct the menu engine to not track this item
53 * - create item and return TRUE, so the item can be handled later
55 BOOL
build_item(struct git_data
*data
, const struct menu_item
*item
,
58 struct windows_menu_data
*windows_menu
= platform
;
59 if (windows_menu
->last
< windows_menu
->first
+ next_active_item
)
62 InsertMenu(windows_menu
->menu
, windows_menu
->index
,
63 MF_STRING
| MF_BYPOSITION
,
64 windows_menu
->first
+ next_active_item
,
67 if (item
->flags
& MI_CHECKED
)
68 CheckMenuItem(windows_menu
->menu
, windows_menu
->index
,
69 MF_BYPOSITION
| MF_CHECKED
);
71 windows_menu
->index
++;
75 void *start_submenu(struct git_data
*this_
, const struct menu_item
*item
,
78 struct windows_menu_data
*parent_menu
= platform
;
79 struct windows_menu_data
*submenu
=
80 malloc(sizeof(struct windows_menu_data
));
81 submenu
->menu
= CreateMenu();
82 InsertMenu(parent_menu
->menu
, parent_menu
->index
,
83 MF_POPUP
| MF_BYPOSITION
, (UINT_PTR
)(submenu
->menu
),
88 submenu
->first
= parent_menu
->first
;
93 void end_submenu(void *parent
, void *submenu
)
99 * These are the functions for handling the context menu.
102 inline STDMETHODIMP
query_context_menu(void *p
, HMENU menu
,
103 UINT index
, UINT first_command
,
104 UINT last_command
, UINT flags
)
106 struct git_menu
*this_menu
= p
;
107 struct git_data
*this_
= this_menu
->git_data
;
108 struct windows_menu_data windows_menu
=
109 { menu
, index
, first_command
, last_command
};
111 if (flags
& CMF_DEFAULTONLY
)
112 return MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, 0);
114 build_cheetah_menu(this_
, &windows_menu
);
116 return MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
,
121 * Perform a couple of transformations, such that a directory
122 * C:\Program Files\Bunch of stuff\in\A dir
124 * /C/Program\ Files/Bunch\ of\ stuff/in/A\ dir
126 * Assumes path is initially a correctly formed Windows-style path.
127 * Returns a new string.
129 static char *convert_directory_format(const char *path
)
136 /* Figure out how much extra space we need to escape spaces */
137 for (i
= 0; i
< MAX_PATH
&& path
[i
] != '\0'; ++i
)
141 converted
= (char *)calloc(size_incr
+ i
+ 1, sizeof(char));
148 for (i
= 0; i
< MAX_PATH
&& path
[i
] != '\0'; ++i
)
167 converted
[1] = converted
[0];
173 static void free_platform_argv(void *data
)
178 __attribute__((unused
))
179 static const char *get_win3264_cmd(void)
181 static struct strbuf buf
= STRBUF_INIT
;
184 strbuf_addf(&buf
, "%s\\SysWOW64\\cmd.exe", getenv("WINDIR"));
189 const char **menu_get_platform_argv(menu_commands cmd
, const void *data
,
190 free_func_t
*free_argv
, void **argv_data
)
193 const char *wd
= data
;
195 const char *history_argv
[] = { "sh", "--login", "-i",
196 "/bin/gitk", "HEAD", "--", NULL
, NULL
};
197 /* start is required because exec_program does not create a window */
199 const char *bash_argv
[] = { "start", "sh", "--login",
202 const char *bash_argv
[] = { NULL
, "/c",
203 "start sh --login -i", NULL
};
205 bash_argv
[0] = get_win3264_cmd();
214 history_argv
[6] = wd
;
216 argv
= xmalloc(sizeof(history_argv
));
217 memcpy(argv
, history_argv
, sizeof(history_argv
));
223 argv
= xmalloc(sizeof(bash_argv
));
224 memcpy(argv
, bash_argv
, sizeof(bash_argv
));
232 *free_argv
= free_platform_argv
;
238 inline STDMETHODIMP
invoke_command(void *p
,
239 LPCMINVOKECOMMANDINFO info
)
241 struct git_menu
*this_menu
= p
;
242 struct git_data
*this_
= this_menu
->git_data
;
243 UINT id
= LOWORD(info
->lpVerb
);
245 if (HIWORD(info
->lpVerb
))
248 handle_menu_item(this_
, id
);
252 inline STDMETHODIMP
get_command_string(void *p
, UINT id
,
253 UINT flags
, UINT
*reserved
,
254 LPSTR name
, UINT size
)
258 if (!(flags
& GCS_HELPTEXT
))
261 text
= get_menu_item_text(id
);
265 if (flags
& GCS_UNICODE
) {
266 size_t len
= strlen(text
) + 1;
267 LPWSTR tw
= malloc(len
* sizeof(wchar_t));
268 /* need to convert terminating NULL as well */
269 mbstowcs(tw
, text
, len
);
270 lstrcpynW((LPWSTR
)name
, tw
, size
);
273 lstrcpynA(name
, text
, size
);
278 DEFINE_STANDARD_METHODS(git_menu
)
280 struct git_menu_virtual_table git_menu_virtual_table
= {
281 query_interface_git_menu
,