Rework the randr restore code
authorChris Michael <cp.michael@samsung.com>
Wed, 29 May 2013 11:35:57 +0000 (12:35 +0100)
committerChris Michael <cp.michael@samsung.com>
Wed, 29 May 2013 11:35:57 +0000 (12:35 +0100)
NB: This matches more closely to how xrandr applies settings

Signed-off-by: Chris Michael <cp.michael@samsung.com>
src/bin/e_randr.c

index 25ffa58..fbc4305 100644 (file)
@@ -11,6 +11,10 @@ static Eina_Bool _e_randr_config_output_update(E_Randr_Output_Config *cfg);
 static E_Randr_Crtc_Config *_e_randr_config_output_crtc_find(E_Randr_Output_Config *cfg);
 static Ecore_X_Randr_Mode _e_randr_config_output_preferred_mode_get(E_Randr_Output_Config *cfg);
 static E_Randr_Output_Config *_e_randr_config_output_new(unsigned int id);
+static E_Randr_Crtc_Config *_e_randr_config_crtc_find(Ecore_X_Randr_Crtc crtc);
+static E_Randr_Output_Config *_e_randr_config_output_find(Ecore_X_Randr_Output output);
+static void _e_randr_config_screen_size_calculate(int *sw, int *sh);
+static void _e_randr_config_mode_geometry(Ecore_X_Randr_Mode mode, Ecore_X_Randr_Orientation orient, Eina_Rectangle *rect);
 
 static Eina_Bool _e_randr_event_cb_screen_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
 static Eina_Bool _e_randr_event_cb_crtc_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
