105b261ecSmrg/*
205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
305b261ecSmrg *
405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining
505b261ecSmrg * a copy of this software and associated documentation files (the
605b261ecSmrg *"Software"), to deal in the Software without restriction, including
705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish,
805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to
905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to
1005b261ecSmrg *the following conditions:
1105b261ecSmrg *
1205b261ecSmrg *The above copyright notice and this permission notice shall be
1305b261ecSmrg *included in all copies or substantial portions of the Software.
1405b261ecSmrg *
1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2205b261ecSmrg *
2305b261ecSmrg *Except as contained in this notice, the name of the XFree86 Project
2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use
2505b261ecSmrg *or other dealings in this Software without prior written authorization
2605b261ecSmrg *from the XFree86 Project.
2705b261ecSmrg *
2805b261ecSmrg * Authors:     Earle F. Philhower, III
2905b261ecSmrg */
3005b261ecSmrg
3105b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H
3205b261ecSmrg#include <xwin-config.h>
3305b261ecSmrg#endif
3405b261ecSmrg#include <X11/Xatom.h>
3505b261ecSmrg#include "propertyst.h"
3605b261ecSmrg#include "windowstr.h"
3705b261ecSmrg#include "winmultiwindowclass.h"
3805b261ecSmrg#include "win.h"
3905b261ecSmrg
4005b261ecSmrg/*
4105b261ecSmrg * Local function
4205b261ecSmrg */
4305b261ecSmrg
4405b261ecSmrgDEFINE_ATOM_HELPER(AtmWmWindowRole, "WM_WINDOW_ROLE")
4505b261ecSmrg
4605b261ecSmrgint
4735c4bbdfSmrgwinMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
4805b261ecSmrg{
4935c4bbdfSmrg    struct _Window *pwin;
5035c4bbdfSmrg    struct _Property *prop;
5135c4bbdfSmrg    int len_name, len_class;
5235c4bbdfSmrg
5335c4bbdfSmrg    if (!pWin || !res_name || !res_class) {
5435c4bbdfSmrg        ErrorF("winMultiWindowGetClassHint - pWin, res_name, or res_class was "
5535c4bbdfSmrg               "NULL\n");
5635c4bbdfSmrg        return 0;
5705b261ecSmrg    }
5835c4bbdfSmrg
5935c4bbdfSmrg    pwin = (struct _Window *) pWin;
6035c4bbdfSmrg
6135c4bbdfSmrg    if (pwin->optional)
6235c4bbdfSmrg        prop = (struct _Property *) pwin->optional->userProps;
6335c4bbdfSmrg    else
6435c4bbdfSmrg        prop = NULL;
6535c4bbdfSmrg
6635c4bbdfSmrg    *res_name = *res_class = NULL;
6735c4bbdfSmrg
6835c4bbdfSmrg    while (prop) {
6935c4bbdfSmrg        if (prop->propertyName == XA_WM_CLASS
7035c4bbdfSmrg            && prop->type == XA_STRING && prop->format == 8 && prop->data) {
7135c4bbdfSmrg            /*
7235c4bbdfSmrg              WM_CLASS property should consist of 2 null terminated strings, but we
7335c4bbdfSmrg              must handle the cases when one or both is absent or not null terminated
7435c4bbdfSmrg            */
7535c4bbdfSmrg            len_name = strlen((char *) prop->data);
7635c4bbdfSmrg            if (len_name > prop->size) len_name = prop->size;
7735c4bbdfSmrg
7835c4bbdfSmrg            (*res_name) = malloc(len_name + 1);
7935c4bbdfSmrg
8035c4bbdfSmrg            if (!*res_name) {
8135c4bbdfSmrg                ErrorF("winMultiWindowGetClassHint - *res_name was NULL\n");
8235c4bbdfSmrg                return 0;
8335c4bbdfSmrg            }
8435c4bbdfSmrg
8535c4bbdfSmrg            /* Copy name and ensure null terminated */
8635c4bbdfSmrg            strncpy((*res_name), prop->data, len_name);
8735c4bbdfSmrg            (*res_name)[len_name] = '\0';
8835c4bbdfSmrg
8935c4bbdfSmrg            /* Compute length of class name, it could be that it is absent or not null terminated */
9035c4bbdfSmrg            len_class = (len_name >= prop->size) ? 0 : (strlen(((char *) prop->data) + 1 + len_name));
9135c4bbdfSmrg            if (len_class > prop->size - 1 - len_name) len_class = prop->size - 1 - len_name;
9235c4bbdfSmrg
9335c4bbdfSmrg            (*res_class) = malloc(len_class + 1);
9435c4bbdfSmrg
9535c4bbdfSmrg            if (!*res_class) {
9635c4bbdfSmrg                ErrorF("winMultiWindowGetClassHint - *res_class was NULL\n");
9735c4bbdfSmrg
9835c4bbdfSmrg                /* Free the previously allocated res_name */
9935c4bbdfSmrg                free(*res_name);
10035c4bbdfSmrg                return 0;
10135c4bbdfSmrg            }
10235c4bbdfSmrg
10335c4bbdfSmrg            /* Copy class name and ensure null terminated */
10435c4bbdfSmrg            strncpy((*res_class), ((char *) prop->data) + 1 + len_name, len_class);
10535c4bbdfSmrg            (*res_class)[len_class] = '\0';
10635c4bbdfSmrg
10735c4bbdfSmrg            return 1;
10835c4bbdfSmrg        }
10935c4bbdfSmrg        else
11035c4bbdfSmrg            prop = prop->next;
11105b261ecSmrg    }
11205b261ecSmrg
11335c4bbdfSmrg    return 0;
11435c4bbdfSmrg}
11505b261ecSmrg
11605b261ecSmrgint
11735c4bbdfSmrgwinMultiWindowGetWMHints(WindowPtr pWin, WinXWMHints * hints)
11805b261ecSmrg{
11935c4bbdfSmrg    struct _Window *pwin;
12035c4bbdfSmrg    struct _Property *prop;
12105b261ecSmrg
12235c4bbdfSmrg    if (!pWin || !hints) {
12335c4bbdfSmrg        ErrorF("winMultiWindowGetWMHints - pWin or hints was NULL\n");
12435c4bbdfSmrg        return 0;
12505b261ecSmrg    }
12605b261ecSmrg
12735c4bbdfSmrg    pwin = (struct _Window *) pWin;
12835c4bbdfSmrg
12935c4bbdfSmrg    if (pwin->optional)
13035c4bbdfSmrg        prop = (struct _Property *) pwin->optional->userProps;
13135c4bbdfSmrg    else
13235c4bbdfSmrg        prop = NULL;
13335c4bbdfSmrg
13435c4bbdfSmrg    memset(hints, 0, sizeof(WinXWMHints));
13535c4bbdfSmrg
13635c4bbdfSmrg    while (prop) {
13735c4bbdfSmrg        if (prop->propertyName == XA_WM_HINTS && prop->data) {
13835c4bbdfSmrg            memcpy(hints, prop->data, sizeof(WinXWMHints));
13935c4bbdfSmrg            return 1;
14035c4bbdfSmrg        }
14135c4bbdfSmrg        else
14235c4bbdfSmrg            prop = prop->next;
14305b261ecSmrg    }
14405b261ecSmrg
14535c4bbdfSmrg    return 0;
14635c4bbdfSmrg}
14705b261ecSmrg
14805b261ecSmrgint
14935c4bbdfSmrgwinMultiWindowGetWindowRole(WindowPtr pWin, char **res_role)
15005b261ecSmrg{
15135c4bbdfSmrg    struct _Window *pwin;
15235c4bbdfSmrg    struct _Property *prop;
15335c4bbdfSmrg    int len_role;
15435c4bbdfSmrg
15535c4bbdfSmrg    if (!pWin || !res_role)
15635c4bbdfSmrg        return 0;
15735c4bbdfSmrg
15835c4bbdfSmrg    pwin = (struct _Window *) pWin;
15935c4bbdfSmrg
16035c4bbdfSmrg    if (pwin->optional)
16135c4bbdfSmrg        prop = (struct _Property *) pwin->optional->userProps;
16235c4bbdfSmrg    else
16335c4bbdfSmrg        prop = NULL;
16435c4bbdfSmrg
16535c4bbdfSmrg    *res_role = NULL;
16635c4bbdfSmrg    while (prop) {
16735c4bbdfSmrg        if (prop->propertyName == AtmWmWindowRole()
16835c4bbdfSmrg            && prop->type == XA_STRING && prop->format == 8 && prop->data) {
16935c4bbdfSmrg            len_role = prop->size;
17035c4bbdfSmrg
17135c4bbdfSmrg            (*res_role) = malloc(len_role + 1);
17235c4bbdfSmrg
17335c4bbdfSmrg            if (!*res_role) {
17435c4bbdfSmrg                ErrorF("winMultiWindowGetWindowRole - *res_role was NULL\n");
17535c4bbdfSmrg                return 0;
17635c4bbdfSmrg            }
17735c4bbdfSmrg
17835c4bbdfSmrg            strncpy((*res_role), prop->data, len_role);
17935c4bbdfSmrg            (*res_role)[len_role] = 0;
18035c4bbdfSmrg
18135c4bbdfSmrg            return 1;
18235c4bbdfSmrg        }
18335c4bbdfSmrg        else
18435c4bbdfSmrg            prop = prop->next;
18505b261ecSmrg    }
18605b261ecSmrg
18735c4bbdfSmrg    return 0;
18835c4bbdfSmrg}
18905b261ecSmrg
19005b261ecSmrgint
19135c4bbdfSmrgwinMultiWindowGetWMNormalHints(WindowPtr pWin, WinXSizeHints * hints)
19205b261ecSmrg{
19335c4bbdfSmrg    struct _Window *pwin;
19435c4bbdfSmrg    struct _Property *prop;
19505b261ecSmrg
19635c4bbdfSmrg    if (!pWin || !hints) {
19735c4bbdfSmrg        ErrorF("winMultiWindowGetWMNormalHints - pWin or hints was NULL\n");
19835c4bbdfSmrg        return 0;
19905b261ecSmrg    }
20005b261ecSmrg
20135c4bbdfSmrg    pwin = (struct _Window *) pWin;
20235c4bbdfSmrg
20335c4bbdfSmrg    if (pwin->optional)
20435c4bbdfSmrg        prop = (struct _Property *) pwin->optional->userProps;
20535c4bbdfSmrg    else
20635c4bbdfSmrg        prop = NULL;
20735c4bbdfSmrg
20835c4bbdfSmrg    memset(hints, 0, sizeof(WinXSizeHints));
20935c4bbdfSmrg
21035c4bbdfSmrg    while (prop) {
21135c4bbdfSmrg        if (prop->propertyName == XA_WM_NORMAL_HINTS && prop->data) {
21235c4bbdfSmrg            memcpy(hints, prop->data, sizeof(WinXSizeHints));
21335c4bbdfSmrg            return 1;
21435c4bbdfSmrg        }
21535c4bbdfSmrg        else
21635c4bbdfSmrg            prop = prop->next;
21705b261ecSmrg    }
21805b261ecSmrg
21935c4bbdfSmrg    return 0;
22005b261ecSmrg}
22105b261ecSmrg
22205b261ecSmrgint
22335c4bbdfSmrgwinMultiWindowGetTransientFor(WindowPtr pWin, Window *pDaddyId)
22405b261ecSmrg{
22535c4bbdfSmrg    struct _Window *pwin;
22635c4bbdfSmrg    struct _Property *prop;
22705b261ecSmrg
22835c4bbdfSmrg    if (!pWin) {
22935c4bbdfSmrg        ErrorF("winMultiWindowGetTransientFor - pWin was NULL\n");
23035c4bbdfSmrg        return 0;
23105b261ecSmrg    }
23205b261ecSmrg
23335c4bbdfSmrg    pwin = (struct _Window *) pWin;
23405b261ecSmrg
23535c4bbdfSmrg    if (pwin->optional)
23635c4bbdfSmrg        prop = (struct _Property *) pwin->optional->userProps;
23735c4bbdfSmrg    else
23835c4bbdfSmrg        prop = NULL;
23905b261ecSmrg
24035c4bbdfSmrg    if (pDaddyId)
24135c4bbdfSmrg        *pDaddyId = 0;
24205b261ecSmrg
24335c4bbdfSmrg    while (prop) {
24435c4bbdfSmrg        if (prop->propertyName == XA_WM_TRANSIENT_FOR) {
24535c4bbdfSmrg            if (pDaddyId)
24635c4bbdfSmrg                memcpy(pDaddyId, prop->data, sizeof(Window));
24735c4bbdfSmrg            return 1;
24805b261ecSmrg        }
24935c4bbdfSmrg        else
25035c4bbdfSmrg            prop = prop->next;
25105b261ecSmrg    }
25205b261ecSmrg
25335c4bbdfSmrg    return 0;
25405b261ecSmrg}
25505b261ecSmrg
25605b261ecSmrgint
25735c4bbdfSmrgwinMultiWindowGetWMName(WindowPtr pWin, char **wmName)
25805b261ecSmrg{
25935c4bbdfSmrg    struct _Window *pwin;
26035c4bbdfSmrg    struct _Property *prop;
26135c4bbdfSmrg    int len_name;
26235c4bbdfSmrg
26335c4bbdfSmrg    if (!pWin || !wmName) {
26435c4bbdfSmrg        ErrorF("winMultiWindowGetClassHint - pWin, res_name, or res_class was "
26535c4bbdfSmrg               "NULL\n");
26635c4bbdfSmrg        return 0;
26705b261ecSmrg    }
26835c4bbdfSmrg
26935c4bbdfSmrg    pwin = (struct _Window *) pWin;
27035c4bbdfSmrg
27135c4bbdfSmrg    if (pwin->optional)
27235c4bbdfSmrg        prop = (struct _Property *) pwin->optional->userProps;
27335c4bbdfSmrg    else
27435c4bbdfSmrg        prop = NULL;
27535c4bbdfSmrg
27635c4bbdfSmrg    *wmName = NULL;
27735c4bbdfSmrg
27835c4bbdfSmrg    while (prop) {
27935c4bbdfSmrg        if (prop->propertyName == XA_WM_NAME
28035c4bbdfSmrg            && prop->type == XA_STRING && prop->data) {
28135c4bbdfSmrg            len_name = prop->size;
28235c4bbdfSmrg
28335c4bbdfSmrg            (*wmName) = malloc(len_name + 1);
28435c4bbdfSmrg
28535c4bbdfSmrg            if (!*wmName) {
28635c4bbdfSmrg                ErrorF("winMultiWindowGetWMName - *wmName was NULL\n");
28735c4bbdfSmrg                return 0;
28835c4bbdfSmrg            }
28935c4bbdfSmrg
29035c4bbdfSmrg            strncpy((*wmName), prop->data, len_name);
29135c4bbdfSmrg            (*wmName)[len_name] = 0;
29235c4bbdfSmrg
29335c4bbdfSmrg            return 1;
29435c4bbdfSmrg        }
29535c4bbdfSmrg        else
29635c4bbdfSmrg            prop = prop->next;
29705b261ecSmrg    }
29835c4bbdfSmrg
29935c4bbdfSmrg    return 0;
30005b261ecSmrg}
301