source: golgotha/src/i4/video/win32/win32_input.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 14 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 18.8 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "video/win32/win32_input.hh"
10#include "error/error.hh"
11#include "device/keys.hh"
12#include "device/event.hh"
13#include "main/win_main.hh"
14#include "device/kernel.hh"
15#include "video/win32/resource.h"
16#include "memory/malloc.hh"
17
18i4_bool win32_input_class::class_registered=i4_F;
19
20static win32_input_class *win32_current_input=0;
21HWND current_window_handle;
22HANDLE myPid;
23
24int i4_default_warning(const char *st);
25int i4_default_error(const char *st);
26
27// int i4_win32_error(const char *st)
28// {
29//   if (current_window_handle)
30//   {
31//     MessageBox(current_window_handle, st, "Error!", MB_OK | MB_APPLMODAL);
32//     exit(0);
33//   }
34//   else
35//     i4_default_error(st);
36//   return 1;
37// }
38
39
40i4_bool win32_input_class::process_events()
41{
42  i4_bool ret=i4_F;
43
44  MSG         msg;
45
46  w32         size=20;
47
48//   //check the DirectInput key device if it exists
49//   if(lpdiKey)
50//     lpdiKey->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), keyData, &size, 0);
51
52//  w32         size=20;
53
54  //check the DirectInput key device if it exists
55  /*
56  if(lpdiKey)
57  {
58    ret=lpdiKey->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), keyData, &size, DIGDD_PEEK);
59    if(ret==DI_OK || ret==DI_BUFFEROVERFLOW)
60    {
61      for(int i=0;i<size;i++)
62      {
63        if(keyData[i].dwData&0xff)
64        {  //key down
65          w16 key_code=translate_windows_key(keyData[i].dwOfs);
66          w16 key=i4_key_translate(key_code, 1, modifier_state);
67          i4_key_press_event_class ev(key,key_code, modifier_state);
68          send_event_to_agents(&ev,i4_device_class::FLAG_KEY_PRESS);
69        }
70        else
71        {
72          w16 key_code=translate_windows_key(keyData[i].dwOfs);
73          w16 key=i4_key_translate(key_code, 0, modifier_state);
74          i4_key_release_event_class ev(key,key_code, modifier_state);
75          send_event_to_agents(&ev,i4_device_class::FLAG_KEY_RELEASE);
76        }
77      }
78    }
79  }*/
80
81  while (PeekMessage(&msg, whandle, 0,0, PM_REMOVE)==TRUE)
82  {
83    TranslateMessage(&msg);
84   
85    process(whandle, msg.message, msg.wParam, msg.lParam, msg.time);
86
87    ret=i4_T;
88  }
89  return ret;
90}
91
92long FAR PASCAL WindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
93
94
95/*
96I4_THREAD_PROC_RETURN win32_input_class(I4_THREAD_PROC_ARGLIST)
97{
98  MSG msg;
99  win32_input_class *input=(win32_input_class *)arg_list;
100
101  while (!stop_thread)
102  {   
103    GetMessage(&msg, input->get_window_handle(), 0,0);
104    if (msg.message != WM_USER)
105      input->message_que.que(msg);
106  }
107  thread_running=i4_F;
108}
109*/
110
111void win32_input_class::get_window_area(int &x, int &y, int &w, int &h)
112{
113  RECT r;
114  GetClientRect(whandle, &r);
115
116  w=r.right-r.left;
117  h=r.bottom-r.top;
118
119  NONCLIENTMETRICS cl;
120  cl.cbSize=sizeof(NONCLIENTMETRICS);
121
122  SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
123                       sizeof(NONCLIENTMETRICS),
124                       &cl,
125                       0);
126
127  x=r.left + cl.iBorderWidth;
128  y=r.top + cl.iCaptionHeight;
129 
130 
131}
132
133i4_bool win32_input_class::create_window(sw32 x, sw32 y, w32 w, w32 h,
134                                         i4_display_class *display_responsible_for_close,
135                                         i4_bool takeup_fullscreen)
136
137  if (!class_registered)
138  {
139    WNDCLASS window_class;
140    window_class.style = CS_HREDRAW | CS_VREDRAW;
141    window_class.lpfnWndProc = WindowProc;
142    window_class.cbClsExtra = 0;
143    window_class.cbWndExtra = 0;
144    window_class.hInstance = i4_win32_instance;
145    window_class.hIcon = LoadIcon( i4_win32_instance, MAKEINTRESOURCE(103));
146//      window_class.hIcon = LoadIcon( i4_win32_instance, "102");
147//    window_class.hIcon = (HICON)LoadImage( i4_win32_instance, MAKEINTRESOURCE(IDI_GOLGOTHA), IMAGE_ICON,0,0,LR_LOADTRANSPARENT);
148    window_class.hCursor = LoadCursor( NULL, IDC_ARROW );
149    window_class.hbrBackground = GetStockObject(WHITE_BRUSH);
150    window_class.lpszMenuName = window_name();
151    window_class.lpszClassName = class_name();
152    RegisterClass( &window_class );
153    class_registered=i4_T;
154  }
155
156 
157  if (takeup_fullscreen)
158    whandle = CreateWindowEx(0,
159                             class_name(),
160                             window_name(),
161                             WS_POPUP | WS_EX_TOPMOST,
162                             0,0,
163                             GetSystemMetrics(SM_CXSCREEN),
164                             GetSystemMetrics(SM_CYSCREEN),
165                             NULL,
166                             NULL,
167                             i4_win32_instance,
168                             NULL );
169
170  else
171    whandle = CreateWindowEx(0,
172                             class_name(),
173                             window_name(),
174                             WS_POPUP | WS_EX_TOPMOST,
175                             //                             WS_OVERLAPPEDWINDOW,
176                             x, y, w, h,
177                             NULL,
178                             NULL,
179                             i4_win32_instance,
180                             NULL );
181  if (whandle)
182  {
183    have_window=i4_T;
184    current_window_handle=whandle;
185
186
187    i4_kernel.add_device(this);
188    win32_current_input=this; 
189    display=display_responsible_for_close;
190
191    ShowCursor(FALSE);
192
193    DragAcceptFiles(whandle, i4_T);
194  }
195  else
196    i4_error("failed to create window");
197
198  if (!i4_win32_window_handle)
199    i4_win32_window_handle=whandle;
200
201  //myPid=GetCurrentProcess();
202  //SetPriorityClass(myPid, HIGH_PRIORITY_CLASS);
203
204  if (takeup_fullscreen)
205  {
206    confine.on=i4_T;
207    confine.x1=0;
208    confine.y1=0;
209    confine.x2=w-1;
210    confine.y2=h-1;
211   
212    ShowWindow(whandle, SW_SHOWNORMAL);
213   
214    /*
215    SetWindowPos(whandle,
216                 HWND_TOPMOST,
217                 0,0,
218                 GetSystemMetrics(SM_CXSCREEN),
219                 GetSystemMetrics(SM_CYSCREEN),
220                 SWP_SHOWWINDOW);
221                 */
222  }
223  else
224    ShowWindow(whandle, SW_SHOW);
225
226  UpdateWindow(whandle);
227
228  return i4_T;
229}
230
231void win32_input_class::destroy_window()
232{
233  if (have_window)
234  {
235    PostMessage(whandle, WM_USER, 0,0);  // send message to thread to unblock it
236
237//     stop_thread=i4_T;
238//     while (!thread_running)
239//       Sleep(0);
240
241    have_window=i4_F;
242 
243    if (i4_win32_window_handle==whandle)
244      i4_win32_window_handle=0;
245
246    current_window_handle=0;
247    DestroyWindow(whandle);
248
249    i4_kernel.remove_device(this);
250    win32_current_input=0;
251
252//              if(lpdiKey) lpdiKey->Release(), lpdiKey=NULL;
253//              if(lpdi) lpdi->Release(), lpdi=NULL;
254
255    ShowCursor(TRUE);
256  }
257
258
259
260}
261
262long FAR PASCAL WindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
263{
264  if (win32_current_input)
265    return win32_current_input->process(hWnd, message, wParam, lParam, 0);
266  else
267    return DefWindowProc(hWnd, message, wParam, lParam);
268
269}
270
271win32_input_class::win32_input_class(char *extra_message)
272{
273  mouse_locked   = i4_F;
274  async_mouse    = 0;
275  modifier_state = 0;
276  have_window    = i4_F;
277  active         = i4_F;
278 
279  if (extra_message && (strlen(extra_message) < 128))
280    strcpy(window_message,extra_message);
281  else
282    window_message[0]=0;
283}
284
285
286void win32_input_class::set_async_mouse(dx_threaded_mouse_class *m)
287
288  if (async_mouse)
289  {
290    //dont let this mouse references us anymore
291    //    async_mouse->input = 0;
292  }
293
294  async_mouse = m;
295
296  if (async_mouse)
297  {   
298    //    async_mouse->input = this;
299    //    async_mouse->set_active(active);
300  }
301}
302
303w16 win32_input_class::translate_windows_key(w16 wkey, w32 &m)
304{
305  w16 key;
306  m=0;
307  switch (wkey)
308  {
309    case VK_BACK     : key=I4_BACKSPACE; break;
310    case VK_TAB      : key=I4_TAB;       break;
311    case VK_RETURN   : key=I4_ENTER;     break;
312    case VK_ESCAPE   : key=I4_ESC;       break;
313    case VK_SPACE    : key=I4_SPACE;     break;
314    case VK_UP       : key=I4_UP;        break;
315    case VK_DOWN     : key=I4_DOWN;      break;
316    case VK_LEFT     : key=I4_LEFT;      break;
317    case VK_RIGHT    : key=I4_RIGHT;     break;
318    case VK_CONTROL  :
319    case VK_LCONTROL : key=I4_CTRL_L;  m=I4_MODIFIER_CTRL_L;  break;
320    case VK_RCONTROL : key=I4_CTRL_R;  m=I4_MODIFIER_CTRL_R;  break;
321    case VK_MENU     :
322    case VK_LMENU    : key=I4_ALT_L;   m=I4_MODIFIER_ALT_L;  break;
323    case VK_RMENU    : key=I4_ALT_R;   m=I4_MODIFIER_ALT_R;  break;
324    case VK_SHIFT    :
325    case VK_LSHIFT   : key=I4_SHIFT_L; m=I4_MODIFIER_SHIFT_L; break;
326    case VK_RSHIFT   : key=I4_SHIFT_R; m=I4_MODIFIER_SHIFT_R; break;
327    case VK_CAPITAL  : key=I4_CAPS;      break;
328    case VK_NUMLOCK  : key=I4_NUM_LOCK;  break;
329    case VK_HOME     : key=I4_HOME;      break;
330    case VK_END      : key=I4_END;       break;
331    case VK_DELETE   : key=I4_DEL;       break;
332    case VK_F1       : key=I4_F1;        break;
333    case VK_F2       : key=I4_F2;        break;
334    case VK_F3       : key=I4_F3;        break;
335    case VK_F4       : key=I4_F4;        break;
336    case VK_F5       : key=I4_F5;        break;
337    case VK_F6       : key=I4_F6;        break;
338    case VK_F7       : key=I4_F7;        break;
339    case VK_F8       : key=I4_F8;        break;
340    case VK_F9       : key=I4_F9;        break;
341    case VK_F10      : key=I4_F10;       break;
342    case VK_F11      : key=I4_F11;       break;
343    case VK_F12      : key=I4_F12;       break;
344    case VK_F13      : key=I4_F13;       break;
345    case VK_F14      : key=I4_F14;       break;
346    case VK_F15      : key=I4_F15;       break;
347    case VK_INSERT   : key=I4_INSERT;    break;
348    case VK_PRIOR    : key=I4_PAGEUP;    break;
349    case VK_NEXT     : key=I4_PAGEDOWN;  break;   
350
351    case VK_NUMPAD0  : key=I4_KP0;       break;
352    case VK_NUMPAD1  : key=I4_KP1;       break;
353    case VK_NUMPAD2  : key=I4_KP2;       break;
354    case VK_NUMPAD3  : key=I4_KP3;       break;
355    case VK_NUMPAD4  : key=I4_KP4;       break;
356    case VK_NUMPAD5  : key=I4_KP5;       break;
357    case VK_NUMPAD6  : key=I4_KP6;       break;
358    case VK_NUMPAD7  : key=I4_KP7;       break;
359    case VK_NUMPAD8  : key=I4_KP8;       break;
360    case VK_NUMPAD9  : key=I4_KP9;       break;
361
362    case VK_DIVIDE   : key=I4_KPSLASH;   break;
363    case VK_MULTIPLY : key=I4_KPSTAR;    break;
364    case VK_SUBTRACT : key=I4_KPMINUS;   break;
365    case VK_ADD      : key=I4_KPPLUS;    break;
366    case VK_DECIMAL  : key=I4_KPPERIOD;  break;
367
368    case 0xc0        : key='`'; break;
369    case 0xba        : key=';'; break;
370    case 0xbb        : key='='; break;
371    case 0xbc        : key=','; break;
372    case 0xbd        : key='-'; break;
373    case 0xbe        : key='.'; break;
374    case 0xbf        : key='/'; break;
375    case 0xdb        : key='['; break;
376    case 0xdc        : key='\\'; break;
377    case 0xdd        : key=']'; break;
378    case 0xde        : key='\''; break;
379
380    default :
381      if ((wkey>='A' && wkey<='Z') || (wkey>='0' && wkey<='9'))
382        key = wkey;
383      else
384        key = 0;
385      break;
386  }
387  return key;
388}
389
390i4_bool win32_input_class::lock_mouse_in_place(i4_bool yes_no)
391{
392  //if (async_mouse)
393    //    async_mouse->lock_position(yes_no);
394
395  mouse_locked=yes_no;
396  return i4_T;
397}
398
399void win32_input_class::update_mouse_movement(sw32 new_x, sw32 new_y)
400{   
401  if (!active)
402    return;
403
404  i4_mouse_move_event_class ev(mouse_x, mouse_y, new_x, new_y);
405   
406  int mx,my;
407
408  mx = new_x;
409  my = new_y;
410
411  if (confine.on)
412  {
413    if (mx<confine.x1)
414    {
415      mx=confine.x1;
416      SetCursorPos(mx, my);
417    }
418    if (mouse_y<confine.y1)
419    {
420      my=confine.y1;
421      SetCursorPos(mx, my);
422    }
423
424    if (mouse_x>confine.x2)
425    {
426      mx=confine.x2;
427      SetCursorPos(mx, my);
428    }
429    if (mouse_y>confine.y2)
430    {
431      my=confine.y2;
432      SetCursorPos(mx, my);
433    }
434  }
435       
436  send_event_to_agents(&ev,i4_device_class::FLAG_MOUSE_MOVE);
437
438  if (mouse_locked)
439  {
440    if (mx!=mouse_x || my!=mouse_y)
441      SetCursorPos(mouse_x, mouse_y);
442   }
443  else
444  {
445    mouse_x=mx;
446    mouse_y=my;
447  }   
448}
449
450void win32_input_class::update_mouse_buttons(i4_mouse_button_event_class::btype type,
451                                             mouse_button_state state)
452{
453  if (!active)
454    return;
455 
456  i4_time_class now;
457  if (state==UP)
458  {
459    i4_mouse_button_up_event_class ev_up(type, mouse_x, mouse_y, now, last_up[type]);
460    send_event_to_agents(&ev_up,i4_device_class::FLAG_MOUSE_BUTTON_UP);
461    last_up[type]=now;
462  }
463  else
464  if (state==DOWN)
465  {
466    i4_mouse_button_down_event_class ev_down(type, mouse_x, mouse_y, now, last_down[type]);
467    send_event_to_agents(&ev_down,i4_device_class::FLAG_MOUSE_BUTTON_DOWN);
468    last_down[type]=now;
469  }   
470}
471
472
473sw32 win32_input_class::process(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, DWORD time)
474{
475  PAINTSTRUCT ps;
476  HDC         hdc;
477
478  if (!have_window)
479    return DefWindowProc(hWnd, message, wParam, lParam);
480
481  switch( message )
482  {
483    case WM_DROPFILES :
484    {
485      HANDLE drop=(HANDLE) wParam;
486      POINT point;
487      DragQueryPoint(drop, &point);
488
489      i4_window_got_drop_class de(0);
490
491      int t=DragQueryFile(drop, 0xffffffff, 0,0);
492      de.drag_info.t_filenames=t;
493      de.drag_info.filenames=(i4_str **)i4_malloc(sizeof(i4_str *) * t, "");
494      de.drag_info.drag_object_type=i4_drag_info_struct::FILENAMES;
495      de.drag_info.x=point.x;
496      de.drag_info.y=point.y;
497
498      for (int i=0; i<t; i++)
499      {
500        char buf[500];
501        DragQueryFile(drop, i, buf, 500);
502        de.drag_info.filenames[i]=new i4_str(buf);
503      }
504
505      DragFinish(drop);
506
507      send_event_to_agents(&de, i4_device_class::FLAG_DRAG_DROP_EVENTS);
508
509      SetFocus(hWnd);
510
511    } break;
512     
513    case WM_PAINT :
514      if (window_message[0])
515      {
516        BeginPaint(hWnd,&ps);
517        EndPaint(hWnd,&ps);
518        hdc = GetDC(hWnd);
519        TextOut(hdc,0,0,window_message,strlen(window_message));       
520        ReleaseDC(hWnd,hdc);
521      }
522      redraw();
523      break;
524
525#if 0
526    case WM_SETCURSOR:
527    {
528      if (win32_display_instance.accel->remove_cursor())
529      {
530        ShowCursor(FALSE);
531        return TRUE;
532      }
533    } break;
534#endif
535
536
537    case WM_SIZE :
538      resize(LOWORD(lParam), HIWORD(lParam));
539      break;
540
541    case WM_MOVE :
542      move(LOWORD(lParam), HIWORD(lParam));
543      break;
544
545
546    case WM_MOUSEMOVE :
547    {
548      if (!async_mouse)
549        update_mouse_movement(LOWORD(lParam),HIWORD(lParam));
550    } break;
551
552    case WM_LBUTTONDOWN :
553    {
554      if (!async_mouse)
555        update_mouse_buttons(i4_mouse_button_event_class::LEFT, DOWN);
556    } break;
557
558    case WM_LBUTTONUP :
559    {
560      if (!async_mouse)
561        update_mouse_buttons(i4_mouse_button_event_class::LEFT, UP);
562    } break;
563
564
565    case WM_RBUTTONDOWN :
566    {
567      if (!async_mouse)
568        update_mouse_buttons(i4_mouse_button_event_class::RIGHT, DOWN);
569    } break;
570
571    case WM_RBUTTONUP :
572    {
573      if (!async_mouse)
574        update_mouse_buttons(i4_mouse_button_event_class::RIGHT, UP);
575    } break;
576
577    case WM_MBUTTONDOWN :
578    {
579      if (!async_mouse)
580        update_mouse_buttons(i4_mouse_button_event_class::CENTER, DOWN);
581    } break;
582
583    case WM_MBUTTONUP :
584    {
585      if (!async_mouse)
586        update_mouse_buttons(i4_mouse_button_event_class::CENTER, UP);
587    } break;
588
589    case WM_SETFOCUS:
590      set_active(i4_T);
591     
592//       if (async_mouse)
593//         async_mouse->set_active(i4_T);
594
595    break;
596
597    case WM_KILLFOCUS:                 
598      set_active(i4_F);
599     
600//       if (async_mouse)
601//         async_mouse->set_active(i4_F);
602
603    break;
604
605
606    case WM_ACTIVATEAPP :
607      set_active((i4_bool)wParam);
608     
609//       if (async_mouse)
610//         async_mouse->set_active((i4_bool)wParam);
611    break;
612
613    case WM_SYSCOMMAND:
614    {
615      switch (wParam)
616      {
617      case SC_CLOSE:
618        i4_display_close_event_class dc(display);
619        send_event_to_agents(&dc, i4_device_class::FLAG_DISPLAY_CLOSE);
620        close_event();
621        return 0;
622      }
623    }
624
625    case WM_DESTROY:
626    {
627     
628    } return 0;
629
630    case WM_SYSKEYDOWN :
631    case WM_KEYDOWN :
632    {
633      w32 m;
634      w16 key_code=translate_windows_key(wParam, m);
635      modifier_state|=m;
636
637      w16 key=i4_key_translate(key_code, 1, modifier_state);
638      i4_time_class t(time);
639     
640      i4_key_press_event_class ev(key,key_code, modifier_state, t);
641      send_event_to_agents(&ev,i4_device_class::FLAG_KEY_PRESS);
642    } break;
643
644    case WM_SYSKEYUP :
645    case WM_KEYUP :
646    {
647      w32 m;
648      w16 key_code=translate_windows_key(wParam,m);
649      modifier_state&=~m;
650
651      w16 key=i4_key_translate(key_code, 0, modifier_state);
652      i4_time_class t(time);
653
654      i4_key_release_event_class ev(key,key_code, modifier_state, t);
655      send_event_to_agents(&ev,i4_device_class::FLAG_KEY_RELEASE);
656    } break;
657
658  }
659
660  return DefWindowProc(hWnd, message, wParam, lParam);
661}
662
663
664
665// BOOL win32_input_class::CreateKeyboard(GUID &guid, LPDIRECTINPUTDEVICE& lpdiKey, DWORD dwAccess)
666// {
667/*  HRESULT err=lpdi->CreateDevice(guid, &lpdiKey, NULL);
668
669  if(err!=DI_OK)
670  {
671    i4_warning("Unable to create DirectInput keyboard device!\n\0");
672    goto fail;
673  }
674 
675  // Tell DirectInput that we want to receive data in keyboard format
676  err=lpdiKey->SetDataFormat(&c_dfDIKeyboard);
677  if(err!=DI_OK)
678  {
679    i4_warning("Unable to access DirectInput device as a keyboard!\n\0");
680    goto fail;
681  }
682  // set desired access mode
683  err=lpdiKey->SetCooperativeLevel(current_window_handle, dwAccess);
684  if(err != DI_OK)
685  {
686    i4_warning("Unable to set DirectInput keyboard cooperativity level!\n\0");
687    goto fail;
688  }
689  return TRUE;
690fail:
691  if(lpdiKey) lpdiKey->Release(), lpdiKey=0; */
692//  return FALSE;
693//}
694
695/*BOOL win32_input_class::InitDInput(void)
696{
697  HRESULT err;
698  GUID    guid=GUID_SysKeyboard;
699
700  err=DirectInputCreate(i4_win32_instance, DIRECTINPUT_VERSION, &lpdi, NULL);
701  if(err!=DI_OK)
702  {
703    i4_warning("Unable to create DirectInput object!\n\0");
704    return FALSE;
705  }
706  i4_warning("DirectInput object initialized...\n\0");
707 
708  // Create a keyboard obj
709        if(CreateKeyboard(guid, lpdiKey, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND))
710  {
711    lpdiKey->Acquire();
712    i4_warning("Keyboard found and acquired...\n\0");
713
714    return TRUE;
715  }
716  if(lpdiKey) lpdiKey->Release(), lpdiKey=NULL;
717  if(lpdi) lpdi->Release(), lpdi=NULL;
718  return FALSE;
719} */
720
Note: See TracBrowser for help on using the repository browser.