@@ -363,266 +367,221 @@ _e_randr_config_restore(void)
 {
    Ecore_X_Window root = 0;
    Ecore_X_Randr_Crtc *crtcs;
+   /* Ecore_X_Randr_Output primary = 0; */
    int ncrtcs = 0;
-   int sw = 0, sh = 0;
+   int sw = 0, sh = 0, cw = 0, ch = 0;
 
-   printf("E_RANDR Restore\n");
+   printf("E_RANDR CONFIG RESTORE\n");
 
-   /* grab the root window */
-   root = ecore_x_window_root_first_get();
+   /* grab the X server so that we can apply settings without triggering 
+    * any randr event updates until we are done */
+   ecore_x_grab();
 
-   /* get the current screen size */
-   ecore_x_randr_screen_current_size_get(root, &sw, &sh, NULL, NULL);
-   printf("\tCurrent Screen Size: %d %d\n", sw, sh);
+   /* get existing primary output */
+   /* primary = ecore_x_randr_primary_output_get(root); */
 
-   /* set the screen size */
-   /* NB: Disabled for now as our saved screen size may not be valid 
-    * if any of our saved outputs are missing in X */
-   /* ecore_x_randr_screen_current_size_set(root, e_randr_cfg->screen.width,  */
-   /*                                       e_randr_cfg->screen.height, -1, -1); */
+   /* get existing screen size */
+   ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
 
-   /* try to get the list of existing crtcs from X */
+   /* calculate new screen size */
+   _e_randr_config_screen_size_calculate(&sw, &sh);
+   printf("\tCalculated Screen Size: %d %d\n", sw, sh);
+
+   /* get the root window */
+   root = ecore_x_window_root_first_get();
+
+   /* get a list of crtcs from X */
    if ((crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs)))
      {
-        int i = 0;
-        Eina_List *valid_crtcs = NULL;
-        Eina_List *l;
-        E_Randr_Crtc_Config *crtc_cfg;
-        Eina_Bool primary_set = EINA_FALSE;
-
-        printf("\tHave Crtcs\n");
+        Ecore_X_Randr_Output *outputs;
+        int c = 0, noutputs = 0;
 
-        /* for each crtc that X has, check our config and see if we have it */
-        for (i = 0; i < ncrtcs; i++)
+        /* loop the X crtcs */
+        for (c = 0; c < ncrtcs; c++)
           {
-             Eina_Bool crtc_found = EINA_FALSE;
-
-             printf("\t\tChecking For Crtc: %d in Our Config\n", crtcs[i]);
-
-             /* loop our config and find this crtc */
-             EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
+             E_Randr_Crtc_Config *cfg;
+             Evas_Coord x, y, w, h;
+             Ecore_X_Randr_Mode mode = 0;
+             Ecore_X_Randr_Orientation orient = 
+               ECORE_X_RANDR_ORIENTATION_ROT_0;
+             Eina_Rectangle rect;
+
+             /* Firstly, disable any crtcs which are disabled in our config OR 
+              * which are larger than the target size */
+
+             /* try to find this crtc in our config */
+             if ((cfg = _e_randr_config_crtc_find(crtcs[c])))
                {
-                  /* try to find this crtc */
-                  if (crtc_cfg->xid != crtcs[i]) continue;
-
-                  crtc_found = EINA_TRUE;
-                  printf("\t\t\tFound Crtc in Config\n");
-                  valid_crtcs = eina_list_append(valid_crtcs, crtc_cfg);
+                  x = cfg->x;
+                  y = cfg->y;
+                  w = cfg->width;
+                  h = cfg->height;
+                  mode = cfg->mode;
+                  orient = cfg->orient;
                }
-
-             if (!crtc_found)
+             else
                {
-                  printf("\t\t\tCrtc Not Found in Config\n");
-                  printf("\t\t\t\tCreating New\n");
-                  /* create new crtc config */
-                  if ((crtc_cfg = E_NEW(E_Randr_Crtc_Config, 1)))
+                  /* this crtc is not in our config. get values from X */
+#if ((ECORE_VERSION_MAJOR >= 1) && (ECORE_VERSION_MINOR >= 8))
+                  Ecore_X_Randr_Crtc_Info *cinfo;
+
+                  /* get crtc info from X */
+                  if ((cinfo = ecore_x_randr_crtc_info_get(root, crtcs[c])))
                     {
-                       /* assign id */
-                       crtc_cfg->xid = crtcs[i];
-                       crtc_cfg->exists = EINA_TRUE;
+                       x = cinfo->x;
+                       y = cinfo->y;
+                       w = cinfo->width;
+                       h = cinfo->height;
+                       mode = cinfo->mode;
+                       orient = cinfo->rotation;
+
+                       ecore_x_randr_crtc_info_free(cinfo);
+                    }
+#else
+                  /* get geometry of this crtc */
+                  ecore_x_randr_crtc_geometry_get(root, crtcs[c], 
+                                                  &x, &y, &w, &h);
+
+                  /* get mode */
+                  mode = ecore_x_randr_crtc_mode_get(root, crtcs[c]);
 
-                       /* fill in crtc_cfg values from X */
-                       _e_randr_config_crtc_update(crtc_cfg);
+                  /* get orientation */
+                  orient = ecore_x_randr_crtc_orientation_get(root, crtcs[c]);
+#endif
+               }
 
-                       printf("\t\t\t\tNew Crtc Geom: %d %d %d %d\n",
-                              crtc_cfg->x, crtc_cfg->y, crtc_cfg->width, 
-                              crtc_cfg->height);
-                       printf("\t\t\t\tNew Crtc Mode: %d\n", crtc_cfg->mode);
+             /* at this point, we should have geometry, mode and orientation.
+              * We can now proceed to calculate crtc size */
+             _e_randr_config_mode_geometry(mode, orient, &rect);
 
-                       /* append to randr cfg */
-                       e_randr_cfg->crtcs = 
-                         eina_list_append(e_randr_cfg->crtcs, crtc_cfg);
+             x += rect.x;
+             y += rect.y;
+             w = rect.w;
+             h = rect.h;
 
-                       e_randr_config_save();
+             /* if it fits within the screen and is "enabled", skip it */
+             if (((x + w) <= sw) && ((y + h) <= sh) && (mode != 0))
+               continue;
 
-                       /* append to our short list */
-                       valid_crtcs = eina_list_append(valid_crtcs, crtc_cfg);
-                    }
-               }
+             /* it does not fit or disabled in our config. disable it in X */
+             ecore_x_randr_crtc_settings_set(root, crtcs[c], NULL, 0, 0, 0, 0, 
+                                             ECORE_X_RANDR_ORIENTATION_ROT_0);
           }
 
-        free(crtcs);
-
-        printf("\t\tLooping Valid Crtcs\n");
+        /* apply the new screen size */
+        if ((sw != cw) || (sh != ch))
+          ecore_x_randr_screen_current_size_set(root, sw, sh, -1, -1);
 
