8 #include "systeminfo.h"
11 * These are the functions for handling the context menu.
14 static STDMETHODIMP
query_context_menu(void *p
, HMENU menu
,
15 UINT index
, UINT first_command
,
16 UINT last_command
, UINT flags
)
18 struct git_menu
*this_menu
= p
;
19 struct git_data
*this_
= this_menu
->git_data
;
21 if (flags
& CMF_DEFAULTONLY
)
22 return MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, 0);
24 InsertMenu(menu
, index
, MF_SEPARATOR
| MF_BYPOSITION
,
26 InsertMenu(menu
, index
+1, MF_STRING
| MF_BYPOSITION
,
27 first_command
+1, _T("&Git Gui"));
29 return MAKE_HRESULT(SEVERITY_SUCCESS
, FACILITY_NULL
, 2);
33 * Perform a couple of transformations, such that a directory
34 * C:\Program Files\Bunch of stuff\in\A dir
36 * /C/Program\ Files/Bunch\ of\ stuff/in/A\ dir
38 * Assumes path is initially a correctly formed Windows-style path.
39 * Returns a new string.
41 static char *convert_directory_format(const char *path
)
48 /* Figure out how much extra space we need to escape spaces */
49 for (i
= 0; i
< MAX_PATH
&& path
[i
] != '\0'; ++i
)
53 converted
= (char *)calloc(size_incr
+ i
+ 1, sizeof(char));
60 for (i
= 0; i
< MAX_PATH
&& path
[i
] != '\0'; ++i
)
79 converted
[1] = converted
[0];
85 static void adjust_path_for_git(const char *msys_path
)
87 static int initialized
= 0;
90 const char *old_path
= getenv("PATH");
91 size_t old_len
= strlen(old_path
);
92 size_t msys_path_len
= strlen(msys_path
);
93 char *new_path
= malloc(old_len
+ 2 * msys_path_len
+ 23);
96 sprintf(new_path
, "PATH=%s\\bin;%s\\mingw\\bin;%s",
97 old_path
, msys_path
, msys_path
);
103 static STDMETHODIMP
invoke_command(void *p
,
104 LPCMINVOKECOMMANDINFO info
)
106 struct git_menu
*this_menu
= p
;
107 struct git_data
*this_
= this_menu
->git_data
;
108 int command
= LOWORD(info
->lpVerb
);
110 if (HIWORD(info
->lpVerb
) != 0)
115 STARTUPINFO si
= { sizeof(si
) };
116 PROCESS_INFORMATION pi
;
118 TCHAR
* msysPath
= msys_path();
126 adjust_path_for_git(msysPath
);
127 wsprintf(command
, TEXT("wish.exe \"%s/bin/git-gui\""),
132 if (wd
== NULL
|| strlen(wd
) == 0)
133 wd
= info
->lpDirectory
;
135 dwAttr
= FILE_ATTRIBUTE_DIRECTORY
;
136 fa
= GetFileAttributes(wd
);
138 wd
= info
->lpDirectory
;
140 debug_git("Trying to spawn '%s' in working directory '%s'\n", command
, wd
);
147 0, NULL
, wd
, &si
, &pi
))
149 CloseHandle(pi
.hProcess
);
150 CloseHandle(pi
.hThread
);
154 debug_git("[ERROR] %s/%s:%d Could not create git gui process (%d) Command: %s",
155 __FILE__
, __FUNCTION__
, __LINE__
,
156 GetLastError(), command
);
161 debug_git("[ERROR] %s/%s:%d Could not find msysPath",
162 __FILE__
, __FUNCTION__
, __LINE__
);
171 static STDMETHODIMP
get_command_string(void *p
, UINT id
,
172 UINT flags
, UINT
*reserved
,
173 LPSTR name
, UINT size
)
176 struct git_menu
*this_menu
= p
;
177 struct git_data
*this_
= this_menu
->git_data
;
183 if (flags
& GCS_HELPTEXT
) {
184 LPCTSTR text
= _T("Launch the GIT Gui in the local or chosen directory.");
185 size_t len
= strlen(text
) + 1;
186 LPWSTR tw
= malloc(len
* sizeof(wchar_t));
187 /* need to convert terminating NULL as well */
188 mbstowcs(tw
, text
, len
);
189 /* use Win32 lstrcpyn to [automatically] avoid buffer overflow */
190 if (flags
& GCS_UNICODE
)
191 lstrcpynW((LPWSTR
)name
, tw
, size
);
193 lstrcpynA(name
, text
, size
);
202 DEFINE_STANDARD_METHODS(git_menu
)
204 struct git_menu_virtual_table git_menu_virtual_table
= {
205 query_interface_git_menu
,