~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/winex11.drv/xinerama.c

Version: ~ [ wine-1.5.31 ] ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Xinerama support
  3  *
  4  * Copyright 2006 Alexandre Julliard
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include "config.h"
 22 #include "wine/port.h"
 23 
 24 #include <stdarg.h>
 25 #include <stdlib.h>
 26 #include <X11/Xlib.h>
 27 #ifdef HAVE_X11_EXTENSIONS_XINERAMA_H
 28 #include <X11/extensions/Xinerama.h>
 29 #endif
 30 #include "wine/library.h"
 31 #include "x11drv.h"
 32 #include "wine/debug.h"
 33 
 34 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
 35 
 36 static MONITORINFOEXW default_monitor =
 37 {
 38     sizeof(default_monitor),    /* cbSize */
 39     { 0, 0, 0, 0 },             /* rcMonitor */
 40     { 0, 0, 0, 0 },             /* rcWork */
 41     MONITORINFOF_PRIMARY,       /* dwFlags */
 42     { '\\','\\','.','\\','D','I','S','P','L','A','Y','1',0 }   /* szDevice */
 43 };
 44 
 45 static MONITORINFOEXW *monitors;
 46 static int nb_monitors;
 47 
 48 static inline MONITORINFOEXW *get_primary(void)
 49 {
 50     /* default to 0 if specified primary is invalid */
 51     int idx = primary_monitor;
 52     if (idx >= nb_monitors) idx = 0;
 53     return &monitors[idx];
 54 }
 55 
 56 static inline HMONITOR index_to_monitor( int index )
 57 {
 58     return (HMONITOR)(UINT_PTR)(index + 1);
 59 }
 60 
 61 static inline int monitor_to_index( HMONITOR handle )
 62 {
 63     UINT_PTR index = (UINT_PTR)handle;
 64     if (index < 1 || index > nb_monitors) return -1;
 65     return index - 1;
 66 }
 67 
 68 static void query_work_area( RECT *rc_work )
 69 {
 70     Atom type;
 71     int format;
 72     unsigned long count, remaining;
 73     long *work_area;
 74 
 75     if (!XGetWindowProperty( gdi_display, DefaultRootWindow(gdi_display), x11drv_atom(_NET_WORKAREA), 0,
 76                              ~0, False, XA_CARDINAL, &type, &format, &count,
 77                              &remaining, (unsigned char **)&work_area ))
 78     {
 79         if (type == XA_CARDINAL && format == 32 && count >= 4)
 80         {
 81             SetRect( rc_work, work_area[0], work_area[1],
 82                      work_area[0] + work_area[2], work_area[1] + work_area[3] );
 83         }
 84         XFree( work_area );
 85     }
 86 }
 87 
 88 #ifdef SONAME_LIBXINERAMA
 89 
 90 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
 91 
 92 MAKE_FUNCPTR(XineramaQueryExtension);
 93 MAKE_FUNCPTR(XineramaQueryScreens);
 94 
 95 static void load_xinerama(void)
 96 {
 97     void *handle;
 98 
 99     if (!(handle = wine_dlopen(SONAME_LIBXINERAMA, RTLD_NOW, NULL, 0)))
100     {
101         WARN( "failed to open %s\n", SONAME_LIBXINERAMA );
102         return;
103     }
104     pXineramaQueryExtension = wine_dlsym( handle, "XineramaQueryExtension", NULL, 0 );
105     if (!pXineramaQueryExtension) WARN( "XineramaQueryScreens not found\n" );
106     pXineramaQueryScreens = wine_dlsym( handle, "XineramaQueryScreens", NULL, 0 );
107     if (!pXineramaQueryScreens) WARN( "XineramaQueryScreens not found\n" );
108 }
109 
110 static int query_screens(void)
111 {
112     int i, count, event_base, error_base;
113     XineramaScreenInfo *screens;
114     RECT rc_work = {0, 0, 0, 0};
115 
116     if (!monitors)  /* first time around */
117         load_xinerama();
118 
119     query_work_area( &rc_work );
120 
121     if (!pXineramaQueryExtension || !pXineramaQueryScreens ||
122         !pXineramaQueryExtension( gdi_display, &event_base, &error_base ) ||
123         !(screens = pXineramaQueryScreens( gdi_display, &count ))) return 0;
124 
125     if (monitors != &default_monitor) HeapFree( GetProcessHeap(), 0, monitors );
126     if ((monitors = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*monitors) )))
127     {
128         nb_monitors = count;
129         for (i = 0; i < nb_monitors; i++)
130         {
131             monitors[i].cbSize = sizeof( monitors[i] );
132             monitors[i].rcMonitor.left   = screens[i].x_org;
133             monitors[i].rcMonitor.top    = screens[i].y_org;
134             monitors[i].rcMonitor.right  = screens[i].x_org + screens[i].width;
135             monitors[i].rcMonitor.bottom = screens[i].y_org + screens[i].height;
136             monitors[i].dwFlags          = 0;
137             if (!IntersectRect( &monitors[i].rcWork, &rc_work, &monitors[i].rcMonitor ))
138                 monitors[i].rcWork = monitors[i].rcMonitor;
139             /* FIXME: using the same device name for all monitors for now */
140             lstrcpyW( monitors[i].szDevice, default_monitor.szDevice );
141         }
142 
143         get_primary()->dwFlags |= MONITORINFOF_PRIMARY;
144     }
145     else count = 0;
146 
147     XFree( screens );
148     return count;
149 }
150 
151 #else  /* SONAME_LIBXINERAMA */
152 
153 static inline int query_screens(void)
154 {
155     return 0;
156 }
157 
158 #endif  /* SONAME_LIBXINERAMA */
159 
160 void xinerama_init( unsigned int width, unsigned int height )
161 {
162     MONITORINFOEXW *primary;
163     int i;
164     RECT rect;
165 
166     wine_tsx11_lock();
167 
168     SetRect( &rect, 0, 0, width, height );
169 
170     if (root_window != DefaultRootWindow( gdi_display ) || !query_screens())
171     {
172         default_monitor.rcWork = default_monitor.rcMonitor = rect;
173         if (root_window == DefaultRootWindow( gdi_display ))
174             query_work_area( &default_monitor.rcWork );
175         nb_monitors = 1;
176         monitors = &default_monitor;
177     }
178 
179     primary = get_primary();
180 
181     /* coordinates (0,0) have to point to the primary monitor origin */
182     OffsetRect( &rect, -primary->rcMonitor.left, -primary->rcMonitor.top );
183     for (i = 0; i < nb_monitors; i++)
184     {
185         OffsetRect( &monitors[i].rcMonitor, rect.left, rect.top );
186         OffsetRect( &monitors[i].rcWork, rect.left, rect.top );
187         TRACE( "monitor %p: %s work %s%s\n",
188                index_to_monitor(i), wine_dbgstr_rect(&monitors[i].rcMonitor),
189                wine_dbgstr_rect(&monitors[i].rcWork),
190                (monitors[i].dwFlags & MONITORINFOF_PRIMARY) ? " (primary)" : "" );
191     }
192 
193     virtual_screen_rect = rect;
194     screen_width = primary->rcMonitor.right - primary->rcMonitor.left;
195     screen_height = primary->rcMonitor.bottom - primary->rcMonitor.top;
196     TRACE( "virtual size: %s primary size: %dx%d\n",
197            wine_dbgstr_rect(&rect), screen_width, screen_height );
198 
199     wine_tsx11_unlock();
200     ClipCursor( NULL );  /* reset the cursor clip rectangle */
201 }
202 
203 
204 /***********************************************************************
205  *              X11DRV_GetMonitorInfo  (X11DRV.@)
206  */
207 BOOL CDECL X11DRV_GetMonitorInfo( HMONITOR handle, LPMONITORINFO info )
208 {
209     int i = monitor_to_index( handle );
210 
211     if (i == -1)
212     {
213         SetLastError( ERROR_INVALID_HANDLE );
214         return FALSE;
215     }
216     info->rcMonitor = monitors[i].rcMonitor;
217     info->rcWork = monitors[i].rcWork;
218     info->dwFlags = monitors[i].dwFlags;
219     if (info->cbSize >= sizeof(MONITORINFOEXW))
220         lstrcpyW( ((MONITORINFOEXW *)info)->szDevice, monitors[i].szDevice );
221     return TRUE;
222 }
223 
224 
225 /***********************************************************************
226  *              X11DRV_EnumDisplayMonitors  (X11DRV.@)
227  */
228 BOOL CDECL X11DRV_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
229 {
230     int i;
231 
232     if (hdc)
233     {
234         POINT origin;
235         RECT limit;
236 
237         if (!GetDCOrgEx( hdc, &origin )) return FALSE;
238         if (GetClipBox( hdc, &limit ) == ERROR) return FALSE;
239 
240         if (rect && !IntersectRect( &limit, &limit, rect )) return TRUE;
241 
242         for (i = 0; i < nb_monitors; i++)
243         {
244             RECT monrect = monitors[i].rcMonitor;
245             OffsetRect( &monrect, -origin.x, -origin.y );
246             if (IntersectRect( &monrect, &monrect, &limit ))
247                 if (!proc( index_to_monitor(i), hdc, &monrect, lp ))
248                     return FALSE;
249         }
250     }
251     else
252     {
253         for (i = 0; i < nb_monitors; i++)
254         {
255             RECT unused;
256             if (!rect || IntersectRect( &unused, &monitors[i].rcMonitor, rect ))
257                 if (!proc( index_to_monitor(i), 0, &monitors[i].rcMonitor, lp ))
258                     return FALSE;
259         }
260     }
261     return TRUE;
262 }
263 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.