-        /* for each X crtc that we have config for, check outputs */
-        EINA_LIST_FOREACH(valid_crtcs, l, crtc_cfg)
+        /* apply any stored crtc settings */
+        for (c = 0; c < ncrtcs; c++)
           {
-             Ecore_X_Randr_Output *outputs;
-             int noutputs;
-             Eina_List *valid_outputs = NULL;
+             E_Randr_Crtc_Config *cfg;
 
-             /* we have this crtc. try to get list of outputs from X */
-             if ((outputs = 
-                  ecore_x_randr_crtc_outputs_get(root, crtc_cfg->xid, &noutputs)))
+             /* try to find this crtc in our config */
+             if ((cfg = _e_randr_config_crtc_find(crtcs[c])))
                {
-                  int j = 0;
+                  Eina_List *l, *valid = NULL;
+                  E_Randr_Output_Config *output_cfg;
+                  Ecore_X_Randr_Output *coutputs;
+                  int count = 0;
 
-                  printf("\t\t\tHave X Outputs For Crtc: %d\n", crtc_cfg->xid);
-
-                  /* loop the X outputs and find a matching config */
-                  for (j = 0; j < noutputs; j++)
+                  /* loop any outputs in this crtc cfg */
+                  EINA_LIST_FOREACH(cfg->outputs, l, output_cfg)
                     {
-                       Eina_List *ll;
-                       E_Randr_Output_Config *output_cfg;
                        Ecore_X_Randr_Connection_Status status = 
                          ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
 
+                       /* get connection status */
                        status = 
                          ecore_x_randr_output_connection_status_get(root, 
-                                                                    outputs[j]);
+                                                                    output_cfg->xid);
+
+                       /* skip this output if it is not connected */
                        if (status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
                          continue;
 
-                       printf("\t\t\t\tChecking for Output: %d in Our Config\n", outputs[j]);
-
-                       /* loop our outputs for this crtc */
-                       EINA_LIST_FOREACH(crtc_cfg->outputs, ll, output_cfg)
-                         {
-                            /* try to find this output */
-                            if (output_cfg->xid != outputs[j]) continue;
-
-                            /* we have this output */
-                            printf("\t\t\t\tFound Output In Config: %d\n", outputs[j]);
-
-                            /* add this output config to the list of 
-                             * ones that we are going to restore for 
-                             * this crtc */
-                            valid_outputs = 
-                              eina_list_append(valid_outputs, output_cfg);
-
-                            break;
-                         }
+                       /* append to the list of valid outputs */
+                       valid = eina_list_append(valid, output_cfg);
                     }
 
-                  free(outputs);
-               }
-             else
-               {
-                  printf("\t\t\tNo Outputs For Crtc: %d\n", crtc_cfg->xid);
-                  /* crtc has no outputs assigned */
-                  /* Need to check possibles */
-               }
-
-             /* apply settings for this crtc */
-             printf("\t\t\t\tApplying Crtc Settings: %d\n", crtc_cfg->xid);
-
-             if (!crtc_cfg->mode)
-               {
-                  printf("\t\t\t\t\tCRTC HAS NO MODE !!!\n");
-                  ecore_x_randr_crtc_settings_set(root, crtc_cfg->xid, 
-                                                  NULL, 0, 0, 0, 0, 
-                                                  ECORE_X_RANDR_ORIENTATION_ROT_0);
-               }
-             else 
-               {
-                  int ocount, c = 0;
-
-                  ocount = eina_list_count(valid_outputs);
-                  printf("\t\t\t\t\tNum Outputs: %d\n", ocount);
+                  count = eina_list_count(valid);
 
-                  if (ocount > 0)
+                  /* try to allocate space for x randr outputs */
+                  if ((coutputs = calloc(count, sizeof(Ecore_X_Randr_Output))))
                     {
-                       Ecore_X_Randr_Output *couts;
-                       Eina_List *o;
-                       E_Randr_Output_Config *out;
-                       Eina_Bool need_size_set = EINA_FALSE;
+                       int o = 0;
 
-                       couts = malloc(ocount * sizeof(Ecore_X_Randr_Output));
-                       EINA_LIST_FOREACH(valid_outputs, o, out)
+                       /* for each entry in valid outputs, place in X list */
+                       EINA_LIST_FOREACH(valid, l, output_cfg)
                          {
-                            couts[c] = out->xid;
-                            c++;
+                            coutputs[o] = output_cfg->xid;
+                            o++;
                          }
 
-                       switch (crtc_cfg->orient)
-                         {
-                          case ECORE_X_RANDR_ORIENTATION_ROT_0:
-                          case ECORE_X_RANDR_ORIENTATION_ROT_180:
-                            if (sw < (crtc_cfg->x + crtc_cfg->width))
-                              {
-                                 sw += crtc_cfg->width;
-                                 need_size_set = EINA_TRUE;
-                              }
-                            if (sh < (crtc_cfg->y + crtc_cfg->height))
-                              {
-                                 sh = (crtc_cfg->y + crtc_cfg->height);
-                                 need_size_set = EINA_TRUE;
-                              }
-                            break;
-                          case ECORE_X_RANDR_ORIENTATION_ROT_90:
-                          case ECORE_X_RANDR_ORIENTATION_ROT_270:
-                            if (sw < (crtc_cfg->x + crtc_cfg->width))
-                              {
-                                 sw = (crtc_cfg->x + crtc_cfg->width);
-                                 need_size_set = EINA_TRUE;
-                              }
-                            if (sh < (crtc_cfg->y + crtc_cfg->height))
-                              {
-                                 sh += crtc_cfg->height;
-                                 need_size_set = EINA_TRUE;
-                              }
-                            break;
-                          default:
-                            break;
-                         }
+                    }
 
-                       if (need_size_set)
-                         {
+                  /* apply our stored crtc settings */
+                  ecore_x_randr_crtc_settings_set(root, crtcs[c], coutputs, 
+                                                  count, cfg->x, cfg->y, 
+                                                  cfg->mode, cfg->orient);
 
-                            printf("\t\t\t\t\tNew Screen Size: %d %d\n", 
-                                   sw, sh);
-                            ecore_x_randr_screen_current_size_set(root, 
-                                                                  sw, sh, 
-                                                                  -1, -1);
-                            need_size_set = EINA_FALSE;
-                         }
+                  /* cleanup */
+                  eina_list_free(valid);
+                  free(coutputs);
+               }
+          }
 
