Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 1 | // pjsua_wince.cpp : Defines the entry point for the application. |
| 2 | // |
| 3 | |
| 4 | #include "stdafx.h" |
| 5 | #include "pjsua_wince.h" |
| 6 | #include <commctrl.h> |
| 7 | #include <pjsua-lib/pjsua.h> |
| 8 | |
| 9 | #define MAX_LOADSTRING 100 |
| 10 | |
| 11 | // Global Variables: |
| 12 | static HINSTANCE hInst; |
| 13 | static HWND hMainWnd; |
| 14 | static HWND hwndCB; |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 15 | static HWND hwndGlobalStatus, hwndURI, hwndCallStatus; |
| 16 | static HWND hwndActionButton, hwndExitButton; |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 17 | |
| 18 | static pj_pool_t *g_pool; |
| 19 | static pj_str_t g_local_uri; |
| 20 | static int g_current_acc; |
| 21 | static int g_current_call = PJSUA_INVALID_ID; |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 22 | static int g_current_action; |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 23 | |
| 24 | enum |
| 25 | { |
| 26 | ID_GLOBAL_STATUS = 21, |
| 27 | ID_URI, |
| 28 | ID_CALL_STATUS, |
| 29 | ID_POLL_TIMER, |
| 30 | }; |
| 31 | |
| 32 | enum |
| 33 | { |
| 34 | ID_MENU_NONE = 64, |
| 35 | ID_MENU_CALL, |
| 36 | ID_MENU_ANSWER, |
| 37 | ID_MENU_DISCONNECT, |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 38 | ID_BTN_ACTION, |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 39 | }; |
| 40 | |
Benny Prijono | 5da5043 | 2006-08-07 10:24:52 +0000 | [diff] [blame] | 41 | #define DEFAULT_URI "sip:192.168.0.7" |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 42 | |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 43 | |
| 44 | // Forward declarations of functions included in this code module: |
| 45 | static ATOM MyRegisterClass (HINSTANCE, LPTSTR); |
| 46 | BOOL InitInstance (HINSTANCE, int); |
| 47 | static void OnCreate (HWND hWnd); |
| 48 | static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); |
| 49 | |
| 50 | |
| 51 | |
| 52 | ///////////////////////////////////////////////////////////////////////////// |
| 53 | |
| 54 | static void OnError(const wchar_t *title, pj_status_t status) |
| 55 | { |
| 56 | char errmsg[PJ_ERR_MSG_SIZE]; |
| 57 | PJ_DECL_UNICODE_TEMP_BUF(werrmsg, PJ_ERR_MSG_SIZE); |
| 58 | |
| 59 | pj_strerror(status, errmsg, sizeof(errmsg)); |
| 60 | |
| 61 | MessageBox(NULL, PJ_STRING_TO_NATIVE(errmsg, werrmsg, PJ_ERR_MSG_SIZE), |
| 62 | title, MB_OK); |
| 63 | } |
| 64 | |
| 65 | |
| 66 | static void SetLocalURI(const char *uri, int len, bool enabled=true) |
| 67 | { |
| 68 | wchar_t tmp[128]; |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 69 | if (len==-1) len=pj_ansi_strlen(uri); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 70 | pj_ansi_to_unicode(uri, len, tmp, PJ_ARRAY_SIZE(tmp)); |
| 71 | SetDlgItemText(hMainWnd, ID_GLOBAL_STATUS, tmp); |
| 72 | EnableWindow(hwndGlobalStatus, enabled?TRUE:FALSE); |
| 73 | } |
| 74 | |
| 75 | |
| 76 | |
| 77 | static void SetURI(const char *uri, int len, bool enabled=true) |
| 78 | { |
| 79 | wchar_t tmp[128]; |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 80 | if (len==-1) len=pj_ansi_strlen(uri); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 81 | pj_ansi_to_unicode(uri, len, tmp, PJ_ARRAY_SIZE(tmp)); |
| 82 | SetDlgItemText(hMainWnd, ID_URI, tmp); |
| 83 | EnableWindow(hwndURI, enabled?TRUE:FALSE); |
| 84 | } |
| 85 | |
| 86 | |
| 87 | static void SetCallStatus(const char *state, int len) |
| 88 | { |
| 89 | wchar_t tmp[128]; |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 90 | if (len==-1) len=pj_ansi_strlen(state); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 91 | pj_ansi_to_unicode(state, len, tmp, PJ_ARRAY_SIZE(tmp)); |
| 92 | SetDlgItemText(hMainWnd, ID_CALL_STATUS, tmp); |
| 93 | } |
| 94 | |
| 95 | static void SetAction(int action, bool enable=true) |
| 96 | { |
| 97 | HMENU hMenu; |
| 98 | |
| 99 | hMenu = CommandBar_GetMenu(hwndCB, 0); |
| 100 | |
| 101 | RemoveMenu(hMenu, ID_MENU_NONE, MF_BYCOMMAND); |
| 102 | RemoveMenu(hMenu, ID_MENU_CALL, MF_BYCOMMAND); |
| 103 | RemoveMenu(hMenu, ID_MENU_ANSWER, MF_BYCOMMAND); |
| 104 | RemoveMenu(hMenu, ID_MENU_DISCONNECT, MF_BYCOMMAND); |
| 105 | |
| 106 | switch (action) { |
| 107 | case ID_MENU_NONE: |
| 108 | InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("None")); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 109 | SetWindowText(hwndActionButton, TEXT("-")); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 110 | break; |
| 111 | case ID_MENU_CALL: |
| 112 | InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("Call")); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 113 | SetWindowText(hwndActionButton, TEXT("&Call")); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 114 | break; |
| 115 | case ID_MENU_ANSWER: |
| 116 | InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("Answer")); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 117 | SetWindowText(hwndActionButton, TEXT("&Answer")); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 118 | break; |
| 119 | case ID_MENU_DISCONNECT: |
| 120 | InsertMenu(hMenu, ID_EXIT, MF_BYCOMMAND, action, TEXT("Hangup")); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 121 | SetWindowText(hwndActionButton, TEXT("&Hangup")); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 122 | break; |
| 123 | } |
| 124 | |
| 125 | EnableMenuItem(hMenu, action, MF_BYCOMMAND | (enable?MF_ENABLED:MF_GRAYED)); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 126 | DrawMenuBar(hMainWnd); |
| 127 | |
| 128 | g_current_action = action; |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 129 | } |
| 130 | |
| 131 | |
| 132 | /* |
| 133 | * Handler when invite state has changed. |
| 134 | */ |
| 135 | static void on_call_state(pjsua_call_id call_id, pjsip_event *e) |
| 136 | { |
| 137 | pjsua_call_info call_info; |
| 138 | |
| 139 | PJ_UNUSED_ARG(e); |
| 140 | |
| 141 | pjsua_call_get_info(call_id, &call_info); |
| 142 | |
| 143 | if (call_info.state == PJSIP_INV_STATE_DISCONNECTED) { |
| 144 | |
| 145 | g_current_call = PJSUA_INVALID_ID; |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 146 | SetURI(DEFAULT_URI, -1); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 147 | SetAction(ID_MENU_CALL); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 148 | //SetCallStatus(call_info.state_text.ptr, call_info.state_text.slen); |
| 149 | SetCallStatus(call_info.last_status_text.ptr, call_info.last_status_text.slen); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 150 | |
| 151 | } else { |
Benny Prijono | edba079 | 2006-08-06 18:23:56 +0000 | [diff] [blame] | 152 | //if (g_current_call == PJSUA_INVALID_ID) |
| 153 | // g_current_call = call_id; |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 154 | |
| 155 | if (call_info.remote_contact.slen) |
| 156 | SetURI(call_info.remote_contact.ptr, call_info.remote_contact.slen, false); |
| 157 | else |
| 158 | SetURI(call_info.remote_info.ptr, call_info.remote_info.slen, false); |
Benny Prijono | edba079 | 2006-08-06 18:23:56 +0000 | [diff] [blame] | 159 | |
| 160 | if (call_info.state == PJSIP_INV_STATE_CONFIRMED) |
| 161 | SetAction(ID_MENU_DISCONNECT); |
| 162 | |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 163 | SetCallStatus(call_info.state_text.ptr, call_info.state_text.slen); |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | |
| 168 | /* |
| 169 | * Callback on media state changed event. |
| 170 | * The action may connect the call to sound device, to file, or |
| 171 | * to loop the call. |
| 172 | */ |
| 173 | static void on_call_media_state(pjsua_call_id call_id) |
| 174 | { |
| 175 | pjsua_call_info call_info; |
| 176 | |
| 177 | pjsua_call_get_info(call_id, &call_info); |
| 178 | |
| 179 | if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) { |
| 180 | pjsua_conf_connect(call_info.conf_slot, 0); |
| 181 | pjsua_conf_connect(0, call_info.conf_slot); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | |
| 186 | /** |
| 187 | * Handler when there is incoming call. |
| 188 | */ |
| 189 | static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, |
| 190 | pjsip_rx_data *rdata) |
| 191 | { |
| 192 | pjsua_call_info call_info; |
| 193 | |
| 194 | PJ_UNUSED_ARG(acc_id); |
| 195 | PJ_UNUSED_ARG(rdata); |
| 196 | |
| 197 | if (g_current_call != PJSUA_INVALID_ID) { |
Benny Prijono | edba079 | 2006-08-06 18:23:56 +0000 | [diff] [blame] | 198 | pj_str_t reason; |
| 199 | reason = pj_str("Another call is in progress"); |
| 200 | pjsua_call_answer(call_id, PJSIP_SC_BUSY_HERE, &reason, NULL); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 201 | return; |
| 202 | } |
| 203 | |
| 204 | g_current_call = call_id; |
| 205 | |
| 206 | pjsua_call_get_info(call_id, &call_info); |
| 207 | |
| 208 | SetAction(ID_MENU_ANSWER); |
| 209 | SetURI(call_info.remote_info.ptr, call_info.remote_info.slen, false); |
Benny Prijono | fd27c66 | 2006-08-09 11:59:26 +0000 | [diff] [blame] | 210 | pjsua_call_answer(call_id, 200, NULL, NULL); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 211 | } |
| 212 | |
| 213 | |
| 214 | /* |
| 215 | * Handler registration status has changed. |
| 216 | */ |
| 217 | static void on_reg_state(pjsua_acc_id acc_id) |
| 218 | { |
| 219 | PJ_UNUSED_ARG(acc_id); |
| 220 | |
| 221 | // Log already written. |
| 222 | } |
| 223 | |
| 224 | |
| 225 | /* |
| 226 | * Handler on buddy state changed. |
| 227 | */ |
| 228 | static void on_buddy_state(pjsua_buddy_id buddy_id) |
| 229 | { |
| 230 | } |
| 231 | |
| 232 | |
| 233 | /** |
| 234 | * Incoming IM message (i.e. MESSAGE request)! |
| 235 | */ |
| 236 | static void on_pager(pjsua_call_id call_id, const pj_str_t *from, |
| 237 | const pj_str_t *to, const pj_str_t *contact, |
| 238 | const pj_str_t *mime_type, const pj_str_t *text) |
| 239 | { |
| 240 | } |
| 241 | |
| 242 | |
| 243 | /** |
| 244 | * Received typing indication |
| 245 | */ |
| 246 | static void on_typing(pjsua_call_id call_id, const pj_str_t *from, |
| 247 | const pj_str_t *to, const pj_str_t *contact, |
| 248 | pj_bool_t is_typing) |
| 249 | { |
| 250 | } |
| 251 | |
| 252 | |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 253 | static BOOL OnInitStack(void) |
| 254 | { |
| 255 | pjsua_config cfg; |
| 256 | pjsua_logging_config log_cfg; |
| 257 | pjsua_media_config media_cfg; |
| 258 | pjsua_transport_config udp_cfg; |
| 259 | pjsua_transport_config rtp_cfg; |
| 260 | pjsua_transport_id transport_id; |
| 261 | pjsua_transport_info transport_info; |
Benny Prijono | 7c3741f | 2006-08-05 21:07:15 +0000 | [diff] [blame] | 262 | pj_str_t tmp; |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 263 | pj_status_t status; |
| 264 | |
| 265 | /* Create pjsua */ |
| 266 | status = pjsua_create(); |
| 267 | if (status != PJ_SUCCESS) { |
| 268 | OnError(TEXT("Error creating pjsua"), status); |
| 269 | return FALSE; |
| 270 | } |
| 271 | |
| 272 | /* Create global pool for application */ |
| 273 | g_pool = pjsua_pool_create("pjsua", 4000, 4000); |
| 274 | |
| 275 | /* Init configs */ |
| 276 | pjsua_config_default(&cfg); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 277 | pjsua_media_config_default(&media_cfg); |
| 278 | pjsua_transport_config_default(&udp_cfg); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 279 | udp_cfg.port = 50060; |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 280 | pjsua_transport_config_default(&rtp_cfg); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 281 | rtp_cfg.port = 40000; |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 282 | |
Benny Prijono | 4e05b47 | 2006-10-16 15:52:31 +0000 | [diff] [blame] | 283 | pjsua_logging_config_default(&log_cfg); |
| 284 | log_cfg.level = 5; |
| 285 | log_cfg.log_filename = pj_str("\\pjsua.txt"); |
| 286 | log_cfg.msg_logging = 1; |
| 287 | log_cfg.decor = pj_log_get_decor() | PJ_LOG_HAS_CR; |
| 288 | |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 289 | /* Setup media */ |
| 290 | media_cfg.clock_rate = 8000; |
Benny Prijono | 5da5043 | 2006-08-07 10:24:52 +0000 | [diff] [blame] | 291 | media_cfg.ec_options = PJMEDIA_ECHO_SIMPLE; |
Benny Prijono | fd27c66 | 2006-08-09 11:59:26 +0000 | [diff] [blame] | 292 | media_cfg.ec_tail_len = 256; |
Benny Prijono | edba079 | 2006-08-06 18:23:56 +0000 | [diff] [blame] | 293 | media_cfg.quality = 1; |
| 294 | media_cfg.ptime = 20; |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 295 | |
| 296 | /* Initialize application callbacks */ |
| 297 | cfg.cb.on_call_state = &on_call_state; |
| 298 | cfg.cb.on_call_media_state = &on_call_media_state; |
| 299 | cfg.cb.on_incoming_call = &on_incoming_call; |
| 300 | cfg.cb.on_reg_state = &on_reg_state; |
| 301 | cfg.cb.on_buddy_state = &on_buddy_state; |
| 302 | cfg.cb.on_pager = &on_pager; |
| 303 | cfg.cb.on_typing = &on_typing; |
| 304 | |
| 305 | /* Initialize pjsua */ |
| 306 | status = pjsua_init(&cfg, &log_cfg, &media_cfg); |
| 307 | if (status != PJ_SUCCESS) { |
| 308 | OnError(TEXT("Initialization error"), status); |
| 309 | return FALSE; |
| 310 | } |
| 311 | |
| 312 | /* Set codec priority */ |
Benny Prijono | edba079 | 2006-08-06 18:23:56 +0000 | [diff] [blame] | 313 | pjsua_codec_set_priority(pj_cstr(&tmp, "pcmu"), 240); |
| 314 | pjsua_codec_set_priority(pj_cstr(&tmp, "pcma"), 230); |
| 315 | pjsua_codec_set_priority(pj_cstr(&tmp, "speex/8000"), 190); |
Benny Prijono | fd27c66 | 2006-08-09 11:59:26 +0000 | [diff] [blame] | 316 | pjsua_codec_set_priority(pj_cstr(&tmp, "ilbc"), 189); |
Benny Prijono | edba079 | 2006-08-06 18:23:56 +0000 | [diff] [blame] | 317 | pjsua_codec_set_priority(pj_cstr(&tmp, "speex/16000"), 180); |
Benny Prijono | 7c3741f | 2006-08-05 21:07:15 +0000 | [diff] [blame] | 318 | pjsua_codec_set_priority(pj_cstr(&tmp, "speex/32000"), 0); |
Benny Prijono | fd27c66 | 2006-08-09 11:59:26 +0000 | [diff] [blame] | 319 | pjsua_codec_set_priority(pj_cstr(&tmp, "gsm"), 100); |
Benny Prijono | 7c3741f | 2006-08-05 21:07:15 +0000 | [diff] [blame] | 320 | |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 321 | |
| 322 | /* Add UDP transport and the corresponding PJSUA account */ |
| 323 | status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, |
| 324 | &udp_cfg, &transport_id); |
| 325 | if (status != PJ_SUCCESS) { |
| 326 | OnError(TEXT("Error starting SIP transport"), status); |
| 327 | return FALSE; |
| 328 | } |
| 329 | |
| 330 | pjsua_transport_get_info(transport_id, &transport_info); |
| 331 | |
| 332 | g_local_uri.ptr = (char*)pj_pool_alloc(g_pool, 128); |
| 333 | g_local_uri.slen = pj_ansi_sprintf(g_local_uri.ptr, |
| 334 | "<sip:%.*s:%d>", |
| 335 | (int)transport_info.local_name.host.slen, |
| 336 | transport_info.local_name.host.ptr, |
| 337 | transport_info.local_name.port); |
| 338 | |
| 339 | |
| 340 | /* Add local account */ |
| 341 | pjsua_acc_add_local(transport_id, PJ_TRUE, &g_current_acc); |
| 342 | pjsua_acc_set_online_status(g_current_acc, PJ_TRUE); |
| 343 | |
| 344 | /* Start pjsua */ |
| 345 | status = pjsua_start(); |
| 346 | if (status != PJ_SUCCESS) { |
| 347 | OnError(TEXT("Error starting pjsua"), status); |
| 348 | return FALSE; |
| 349 | } |
| 350 | |
| 351 | return TRUE; |
| 352 | } |
| 353 | |
| 354 | |
| 355 | ////////////////////////////////////////////////////////////////////////////// |
| 356 | |
| 357 | int WINAPI WinMain(HINSTANCE hInstance, |
| 358 | HINSTANCE hPrevInstance, |
| 359 | LPTSTR lpCmdLine, |
| 360 | int nCmdShow) |
| 361 | { |
| 362 | MSG msg; |
| 363 | HACCEL hAccelTable; |
| 364 | |
| 365 | |
| 366 | |
| 367 | // Perform application initialization: |
| 368 | if (!InitInstance (hInstance, nCmdShow)) |
| 369 | { |
| 370 | return FALSE; |
| 371 | } |
| 372 | |
| 373 | hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_PJSUA_WINCE); |
| 374 | |
| 375 | |
| 376 | // Main message loop: |
| 377 | while (GetMessage(&msg, NULL, 0, 0)) |
| 378 | { |
| 379 | if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) |
| 380 | { |
| 381 | TranslateMessage(&msg); |
| 382 | DispatchMessage(&msg); |
| 383 | } |
| 384 | } |
| 385 | |
| 386 | return msg.wParam; |
| 387 | } |
| 388 | |
| 389 | static ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass) |
| 390 | { |
| 391 | WNDCLASS wc; |
| 392 | |
| 393 | wc.style = CS_HREDRAW | CS_VREDRAW; |
| 394 | wc.lpfnWndProc = (WNDPROC) WndProc; |
| 395 | wc.cbClsExtra = 0; |
| 396 | wc.cbWndExtra = 0; |
| 397 | wc.hInstance = hInstance; |
| 398 | wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PJSUA_WINCE)); |
| 399 | wc.hCursor = 0; |
| 400 | wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); |
| 401 | wc.lpszMenuName = 0; |
| 402 | wc.lpszClassName = szWindowClass; |
| 403 | |
| 404 | return RegisterClass(&wc); |
| 405 | } |
| 406 | |
| 407 | |
| 408 | |
| 409 | BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) |
| 410 | { |
| 411 | HWND hWnd; |
| 412 | TCHAR szTitle[MAX_LOADSTRING]; |
| 413 | TCHAR szWindowClass[MAX_LOADSTRING]; |
| 414 | |
| 415 | hInst = hInstance; |
| 416 | |
| 417 | /* Init stack */ |
| 418 | if (OnInitStack() == FALSE) |
| 419 | return FALSE; |
| 420 | |
| 421 | LoadString(hInstance, IDC_PJSUA_WINCE, szWindowClass, MAX_LOADSTRING); |
| 422 | MyRegisterClass(hInstance, szWindowClass); |
| 423 | |
| 424 | LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); |
| 425 | hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE, |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 426 | CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 200, |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 427 | NULL, NULL, hInstance, NULL); |
| 428 | |
| 429 | if (!hWnd) |
| 430 | { |
| 431 | return FALSE; |
| 432 | } |
| 433 | |
| 434 | hMainWnd = hWnd; |
| 435 | ShowWindow(hWnd, nCmdShow); |
| 436 | UpdateWindow(hWnd); |
| 437 | if (hwndCB) |
| 438 | CommandBar_Show(hwndCB, TRUE); |
| 439 | |
| 440 | SetTimer(hMainWnd, ID_POLL_TIMER, 50, NULL); |
| 441 | return TRUE; |
| 442 | } |
| 443 | |
| 444 | |
| 445 | static void OnCreate(HWND hWnd) |
| 446 | { |
| 447 | enum |
| 448 | { |
| 449 | X = 10, |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 450 | Y = 40, |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 451 | W = 220, |
| 452 | H = 30, |
| 453 | }; |
| 454 | |
| 455 | DWORD dwStyle; |
| 456 | |
| 457 | hMainWnd = hWnd; |
| 458 | |
| 459 | hwndCB = CommandBar_Create(hInst, hWnd, 1); |
| 460 | CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0); |
| 461 | CommandBar_AddAdornments(hwndCB, 0, 0); |
| 462 | |
| 463 | // Create global status text |
| 464 | dwStyle = WS_CHILD | WS_VISIBLE | WS_DISABLED | ES_LEFT; |
| 465 | hwndGlobalStatus = CreateWindow( |
| 466 | TEXT("EDIT"), // Class name |
| 467 | NULL, // Window text |
| 468 | dwStyle, // Window style |
| 469 | X, // x-coordinate of the upper-left corner |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 470 | Y+0, // y-coordinate of the upper-left corner |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 471 | W, // Width of the window for the edit |
| 472 | // control |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 473 | H-5, // Height of the window for the edit |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 474 | // control |
| 475 | hWnd, // Window handle to the parent window |
| 476 | (HMENU) ID_GLOBAL_STATUS, // Control identifier |
| 477 | hInst, // Instance handle |
| 478 | NULL); // Specify NULL for this parameter when |
| 479 | // you create a control |
| 480 | SetLocalURI(g_local_uri.ptr, g_local_uri.slen, false); |
| 481 | |
| 482 | |
| 483 | // Create URI edit |
| 484 | dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER; |
| 485 | hwndURI = CreateWindow ( |
| 486 | TEXT("EDIT"), // Class name |
| 487 | NULL, // Window text |
| 488 | dwStyle, // Window style |
| 489 | X, // x-coordinate of the upper-left corner |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 490 | Y+H, // y-coordinate of the upper-left corner |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 491 | W, // Width of the window for the edit |
| 492 | // control |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 493 | H-5, // Height of the window for the edit |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 494 | // control |
| 495 | hWnd, // Window handle to the parent window |
| 496 | (HMENU) ID_URI, // Control identifier |
| 497 | hInst, // Instance handle |
| 498 | NULL); // Specify NULL for this parameter when |
| 499 | // you create a control |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 500 | |
| 501 | // Create action Button |
| 502 | hwndActionButton = CreateWindow( L"button", L"Action", |
| 503 | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| 504 | X, Y+2*H, |
| 505 | 60, H-5, hWnd, |
| 506 | (HMENU) ID_BTN_ACTION, |
| 507 | hInst, NULL ); |
| 508 | |
| 509 | // Create exit button |
| 510 | hwndExitButton = CreateWindow( L"button", L"E&xit", |
| 511 | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, |
| 512 | X+70, Y+2*H, |
| 513 | 60, H-5, hWnd, |
| 514 | (HMENU) ID_EXIT, |
| 515 | hInst, NULL ); |
| 516 | |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 517 | |
| 518 | // Create call status edit |
| 519 | dwStyle = WS_CHILD | WS_VISIBLE | WS_DISABLED; |
| 520 | hwndCallStatus = CreateWindow ( |
| 521 | TEXT("EDIT"), // Class name |
| 522 | NULL, // Window text |
| 523 | dwStyle, // Window style |
| 524 | X, // x-coordinate of the upper-left corner |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 525 | Y+3*H, // y-coordinate of the upper-left corner |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 526 | W, // Width of the window for the edit |
| 527 | // control |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 528 | H-5, // Height of the window for the edit |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 529 | // control |
| 530 | hWnd, // Window handle to the parent window |
| 531 | (HMENU) ID_CALL_STATUS, // Control identifier |
| 532 | hInst, // Instance handle |
| 533 | NULL); // Specify NULL for this parameter when |
| 534 | // you create a control |
| 535 | SetCallStatus("Ready", 5); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 536 | SetAction(ID_MENU_CALL); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 537 | SetURI(DEFAULT_URI, -1); |
Benny Prijono | 39ea7f0 | 2006-09-14 13:52:29 +0000 | [diff] [blame] | 538 | SetFocus(hWnd); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 539 | |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 540 | } |
| 541 | |
| 542 | |
| 543 | static void OnDestroy(void) |
| 544 | { |
| 545 | pjsua_destroy(); |
| 546 | } |
| 547 | |
| 548 | static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
| 549 | { |
| 550 | int wmId, wmEvent; |
| 551 | |
| 552 | switch (message) { |
Benny Prijono | 39ea7f0 | 2006-09-14 13:52:29 +0000 | [diff] [blame] | 553 | case WM_KEYUP: |
| 554 | if (wParam==114) { |
| 555 | wParam = ID_MENU_CALL; |
| 556 | } else if (wParam==115) { |
| 557 | if (g_current_call == PJSUA_INVALID_ID) |
| 558 | wParam = ID_EXIT; |
| 559 | else |
| 560 | wParam = ID_MENU_DISCONNECT; |
| 561 | } else |
| 562 | break; |
| 563 | |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 564 | case WM_COMMAND: |
| 565 | wmId = LOWORD(wParam); |
| 566 | wmEvent = HIWORD(wParam); |
Benny Prijono | f20687a | 2006-08-04 18:27:19 +0000 | [diff] [blame] | 567 | if (wmId == ID_BTN_ACTION) |
| 568 | wmId = g_current_action; |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 569 | switch (wmId) |
| 570 | { |
| 571 | case ID_MENU_CALL: |
| 572 | if (g_current_call != PJSUA_INVALID_ID) { |
| 573 | MessageBox(NULL, TEXT("Can not make call"), |
| 574 | TEXT("You already have one call active"), MB_OK); |
| 575 | } |
| 576 | pj_str_t dst_uri; |
| 577 | wchar_t text[256]; |
| 578 | char tmp[256]; |
| 579 | pj_status_t status; |
| 580 | |
| 581 | GetWindowText(hwndURI, text, PJ_ARRAY_SIZE(text)); |
| 582 | pj_unicode_to_ansi(text, pj_unicode_strlen(text), |
| 583 | tmp, sizeof(tmp)); |
| 584 | dst_uri.ptr = tmp; |
| 585 | dst_uri.slen = pj_ansi_strlen(tmp); |
| 586 | status = pjsua_call_make_call(g_current_acc, |
| 587 | &dst_uri, 0, NULL, |
| 588 | NULL, &g_current_call); |
| 589 | if (status != PJ_SUCCESS) |
| 590 | OnError(TEXT("Unable to make call"), status); |
| 591 | break; |
| 592 | case ID_MENU_ANSWER: |
| 593 | if (g_current_call == PJSUA_INVALID_ID) |
| 594 | MessageBox(NULL, TEXT("Can not answer"), |
| 595 | TEXT("There is no call!"), MB_OK); |
Benny Prijono | edba079 | 2006-08-06 18:23:56 +0000 | [diff] [blame] | 596 | else |
| 597 | pjsua_call_answer(g_current_call, 200, NULL, NULL); |
Benny Prijono | 01f0154 | 2006-08-01 23:09:35 +0000 | [diff] [blame] | 598 | break; |
| 599 | case ID_MENU_DISCONNECT: |
| 600 | if (g_current_call == PJSUA_INVALID_ID) |
| 601 | MessageBox(NULL, TEXT("Can not disconnect"), |
| 602 | TEXT("There is no call!"), MB_OK); |
| 603 | else |
| 604 | pjsua_call_hangup(g_current_call, PJSIP_SC_DECLINE, NULL, NULL); |
| 605 | break; |
| 606 | case ID_EXIT: |
| 607 | DestroyWindow(hWnd); |
| 608 | break; |
| 609 | default: |
| 610 | return DefWindowProc(hWnd, message, wParam, lParam); |
| 611 | } |
| 612 | break; |
| 613 | |
| 614 | case WM_CREATE: |
| 615 | OnCreate(hWnd); |
| 616 | break; |
| 617 | |
| 618 | case WM_DESTROY: |
| 619 | OnDestroy(); |
| 620 | CommandBar_Destroy(hwndCB); |
| 621 | PostQuitMessage(0); |
| 622 | break; |
| 623 | |
| 624 | case WM_TIMER: |
| 625 | pjsua_handle_events(1); |
| 626 | break; |
| 627 | |
| 628 | default: |
| 629 | return DefWindowProc(hWnd, message, wParam, lParam); |
| 630 | } |
| 631 | return 0; |
| 632 | } |
| 633 | |