1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 
5 #include "ecore_wl2_private.h"
6 
7 static void
_cb_geometry(void * data,struct wl_output * wl_output EINA_UNUSED,int x,int y,int w,int h,int subpixel EINA_UNUSED,const char * make,const char * model,int transform)8 _cb_geometry(void *data, struct wl_output *wl_output EINA_UNUSED, int x, int y, int w, int h, int subpixel EINA_UNUSED, const char *make, const char *model, int transform)
9 {
10    Ecore_Wl2_Output *output;
11    int ot;
12 
13    output = data;
14    if (!output) return;
15 
16    eina_stringshare_replace(&output->make, make);
17    eina_stringshare_replace(&output->model, model);
18 
19    output->mw = w;
20    output->mh = h;
21    output->geometry.x = x;
22    output->geometry.y = y;
23 
24    ot = output->transform;
25 
26    if (transform & 0x4)
27      ERR("Cannot support output transformation");
28 
29    transform &= 0x3;
30    if (output->transform != transform)
31      {
32         Ecore_Wl2_Event_Output_Transform *ev;
33 
34         output->transform = transform;
35 
36         ev = calloc(1, sizeof(Ecore_Wl2_Event_Output_Transform));
37         if (ev)
38           {
39              ev->output = output;
40              ev->old_transform = ot;
41              ev->transform = transform;
42              ecore_event_add(ECORE_WL2_EVENT_OUTPUT_TRANSFORM, ev, NULL, NULL);
43           }
44      }
45 }
46 
47 static void
_cb_mode(void * data,struct wl_output * wl_output EINA_UNUSED,unsigned int flags,int w,int h,int refresh EINA_UNUSED)48 _cb_mode(void *data, struct wl_output *wl_output EINA_UNUSED, unsigned int flags, int w, int h, int refresh EINA_UNUSED)
49 {
50    Ecore_Wl2_Output *output;
51 
52    output = data;
53    if (!output) return;
54 
55    if (flags & WL_OUTPUT_MODE_CURRENT)
56      {
57         output->geometry.w = w;
58         output->geometry.h = h;
59      }
60 }
61 
62 static void
_cb_done(void * data EINA_UNUSED,struct wl_output * output EINA_UNUSED)63 _cb_done(void *data EINA_UNUSED, struct wl_output *output EINA_UNUSED)
64 {
65    /* NB: Use this event to raise any "output (re)configured events" */
66 }
67 
68 static void
_cb_scale(void * data EINA_UNUSED,struct wl_output * output EINA_UNUSED,int scale EINA_UNUSED)69 _cb_scale(void *data EINA_UNUSED, struct wl_output *output EINA_UNUSED, int scale EINA_UNUSED)
70 {
71 
72 }
73 
74 static const struct wl_output_listener _output_listener =
75 {
76    _cb_geometry,
77    _cb_mode,
78    _cb_done,
79    _cb_scale
80 };
81 
82 void
_ecore_wl2_output_add(Ecore_Wl2_Display * display,unsigned int id)83 _ecore_wl2_output_add(Ecore_Wl2_Display *display, unsigned int id)
84 {
85    Ecore_Wl2_Output *output;
86 
87    output = calloc(1, sizeof(Ecore_Wl2_Output));
88    if (!output) return;
89 
90    output->display = display;
91 
92    output->wl_output =
93      wl_registry_bind(display->wl.registry, id, &wl_output_interface, 2);
94 
95    display->outputs =
96      eina_inlist_append(display->outputs, EINA_INLIST_GET(output));
97 
98    wl_output_add_listener(output->wl_output, &_output_listener, output);
99 }
100 
101 void
_ecore_wl2_output_del(Ecore_Wl2_Output * output)102 _ecore_wl2_output_del(Ecore_Wl2_Output *output)
103 {
104    Ecore_Wl2_Display *display;
105 
106    if (!output) return;
107 
108    display = output->display;
109 
110    if (output->wl_output) wl_output_destroy(output->wl_output);
111    if (output->make) eina_stringshare_del(output->make);
112    if (output->model) eina_stringshare_del(output->model);
113 
114    display->outputs =
115      eina_inlist_remove(display->outputs, EINA_INLIST_GET(output));
116 
117    free(output);
118 }
119 
120 Ecore_Wl2_Output *
_ecore_wl2_output_find(Ecore_Wl2_Display * display,struct wl_output * op)121 _ecore_wl2_output_find(Ecore_Wl2_Display *display, struct wl_output *op)
122 {
123    Ecore_Wl2_Output *wl2op;
124 
125    EINA_INLIST_FOREACH(display->outputs, wl2op)
126      if (wl2op->wl_output == op) return wl2op;
127 
128    return NULL;
129 }
130 
131 EAPI int
ecore_wl2_output_dpi_get(Ecore_Wl2_Output * output)132 ecore_wl2_output_dpi_get(Ecore_Wl2_Output *output)
133 {
134    int w, h, mw, mh, dpi;
135    double target;
136 
137    EINA_SAFETY_ON_NULL_RETURN_VAL(output, 75);
138 
139    mw = output->mw;
140    if (mw <= 0) return 75;
141 
142    mh = output->mh;
143    if (mh <= 0) return 75;
144 
145    w = output->geometry.w;
146    h = output->geometry.h;
147 
148    target = (round((sqrt(mw * mw + mh * mh) / 25.4) * 10) / 10);
149    dpi = (round((sqrt(w * w + h * h) / target) * 10) / 10);
150 
151    return dpi;
152 }
153 
154 EAPI int
ecore_wl2_output_transform_get(Ecore_Wl2_Output * output)155 ecore_wl2_output_transform_get(Ecore_Wl2_Output *output)
156 {
157    EINA_SAFETY_ON_NULL_RETURN_VAL(output, 0);
158    return output->transform;
159 }
160