tizen beta release
[framework/web/wrt-plugins-common.git] / src / modules / tizen / DEPRACATED / Display / Screen.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 #include "Screen.h"
17 #include <stdio.h>
18 #include <limits.h>
19 #include <algorithm>
20 #include <commons/Exception.h>
21 #include <API/Display/EventChangeState.h>
22
23 // TODO: attach to platform event informing about changed size!
24
25 namespace {
26 const char* COMMAND_XDPYINFO = "xdpyinfo";
27 const char* PATTERN_COLOR_DEPTH = "depth of root window:\\s+(\\d+)\\s+planes";
28 const char* PATTERN_SIZE = "dimensions:\\s+(\\d+)x(\\d+)";
29 } // anonymous
30
31 namespace WrtPlugins {
32 namespace Platform {
33 namespace Display {
34 unsigned short Screen::getColorDepth() const
35 {
36     unsigned short colorDepth = 0;
37     if (!getXDpyProperty(PATTERN_COLOR_DEPTH, &colorDepth)) {
38         ThrowMsg(Commons::PlatformException, "Could not read color depth.");
39     }
40     return colorDepth;
41 }
42
43 Dimension Screen::getSize() const
44 {
45     unsigned int width = 0, height = 0;
46     if (!getXDpyProperty(PATTERN_SIZE, &width, &height)) {
47         ThrowMsg(Commons::PlatformException, "Could not read size.");
48     }
49     return Dimension(width, height);
50 }
51
52 Dimension Screen::getActualSize() const
53 {
54     unsigned int width = 0, height = 0;
55     if (!getXDpyProperty(PATTERN_SIZE, &width, &height)) {
56         ThrowMsg(Commons::PlatformException, "Could not read size.");
57     }
58     if (getOrientation() == Api::Display::O_LANDSCAPE) {
59         std::swap(width, height);
60     }
61     return Dimension(width, height);
62 }
63
64 Api::Display::Orientation Screen::getOrientation() const
65 {
66     appcore_rm rot = APPCORE_RM_UNKNOWN;
67     if (appcore_get_rotation_state(&rot) != 0) {
68         ThrowMsg(Commons::PlatformException, "Could not get orientation.");
69     }
70     switch (rot) {
71     case APPCORE_RM_LANDSCAPE_NORMAL:
72     case APPCORE_RM_LANDSCAPE_REVERSE:
73         return Api::Display::O_LANDSCAPE;
74     default:
75         return Api::Display::O_PORTRAIT;
76     }
77 }
78
79 Api::Display::State Screen::getState() const
80 {
81     Try {
82         int state = m_powerState.getInt();
83         switch (state) {
84         case VCONFKEY_PM_STATE_NORMAL:
85             return Api::Display::ST_ON;
86         case VCONFKEY_PM_STATE_LCDDIM:
87             return Api::Display::ST_DIM;
88         default:
89             return Api::Display::ST_OFF;
90         }
91     }
92     Catch(Commons::ConversionException) {
93         ReThrowMsg(Commons::PlatformException,
94                    "Could not get device's power state.");
95     }
96 }
97
98 void Screen::addOnChangeOrientation(
99         const Api::Display::EventChangeOrientationEmitterPtr& emitter)
100 {
101     m_onChangeOrientation.attach(emitter);
102     ChangeOrientationEmitters::LockType lock = m_onChangeOrientation.getLock();
103     if (m_onChangeOrientation.size() == 1) {
104         if (appcore_set_rotation_cb(onChangeOrientation, this) != 0) {
105             ThrowMsg(Commons::PlatformException,
106                      "Could not attach to platform event.");
107         }
108     }
109 }
110
111 void Screen::removeOnChangeOrientation(
112         Api::Display::EventChangeOrientationEmitter::IdType id)
113 {
114     m_onChangeOrientation.detach(id);
115     ChangeOrientationEmitters::LockType lock = m_onChangeOrientation.getLock();
116     if (m_onChangeOrientation.size() == 0) {
117         if (appcore_unset_rotation_cb() != 0) {
118             ThrowMsg(Commons::PlatformException,
119                      "Could not detach from platform event.");
120         }
121     }
122 }
123
124 void Screen::addOnChangeState(
125         const Api::Display::EventChangeStateEmitterPtr& emitter)
126 {
127     m_onChangeState.attach(emitter);
128     ChangeStateEmitters::LockType lock = m_onChangeState.getLock();
129     if (m_onChangeState.size() == 1) {
130         m_powerState.attachCallback(onChangeState, this);
131     }
132 }
133
134 void Screen::removeOnChangeState(
135         Api::Display::EventChangeStateEmitter::IdType id)
136 {
137     m_onChangeState.detach(id);
138     ChangeStateEmitters::LockType lock = m_onChangeState.getLock();
139     if (m_onChangeState.size() == 0) {
140         m_powerState.detachCallback();
141     }
142 }
143
144 Screen::Screen(std::size_t index) :
145     m_index(index),
146     m_powerState(VCONFKEY_PM_STATE)
147 {
148 }
149
150 bool Screen::getXDpyProperty(const char* pattern,
151         const pcrecpp::Arg& arg1,
152         const pcrecpp::Arg& arg2)
153 {
154     FILE* pipe = popen(COMMAND_XDPYINFO, "r");
155     if (pipe == NULL) {
156         ThrowMsg(Commons::PlatformException,
157                  "Could not initialize pipe to xdpyinfo.");
158     }
159
160     bool matched = false;
161     pcrecpp::RE re(pattern);
162     char line[LINE_MAX] = { 0 };
163     while (fgets(line, LINE_MAX, pipe)) {
164         if (re.PartialMatch(line, arg1, arg2)) {
165             matched = true;
166             break;
167         }
168     }
169     pclose(pipe);
170
171     return matched;
172 }
173
174 void Screen::onChangeState(const VConf::Node* /*node*/,
175         void* data)
176 {
177     Screen* this_ = static_cast<Screen*>(data);
178     Api::Display::EventChangeStatePtr event(new Api::Display::EventChangeState());
179     Try {
180         event->setState(this_->getState());
181     }
182     Catch(Commons::PlatformException) {
183         event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
184     }
185     this_->m_onChangeState.emit(event);
186 }
187
188 int Screen::onChangeOrientation(appcore_rm rot,
189         void* data)
190 {
191     Screen* this_ = static_cast<Screen*>(data);
192     Api::Display::EventChangeOrientationPtr event(
193         new Api::Display::EventChangeOrientation());
194     Try {
195         event->setOrientation(this_->getOrientation());
196     }
197     Catch(Commons::PlatformException) {
198         event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
199     }
200     this_->m_onChangeOrientation.emit(event);
201     //TODO check returned value
202     return 0;
203 }
204 } // Display
205 } // Platform
206 } // WrtPlugins
207