LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-11-2010, 02:59 AM   #1
Piacio
LQ Newbie
 
Registered: Jul 2010
Posts: 6

Rep: Reputation: 0
[C] X11 window of fixed aspect ratio


Hi!
I'using the X11 libraries to generate and managing a simple window. With:

Code:
XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 608, 256, 1, WhitePixel(d,s),BlackPixel(d, s));
I can create a window of the desired aspect ratio, but if the user want to resize the window, the aspect ratio will be lost.
Does anybody know if I can fix the aspect ratio or make the dimension of the window unchangeable?

Thanks
 
Old 11-11-2010, 09:03 AM   #2
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: FreeBSD,Debian wheezy
Posts: 811

Rep: Reputation: 178Reputation: 178
You're talking about the user resizing the window, so obviously this window is a child of the root window. And it's the window manager which handles the resizing. So it's the window manager which will need to impose any constraints on user-requested window resizing (with the mouse).

So you're at the mercy of whatever window manager you're running, but that should be no problem.

You can request the minimum size, maximum size, minimum and maximum aspect ratio, increment for the window size (ever notice how xterm always keeps its height as a multiple of one line of print, and its width as a multiple of one character?), and something called win_gravity, which you probably won't need.

For more details, do this:
Code:
man xsizehints
Your code should look something like this:
Code:
XSizeHints *size_hints;

...

size_hints=XAllocSizeHints();

if(size_hints==NULL)
{
  ... handle the error
}

... futz around here, as suggested by "man xsizehints"

XSetWMNormalHints(the_display,
                  the_window,
                  size_hints,
                 );
Hope this helps.
 
Old 11-12-2010, 04:25 AM   #3
Piacio
LQ Newbie
 
Registered: Jul 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Thank you!
The XSizeHints is just what I needed.
Sorry, but I'm very newbie on the x11 libraries.
 
Old 11-12-2010, 08:27 AM   #4
Piacio
LQ Newbie
 
Registered: Jul 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Sorry, I'm still having problems here. I've tried something like this to fix the aspect ratio to 19:8 (the same as the video original source to be played back in the window):

Code:
size_hints->flags= USPosition | PAspect | PMinSize | PMaxSize;
size_hints->min_width=608;
size_hints->min_height=256;
size_hints->max_width=608*2;
size_hints->max_height=256*2;
size_hints->min_aspect.x=19;
size_hints->max_aspect.x=size_hints->min_aspect.x;
size_hints->min_aspect.y=8;
size_hints->max_aspect.y=size_hints->min_aspect.y;
	
s = DefaultScreen(d);
w = XCreateSimpleWindow(d, RootWindow(d, s), 100, 100, 608, 256, 1,
	WhitePixel(d,s),BlackPixel(d, s));
XSetWMNormalHints(d,w,size_hints);
XMapWindow(d, w);
If you check the values for min_aspect and max_aspect with this:

Code:
XSizeHints *hints_return = XAllocSizeHints();
long *supplied_return = (long *) malloc(sizeof(long));
XGetWMNormalHints(d, w, hints_return, supplied_return);
printf("minAs x %d y %d maxAs x %d y %d\n", hints_return->min_aspect.x, hints_return->min_aspect.y, hints_return->max_aspect.x, hints_return->max_aspect.y);
you get the correct values for the aspect ratio:

minAs x 19 y 8 maxAs x 19 y 8

However, the user can still change the aspect ratio to whatever it wants; the maximum and minimum sizes provided by min and max width and height are instead enforced.

I'm really confused at this point. What's happening?

Thanks,
Alberto
 
Old 11-12-2010, 01:45 PM   #5
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: FreeBSD,Debian wheezy
Posts: 811

Rep: Reputation: 178Reputation: 178
Well, that's pretty interesting. I must confess I'd never looked into controlling the aspect ratio of a window until you raised the question. But just for kicks and grins, I ran the following shell script, and up popped a window with an enforced aspect ratio. When you run this shell script, what do you get?
Code:
rm -rf 1; cat <<EOD > 1.c; gcc -Wall -Werror -lX11 1.c -o 1; ./1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>

int
main(void)
{
  {
    Display    *d;
    int         s;
    Window      w;
    XSizeHints *size_hints;

    d=XOpenDisplay(NULL);

    if(d==NULL)
    {
      fprintf(stderr,"XOpenDisplay() failed\n");

      exit(1);
    }

    s=DefaultScreen(d);

    w=XCreateSimpleWindow(d,
                          RootWindow(d,s),
                          100,
                          100,
                          608,
                          256,
                          1,
                          WhitePixel(d,s),
                          BlackPixel(d,s)
                         );

    size_hints=XAllocSizeHints();

    if(size_hints==NULL)
    {
      fprintf(stderr,"XMallocSizeHints() failed\n");

      exit(1);
    }

    size_hints->flags=USPosition | PAspect | PMinSize | PMaxSize;
    size_hints->min_width=608;
    size_hints->min_height=256;
    size_hints->max_width=608*2;
    size_hints->max_height=256*2;
    size_hints->min_aspect.x=19;
    size_hints->max_aspect.x=size_hints->min_aspect.x;
    size_hints->min_aspect.y=8;
    size_hints->max_aspect.y=size_hints->min_aspect.y;

    XSetWMNormalHints(d,w,size_hints);

    XMapWindow(d,w);

    XFlush(d);

    while(1)
    {
      sleep(1);
    }

    return 0;
  }

} /* main() */

EOD
 
Old 11-15-2010, 02:42 AM   #6
Piacio
LQ Newbie
 