-                       printf("\t\t\t\t\tCrtc Settings: %d %d %d %d %d %d\n", 
-                              crtc_cfg->xid, crtc_cfg->x, crtc_cfg->y, 
-                              crtc_cfg->width, crtc_cfg->height, 
-                              crtc_cfg->mode);
+        /* free list of crtcs */
+        free(crtcs);
 
-                       ecore_x_randr_crtc_settings_set(root, crtc_cfg->xid, 
-                                                       couts, ocount, 
-                                                       crtc_cfg->x, 
-                                                       crtc_cfg->y, 
-                                                       crtc_cfg->mode, 
-                                                       crtc_cfg->orient);
+        /* apply primary if we have one set */
+        if (e_randr_cfg->primary)
+          {
+             Eina_Bool primary_set = EINA_FALSE;
 
-                       if (!primary_set)
-                         {
-                            EINA_LIST_FOREACH(valid_outputs, o, out)
-                              {
-                                 if ((out->primary) && 
-                                     ((int)out->xid == e_randr_cfg->primary))
-                                   {
-                                      ecore_x_randr_primary_output_set(root, out->xid);
-                                      primary_set = EINA_TRUE;
-                                      break;
-                                   }
-                              }
-                         }
+             /* get list of valid outputs */
+             if ((outputs = ecore_x_randr_outputs_get(root, &noutputs)))
+               {
+                  /* loop valid outputs and check that our primary exists */
+                  for (c = 0; c < noutputs; c++)
+                    {
+                       Ecore_X_Randr_Connection_Status status = 
+                         ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
+
+                       /* skip if this output is not one we are looking for */
+                       if ((int)outputs[c] != e_randr_cfg->primary)
+                         continue;
+
+                       /* check that this output is actually connected */
+                       status = 
+                         ecore_x_randr_output_connection_status_get(root, 
+                                                                    outputs[c]);
 
-                       if (!primary_set)
+                       /* if it is actually connected, set primary */
+                       if (status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
                          {
-                            /* if no primary was set, set it to the first output */
-                            out = eina_list_nth(valid_outputs, 0);
-                            ecore_x_randr_primary_output_set(root, out->xid);
-                            e_randr_cfg->primary = (int)out->xid;
-                            e_randr_config_save();
+                            ecore_x_randr_primary_output_set(root, outputs[c]);
                             primary_set = EINA_TRUE;
+                            break;
                          }
-
-                       free(couts);
                     }
+
+                  /* free list of outputs */
+                  free(outputs);
                }
-             eina_list_free(valid_outputs);
+
+             /* fallback to no primary */
+             if (!primary_set)
+               ecore_x_randr_primary_output_set(root, 0);
           }
-        eina_list_free(valid_crtcs);
+        else
+          ecore_x_randr_primary_output_set(root, 0);
      }
 
