/* Returns the physical display size as reported by X11: */
void PsychGetDisplaySize(int screenNumber, int *width, int *height)
{
    if(screenNumber>=numDisplays)
        PsychErrorExitMsg(PsychError_internal, "screenNumber passed to PsychGetDisplaySize() is out of range");
    *width = (int) XDisplayWidthMM(displayCGIDs[screenNumber], PsychGetXScreenIdForScreen(screenNumber));
    *height = (int) XDisplayHeightMM(displayCGIDs[screenNumber], PsychGetXScreenIdForScreen(screenNumber));
}
Example #2
0
/** 
 * This method will expand the graphics panel already openned to the maximun of the display area scaled by the scale value supplied.
 * 
 * @param scale Porcentage (0-100) of the display width to use.
 */
void resizemax(float scale)
{
	Display *disp;
	float ax, ay;
	int X, Y;

	/* Xlib code */
	disp = XOpenDisplay(NULL);
	if (disp == NULL) {
		fprintf(stderr, "No Display.\n");
		exit(-1);
	} else {
		Y = XDisplayHeightMM(disp, 0);
		X = XDisplayWidthMM(disp, 0) / (0.9);
	}
	XCloseDisplay(disp);
	/* End of Xlib code */

	ay = (double) Y / (double) X;
	ax = X / 25.4 * scale;
	cpgpap(ax, ay);
	cpgpage();

    BASIC_ASPECT = ay;
}
Example #3
0
float get_DPI_scale()
{
	Display* display = XOpenDisplay(nullptr);
	const int width = XDisplayWidth(display, 0);
	const int widthMM = XDisplayWidthMM(display, 0);
	XCloseDisplay(display);
	return width/(92*0.0393700787402f*widthMM);
}
Example #4
0
std::pair<int, int> getDPI() {
	Display * dpy = XOpenDisplay(nullptr);
	int screen = 0; //TODO: find a way to get the current screen
	int horizontalDPI = ((((double) XDisplayWidth(dpy, screen)) * 25.4)
			/ ((double) XDisplayWidthMM(dpy, screen)));
	int verticalDPI = ((((double) XDisplayHeight(dpy, screen)) * 25.4)
			/ ((double) XDisplayHeightMM(dpy, screen)));
	return std::pair<int, int>(horizontalDPI, verticalDPI);
}
Example #5
0
// INPUT   display, screen n°
// OUTPUT  int * int (size in mm)
CAMLprim value
caml_xscreen_sizemm(value disp, value screen)
{
  CAMLparam2(disp, screen);

  int w = XDisplayWidthMM ((Display*) disp, Int_val(screen));
  int h = XDisplayHeightMM ((Display*) disp, Int_val(screen));

  CAMLreturn(Int_pair(w,h));
}
Example #6
0
File: s52glx.c Project: sduclos/S52
int main(int argc, char* argv[])
{
    (void)argc;
    (void)argv;

    Display     *dpy = _getXdis  ();
    XVisualInfo *vis = _getXvis  (dpy, _attr);
    Window       win = _setXwin  (dpy, vis);
    GLXContext   ctx = _getGLXctx(dpy, vis);

    // bind the rendering context to the window
    Bool ret = glXMakeCurrent(dpy, win, ctx);
    if (False == ret) {
        printf("ERROR: glXMakeCurrent() fail\n");
        exit(0);
    }

    {   // init S52 lib (Screen No 0)
#ifdef SET_SCREEN_SIZE
        int w      = 1280;
        int h      = 1024;
        int wmm    = 376;
        int hmm    = 307;
#else
        int h   = XDisplayHeight  (dpy, 0);
        int hmm = XDisplayHeightMM(dpy, 0);
        int w   = XDisplayWidth   (dpy, 0);
        int wmm = XDisplayWidthMM (dpy, 0);
#endif
        S52_init(w, h, wmm, hmm, NULL);
    }

    // differ from w/h
    S52_setViewPort(0, 0, WIDTH, HEIGHT);

    /* debug - use for timing rendering
    S52_setMarinerParam(S52_CMD_WRD_FILTER, S52_CMD_WRD_FILTER_SY);
    //S52_setMarinerParam(S52_CMD_WRD_FILTER, S52_CMD_WRD_FILTER_LS);
    S52_setMarinerParam(S52_CMD_WRD_FILTER, S52_CMD_WRD_FILTER_LC);
    S52_setMarinerParam(S52_CMD_WRD_FILTER, S52_CMD_WRD_FILTER_AC);
    S52_setMarinerParam(S52_CMD_WRD_FILTER, S52_CMD_WRD_FILTER_AP);
    S52_setMarinerParam(S52_CMD_WRD_FILTER, S52_CMD_WRD_FILTER_TX);
    //*/

    // load cell from s52.cfg
    S52_loadCell(NULL, NULL);

    { // main loop
        XEvent event;
        while (True) {
            do {
                XNextEvent(dpy, &event);
                switch (event.type) {
                case ConfigureNotify: break;
                //case GraphicsExpose:
                //    S52_setViewPort(0, 0, event.xconfigure.width, event.xconfigure.height); break;
                //case ...

                case KeyPress:
                case KeyRelease:
                    {
                        unsigned int keycode = ((XKeyEvent *)&event)->keycode;
                        unsigned int keysym  = XkbKeycodeToKeysym(dpy, keycode, 0, 1);

                        // ESC - quit
                        if (XK_Escape == keysym) {
                            goto exit;
                        }
                    }
                }
            } while (XPending(dpy));
            S52_draw();
            S52_drawLast();  // nothing to do

            glXSwapBuffers(dpy,  win);
        }
    }

exit:

    XKillClient(dpy, win);

    S52_done();

    return True;
}
Example #7
0
	void X11Window::create(XVisualInfo *visual, DisplayWindowSite *new_site, const DisplayWindowDescription &desc)
	{
		site = new_site;

		// Reset all variables
		close_window();

		handle.screen = visual->screen;
		atoms = X11Atoms(handle.display);

		int disp_width_px = XDisplayWidth(handle.display, handle.screen);
		int disp_height_px = XDisplayHeight(handle.display, handle.screen);
		int disp_width_mm = XDisplayWidthMM(handle.display, handle.screen);

		// Get DPI of screen or use 96.0f if Xlib doesn't have a value.
		ppi = (disp_width_mm < 24) ? 96.0f : (25.4f * static_cast<float>(disp_width_px) / static_cast<float>(disp_width_mm));

		// Update pixel ratio.
		set_pixel_ratio(pixel_ratio);

		// Get X11 root window.
		auto _root_window = RootWindow(handle.display, handle.screen);

		// Get and validate initial window position and size.
		int win_x = desc.get_position().left * pixel_ratio;
		int win_y = desc.get_position().top * pixel_ratio;
		int win_width = desc.get_size().width * pixel_ratio;
		int win_height = desc.get_size().height * pixel_ratio;

		if (win_width <= 0)
			throw Exception("Invalid window width.");

		if (win_height <= 0)
			throw Exception("Invalid window height.");

		// Set values if fullscreen requested.
		if (desc.is_fullscreen())
		{
			win_x = 0;
			win_y = 0;
			win_width = disp_width_px;
			win_height = disp_height_px;
		}

		// Center window if position supplied is (-1, -1)
		if (win_x == -1 && win_y == -1)
		{
			win_x = (disp_width_px - win_width)/2 - 1;
			win_y = (disp_height_px - win_height)/2 - 1;
		}

		// Set minimum and maximum size
		this->resize_allowed = desc.get_allow_resize() || desc.is_fullscreen(); // Fullscreen mode needs a resizable window.
		if (resize_allowed)
		{
			minimum_size = Size(_ResizeMinimumSize_, _ResizeMinimumSize_);
			maximum_size = Size(0, 0); // No maximum size by default.
		}
		else
		{
			minimum_size = Size(win_width, win_height);
			maximum_size = Size(win_width, win_height);
		}

		// Setup X11 size hints.
		this->size_hints = XAllocSizeHints();
		if (size_hints == NULL)
			throw Exception("Failed to allocate X11 XSizeHints structure.");

		size_hints->flags       = PMinSize | (resize_allowed ? 0 : PMaxSize);
		size_hints->flags      |= PResizeInc | PBaseSize | PWinGravity;

		// x, y, width, height are obsolete.
		size_hints->flags      |= USSize | USPosition;	// See http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472522864

		size_hints->min_width   = minimum_size.width;
		size_hints->min_height  = minimum_size.height;
		size_hints->max_width   = maximum_size.width;
		size_hints->max_height  = maximum_size.height;
		size_hints->width_inc   = 1;
		size_hints->height_inc  = 1;
		size_hints->base_width  = win_width;
		size_hints->base_height = win_height;
		size_hints->win_gravity = NorthWestGravity;

		// Setup X11 colormap.
		//
		// The X.Org XServer implementation used on most systems requires that
		// a color-map be set for the window. Additionally, windows with a
		// different color-depth than its parent must have the border-pixel flag
		// set when creating them. Failure to do either will cause XCreateWindow()
		// to result in a BadMatch error.
		//
		// Source: stackoverflow.com/questions/3645632
		color_map = XCreateColormap(handle.display, _root_window, visual->visual, AllocNone);

		// Static popups are unresizable captionless popup windows.
		// These windows should not be decorated.
		bool is_static_popup = desc.is_popup() && !desc.has_caption() && !desc.get_allow_resize();

		// Tell X11 to perserve graphical content under small popup windows to avoid redraws.
		bool save_under = desc.is_popup() && ( (win_width * win_height) < (256 * 256 * pixel_ratio * pixel_ratio) );

		// Setup window attributes.
		XSetWindowAttributes attr = XSetWindowAttributes {
			.background_pixmap  = None, /* default */
			.background_pixel   =  0ul, /* default: undefined */
			.border_pixmap      = CopyFromParent, /* default */
			.border_pixel       =  0ul, /* see color_map details above */
			.bit_gravity        = ForgetGravity, /* default */
			.win_gravity        = NorthWestGravity, /* default */
			.backing_store      = NotUseful, /* default */
			.backing_planes     = -1ul, /* default */
			.backing_pixel      =  0ul, /* default */
			.save_under         = save_under ? True : False,
			.event_mask         = KeyPressMask
								| KeyReleaseMask
								| ButtonPressMask
								| ButtonReleaseMask
								| EnterWindowMask
								| LeaveWindowMask
								| PointerMotionMask
								| KeymapStateMask
								| ExposureMask
								// | VisibilityChangeMask
								| StructureNotifyMask
								| FocusChangeMask
								| PropertyChangeMask ,
			.do_not_propagate_mask  = NoEventMask, /* default */
			.override_redirect      = is_static_popup ? True : False,
			.colormap               = color_map, /* see color_map details above */
			.cursor                 = None /* default; Let X11 handle the cursor for now. */
		};

		this->system_cursor = XCreateFontCursor(handle.display, XC_left_ptr); // This is allowed to fail

		log_event("debug", "clan::X11Window::create(): Creating window...");
		log_event("debug", "    x%1 y%2 w%3 h%4 b%5 d%6", win_x, win_y, win_width, win_height, border_width, visual->depth);
		log_event("debug", "    a.su%1, a.od%2", save_under, is_static_popup);

		// Create window
		handle.window = XCreateWindow(
				handle.display, _root_window,
				win_x, win_y, win_width, win_height, border_width,
				visual->depth, InputOutput, visual->visual,
				CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap,
				&attr
				);

		if (!handle.window)
			throw Exception("Unable to create the X11 window");

		if (!desc.get_owner().is_null())
		{
			DisplayWindow owner = desc.get_owner();
			XSetTransientForHint(handle.display, handle.window, owner.get_handle().window);
		}

		// Setup the hidden cursor (Maybe this should be done only once when required)
		char data[64]; // 8x8
		memset(data, 0, 64);

		XColor black_color;
		memset(&black_color, 0, sizeof(black_color));

		cursor_bitmap = XCreateBitmapFromData(handle.display, handle.window, data, 8, 8);
		hidden_cursor = XCreatePixmapCursor(handle.display, cursor_bitmap, cursor_bitmap, &black_color, &black_color, 0,0);

		// Set title of window:
		set_title(desc.get_title());

		{   // Inform the window manager who we are, so it can kill us if we're not good for its universe.
			Atom atom;
			int32_t pid = getpid();
			if (pid > 0)
			{
				atom = atoms.get_atom(handle.display, "_NET_WM_PID", False);
				XChangeProperty(handle.display, handle.window, atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &pid, 1);
			}

			char hostname[256];
			if (gethostname(hostname, sizeof(hostname)) > -1)
			{
				hostname[255] = 0;
				atom = atoms.get_atom(handle.display, "WM_CLIENT_MACHINE", False);
				XChangeProperty(handle.display, handle.window, atom, XA_STRING, 8, PropModeReplace, (unsigned char *) hostname, strlen(hostname));
			}
		}

		// Set-up window type/styling.
		// TODO Support more window types, broaden ClanLib window type support, etc.
		if (atoms["_NET_WM_WINDOW_TYPE"] != None)
		{
			Atom type = None;
			std::string name;

			if (desc.is_dialog())
			{
				name = "_NET_WM_WINDOW_TYPE_DIALOG";
				type = atoms[name];
			}
			else if (desc.is_popup())
			{
				if (is_static_popup)
				{
					name = "_NET_WM_WINDOW_TYPE_TOOLTIP";
					type = atoms[name];
				}
				else if (desc.has_caption()) // A pop-up with title bar -> utility
				{
					name = "_NET_WM_WINDOW_TYPE_UTILITY";
					type = atoms[name];
				} // else, a pop-up without a title bar -> popup-menu, combo, dropdown, tooltip, ...

				if (type == None) { name = "_NET_WM_WINDOW_TYPE_POPUP_MENU"; type = atoms[name]; }
				if (type == None) { name = "_NET_WM_WINDOW_TYPE_COMBO"; type = atoms[name]; }
				if (type == None) { name = "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"; type = atoms[name]; }
			} // else if (desc.is_normal())

			// Fallback to normal window type if WM doesn't support what we want.
			if (type == None) { name = "_NET_WM_WINDOW_TYPE_NORMAL"; type = atoms[name]; }

			if (type != None) // Ensure selected type exists.
			{
				XChangeProperty(handle.display, handle.window, atoms["_NET_WM_WINDOW_TYPE"], XA_ATOM, 32, PropModeReplace, (unsigned char *)&type, 1);
				log_event("debug", "clan::X11Window::create(): Creating window of type '%1'.", name);
			}
			else
			{
				log_event("debug", "clan::X11Window::create(): Failed to find a suitable window type.");
			}
		}
		else
		{
			log_event("debug", "clan::X11Window::create(): _NET_WM_WINDOW_TYPE does not exist.");
		}

		// Set size hints
		XSetWMNormalHints(handle.display, handle.window, size_hints);

		{	// Subscribe to WM events.
			Atom protocol = atoms["WM_DELETE_WINDOW"];
			Status result = XSetWMProtocols(handle.display, handle.window, &protocol, 1);
			if (result == 0)
				log_event("debug", "clan::X11Window::create(): Failed to set WM_PROTOCOLS.");
		}

		{	// Make auto-repeat keys detectable.
			Bool supports_detectable_autorepeat;
			XkbSetDetectableAutoRepeat(handle.display, True, &supports_detectable_autorepeat);
		}

		{	// Make window full-screen if requested.
			if (atoms["_NET_WM_STATE"] == None && atoms["_NET_WM_STATE_FULLSCREEN"])
			{
				fullscreen = false;
				log_event("debug", "clan::X11Window: Fullscreen not supported by WM.");
			}
			else
			{
				fullscreen = desc.is_fullscreen();
			}

			if (fullscreen)
			{
				Atom state = atoms["_NET_WM_STATE_FULLSCREEN"];
				XChangeProperty(handle.display, handle.window, atoms["_NET_WM_STATE"], XA_ATOM, 32, PropModeReplace, (unsigned char *)&state, 1);
			}
		}

		update_frame_extents();

		auto new_client_area = desc.get_position_client_area() // supplied position is at ? client area : window area;
			? Rect::xywh(win_x, win_y, win_width, win_height)
			: Rect::xywh(win_x + frame_extents.left, win_y + frame_extents.right, win_width, win_height)
			;

		process_window_resize(new_client_area);

		// Set window visibility
		if (desc.is_visible())
		{
			show(false);
		}

		// Setup the clipboard
		clipboard.setup();

		// Go looking for joysticks:
		setup_joysticks();
	}

	void X11Window::update_frame_extents()
	{
		frame_extents = Rect { border_width, border_width, border_width, border_width };

		if (atoms["_NET_FRAME_EXTENTS"] == None)
			return;

		// Request frame extents from WM.
		if (atoms["_NET_REQUEST_FRAME_EXTENTS"] != None)
		{
			XEvent event;
			memset(&event, 0, sizeof(event));

			event.type = ClientMessage;
			event.xclient.window = handle.window;
			event.xclient.format = 32;
			event.xclient.message_type = atoms["_NET_REQUEST_FRAME_EXTENTS"];

			XSendEvent(handle.display, RootWindow(handle.display, handle.screen), False, SubstructureNotifyMask | SubstructureRedirectMask, &event);

			int timer = 10;
			while(true)
			{
				if (timer < 0)
				{
					log_event("debug", "clan::X11Window: Your window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation.");
					break;
				}

				if (XCheckMaskEvent(handle.display, PropertyNotify, &event))
				{
					break;
				}

				clan::System::sleep(5);
				timer--;
			}
		}

		unsigned long  item_count;
		// _NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32
		unsigned char *data = atoms.get_property(handle.window, "_NET_FRAME_EXTENTS", item_count);
		if (data == NULL)
			return;

		if (item_count >= 4)
		{
			long *cardinal = (long *)data;
			frame_extents.left   = cardinal[0];
			frame_extents.right  = cardinal[1];
			frame_extents.top    = cardinal[2];
			frame_extents.bottom = cardinal[3];
		}

		XFree(data);
	}