Registered: Jul 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Ok,
I've tried to run your code on two different OS:
- On ubuntu 9.04 it works fine
- On Max OS X persist the same problem of my code
So I think this is due to the different window manager that are running, true?

Now I don't really know what to do...

By the way,
thank you for your help.
 
Old 11-15-2010, 06:56 AM   #7
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: FreeBSD,Debian wheezy
Posts: 811

Rep: Reputation: 178Reputation: 178
Quote:
Originally Posted by Piacio View Post
So I think this is due to the different window manager that are running, true?
Exactly.

Try running the following on your Mac. It's crude, but it might work. I'm dying of curiosity. Does it fix the problem?

Incidentally, if you're curious about why I turned EXACT on, try turning it off and turn VERBOSE on. You'll not only get interesting printed output as the size settles down, it will also make your window look a little funny as you resize it.

You can also try that experiment under Linux for amusement purposes if none of this changes anything on your Mac.
Code:
rm -rf 2; cat <<EOD > 2.c; gcc -Wall -Werror -lX11 2.c -o 2; ./2
#define AUTOMATIC 0
#define MANUAL    1
#define VERBOSE   0
#define EXACT     1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>

int
main(void)
{
  {
    Display    *d;
    int         s;
    Window      w;
    XEvent      the_event;
#if AUTOMATIC
    XSizeHints *size_hints;
#endif
#if MANUAL
    Window       root_return;
    int          x_return;
    int          y_return;
    unsigned int width_return;
    unsigned int height_return;
    unsigned int border_width_return;
    unsigned int depth_return;
    unsigned int width_new;
    unsigned int height_new;
#endif

    d=XOpenDisplay(NULL);

    if(d==NULL)
    {
      fprintf(stderr,"XOpenDisplay() failed\n");

      exit(1);
    }

    s=DefaultScreen(d);

    w=XCreateSimpleWindow(d,
                          RootWindow(d,s),
                          100,
                          100,
                          608,
                          256,
                          1,
                          WhitePixel(d,s),
                          BlackPixel(d,s)
                         );

#if AUTOMATIC
    size_hints=XAllocSizeHints();

    if(size_hints==NULL)
    {
      fprintf(stderr,"XMallocSizeHints() failed\n");

      exit(1);
    }

    size_hints->flags=USPosition | PAspect | PMinSize | PMaxSize;
    size_hints->min_width=608;
    size_hints->min_height=256;
    size_hints->max_width=608*2;
    size_hints->max_height=256*2;
    size_hints->min_aspect.x=19;
    size_hints->max_aspect.x=size_hints->min_aspect.x;
    size_hints->min_aspect.y=8;
    size_hints->max_aspect.y=size_hints->min_aspect.y;

    XSetWMNormalHints(d,w,size_hints);
#endif

#if MANUAL
#define MIN_WIDTH  608
#define MIN_HEIGHT 256
#define MAX_WIDTH  (MIN_WIDTH*2)
#define MAX_HEIGHT (MIN_HEIGHT*2)
#define ASPECT_X   19
#define ASPECT_Y   8

    XSelectInput(d,w,StructureNotifyMask);
#endif

    XMapWindow(d,w);

    for(;;)
    {
      XNextEvent(d,&the_event);

      switch(the_event.type)
      {
#if MANUAL
        case ConfigureNotify:
        {
          XGetGeometry(d,
                       w,
                       &root_return,
                       &x_return,
                       &y_return,
                       &width_return,
                       &height_return,
                       &border_width_return,
                       &depth_return
                      );

          width_new =width_return;
          height_new=height_return;

          if(width_new*ASPECT_Y < height_new*ASPECT_X)
          {
            height_new=(width_new*ASPECT_Y)/ASPECT_X;
          }
          else
          if(width_new*ASPECT_Y > height_new*ASPECT_X)
          {
            width_new=(height_new*ASPECT_X)/ASPECT_Y;
          }

          if((width_new <MIN_WIDTH ) ||
             (height_new<MIN_HEIGHT)
            )
          {
            width_new =MIN_WIDTH;
            height_new=MIN_HEIGHT;
          }

          if((width_new >MAX_WIDTH ) ||
             (height_new>MAX_HEIGHT)
            )
          {
            width_new =MAX_WIDTH;
            height_new=MAX_HEIGHT;
          }

          if((height_new!=height_return) ||
             (width_new !=width_return )
            )
          {
#if EXACT
            width_new =width_new -width_new %ASPECT_X;
            height_new=(width_new*ASPECT_Y)/ASPECT_X;
#endif
#if VERBOSE
            printf("resizing from %4d,%4d to %4d,%4d\n",
                   width_return,
                   height_return,
                   width_new,
                   height_new
                  );
#endif
            XResizeWindow(d,w,width_new,height_new);
          }

          break;
        }
#endif
        default: break;
      }
    }

    return 0;
  }

} /* main() */

EOD
 
Old 11-15-2010, 10:26 AM   #8
Piacio
LQ Newbie
 
Registered: Jul 2010
Posts: 6

Original Poster
Rep: Reputation: 0
Perfect, problem fixed properly.

Thank you for your work.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
MPlayer 16:10 Aspect Ratio Linkhiei Linux - Software 9 01-18-2012 05:26 PM
Set aspect ratio from 4:3 to 16:9? antareslq Linux - Newbie 4 09-26-2010 04:36 AM
Mplayer Aspect Ratio Glock Shooter Linux - Software 6 11-22-2003 06:19 PM
16/9 aspect ratio abby_normal Linux - Software 4 11-03-2003 03:40 PM
16:9 aspect ratio resolution possible? rikw Linux - Software 0 09-04-2001 09:25 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:40 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration