2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3 * Copyright (C) 2004-2008 Kim Woelders
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies of the Software, its documentation and marketing & publicity
14 * materials, and acknowledgment shall be given in the documentation, materials
15 * and software packages that this Software was used.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #include <X11/extensions/xf86vmode.h>
32 static int std_vid_modes_num = 0;
33 static int std_vid_mode_cur = 0;
34 static XF86VidModeModeInfo **std_vid_modes = NULL;
36 static Win zoom_mask_1 = 0;
37 static Win zoom_mask_2 = 0;
38 static Win zoom_mask_3 = 0;
39 static Win zoom_mask_4 = 0;
40 static EWin *zoom_last_ewin = NULL;
41 static int zoom_last_x, zoom_last_y;
42 static char zoom_can = 0;
47 XF86VidModeGetAllModeLines(disp, Dpy.screen,
48 &std_vid_modes_num, &std_vid_modes);
51 static XF86VidModeModeInfo *
52 FindMode(int w, int h)
54 XF86VidModeModeInfo *chosen = NULL;
55 int i, closest = 0x7fffffff;
57 for (i = 0; i < std_vid_modes_num; i++)
59 int value = 0x7fffffff;
61 if ((std_vid_modes[i]->hdisplay >= w) &&
62 (std_vid_modes[i]->vdisplay >= h))
63 value = ((std_vid_modes[i]->hdisplay - w) +
64 (std_vid_modes[i]->vdisplay - h));
68 chosen = std_vid_modes[i];
75 GetModeIndex(unsigned int dotclock, XF86VidModeModeLine * line)
78 const XF86VidModeModeInfo *info;
80 for (i = 0; i < std_vid_modes_num; i++)
82 info = std_vid_modes[i];
83 if (info->dotclock == dotclock &&
84 info->hdisplay == line->hdisplay &&
85 info->vdisplay == line->vdisplay)
91 static const XF86VidModeModeInfo *
92 SwitchRes(char inout, int x, int y, int w, int h)
94 static int vp_x, vp_y;
95 XF86VidModeModeInfo *mode = NULL;
102 XF86VidModeModeLine curmode;
105 if (!XF86VidModeGetModeLine(disp, scr, &dotclock, &curmode))
107 XF86VidModeGetViewPort(disp, scr, &vp_x, &vp_y);
109 mode = FindMode(w, h);
112 XF86VidModeLockModeSwitch(disp, scr, 0);
113 std_vid_mode_cur = GetModeIndex(dotclock, &curmode);
114 XF86VidModeSwitchToMode(disp, scr, mode);
115 XF86VidModeSetViewPort(disp, scr, x, y);
116 XF86VidModeLockModeSwitch(disp, scr, 1);
121 mode = std_vid_modes[std_vid_mode_cur];
122 XF86VidModeLockModeSwitch(disp, scr, 0);
123 XF86VidModeSwitchToMode(disp, scr, mode);
124 XF86VidModeSetViewPort(disp, scr, vp_x, vp_y);
125 #if 0 /* No, don't lock or we can't switch resolution */
126 XF86VidModeLockModeSwitch(disp, scr, 1);
135 int ev_base, er_base;
137 if (XF86VidModeQueryExtension(disp, &ev_base, &er_base))
146 return zoom_last_ewin;
152 if ((InZoom()) && (ewin != zoom_last_ewin))
179 if (std_vid_modes_num > 1)
185 ZoomMask(int x, int y, int w, int h)
189 if (x < 0 || y < 0 || w <= 0 || h <= 0)
192 win = ECreateWindow(VROOT, x, y, w, h, 0);
193 ESetWindowBackground(win, Dpy.pixel_black);
203 const XF86VidModeModeInfo *mode;
212 ewin = zoom_last_ewin;
213 /* XUngrabPointer(disp, CurrentTime); */
214 EwinMove(ewin, zoom_last_x, zoom_last_y);
216 EDestroyWindow(zoom_mask_1);
218 EDestroyWindow(zoom_mask_2);
220 EDestroyWindow(zoom_mask_3);
222 EDestroyWindow(zoom_mask_4);
223 SwitchRes(0, 0, 0, 0, 0);
226 zoom_last_ewin = NULL;
231 mode = SwitchRes(1, 0, 0, ewin->client.w, ewin->client.h);
234 int x1, y1, x2, y2, bl, br, bt, bb;
236 zoom_last_ewin = ewin;
237 zoom_last_x = EoGetX(ewin);
238 zoom_last_y = EoGetY(ewin);
239 x1 = (mode->hdisplay - ewin->client.w) / 2;
242 y1 = (mode->vdisplay - ewin->client.h) / 2;
245 x2 = mode->hdisplay - ewin->client.w - x1;
248 y2 = mode->vdisplay - ewin->client.h - y1;
252 EwinBorderGetSize(ewin, &bl, &br, &bt, &bb);
253 EwinMove(ewin, -bl + x1, -bt + y1);
254 FocusToEWin(ewin, FOCUS_SET);
256 #if 0 /* Doesn't work as intended */
257 XGrabPointer(disp, EwinGetClientXwin(ewin), True,
258 ButtonPressMask | ButtonReleaseMask |
259 PointerMotionMask | ButtonMotionMask |
260 EnterWindowMask | LeaveWindowMask,
261 GrabModeAsync, GrabModeAsync,
262 EwinGetClientXwin(ewin), None, CurrentTime);
264 zoom_mask_1 = ZoomMask(0, 0, x1, mode->vdisplay);
265 zoom_mask_2 = ZoomMask(0, 0, mode->hdisplay, y1);
266 zoom_mask_3 = ZoomMask(x1 + ewin->client.w, 0, x2, mode->vdisplay);
267 zoom_mask_4 = ZoomMask(0, y1 + ewin->client.h, mode->hdisplay, y2);