-//   if (need_reset) ecore_x_randr_screen_reset(root);
+   /* release the server grab */
+   ecore_x_ungrab();
+
+   ecore_x_randr_screen_reset(root);
 }
 
 static Eina_Bool 
@@ -1150,3 +1109,229 @@ _e_randr_config_output_new(unsigned int id)
 
    return cfg;
 }
+
+static E_Randr_Crtc_Config *
+_e_randr_config_crtc_find(Ecore_X_Randr_Crtc crtc)
+{
+   Eina_List *l;
+   E_Randr_Crtc_Config *crtc_cfg;
+
+   EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
+     {
+        if (crtc_cfg->xid == crtc)
+          return crtc_cfg;
+     }
+
+   return NULL;
+}
+
+static E_Randr_Output_Config *
+_e_randr_config_output_find(Ecore_X_Randr_Output output)
+{
+   Eina_List *l;
+   E_Randr_Crtc_Config *crtc_cfg;
+   E_Randr_Output_Config *output_cfg;
+
+   EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
+     {
+        Eina_List *ll;
+
+        EINA_LIST_FOREACH(crtc_cfg->outputs, ll, output_cfg)
+          {
+             if (output_cfg->xid == output)
+               return output_cfg;
+          }
+     }
+
+   return NULL;
+}
+
+static void 
+_e_randr_config_screen_size_calculate(int *sw, int *sh)
+{
+   Ecore_X_Window root = 0;
+   Ecore_X_Randr_Output *outputs;
+   int noutputs = 0;
+   int minw = 0, minh = 0;
+   int maxw = 0, maxh = 0;
+
+   /* get the root window */
+   root = ecore_x_window_root_first_get();
+
+   /* get the min and max screen size */
+   ecore_x_randr_screen_size_range_get(root, &minw, &minh, &maxw, &maxh);
+
+   /* get outputs from X */
+   if ((outputs = ecore_x_randr_outputs_get(root, &noutputs)))
+     {
+        int i = 0;
+
+        /* loop X outputs */
+        for (i = 0; i < noutputs; i++)
+          {
+             E_Randr_Output_Config *output_cfg;
+             Ecore_X_Randr_Connection_Status status = 
+               ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
+             Ecore_X_Randr_Orientation orient = 
+               ECORE_X_RANDR_ORIENTATION_ROT_0;
+             Ecore_X_Randr_Mode mode = 0;
+             int x = 0, y = 0, w = 0, h = 0;
+             Eina_Rectangle rect;
+
+             /* get connection status */
+             status = 
+               ecore_x_randr_output_connection_status_get(root, outputs[i]);
+
+             /* skip this output if it is not connected */
+             if (status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
+               continue;
+
+             /* see if we have this output in our config */
+             if ((output_cfg = _e_randr_config_output_find(outputs[i])))
+               {
+                  E_Randr_Crtc_Config *crtc_cfg;
+
+                  /* try to find the crtc config for this output */
+                  if ((crtc_cfg = _e_randr_config_crtc_find(output_cfg->crtc)))
+                    {
+                       /* if this crtc is disabled in our config, skip it
+                        * 
+                        * NB: Since we will end up disabling this crtc, then 
+                        * we should not use it to calculate screen size */
+                       if (!crtc_cfg->mode) continue;
+
+                       /* get geometry and mode */
+                       x = crtc_cfg->x;
+                       y = crtc_cfg->y;
+                       w = crtc_cfg->width;
+                       h = crtc_cfg->height;
+                       mode = crtc_cfg->mode;
+                       orient = crtc_cfg->orient;
+                    }
+               }
+
+             /* if we have no config for this output. get values from X */
+             if ((!w) || (!h))
+               {
+                  Ecore_X_Randr_Crtc crtc = 0;
+
+#if ((ECORE_VERSION_MAJOR >= 1) && (ECORE_VERSION_MINOR >= 8))
+                  Ecore_X_Randr_Crtc_Info *cinfo;
+
+                  /* get crtc info from X */
+                  if ((cinfo = ecore_x_randr_crtc_info_get(root, crtc)))
+                    {
+                       x = cinfo->x;
+                       y = cinfo->y;
+                       w = cinfo->width;
+                       h = cinfo->height;
+                       mode = cinfo->mode;
+                       orient = cinfo->rotation;
+
+                       ecore_x_randr_crtc_info_free(cinfo);
+                    }
+#else
+                  /* get geometry of this crtc */
+                  ecore_x_randr_crtc_geometry_get(root, crtc, &x, &y, &w, &h);
+
+                  /* get mode */
+                  mode = ecore_x_randr_crtc_mode_get(root, crtc);
+
+                  /* get orientation */
+                  orient = ecore_x_randr_crtc_orientation_get(root, crtc);
+#endif
+               }
+
+             /* at this point, we should have geometry, mode and orientation.
+              * We can now proceed to calculate screen size */
+
+             _e_randr_config_mode_geometry(mode, orient, &rect);
+
+             x += rect.x;
+             y += rect.y;
+             w = rect.w;
+             h = rect.h;
+
+             if ((x + w) > *sw)
+               *sw = (x + w);
+             if ((y + h) > *sh)
+               *sh = (y + h);
+          }
+
+        /* free any space allocated */
+        free(outputs);
+     }
+
+   if ((*sw > maxw) || (*sh > maxh))
+     {
+        printf("Calculated Screen Size %dx%d is Larger Than Max %dx%d!!!\n", 
+               *sw, *sh, maxw, maxh);
+     }
+   else
+     {
+        if (*sw < minw) *sw = minw;
+        if (*sh < minh) *sh = minh;
+     }
+}
+
+static void 
+_e_randr_config_mode_geometry(Ecore_X_Randr_Mode mode, Ecore_X_Randr_Orientation orient, Eina_Rectangle *rect)
+{
+   Ecore_X_Window root = 0;
+   Evas_Point p[4];
+   int mw = 0, mh = 0;
+   int mode_width = 0, mode_height = 0;
+   int i = 0;
+   Eina_Rectangle tmp;
+
+   /* get the root window */
+   root = ecore_x_window_root_first_get();
+
+   /* get the size of this mode */
+   ecore_x_randr_mode_size_get(root, mode, &mode_width, &mode_height);
+
+   /* based on orientation, calculate mode sizes */
+   switch (orient)
+     {
+      case ECORE_X_RANDR_ORIENTATION_ROT_0:
+      case ECORE_X_RANDR_ORIENTATION_ROT_180:
+        mw = mode_width;
+        mh = mode_height;
+        break;
+      case ECORE_X_RANDR_ORIENTATION_ROT_90:
+      case ECORE_X_RANDR_ORIENTATION_ROT_270:
+        mw = mode_height;
+        mh = mode_width;
+        break;
+      default:
+        break;
+     }
+
+   p[0].x = 0;
+   p[0].y = 0;
+   p[1].x = mw;
+   p[1].y = 0;
+   p[2].x = mw;
+   p[2].y = mh;
+   p[3].x = 0;
+   p[3].y = mh;
+
+   for (i = 0; i < 4; i++)
+     {
+        double x = 0.0, y = 0.0;
+
+        x = p[i].x;
+        y = p[i].y;
+
+        eina_rectangle_coords_from(&tmp, floor(x), floor(y), ceil(x), ceil(y));
+        if (i == 0)
+          *rect = tmp;
+        else
+          {
+             if (tmp.x < rect->x) rect->x = tmp.x;
+             if (tmp.y < rect->y) rect->y = tmp.y;
+             if (tmp.w > rect->w) rect->w = tmp.w;
+             if (tmp.h > rect->h) rect->h = tmp.h;
+          }
+     }
+}