1693 m->by = -bh; |
1723 m->by = -bh; |
1694 } |
1724 } |
1695 |
1725 |
1696 Bool |
1726 Bool |
1697 updategeom(void) { |
1727 updategeom(void) { |
1698 int i, j, nn = 1, n = 1; |
1728 Bool dirty = False; |
1699 Client *c; |
1729 |
1700 Monitor *newmons = NULL, *m = NULL, *tm; |
|
1701 |
|
1702 /* TODO: |
|
1703 * This function needs to be seriously re-designed: |
|
1704 * |
|
1705 * #ifdef XINERAMA |
|
1706 * 1. Determine number of already existing monitors n |
|
1707 * 2. Determine number of monitors Xinerama reports nn |
|
1708 * 3. if(n <= nn) { |
|
1709 * if(n < nn) { |
|
1710 * append nn-n monitors to current struct |
|
1711 * flag dirty |
|
1712 * } |
|
1713 * for(i = 0; i < nn; i++) { |
|
1714 * if(oldgeom != newgeom) { |
|
1715 * apply newgeom; |
|
1716 * flag dirty; |
|
1717 * } |
|
1718 * } |
|
1719 * } |
|
1720 * else { |
|
1721 * detach all clients |
|
1722 * destroy current monitor struct |
|
1723 * create new monitor struct |
|
1724 * attach all clients to first monitor |
|
1725 * flag dirty; |
|
1726 * } |
|
1727 * return dirty flag to caller |
|
1728 * if dirty is seen by caller: |
|
1729 * re-arrange bars/pixmaps |
|
1730 * arrange() |
|
1731 * #else |
|
1732 * don't share between XINERAMA and non-XINERAMA handling if it gets |
|
1733 * too ugly |
|
1734 * #endif |
|
1735 */ |
|
1736 #ifdef XINERAMA |
|
1737 XineramaScreenInfo *info = NULL; |
|
1738 Bool *flags = NULL; |
|
1739 |
|
1740 if(XineramaIsActive(dpy)) |
|
1741 info = XineramaQueryScreens(dpy, &n); |
|
1742 flags = (Bool *)malloc(sizeof(Bool) * n); |
|
1743 for(i = 0; i < n; i++) |
|
1744 flags[i] = False; |
|
1745 /* next double-loop seeks any combination of retrieved Xinerama info |
|
1746 * with existing monitors, this is used to avoid unnecessary |
|
1747 * re-allocations of monitor structs */ |
|
1748 for(i = 0, nn = n; i < n; i++) |
|
1749 for(j = 0, m = mons; m; m = m->next, j++) |
|
1750 if(!flags[j]) { |
|
1751 if((flags[j] = ( |
|
1752 info[i].x_org == m->mx |
|
1753 && info[i].y_org == m->my |
|
1754 && info[i].width == m->mw |
|
1755 && info[i].height == m->mh) |
|
1756 )) |
|
1757 --nn; |
|
1758 } |
|
1759 if(nn == 0) { /* no need to re-allocate monitors */ |
|
1760 j = 0; |
|
1761 for(i = 0, m = mons; m; m = m->next, i++) { |
|
1762 m->num = info[i].screen_number; |
|
1763 if(info[i].x_org != m->mx |
|
1764 || info[i].y_org != m->my |
|
1765 || info[i].width != m->mw |
|
1766 || info[i].height != m->mh) |
|
1767 { |
|
1768 m->mx = m->wx = info[i].x_org; |
|
1769 m->my = m->wy = info[i].y_org; |
|
1770 m->mw = m->ww = info[i].width; |
|
1771 m->mh = m->wh = info[i].height; |
|
1772 updatebarpos(m); |
|
1773 j++; |
|
1774 } |
|
1775 } |
|
1776 XFree(info); |
|
1777 free(flags); |
|
1778 return j > 0; |
|
1779 } |
|
1780 /* next algorithm only considers unique geometries as separate screens */ |
|
1781 for(i = 0; i < n; i++) |
|
1782 flags[i] = False; /* used for ignoring certain monitors */ |
|
1783 for(i = 0, nn = n; i < n; i++) |
|
1784 for(j = 0; j < n; j++) |
|
1785 if(i != j && !flags[i]) { |
|
1786 if((flags[i] = ( |
|
1787 info[i].x_org == info[j].x_org |
|
1788 && info[i].y_org == info[j].y_org |
|
1789 && info[i].width == info[j].width |
|
1790 && info[i].height == info[j].height) |
|
1791 )) |
|
1792 --nn; |
|
1793 } |
|
1794 #endif /* XINERAMA */ |
|
1795 /* allocate monitor(s) for the new geometry setup */ |
|
1796 for(i = 0; i < nn; i++) { |
|
1797 if(!(m = (Monitor *)malloc(sizeof(Monitor)))) |
|
1798 die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); |
|
1799 m->next = newmons; |
|
1800 newmons = m; |
|
1801 } |
|
1802 /* initialise monitor(s) */ |
|
1803 #ifdef XINERAMA |
1730 #ifdef XINERAMA |
1804 if(XineramaIsActive(dpy)) { |
1731 if(XineramaIsActive(dpy)) { |
1805 for(i = 0, m = newmons; m && i < n; i++) { |
1732 int i, j, n, nn; |
1806 if(!flags[i]) { /* only use screens that aren't dublettes */ |
1733 Monitor *m; |
1807 m->num = info[i].screen_number; |
1734 XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); |
1808 m->mx = m->wx = info[i].x_org; |
1735 XineramaScreenInfo *unique = NULL; |
1809 m->my = m->wy = info[i].y_org; |
1736 |
1810 m->mw = m->ww = info[i].width; |
1737 info = XineramaQueryScreens(dpy, &nn); |
1811 m->mh = m->wh = info[i].height; |
1738 for(n = 0, m = mons; m; m = m->next, n++); |
1812 m = m->next; |
1739 /* only consider unique geometries as separate screens */ |
|
1740 if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn))) |
|
1741 die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn); |
|
1742 for(i = 0, j = 0; i < nn; i++) |
|
1743 if(isuniquegeom(unique, j, &info[i])) |
|
1744 memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); |
|
1745 XFree(info); |
|
1746 nn = j; |
|
1747 if(n <= nn) { |
|
1748 for(i = 0; i < (nn - n); i++) { /* new monitors available */ |
|
1749 for(m = mons; m && m->next; m = m->next); |
|
1750 if(m) |
|
1751 m->next = createmon(); |
|
1752 else |
|
1753 mons = createmon(); |
1813 } |
1754 } |
1814 } |
1755 for(i = 0, m = mons; i < nn && m; m = m->next, i++) |
1815 XFree(info); |
1756 if(i >= n |
1816 free(flags); |
1757 || (unique[i].x_org != m->mx || unique[i].y_org != m->my |
|
1758 || unique[i].width != m->mw || unique[i].height != m->mh)) |
|
1759 { |
|
1760 dirty = True; |
|
1761 m->num = unique[i].screen_number; |
|
1762 m->mx = m->wx = unique[i].x_org; |
|
1763 m->my = m->wy = unique[i].y_org; |
|
1764 m->mw = m->ww = unique[i].width; |
|
1765 m->mh = m->wh = unique[i].height; |
|
1766 updatebarpos(m); |
|
1767 } |
|
1768 } |
|
1769 else { /* less monitors available */ |
|
1770 cleanup(); |
|
1771 setup(); |
|
1772 } |
|
1773 free(unique); |
1817 } |
1774 } |
1818 else |
1775 else |
1819 #endif /* XINERAMA */ |
1776 #endif /* XINERAMA */ |
1820 /* default monitor setup */ |
1777 /* default monitor setup */ |
1821 { |
1778 { |
1822 m->num = 0; |
1779 if(!mons) |
1823 m->mx = m->wx = 0; |
1780 mons = createmon(); |
1824 m->my = m->wy = 0; |
1781 if(mons->mw != sw || mons->mh != sh) { |
1825 m->mw = m->ww = sw; |
1782 dirty = True; |
1826 m->mh = m->wh = sh; |
1783 mons->mw = mons->ww = sw; |
1827 } |
1784 mons->mh = mons->wh = sh; |
1828 /* bar geometry setup */ |
1785 updatebarpos(mons); |
1829 for(m = newmons; m; m = m->next) { |
1786 } |
1830 m->sel = m->stack = m->clients = NULL; |
1787 } |
1831 m->seltags = 0; |
1788 if(dirty) { |
1832 m->sellt = 0; |
1789 selmon = mons; |
1833 m->tagset[0] = m->tagset[1] = 1; |
1790 selmon = wintomon(root); |
1834 m->mfact = mfact; |
1791 } |
1835 m->showbar = showbar; |
1792 return dirty; |
1836 m->topbar = topbar; |
|
1837 m->lt[0] = &layouts[0]; |
|
1838 m->lt[1] = &layouts[1 % LENGTH(layouts)]; |
|
1839 m->ltsymbol = layouts[0].symbol; |
|
1840 updatebarpos(m); |
|
1841 } |
|
1842 /* reassign left over clients of disappeared monitors */ |
|
1843 for(tm = mons; tm; tm = tm->next) |
|
1844 while(tm->clients) { |
|
1845 c = tm->clients; |
|
1846 tm->clients = c->next; |
|
1847 detachstack(c); |
|
1848 c->mon = newmons; |
|
1849 attach(c); |
|
1850 attachstack(c); |
|
1851 } |
|
1852 /* select focused monitor */ |
|
1853 cleanupmons(); |
|
1854 selmon = mons = newmons; |
|
1855 selmon = wintomon(root); |
|
1856 return True; |
|
1857 } |
1793 } |
1858 |
1794 |
1859 void |
1795 void |
1860 updatenumlockmask(void) { |
1796 updatenumlockmask(void) { |
1861 unsigned int i, j; |
1797 unsigned int i, j; |