1/*
2 * libjingle
3 * Copyright 2012, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 *  1. Redistributions of source code must retain the above copyright notice,
9 *     this list of conditions and the following disclaimer.
10 *  2. Redistributions in binary form must reproduce the above copyright notice,
11 *     this list of conditions and the following disclaimer in the documentation
12 *     and/or other materials provided with the distribution.
13 *  3. The name of the author may not be used to endorse or promote products
14 *     derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef PEERCONNECTION_SAMPLES_CLIENT_MAIN_WND_H_
29#define PEERCONNECTION_SAMPLES_CLIENT_MAIN_WND_H_
30#pragma once
31
32#include <map>
33#include <string>
34
35#include "talk/app/webrtc/mediastreaminterface.h"
36#include "talk/examples/peerconnection/client/peer_connection_client.h"
37#include "talk/media/base/mediachannel.h"
38#include "talk/media/base/videocommon.h"
39#include "talk/media/base/videoframe.h"
40#include "talk/media/base/videorenderer.h"
41#include "webrtc/base/win32.h"
42
43class MainWndCallback {
44 public:
45  virtual void StartLogin(const std::string& server, int port) = 0;
46  virtual void DisconnectFromServer() = 0;
47  virtual void ConnectToPeer(int peer_id) = 0;
48  virtual void DisconnectFromCurrentPeer() = 0;
49  virtual void UIThreadCallback(int msg_id, void* data) = 0;
50  virtual void Close() = 0;
51 protected:
52  virtual ~MainWndCallback() {}
53};
54
55// Pure virtual interface for the main window.
56class MainWindow {
57 public:
58  virtual ~MainWindow() {}
59
60  enum UI {
61    CONNECT_TO_SERVER,
62    LIST_PEERS,
63    STREAMING,
64  };
65
66  virtual void RegisterObserver(MainWndCallback* callback) = 0;
67
68  virtual bool IsWindow() = 0;
69  virtual void MessageBox(const char* caption, const char* text,
70                          bool is_error) = 0;
71
72  virtual UI current_ui() = 0;
73
74  virtual void SwitchToConnectUI() = 0;
75  virtual void SwitchToPeerList(const Peers& peers) = 0;
76  virtual void SwitchToStreamingUI() = 0;
77
78  virtual void StartLocalRenderer(webrtc::VideoTrackInterface* local_video) = 0;
79  virtual void StopLocalRenderer() = 0;
80  virtual void StartRemoteRenderer(webrtc::VideoTrackInterface* remote_video) = 0;
81  virtual void StopRemoteRenderer() = 0;
82
83  virtual void QueueUIThreadCallback(int msg_id, void* data) = 0;
84};
85
86#ifdef WIN32
87
88class MainWnd : public MainWindow {
89 public:
90  static const wchar_t kClassName[];
91
92  enum WindowMessages {
93    UI_THREAD_CALLBACK = WM_APP + 1,
94  };
95
96  MainWnd(const char* server, int port, bool auto_connect, bool auto_call);
97  ~MainWnd();
98
99  bool Create();
100  bool Destroy();
101  bool PreTranslateMessage(MSG* msg);
102
103  virtual void RegisterObserver(MainWndCallback* callback);
104  virtual bool IsWindow();
105  virtual void SwitchToConnectUI();
106  virtual void SwitchToPeerList(const Peers& peers);
107  virtual void SwitchToStreamingUI();
108  virtual void MessageBox(const char* caption, const char* text,
109                          bool is_error);
110  virtual UI current_ui() { return ui_; }
111
112  virtual void StartLocalRenderer(webrtc::VideoTrackInterface* local_video);
113  virtual void StopLocalRenderer();
114  virtual void StartRemoteRenderer(webrtc::VideoTrackInterface* remote_video);
115  virtual void StopRemoteRenderer();
116
117  virtual void QueueUIThreadCallback(int msg_id, void* data);
118
119  HWND handle() const { return wnd_; }
120
121  class VideoRenderer : public webrtc::VideoRendererInterface {
122   public:
123    VideoRenderer(HWND wnd, int width, int height,
124                  webrtc::VideoTrackInterface* track_to_render);
125    virtual ~VideoRenderer();
126
127    void Lock() {
128      ::EnterCriticalSection(&buffer_lock_);
129    }
130
131    void Unlock() {
132      ::LeaveCriticalSection(&buffer_lock_);
133    }
134
135    // VideoRendererInterface implementation
136    virtual void SetSize(int width, int height);
137    virtual void RenderFrame(const cricket::VideoFrame* frame);
138
139    const BITMAPINFO& bmi() const { return bmi_; }
140    const uint8* image() const { return image_.get(); }
141
142   protected:
143    enum {
144      SET_SIZE,
145      RENDER_FRAME,
146    };
147
148    HWND wnd_;
149    BITMAPINFO bmi_;
150    rtc::scoped_ptr<uint8[]> image_;
151    CRITICAL_SECTION buffer_lock_;
152    rtc::scoped_refptr<webrtc::VideoTrackInterface> rendered_track_;
153  };
154
155  // A little helper class to make sure we always to proper locking and
156  // unlocking when working with VideoRenderer buffers.
157  template <typename T>
158  class AutoLock {
159   public:
160    explicit AutoLock(T* obj) : obj_(obj) { obj_->Lock(); }
161    ~AutoLock() { obj_->Unlock(); }
162   protected:
163    T* obj_;
164  };
165
166 protected:
167  enum ChildWindowID {
168    EDIT_ID = 1,
169    BUTTON_ID,
170    LABEL1_ID,
171    LABEL2_ID,
172    LISTBOX_ID,
173  };
174
175  void OnPaint();
176  void OnDestroyed();
177
178  void OnDefaultAction();
179
180  bool OnMessage(UINT msg, WPARAM wp, LPARAM lp, LRESULT* result);
181
182  static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
183  static bool RegisterWindowClass();
184
185  void CreateChildWindow(HWND* wnd, ChildWindowID id, const wchar_t* class_name,
186                         DWORD control_style, DWORD ex_style);
187  void CreateChildWindows();
188
189  void LayoutConnectUI(bool show);
190  void LayoutPeerListUI(bool show);
191
192  void HandleTabbing();
193
194 private:
195  rtc::scoped_ptr<VideoRenderer> local_renderer_;
196  rtc::scoped_ptr<VideoRenderer> remote_renderer_;
197  UI ui_;
198  HWND wnd_;
199  DWORD ui_thread_id_;
200  HWND edit1_;
201  HWND edit2_;
202  HWND label1_;
203  HWND label2_;
204  HWND button_;
205  HWND listbox_;
206  bool destroyed_;
207  void* nested_msg_;
208  MainWndCallback* callback_;
209  static ATOM wnd_class_;
210  std::string server_;
211  std::string port_;
212  bool auto_connect_;
213  bool auto_call_;
214};
215#endif  // WIN32
216
217#endif  // PEERCONNECTION_SAMPLES_CLIENT_MAIN_WND_H_
218