root/branches/newosd/src/iface.cpp

Revision 6380, 5.6 kB (checked in by eugene, 6 months ago)

Use the new DropOwner? function to properly specify which owner to unlock.

Line 
1#include "iface.h"
2
3#include <licq_icqd.h>
4#include <licq_translate.h>
5
6#include "conf.h"
7
8using namespace std;
9
10Iface::Iface()
11{
12  g_type_init();
13
14  aosd = aosd_new();
15  aosd_set_transparency(aosd, TRANSPARENCY_COMPOSITE);
16  aosd_set_renderer(aosd, aosd_text_renderer, &trd);
17  aosd_set_names(aosd, "OSD Plugin", "Licq");
18
19  memset(&trd, 0, sizeof(TextRenderData));
20  trd.lay = pango_layout_new_aosd();
21  pango_layout_set_wrap(trd.lay, PANGO_WRAP_WORD_CHAR);
22
23  conf = new Conf();
24
25  updateTextRenderData();
26
27  FOR_EACH_OWNER_START(LOCK_R)
28  {
29    ppidTimers[pOwner->PPID()] = time(NULL);
30  }
31  FOR_EACH_OWNER_END;
32
33  string init = "Licq newosd plugin is initialized.";
34  displayLayout(init, false);
35}
36
37Iface::~Iface()
38{
39  delete conf;
40  ppidTimers.clear();
41  aosd_destroy(aosd);
42  pango_layout_unref_aosd(trd.lay);
43}
44
45void Iface::processSignal(CICQSignal* sig)
46{
47  string msg = "";
48  bool control = true;
49
50  switch (sig->Signal())
51  {
52    case SIGNAL_UPDATExUSER:
53    {
54      if (filterSignal(sig))
55        break;
56
57      ICQUser* u = gUserManager.FetchUser(sig->Id(), sig->PPID(), LOCK_R);
58      if (u == NULL)
59        break;
60
61      msg = u->GetAlias();
62
63      switch (sig->SubSignal())
64      {
65        case USER_STATUS:
66          msg += " changed status to: ";
67          msg += u->StatusStr();
68          if (sig->Argument() > 0)
69            msg += " [logged on]";
70          break;
71
72        case USER_EVENTS:
73          if (sig->Argument() == 0)
74          {
75            msg += " checked your auto-response";
76            break;
77          }
78
79          control = false;
80
81          if (conf->notifyOnly)
82          {
83            msg = "Message from ";
84            msg += u->GetAlias();
85            if (conf->markSecure && u->Secure())
86              msg += " [secured]";
87            msg += ".";
88          }
89          else
90          {
91            CUserEvent* ue = u->EventPeekId(sig->Argument());
92            if (ue == NULL)
93            {
94              msg.clear();
95              break;
96            }
97            if (conf->markSecure && u->Secure())
98              msg += " (S)";
99            msg += ": ";
100            char* trans = gTranslator.ToUnicode(const_cast<char*>(ue->Text()),
101                u->UserEncoding());
102            msg += trans;
103            delete[] trans;
104          }
105          break;
106      }
107
108      gUserManager.DropUser(u);
109      break;
110    }
111
112    case SIGNAL_LOGON:
113    case SIGNAL_LOGOFF:
114      ppidTimers[sig->PPID()] = time(NULL) + conf->quietTimeout;
115      break;
116  }
117
118  if (!msg.empty())
119    displayLayout(msg, control);
120}
121
122void Iface::updateTextRenderData()
123{
124  conf->loadConfig();
125
126  aosd_set_hide_upon_mouse_event(aosd, conf->mouseActive);
127  pango_layout_set_font_aosd(trd.lay, conf->font);
128
129  trd.geom.x_offset = conf->marginHorizontal;
130  trd.geom.y_offset = conf->marginVertical;
131
132  trd.back.color = conf->backColor;
133  trd.back.opacity = conf->backOpacity;
134
135  trd.shadow.x_offset = conf->shadowOffset;
136  trd.shadow.y_offset = conf->shadowOffset;
137  trd.shadow.color = conf->shadowColor;
138  trd.shadow.opacity = conf->shadowOpacity;
139
140  trd.fore.opacity = conf->textOpacity;
141
142  int width = aosd_text_get_screen_wrap_width(aosd, &trd);
143  if (conf->wrapWidth == 0 || width < 0)
144    pango_layout_set_width(trd.lay, -1);
145  else
146    pango_layout_set_width(trd.lay,
147        (width > conf->wrapWidth ? conf->wrapWidth : width) * PANGO_SCALE);
148}
149
150bool Iface::filterSignal(CICQSignal* sig)
151{
152  switch (sig->SubSignal())
153  {
154    case USER_STATUS:
155    case USER_EVENTS:
156      break;
157
158    default:
159      return true;
160  }
161
162  bool isMessage = (sig->SubSignal() == USER_EVENTS && sig->Argument() > 0);
163
164  if (!isMessage && (ppidTimers[sig->PPID()] > time(NULL)))
165    return true;
166
167  ICQOwner* o = gUserManager.FetchOwner(sig->PPID(), LOCK_R);
168  if (o == NULL)
169    return true;
170
171  bool isOwner = (strcmp(o->IdString(), sig->Id()) == 0);
172  unsigned short ourStatus = o->Status();
173
174  gUserManager.DropOwner(o);
175
176  // TODO status check
177
178  if (isOwner)
179  {
180    if (isMessage && conf->showMessage != GROUP_TYPE_NONE)
181      return false;
182
183    return true;
184  }
185
186  ICQUser* u = gUserManager.FetchUser(sig->Id(), sig->PPID(), LOCK_R);
187  if (u == NULL)
188    return true;
189
190  bool ign = u->IgnoreList();
191  bool on = u->OnlineNotify();
192
193  gUserManager.DropUser(u);
194
195  if (ign)
196    return true;
197
198#define GROUP_DISABLED(type) \
199  (conf->type == GROUP_TYPE_NONE || \
200  (conf->type == GROUP_TYPE_ONLINE_NOTIFY && !on))
201
202  if (sig->SubSignal() == USER_STATUS)
203  {
204    if (sig->Argument() == 0 && GROUP_DISABLED(statusChange))
205      return true;
206
207    if (GROUP_DISABLED(logonLogoff))
208      return true;
209  }
210
211  if (sig->SubSignal() == USER_EVENTS)
212  {
213    if (sig->Argument() < 0)
214      return true;
215
216    if (sig->Argument() == 0 && GROUP_DISABLED(autoResponse))
217      return true;
218
219    if (GROUP_DISABLED(showMessage))
220      return true;
221  }
222#undef GROUP_DISABLED
223
224  return false;
225}
226
227void Iface::displayLayout(string& msg, bool control)
228{
229  trd.fore.color = control ? conf->textControlColor : conf->textColor;
230
231  pango_layout_set_text(trd.lay, const_cast<char*>(msg.c_str()), -1);
232
233  if (conf->maxLines != 0 &&
234      pango_layout_get_line_count(trd.lay) > conf->maxLines)
235  {
236    PangoLayoutLine* line =
237      pango_layout_get_line_readonly(trd.lay, conf->maxLines);
238    pango_layout_set_text(trd.lay, const_cast<char*>(msg.c_str()),
239        line->start_index);
240  }
241
242  unsigned width, height;
243
244  aosd_text_get_size(&trd, &width, &height);
245
246  aosd_set_position_with_offset(aosd,
247      conf->posHorizontal, conf->posVertical,
248      width, height, conf->offsetHorizontal, conf->offsetVertical);
249
250  // TODO implement non-waiting mechanism
251
252  aosd_flash(aosd, conf->fadeIn,
253      conf->fadeFull + msg.size() * conf->delayPerChar, conf->fadeOut);
254}
255
256/* vim: set ts=2 sw=2 et : */
Note: See TracBrowser for help on using the browser.